Fix backtest spot
This commit is contained in:
@@ -536,7 +536,7 @@ public class AgentGrain : Grain, IAgentGrain
|
||||
}
|
||||
|
||||
// Check each bot for open positions
|
||||
foreach (var botEntry in userBots)
|
||||
foreach (var botEntry in userBots.Where(b => b.Status == BotStatus.Running))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -173,6 +173,18 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
|
||||
{
|
||||
// Handle fallback for empty AccountName before creating the trading bot instance
|
||||
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))
|
||||
{
|
||||
// Fallback: Get the first account for the user
|
||||
@@ -531,7 +543,7 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger<TradingBotBase>>();
|
||||
var streamProvider = this.GetStreamProvider("ManagingStreamProvider");
|
||||
|
||||
|
||||
// Create the trading bot instance based on TradingType
|
||||
TradingBotBase tradingBot = config.TradingType switch
|
||||
{
|
||||
|
||||
@@ -33,6 +33,12 @@ public class BundleBacktestUniversalConfig
|
||||
[Required]
|
||||
public string BotName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The type of trading (spot or futures)
|
||||
/// </summary>
|
||||
[Required]
|
||||
public TradingType TradingType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to flip positions
|
||||
/// </summary>
|
||||
|
||||
@@ -3986,45 +3986,6 @@ export class TradingClient extends AuthorizedApiBase {
|
||||
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> {
|
||||
let url_ = this.baseUrl + "/Trading/OpenPosition?";
|
||||
if (accountName !== undefined && accountName !== null)
|
||||
@@ -4883,7 +4844,7 @@ export interface TradingBotConfig {
|
||||
timeframe: Timeframe;
|
||||
isForWatchingOnly: boolean;
|
||||
botTradingBalance: number;
|
||||
isForBacktest: boolean;
|
||||
tradingType: TradingType;
|
||||
cooldownPeriod: number;
|
||||
maxLossStreak: number;
|
||||
flipPosition: boolean;
|
||||
@@ -4921,6 +4882,13 @@ export enum Timeframe {
|
||||
OneMinute = "OneMinute",
|
||||
}
|
||||
|
||||
export enum TradingType {
|
||||
Futures = "Futures",
|
||||
BacktestFutures = "BacktestFutures",
|
||||
BacktestSpot = "BacktestSpot",
|
||||
Spot = "Spot",
|
||||
}
|
||||
|
||||
export interface RiskManagement {
|
||||
adverseProbabilityThreshold: number;
|
||||
favorableProbabilityThreshold: number;
|
||||
@@ -5022,6 +4990,7 @@ export interface Position {
|
||||
user: User;
|
||||
initiatorIdentifier: string;
|
||||
recoveryAttempted?: boolean;
|
||||
tradingType?: TradingType;
|
||||
}
|
||||
|
||||
export enum TradeDirection {
|
||||
@@ -5332,6 +5301,7 @@ export interface BundleBacktestUniversalConfig {
|
||||
flipPosition: boolean;
|
||||
cooldownPeriod?: number | null;
|
||||
maxLossStreak?: number;
|
||||
tradingType?: TradingType;
|
||||
scenario?: ScenarioRequest | null;
|
||||
scenarioName?: string | null;
|
||||
maxPositionTimeHours?: number | null;
|
||||
|
||||
@@ -349,7 +349,7 @@ export interface TradingBotConfig {
|
||||
timeframe: Timeframe;
|
||||
isForWatchingOnly: boolean;
|
||||
botTradingBalance: number;
|
||||
isForBacktest: boolean;
|
||||
tradingType: TradingType;
|
||||
cooldownPeriod: number;
|
||||
maxLossStreak: number;
|
||||
flipPosition: boolean;
|
||||
@@ -387,6 +387,13 @@ export enum Timeframe {
|
||||
OneMinute = "OneMinute",
|
||||
}
|
||||
|
||||
export enum TradingType {
|
||||
Futures = "Futures",
|
||||
BacktestFutures = "BacktestFutures",
|
||||
BacktestSpot = "BacktestSpot",
|
||||
Spot = "Spot",
|
||||
}
|
||||
|
||||
export interface RiskManagement {
|
||||
adverseProbabilityThreshold: number;
|
||||
favorableProbabilityThreshold: number;
|
||||
@@ -488,6 +495,7 @@ export interface Position {
|
||||
user: User;
|
||||
initiatorIdentifier: string;
|
||||
recoveryAttempted?: boolean;
|
||||
tradingType?: TradingType;
|
||||
}
|
||||
|
||||
export enum TradeDirection {
|
||||
|
||||
@@ -13,7 +13,8 @@ import {
|
||||
RunBundleBacktestRequest,
|
||||
SignalType,
|
||||
Ticker,
|
||||
Timeframe
|
||||
Timeframe,
|
||||
TradingType
|
||||
} from '../../generated/ManagingApi';
|
||||
import useApiUrlStore from '../../app/store/apiStore';
|
||||
import Toast from '../../components/mollecules/Toast/Toast';
|
||||
@@ -49,6 +50,7 @@ const BundleRequestModal: React.FC<BundleRequestModalProps> = ({
|
||||
const [selectedTimeframe, setSelectedTimeframe] = useState<Timeframe>(Timeframe.FifteenMinutes);
|
||||
const [selectedTickers, setSelectedTickers] = useState<Ticker[]>([]);
|
||||
const [startingCapital, setStartingCapital] = useState<number>(10000);
|
||||
const [selectedTradingType, setSelectedTradingType] = useState<TradingType>(TradingType.BacktestSpot);
|
||||
|
||||
// Advanced parameters state
|
||||
const [cooldownPeriod, setCooldownPeriod] = useState<number>(0);
|
||||
@@ -220,6 +222,7 @@ const BundleRequestModal: React.FC<BundleRequestModalProps> = ({
|
||||
flipPosition: flipPosition,
|
||||
cooldownPeriod: cooldownPeriod,
|
||||
maxLossStreak: maxLossStreak,
|
||||
tradingType: selectedTradingType,
|
||||
scenario: scenario ? {
|
||||
name: scenario.name || 'Custom Scenario',
|
||||
indicators: (scenario.indicators || []).map(indicator => ({
|
||||
@@ -516,6 +519,19 @@ const BundleRequestModal: React.FC<BundleRequestModalProps> = ({
|
||||
</select>
|
||||
</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 */}
|
||||
<div>
|
||||
<h4 className="font-semibold mb-2">Choose your money management approach(s)</h4>
|
||||
|
||||
Reference in New Issue
Block a user