Fix backtest spot
This commit is contained in:
@@ -536,7 +536,7 @@ public class AgentGrain : Grain, IAgentGrain
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check each bot for open positions
|
// Check each bot for open positions
|
||||||
foreach (var botEntry in userBots)
|
foreach (var botEntry in userBots.Where(b => b.Status == BotStatus.Running))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -173,6 +173,18 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
|
|||||||
{
|
{
|
||||||
// Handle fallback for empty AccountName before creating the trading bot instance
|
// Handle fallback for empty AccountName before creating the trading bot instance
|
||||||
var config = _state.State.Config;
|
var config = _state.State.Config;
|
||||||
|
|
||||||
|
if (config.TradingType == TradingType.BacktestFutures)
|
||||||
|
{
|
||||||
|
config.TradingType = TradingType.Futures;
|
||||||
|
_state.State.Config = config;
|
||||||
|
}
|
||||||
|
else if (config.TradingType == TradingType.BacktestSpot)
|
||||||
|
{
|
||||||
|
config.TradingType = TradingType.Spot;
|
||||||
|
_state.State.Config = config;
|
||||||
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(config.AccountName))
|
if (string.IsNullOrEmpty(config.AccountName))
|
||||||
{
|
{
|
||||||
// Fallback: Get the first account for the user
|
// Fallback: Get the first account for the user
|
||||||
@@ -531,7 +543,7 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
|
|||||||
using var scope = _scopeFactory.CreateScope();
|
using var scope = _scopeFactory.CreateScope();
|
||||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger<TradingBotBase>>();
|
var logger = scope.ServiceProvider.GetRequiredService<ILogger<TradingBotBase>>();
|
||||||
var streamProvider = this.GetStreamProvider("ManagingStreamProvider");
|
var streamProvider = this.GetStreamProvider("ManagingStreamProvider");
|
||||||
|
|
||||||
// Create the trading bot instance based on TradingType
|
// Create the trading bot instance based on TradingType
|
||||||
TradingBotBase tradingBot = config.TradingType switch
|
TradingBotBase tradingBot = config.TradingType switch
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,6 +33,12 @@ public class BundleBacktestUniversalConfig
|
|||||||
[Required]
|
[Required]
|
||||||
public string BotName { get; set; } = string.Empty;
|
public string BotName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The type of trading (spot or futures)
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public TradingType TradingType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether to flip positions
|
/// Whether to flip positions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -3986,45 +3986,6 @@ export class TradingClient extends AuthorizedApiBase {
|
|||||||
return Promise.resolve<Trade>(null as any);
|
return Promise.resolve<Trade>(null as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
trading_ClosePosition(identifier: string | undefined): Promise<Position> {
|
|
||||||
let url_ = this.baseUrl + "/Trading/ClosePosition?";
|
|
||||||
if (identifier === null)
|
|
||||||
throw new Error("The parameter 'identifier' cannot be null.");
|
|
||||||
else if (identifier !== undefined)
|
|
||||||
url_ += "identifier=" + encodeURIComponent("" + identifier) + "&";
|
|
||||||
url_ = url_.replace(/[?&]$/, "");
|
|
||||||
|
|
||||||
let options_: RequestInit = {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Accept": "application/json"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.transformOptions(options_).then(transformedOptions_ => {
|
|
||||||
return this.http.fetch(url_, transformedOptions_);
|
|
||||||
}).then((_response: Response) => {
|
|
||||||
return this.processTrading_ClosePosition(_response);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected processTrading_ClosePosition(response: Response): Promise<Position> {
|
|
||||||
const status = response.status;
|
|
||||||
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
|
|
||||||
if (status === 200) {
|
|
||||||
return response.text().then((_responseText) => {
|
|
||||||
let result200: any = null;
|
|
||||||
result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as Position;
|
|
||||||
return result200;
|
|
||||||
});
|
|
||||||
} else if (status !== 200 && status !== 204) {
|
|
||||||
return response.text().then((_responseText) => {
|
|
||||||
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Promise.resolve<Position>(null as any);
|
|
||||||
}
|
|
||||||
|
|
||||||
trading_Trade(accountName: string | null | undefined, moneyManagementName: string | null | undefined, direction: TradeDirection | undefined, ticker: Ticker | undefined, riskLevel: RiskLevel | undefined, isForPaperTrading: boolean | undefined, openPrice: number | null | undefined, moneyManagement: MoneyManagement | undefined): Promise<Position> {
|
trading_Trade(accountName: string | null | undefined, moneyManagementName: string | null | undefined, direction: TradeDirection | undefined, ticker: Ticker | undefined, riskLevel: RiskLevel | undefined, isForPaperTrading: boolean | undefined, openPrice: number | null | undefined, moneyManagement: MoneyManagement | undefined): Promise<Position> {
|
||||||
let url_ = this.baseUrl + "/Trading/OpenPosition?";
|
let url_ = this.baseUrl + "/Trading/OpenPosition?";
|
||||||
if (accountName !== undefined && accountName !== null)
|
if (accountName !== undefined && accountName !== null)
|
||||||
@@ -4883,7 +4844,7 @@ export interface TradingBotConfig {
|
|||||||
timeframe: Timeframe;
|
timeframe: Timeframe;
|
||||||
isForWatchingOnly: boolean;
|
isForWatchingOnly: boolean;
|
||||||
botTradingBalance: number;
|
botTradingBalance: number;
|
||||||
isForBacktest: boolean;
|
tradingType: TradingType;
|
||||||
cooldownPeriod: number;
|
cooldownPeriod: number;
|
||||||
maxLossStreak: number;
|
maxLossStreak: number;
|
||||||
flipPosition: boolean;
|
flipPosition: boolean;
|
||||||
@@ -4921,6 +4882,13 @@ export enum Timeframe {
|
|||||||
OneMinute = "OneMinute",
|
OneMinute = "OneMinute",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum TradingType {
|
||||||
|
Futures = "Futures",
|
||||||
|
BacktestFutures = "BacktestFutures",
|
||||||
|
BacktestSpot = "BacktestSpot",
|
||||||
|
Spot = "Spot",
|
||||||
|
}
|
||||||
|
|
||||||
export interface RiskManagement {
|
export interface RiskManagement {
|
||||||
adverseProbabilityThreshold: number;
|
adverseProbabilityThreshold: number;
|
||||||
favorableProbabilityThreshold: number;
|
favorableProbabilityThreshold: number;
|
||||||
@@ -5022,6 +4990,7 @@ export interface Position {
|
|||||||
user: User;
|
user: User;
|
||||||
initiatorIdentifier: string;
|
initiatorIdentifier: string;
|
||||||
recoveryAttempted?: boolean;
|
recoveryAttempted?: boolean;
|
||||||
|
tradingType?: TradingType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TradeDirection {
|
export enum TradeDirection {
|
||||||
@@ -5332,6 +5301,7 @@ export interface BundleBacktestUniversalConfig {
|
|||||||
flipPosition: boolean;
|
flipPosition: boolean;
|
||||||
cooldownPeriod?: number | null;
|
cooldownPeriod?: number | null;
|
||||||
maxLossStreak?: number;
|
maxLossStreak?: number;
|
||||||
|
tradingType?: TradingType;
|
||||||
scenario?: ScenarioRequest | null;
|
scenario?: ScenarioRequest | null;
|
||||||
scenarioName?: string | null;
|
scenarioName?: string | null;
|
||||||
maxPositionTimeHours?: number | null;
|
maxPositionTimeHours?: number | null;
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ export interface TradingBotConfig {
|
|||||||
timeframe: Timeframe;
|
timeframe: Timeframe;
|
||||||
isForWatchingOnly: boolean;
|
isForWatchingOnly: boolean;
|
||||||
botTradingBalance: number;
|
botTradingBalance: number;
|
||||||
isForBacktest: boolean;
|
tradingType: TradingType;
|
||||||
cooldownPeriod: number;
|
cooldownPeriod: number;
|
||||||
maxLossStreak: number;
|
maxLossStreak: number;
|
||||||
flipPosition: boolean;
|
flipPosition: boolean;
|
||||||
@@ -387,6 +387,13 @@ export enum Timeframe {
|
|||||||
OneMinute = "OneMinute",
|
OneMinute = "OneMinute",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum TradingType {
|
||||||
|
Futures = "Futures",
|
||||||
|
BacktestFutures = "BacktestFutures",
|
||||||
|
BacktestSpot = "BacktestSpot",
|
||||||
|
Spot = "Spot",
|
||||||
|
}
|
||||||
|
|
||||||
export interface RiskManagement {
|
export interface RiskManagement {
|
||||||
adverseProbabilityThreshold: number;
|
adverseProbabilityThreshold: number;
|
||||||
favorableProbabilityThreshold: number;
|
favorableProbabilityThreshold: number;
|
||||||
@@ -488,6 +495,7 @@ export interface Position {
|
|||||||
user: User;
|
user: User;
|
||||||
initiatorIdentifier: string;
|
initiatorIdentifier: string;
|
||||||
recoveryAttempted?: boolean;
|
recoveryAttempted?: boolean;
|
||||||
|
tradingType?: TradingType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TradeDirection {
|
export enum TradeDirection {
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ import {
|
|||||||
RunBundleBacktestRequest,
|
RunBundleBacktestRequest,
|
||||||
SignalType,
|
SignalType,
|
||||||
Ticker,
|
Ticker,
|
||||||
Timeframe
|
Timeframe,
|
||||||
|
TradingType
|
||||||
} from '../../generated/ManagingApi';
|
} from '../../generated/ManagingApi';
|
||||||
import useApiUrlStore from '../../app/store/apiStore';
|
import useApiUrlStore from '../../app/store/apiStore';
|
||||||
import Toast from '../../components/mollecules/Toast/Toast';
|
import Toast from '../../components/mollecules/Toast/Toast';
|
||||||
@@ -49,6 +50,7 @@ const BundleRequestModal: React.FC<BundleRequestModalProps> = ({
|
|||||||
const [selectedTimeframe, setSelectedTimeframe] = useState<Timeframe>(Timeframe.FifteenMinutes);
|
const [selectedTimeframe, setSelectedTimeframe] = useState<Timeframe>(Timeframe.FifteenMinutes);
|
||||||
const [selectedTickers, setSelectedTickers] = useState<Ticker[]>([]);
|
const [selectedTickers, setSelectedTickers] = useState<Ticker[]>([]);
|
||||||
const [startingCapital, setStartingCapital] = useState<number>(10000);
|
const [startingCapital, setStartingCapital] = useState<number>(10000);
|
||||||
|
const [selectedTradingType, setSelectedTradingType] = useState<TradingType>(TradingType.BacktestSpot);
|
||||||
|
|
||||||
// Advanced parameters state
|
// Advanced parameters state
|
||||||
const [cooldownPeriod, setCooldownPeriod] = useState<number>(0);
|
const [cooldownPeriod, setCooldownPeriod] = useState<number>(0);
|
||||||
@@ -220,6 +222,7 @@ const BundleRequestModal: React.FC<BundleRequestModalProps> = ({
|
|||||||
flipPosition: flipPosition,
|
flipPosition: flipPosition,
|
||||||
cooldownPeriod: cooldownPeriod,
|
cooldownPeriod: cooldownPeriod,
|
||||||
maxLossStreak: maxLossStreak,
|
maxLossStreak: maxLossStreak,
|
||||||
|
tradingType: selectedTradingType,
|
||||||
scenario: scenario ? {
|
scenario: scenario ? {
|
||||||
name: scenario.name || 'Custom Scenario',
|
name: scenario.name || 'Custom Scenario',
|
||||||
indicators: (scenario.indicators || []).map(indicator => ({
|
indicators: (scenario.indicators || []).map(indicator => ({
|
||||||
@@ -516,6 +519,19 @@ const BundleRequestModal: React.FC<BundleRequestModalProps> = ({
|
|||||||
</select>
|
</select>
|
||||||
</FormInput>
|
</FormInput>
|
||||||
|
|
||||||
|
{/* Trading Type Selection */}
|
||||||
|
<FormInput label="Select trading type" htmlFor="tradingType">
|
||||||
|
<p className="text-sm text-gray-600 mb-2">Choose between spot or futures backtesting</p>
|
||||||
|
<select
|
||||||
|
className="select select-bordered w-full"
|
||||||
|
value={selectedTradingType}
|
||||||
|
onChange={(e) => setSelectedTradingType(e.target.value as TradingType)}
|
||||||
|
>
|
||||||
|
<option value={TradingType.BacktestSpot}>Spot</option>
|
||||||
|
<option value={TradingType.BacktestFutures}>Futures</option>
|
||||||
|
</select>
|
||||||
|
</FormInput>
|
||||||
|
|
||||||
{/* Money Management Variants */}
|
{/* Money Management Variants */}
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-semibold mb-2">Choose your money management approach(s)</h4>
|
<h4 className="font-semibold mb-2">Choose your money management approach(s)</h4>
|
||||||
|
|||||||
Reference in New Issue
Block a user