Update vitejs + fix bot saving

This commit is contained in:
2025-05-11 20:23:06 +07:00
parent 65c4ec4957
commit 84e09b32a2
20 changed files with 220 additions and 238 deletions

6
package-lock.json generated Normal file
View File

@@ -0,0 +1,6 @@
{
"name": "managing-apps",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}

View File

@@ -125,7 +125,7 @@ public class BacktestController : BaseController
DateTime endDate, DateTime endDate,
MoneyManagement? moneyManagement = null, MoneyManagement? moneyManagement = null,
bool save = false, bool save = false,
decimal cooldownPeriod = 1, int cooldownPeriod = 1,
int maxLossStreak = 0) int maxLossStreak = 0)
{ {
if (string.IsNullOrEmpty(accountName)) if (string.IsNullOrEmpty(accountName))

View File

@@ -1,9 +1,9 @@
using Managing.Application.Abstractions; using Managing.Application.Abstractions;
using Managing.Application.Abstractions.Services; using Managing.Application.Abstractions.Services;
using Managing.Application.Bots;
using Managing.Application.Hubs; using Managing.Application.Hubs;
using Managing.Application.ManageBot.Commands; using Managing.Application.ManageBot.Commands;
using Managing.Common; using Managing.Common;
using Managing.Domain.Bots;
using Managing.Domain.Trades; using Managing.Domain.Trades;
using MediatR; using MediatR;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
@@ -142,10 +142,13 @@ public class BotController : BaseController
BotTradingBalance = request.InitialTradingBalance, BotTradingBalance = request.InitialTradingBalance,
BotType = request.BotType, BotType = request.BotType,
CooldownPeriod = request.CooldownPeriod, CooldownPeriod = request.CooldownPeriod,
MaxLossStreak = request.MaxLossStreak MaxLossStreak = request.MaxLossStreak,
IsForBacktest = false,
FlipPosition = request.BotType == BotType.FlippingBot,
Name = request.Name
}; };
var result = await _mediator.Send(new StartBotCommand(config, request.Identifier, user)); var result = await _mediator.Send(new StartBotCommand(config, request.Name, user));
await NotifyBotSubscriberAsync(); await NotifyBotSubscriberAsync();
return Ok(result); return Ok(result);
@@ -627,4 +630,5 @@ public class StartBotRequest
public int CooldownPeriod { get; set; } public int CooldownPeriod { get; set; }
public int MaxLossStreak { get; set; } public int MaxLossStreak { get; set; }
public string Name { get; set; }
} }

View File

@@ -1,11 +1,11 @@
using Managing.Application.Abstractions; using Managing.Application.Abstractions;
using Managing.Application.Abstractions.Repositories; using Managing.Application.Abstractions.Repositories;
using Managing.Application.Abstractions.Services; using Managing.Application.Abstractions.Services;
using Managing.Application.Bots;
using Managing.Core; using Managing.Core;
using Managing.Core.FixedSizedQueue; using Managing.Core.FixedSizedQueue;
using Managing.Domain.Accounts; using Managing.Domain.Accounts;
using Managing.Domain.Backtests; using Managing.Domain.Backtests;
using Managing.Domain.Bots;
using Managing.Domain.Candles; using Managing.Domain.Candles;
using Managing.Domain.MoneyManagements; using Managing.Domain.MoneyManagements;
using Managing.Domain.Scenarios; using Managing.Domain.Scenarios;
@@ -86,10 +86,10 @@ namespace Managing.Application.Backtesting
var scalpingBot = _botFactory.CreateBacktestScalpingBot(config); var scalpingBot = _botFactory.CreateBacktestScalpingBot(config);
scalpingBot.LoadScenario(scenario.Name); scalpingBot.LoadScenario(scenario.Name);
scalpingBot.User = user;
await scalpingBot.LoadAccount(); await scalpingBot.LoadAccount();
var candles = initialCandles ?? GetCandles(account, ticker, timeframe, startDate, endDate); var candles = initialCandles ?? GetCandles(account, ticker, timeframe, startDate, endDate);
var result = GetBacktestingResult(ticker, scenario, timeframe, scalpingBot, candles, balance, account, var result = GetBacktestingResult(config, scalpingBot, candles);
moneyManagement);
if (user != null) if (user != null)
{ {
@@ -141,11 +141,11 @@ namespace Managing.Application.Backtesting
var flippingBot = _botFactory.CreateBacktestFlippingBot(config); var flippingBot = _botFactory.CreateBacktestFlippingBot(config);
flippingBot.LoadScenario(scenario.Name); flippingBot.LoadScenario(scenario.Name);
flippingBot.User = user;
await flippingBot.LoadAccount(); await flippingBot.LoadAccount();
var candles = initialCandles ?? GetCandles(account, ticker, timeframe, startDate, endDate); var candles = initialCandles ?? GetCandles(account, ticker, timeframe, startDate, endDate);
var result = GetBacktestingResult(ticker, scenario, timeframe, flippingBot, candles, balance, account, var result = GetBacktestingResult(config, flippingBot, candles);
moneyManagement);
if (user != null) if (user != null)
{ {
@@ -193,10 +193,10 @@ namespace Managing.Application.Backtesting
var bot = _botFactory.CreateBacktestScalpingBot(config); var bot = _botFactory.CreateBacktestScalpingBot(config);
bot.LoadScenario(scenario.Name); bot.LoadScenario(scenario.Name);
bot.User = user;
await bot.LoadAccount(); await bot.LoadAccount();
var result = GetBacktestingResult(ticker, scenario, timeframe, bot, candles, balance, account, var result = GetBacktestingResult(config, bot, candles);
moneyManagement);
if (user != null) if (user != null)
{ {
@@ -235,10 +235,10 @@ namespace Managing.Application.Backtesting
var bot = _botFactory.CreateBacktestFlippingBot(config); var bot = _botFactory.CreateBacktestFlippingBot(config);
bot.LoadScenario(scenario.Name); bot.LoadScenario(scenario.Name);
bot.User = user;
await bot.LoadAccount(); await bot.LoadAccount();
var result = GetBacktestingResult(ticker, scenario, timeframe, bot, candles, balance, account, var result = GetBacktestingResult(config, bot, candles);
moneyManagement);
if (user != null) if (user != null)
{ {
@@ -264,21 +264,16 @@ namespace Managing.Application.Backtesting
} }
private Backtest GetBacktestingResult( private Backtest GetBacktestingResult(
Ticker ticker, TradingBotConfig config,
Scenario scenario,
Timeframe timeframe,
ITradingBot bot, ITradingBot bot,
List<Candle> candles, List<Candle> candles)
decimal balance,
Account account,
MoneyManagement moneyManagement)
{ {
if (candles == null || candles.Count == 0) if (candles == null || candles.Count == 0)
{ {
throw new Exception("No candle to backtest"); throw new Exception("No candle to backtest");
} }
bot.WalletBalances.Add(candles.FirstOrDefault().Date, balance); bot.WalletBalances.Add(candles.FirstOrDefault().Date, config.BotTradingBalance);
foreach (var candle in candles) foreach (var candle in candles)
{ {
bot.OptimizedCandles.Enqueue(candle); bot.OptimizedCandles.Enqueue(candle);
@@ -294,9 +289,10 @@ namespace Managing.Application.Backtesting
var finalPnl = bot.GetProfitAndLoss(); var finalPnl = bot.GetProfitAndLoss();
var winRate = bot.GetWinRate(); var winRate = bot.GetWinRate();
var optimizedMoneyManagement = TradingBox.GetBestMoneyManagement(candles, bot.Positions, moneyManagement); var optimizedMoneyManagement =
TradingBox.GetBestMoneyManagement(candles, bot.Positions, config.MoneyManagement);
var stats = TradingHelpers.GetStatistics(bot.WalletBalances); var stats = TradingHelpers.GetStatistics(bot.WalletBalances);
var growthPercentage = TradingHelpers.GetGrowthFromInitalBalance(balance, finalPnl); var growthPercentage = TradingHelpers.GetGrowthFromInitalBalance(config.BotTradingBalance, finalPnl);
var hodlPercentage = TradingHelpers.GetHodlPercentage(candles[0], candles.Last()); var hodlPercentage = TradingHelpers.GetHodlPercentage(candles[0], candles.Last());
var scoringParams = new BacktestScoringParams( var scoringParams = new BacktestScoringParams(
@@ -313,8 +309,7 @@ namespace Managing.Application.Backtesting
var score = BacktestScorer.CalculateTotalScore(scoringParams); var score = BacktestScorer.CalculateTotalScore(scoringParams);
var result = new Backtest(ticker, scenario.Name, bot.Positions, bot.Signals.ToList(), timeframe, candles, var result = new Backtest(config, bot.Positions, bot.Signals.ToList(), candles)
bot.Config.BotType, account.Name)
{ {
FinalPnl = finalPnl, FinalPnl = finalPnl,
WinRate = winRate, WinRate = winRate,
@@ -324,7 +319,6 @@ namespace Managing.Application.Backtesting
WalletBalances = bot.WalletBalances.ToList(), WalletBalances = bot.WalletBalances.ToList(),
Statistics = stats, Statistics = stats,
OptimizedMoneyManagement = optimizedMoneyManagement, OptimizedMoneyManagement = optimizedMoneyManagement,
MoneyManagement = moneyManagement,
StrategiesValues = AggregateValues(strategiesValues, bot.StrategiesValues), StrategiesValues = AggregateValues(strategiesValues, bot.StrategiesValues),
Score = score Score = score
}; };
@@ -430,9 +424,9 @@ namespace Managing.Application.Backtesting
{ {
var candles = await _exchangeService.GetCandlesInflux( var candles = await _exchangeService.GetCandlesInflux(
user.Accounts.First().Exchange, user.Accounts.First().Exchange,
backtest.Ticker, backtest.Config.Ticker,
backtest.StartDate, backtest.StartDate,
backtest.Timeframe, backtest.Config.Timeframe,
backtest.EndDate); backtest.EndDate);
if (candles != null && candles.Count > 0) if (candles != null && candles.Count > 0)
@@ -465,14 +459,15 @@ namespace Managing.Application.Backtesting
try try
{ {
// Get the account // Get the account
var account = new Account { Name = backtest.AccountName, Exchange = TradingExchanges.Binance }; var account = new Account
{ Name = backtest.Config.AccountName, Exchange = TradingExchanges.Evm };
// Use the stored start and end dates to retrieve candles // Use the stored start and end dates to retrieve candles
var candles = _exchangeService.GetCandlesInflux( var candles = _exchangeService.GetCandlesInflux(
account.Exchange, account.Exchange,
backtest.Ticker, backtest.Config.Ticker,
backtest.StartDate, backtest.StartDate,
backtest.Timeframe, backtest.Config.Timeframe,
backtest.EndDate).Result; backtest.EndDate).Result;
if (candles != null && candles.Count > 0) if (candles != null && candles.Count > 0)

View File

@@ -1,5 +1,6 @@
using Managing.Application.Abstractions; using Managing.Application.Abstractions;
using Managing.Application.Abstractions.Services; using Managing.Application.Abstractions.Services;
using Managing.Domain.Bots;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using static Managing.Common.Enums; using static Managing.Common.Enums;

View File

@@ -1,5 +1,6 @@
using Managing.Application.Abstractions; using Managing.Application.Abstractions;
using Managing.Application.Abstractions.Services; using Managing.Application.Abstractions.Services;
using Managing.Domain.Bots;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using static Managing.Common.Enums; using static Managing.Common.Enums;

View File

@@ -1,21 +0,0 @@
using Managing.Domain.MoneyManagements;
using static Managing.Common.Enums;
namespace Managing.Application.Bots;
public class TradingBotConfig
{
public string AccountName { get; set; }
public MoneyManagement MoneyManagement { get; set; }
public Ticker Ticker { get; set; }
public string ScenarioName { get; set; }
public Timeframe Timeframe { get; set; }
public bool IsForBacktest { get; set; }
public bool IsForWatchingOnly { get; set; }
public bool FlipPosition { get; set; }
public BotType BotType { get; set; }
public decimal BotTradingBalance { get; set; }
public int CooldownPeriod { get; set; } = 1;
public int MaxLossStreak { get; set; } = 0;
public string Name { get; set; }
}

View File

@@ -1,4 +1,4 @@
using Managing.Application.Bots; using Managing.Domain.Bots;
using Managing.Domain.Users; using Managing.Domain.Users;
using MediatR; using MediatR;

View File

@@ -1,11 +1,12 @@
using Exilion.TradingAtomics; using System.ComponentModel.DataAnnotations;
using Exilion.TradingAtomics;
using Managing.Domain.Bots;
using Managing.Domain.Candles; using Managing.Domain.Candles;
using Managing.Domain.MoneyManagements; using Managing.Domain.MoneyManagements;
using Managing.Domain.Strategies; using Managing.Domain.Strategies;
using Managing.Domain.Strategies.Base;
using Managing.Domain.Trades; using Managing.Domain.Trades;
using Managing.Domain.Users; using Managing.Domain.Users;
using System.ComponentModel.DataAnnotations;
using Managing.Domain.Strategies.Base;
using static Managing.Common.Enums; using static Managing.Common.Enums;
namespace Managing.Domain.Backtests; namespace Managing.Domain.Backtests;
@@ -13,23 +14,15 @@ namespace Managing.Domain.Backtests;
public class Backtest public class Backtest
{ {
public Backtest( public Backtest(
Ticker ticker, TradingBotConfig config,
string scenario,
List<Position> positions, List<Position> positions,
List<Signal> signals, List<Signal> signals,
Timeframe timeframe, List<Candle> candles)
List<Candle> candles,
BotType botType,
string accountName)
{ {
Ticker = ticker; Config = config;
Positions = positions; Positions = positions;
Signals = signals; Signals = signals;
Timeframe = timeframe;
Candles = candles; Candles = candles;
Scenario = scenario;
BotType = botType;
AccountName = accountName;
WalletBalances = new List<KeyValuePair<DateTime, decimal>>(); WalletBalances = new List<KeyValuePair<DateTime, decimal>>();
StrategiesValues = new Dictionary<StrategyType, StrategiesResultBase>(); StrategiesValues = new Dictionary<StrategyType, StrategiesResultBase>();
@@ -51,13 +44,9 @@ public class Backtest
[Required] public int WinRate { get; set; } [Required] public int WinRate { get; set; }
[Required] public decimal GrowthPercentage { get; set; } [Required] public decimal GrowthPercentage { get; set; }
[Required] public decimal HodlPercentage { get; set; } [Required] public decimal HodlPercentage { get; set; }
[Required] public Ticker Ticker { get; } [Required] public TradingBotConfig Config { get; }
[Required] public string Scenario { get; set; }
[Required] public List<Position> Positions { get; } [Required] public List<Position> Positions { get; }
[Required] public List<Signal> Signals { get; } [Required] public List<Signal> Signals { get; }
[Required] public Timeframe Timeframe { get; }
[Required] public BotType BotType { get; }
[Required] public string AccountName { get; }
[Required] public List<Candle> Candles { get; set; } [Required] public List<Candle> Candles { get; set; }
[Required] public DateTime StartDate { get; set; } [Required] public DateTime StartDate { get; set; }
[Required] public DateTime EndDate { get; set; } [Required] public DateTime EndDate { get; set; }
@@ -65,7 +54,6 @@ public class Backtest
[Required] public decimal Fees { get; set; } [Required] public decimal Fees { get; set; }
[Required] public List<KeyValuePair<DateTime, decimal>> WalletBalances { get; set; } [Required] public List<KeyValuePair<DateTime, decimal>> WalletBalances { get; set; }
[Required] public MoneyManagement OptimizedMoneyManagement { get; set; } [Required] public MoneyManagement OptimizedMoneyManagement { get; set; }
[Required] public MoneyManagement MoneyManagement { get; set; }
[Required] public User User { get; set; } [Required] public User User { get; set; }
[Required] public Dictionary<StrategyType, StrategiesResultBase> StrategiesValues { get; set; } [Required] public Dictionary<StrategyType, StrategiesResultBase> StrategiesValues { get; set; }
[Required] public double Score { get; set; } [Required] public double Score { get; set; }
@@ -73,6 +61,6 @@ public class Backtest
public string GetStringReport() public string GetStringReport()
{ {
return return
$"{Ticker} | {Timeframe} | Positions: {Positions.Count} | Winrate: {WinRate}% | Pnl: {FinalPnl:#.##}$ | %Pnl: {GrowthPercentage:#.##}% | %Hodl: {HodlPercentage:#.##}%"; $"{Config.Ticker} | {Config.Timeframe} | Positions: {Positions.Count} | Winrate: {WinRate}% | Pnl: {FinalPnl:#.##}$ | %Pnl: {GrowthPercentage:#.##}% | %Hodl: {HodlPercentage:#.##}%";
} }
} }

View File

@@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
using Managing.Domain.MoneyManagements;
using static Managing.Common.Enums;
namespace Managing.Domain.Bots;
public class TradingBotConfig
{
[Required] public string AccountName { get; set; }
[Required] public MoneyManagement MoneyManagement { get; set; }
[Required] public Ticker Ticker { get; set; }
[Required] public string ScenarioName { get; set; }
[Required] public Timeframe Timeframe { get; set; }
[Required] public bool IsForWatchingOnly { get; set; }
[Required] public decimal BotTradingBalance { get; set; }
[Required] public BotType BotType { get; set; }
[Required] public bool IsForBacktest { get; set; }
[Required] public int CooldownPeriod { get; set; }
[Required] public int MaxLossStreak { get; set; }
[Required] public bool FlipPosition { get; set; }
[Required] public string Name { get; set; }
}

View File

@@ -26,7 +26,7 @@ public class BacktestRepository : IBacktestRepository
public IEnumerable<Backtest> GetBacktestsByUser(User user) public IEnumerable<Backtest> GetBacktestsByUser(User user)
{ {
var backtests = _backtestRepository.AsQueryable() var backtests = _backtestRepository.AsQueryable()
.Where(b => b.User != null && b.User.Name == user.Name) .Where(b => b.User.Name == user.Name)
.ToList(); .ToList();
return backtests.Select(b => MongoMappers.Map(b)); return backtests.Select(b => MongoMappers.Map(b));

View File

@@ -1,6 +1,6 @@
using Managing.Infrastructure.Databases.MongoDb.Attributes; using Exilion.TradingAtomics;
using Managing.Infrastructure.Databases.MongoDb.Attributes;
using Managing.Infrastructure.Databases.MongoDb.Configurations; using Managing.Infrastructure.Databases.MongoDb.Configurations;
using Exilion.TradingAtomics;
using static Managing.Common.Enums; using static Managing.Common.Enums;
namespace Managing.Infrastructure.Databases.MongoDb.Collections namespace Managing.Infrastructure.Databases.MongoDb.Collections
@@ -12,21 +12,27 @@ namespace Managing.Infrastructure.Databases.MongoDb.Collections
public int WinRate { get; set; } public int WinRate { get; set; }
public decimal GrowthPercentage { get; set; } public decimal GrowthPercentage { get; set; }
public decimal HodlPercentage { get; set; } public decimal HodlPercentage { get; set; }
public Ticker Ticker { get; set; }
public string Scenario { get; set; }
public List<PositionDto> Positions { get; set; } public List<PositionDto> Positions { get; set; }
public List<SignalDto> Signals { get; set; } public List<SignalDto> Signals { get; set; }
public Timeframe Timeframe { get; set; }
public RiskLevel RiskLevel { get; set; }
public string AccountName { get; set; }
public List<CandleDto> Candles { get; set; } public List<CandleDto> Candles { get; set; }
public DateTime StartDate { get; set; } public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; } public DateTime EndDate { get; set; }
public BotType BotType { get; set; }
public MoneyManagementDto MoneyManagement { get; internal set; } public MoneyManagementDto MoneyManagement { get; internal set; }
public MoneyManagementDto OptimizedMoneyManagement { get; internal set; } public MoneyManagementDto OptimizedMoneyManagement { get; internal set; }
public UserDto User { get; set; } public UserDto User { get; set; }
public PerformanceMetrics Statistics { get; set; } public PerformanceMetrics Statistics { get; set; }
public double Score { get; set; } public double Score { get; set; }
// TradingBotConfig properties
public string AccountName { get; set; }
public Ticker Ticker { get; set; }
public string ScenarioName { get; set; }
public Timeframe Timeframe { get; set; }
public bool IsForWatchingOnly { get; set; }
public decimal BotTradingBalance { get; set; }
public BotType BotType { get; set; }
public bool IsForBacktest { get; set; }
public int CooldownPeriod { get; set; }
public int MaxLossStreak { get; set; }
} }
} }

View File

@@ -130,24 +130,34 @@ public static class MongoMappers
if (b == null) if (b == null)
return null; return null;
var config = new TradingBotConfig
{
AccountName = b.AccountName,
Ticker = b.Ticker,
ScenarioName = b.ScenarioName,
Timeframe = b.Timeframe,
IsForWatchingOnly = b.IsForWatchingOnly,
BotTradingBalance = b.BotTradingBalance,
BotType = b.BotType,
IsForBacktest = b.IsForBacktest,
CooldownPeriod = b.CooldownPeriod,
MaxLossStreak = b.MaxLossStreak,
MoneyManagement = Map(b.MoneyManagement)
};
var bTest = new Backtest( var bTest = new Backtest(
b.Ticker, config,
b.Scenario,
b.Positions?.Select(p => Map(p)).ToList() ?? new List<Position>(), b.Positions?.Select(p => Map(p)).ToList() ?? new List<Position>(),
b.Signals?.Select(s => Map(s)).ToList() ?? new List<Signal>(), b.Signals?.Select(s => Map(s)).ToList() ?? new List<Signal>(),
b.Timeframe, b.Candles?.Select(c => Map(c)).ToList() ?? new List<Candle>())
b.Candles?.Select(c => Map(c)).ToList() ?? new List<Candle>(),
b.BotType,
b.AccountName)
{ {
FinalPnl = b.FinalPnl, FinalPnl = b.FinalPnl,
WinRate = b.WinRate, WinRate = b.WinRate,
GrowthPercentage = b.GrowthPercentage, GrowthPercentage = b.GrowthPercentage,
HodlPercentage = b.HodlPercentage, HodlPercentage = b.HodlPercentage,
Id = b.Id.ToString(), Id = b.Id.ToString(),
MoneyManagement = Map(b.MoneyManagement),
OptimizedMoneyManagement = Map(b.OptimizedMoneyManagement), OptimizedMoneyManagement = Map(b.OptimizedMoneyManagement),
User = b.User != null ? Map(b.User) : null, User = Map(b.User),
Statistics = b.Statistics, Statistics = b.Statistics,
StartDate = b.StartDate, StartDate = b.StartDate,
EndDate = b.EndDate, EndDate = b.EndDate,
@@ -171,18 +181,24 @@ public static class MongoMappers
HodlPercentage = result.HodlPercentage, HodlPercentage = result.HodlPercentage,
Positions = Map(result.Positions), Positions = Map(result.Positions),
Signals = result.Signals.Select(s => Map(s)).ToList(), Signals = result.Signals.Select(s => Map(s)).ToList(),
Ticker = result.Ticker, Candles = result.Candles.Select(c => Map(c)).ToList(),
Scenario = result.Scenario, MoneyManagement = Map(result.Config.MoneyManagement),
AccountName = result.AccountName,
BotType = result.BotType,
Timeframe = result.Timeframe,
MoneyManagement = Map(result.MoneyManagement),
OptimizedMoneyManagement = Map(result.OptimizedMoneyManagement), OptimizedMoneyManagement = Map(result.OptimizedMoneyManagement),
User = result.User != null ? Map(result.User) : null, User = Map(result.User),
Statistics = result.Statistics, Statistics = result.Statistics,
StartDate = result.StartDate, StartDate = result.StartDate,
EndDate = result.EndDate, EndDate = result.EndDate,
Score = result.Score Score = result.Score,
AccountName = result.Config.AccountName,
Ticker = result.Config.Ticker,
ScenarioName = result.Config.ScenarioName,
Timeframe = result.Config.Timeframe,
IsForWatchingOnly = result.Config.IsForWatchingOnly,
BotTradingBalance = result.Config.BotTradingBalance,
BotType = result.Config.BotType,
IsForBacktest = result.Config.IsForBacktest,
CooldownPeriod = result.Config.CooldownPeriod,
MaxLossStreak = result.Config.MaxLossStreak
}; };
} }

View File

@@ -59,8 +59,7 @@
"viem": "2.28.0", "viem": "2.28.0",
"wagmi": "^2.15.0", "wagmi": "^2.15.0",
"web3": "^4.16.0", "web3": "^4.16.0",
"zustand": "^4.4.1", "zustand": "^4.4.1"
"@gmx-io/sdk": "0.2.0"
}, },
"devDependencies": { "devDependencies": {
"@types/elliptic": "^6.4.18", "@types/elliptic": "^6.4.18",
@@ -83,7 +82,7 @@
"prettier-plugin-tailwind-css": "^1.5.0", "prettier-plugin-tailwind-css": "^1.5.0",
"tailwindcss": "^3.0.23", "tailwindcss": "^3.0.23",
"typescript": "^5.7.3", "typescript": "^5.7.3",
"vite": "^6.0.11", "vite": "^6.3.5",
"whatwg-fetch": "^3.6.2" "whatwg-fetch": "^3.6.2"
}, },
"msw": { "msw": {

View File

@@ -56,14 +56,14 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
const client = new BotClient({}, apiUrl) const client = new BotClient({}, apiUrl)
const request: StartBotRequest = { const request: StartBotRequest = {
accountName: backtest.accountName, accountName: backtest.config.accountName,
botName: backtest.ticker + '-' + backtest.timeframe.toString(), name: backtest.config.ticker + '-' + backtest.config.timeframe?.toString(),
botType: BotType.ScalpingBot, botType: BotType.ScalpingBot,
isForWatchOnly: isForWatchOnly, isForWatchOnly: isForWatchOnly,
moneyManagementName: backtest.moneyManagement?.name, moneyManagementName: backtest.config.moneyManagement?.name,
scenario: backtest.scenario, scenario: backtest.config.scenarioName,
ticker: backtest.ticker as Ticker, ticker: backtest.config.ticker as Ticker,
timeframe: backtest.timeframe, timeframe: backtest.config.timeframe,
initialTradingBalance: 1000, initialTradingBalance: 1000,
} }
@@ -87,21 +87,23 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
await client await client
.backtest_Run( .backtest_Run(
backtest.accountName, backtest.config.accountName,
backtest.botType, backtest.config.botType,
backtest.ticker as Ticker, backtest.config.ticker as Ticker,
backtest.scenario, backtest.config.scenarioName,
backtest.timeframe, backtest.config.timeframe,
false, // watchOnly false, // watchOnly
backtest.walletBalances[0].value, // balance backtest.walletBalances[0].value, // balance
'', // moneyManagementName (empty since we're passing the optimized moneyManagement object) '', // moneyManagementName (empty since we're passing the optimized moneyManagement object)
startDate, // startDate startDate, // startDate
endDate, // endDate endDate, // endDate
false, // save false, // save
backtest.optimizedMoneyManagement // moneyManagement object backtest.config.cooldownPeriod,
backtest.config.maxLossStreak,
backtest.config.moneyManagement as MoneyManagement, // moneyManagement object
) )
.then((backtest: Backtest) => { .then((backtest: Backtest) => {
t.update('success', `${backtest.ticker} Backtest Succeeded`) t.update('success', `${backtest.config.ticker} Backtest Succeeded`)
setBacktests((arr) => [...arr, backtest]) setBacktests((arr) => [...arr, backtest])
}) })
.catch((err) => { .catch((err) => {
@@ -177,7 +179,7 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
<button <button
className="text-xs" className="text-xs"
onClick={() => onClick={() =>
saveMoneyManagement(backtest.moneyManagement) saveMoneyManagement(backtest.config.moneyManagement)
} }
> >
Save money management Save money management
@@ -193,7 +195,7 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
</li> </li>
</ul> </ul>
</div> </div>
{backtest.ticker} {backtest.config.ticker}
{botStatusResult( {botStatusResult(
backtest.growthPercentage, backtest.growthPercentage,
backtest.hodlPercentage backtest.hodlPercentage
@@ -203,19 +205,19 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
<div> <div>
<CardText <CardText
title="Ticker" title="Ticker"
content={backtest.ticker} content={backtest.config.ticker}
></CardText> ></CardText>
<CardText <CardText
title="Account" title="Account"
content={backtest.accountName} content={backtest.config.accountName}
></CardText> ></CardText>
<CardText <CardText
title="Scenario" title="Scenario"
content={backtest.scenario} content={backtest.config.scenarioName}
></CardText> ></CardText>
<CardText <CardText
title="Timeframe" title="Timeframe"
content={backtest.timeframe} content={backtest.config.timeframe?.toString()}
></CardText> ></CardText>
</div> </div>
</div> </div>

View File

@@ -123,7 +123,7 @@ const BacktestModal: React.FC<BacktestModalProps> = ({
customMoneyManagement customMoneyManagement
); );
t.update('success', `${backtest.ticker} Backtest Succeeded`) t.update('success', `${backtest.config.ticker} Backtest Succeeded`)
setBacktests((arr) => [...arr, backtest]) setBacktests((arr) => [...arr, backtest])
if (showLoopSlider && selectedLoopQuantity > loopCount) { if (showLoopSlider && selectedLoopQuantity > loopCount) {

View File

@@ -50,16 +50,18 @@ const BacktestTable: React.FC<IBacktestCards> = ({ list, isFetching, setBacktest
moneyManagementName.toLowerCase().includes('custom'); moneyManagementName.toLowerCase().includes('custom');
const request: StartBotRequest = { const request: StartBotRequest = {
accountName: backtest.accountName, accountName: backtest.config.accountName,
botName: botName, botType: backtest.config.botType,
botType: backtest.botType,
isForWatchOnly: isForWatchOnly, isForWatchOnly: isForWatchOnly,
// Only use the money management name if it's not a custom money management // Only use the money management name if it's not a custom money management
moneyManagementName: isCustomMoneyManagement ? '' : moneyManagementName, moneyManagementName: isCustomMoneyManagement ? '' : moneyManagementName,
scenario: backtest.scenario, scenario: backtest.config.scenarioName,
ticker: backtest.ticker as Ticker, ticker: backtest.config.ticker as Ticker,
timeframe: backtest.timeframe, timeframe: backtest.config.timeframe,
initialTradingBalance: initialTradingBalance, initialTradingBalance: initialTradingBalance,
cooldownPeriod: backtest.config.cooldownPeriod,
maxLossStreak: backtest.config.maxLossStreak,
name: botName,
} }
await client await client
@@ -162,26 +164,26 @@ const BacktestTable: React.FC<IBacktestCards> = ({ list, isFetching, setBacktest
{ {
Filter: SelectColumnFilter, Filter: SelectColumnFilter,
Header: 'Ticker', Header: 'Ticker',
accessor: 'ticker', accessor: 'config.ticker',
disableSortBy: true, disableSortBy: true,
}, },
{ {
Filter: SelectColumnFilter, Filter: SelectColumnFilter,
Header: 'Timeframe', Header: 'Timeframe',
accessor: 'timeframe', accessor: 'config.timeframe',
disableSortBy: true, disableSortBy: true,
}, },
{ {
Filter: SelectColumnFilter, Filter: SelectColumnFilter,
Header: 'Scenario', Header: 'Scenario',
accessor: 'scenario', accessor: 'config.scenarioName',
disableSortBy: true, disableSortBy: true,
}, },
{ {
Filter: SelectColumnFilter, Filter: SelectColumnFilter,
Header: 'BotType', Header: 'BotType',
accessor: 'botType', accessor: 'config.botType',
disableSortBy: true, disableSortBy: true,
}, },
], ],

View File

@@ -2544,13 +2544,9 @@ export interface Backtest {
winRate: number; winRate: number;
growthPercentage: number; growthPercentage: number;
hodlPercentage: number; hodlPercentage: number;
ticker: Ticker; config: TradingBotConfig;
scenario: string;
positions: Position[]; positions: Position[];
signals: Signal[]; signals: Signal[];
timeframe: Timeframe;
botType: BotType;
accountName: string;
candles: Candle[]; candles: Candle[];
startDate: Date; startDate: Date;
endDate: Date; endDate: Date;
@@ -2558,12 +2554,46 @@ export interface Backtest {
fees: number; fees: number;
walletBalances: KeyValuePairOfDateTimeAndDecimal[]; walletBalances: KeyValuePairOfDateTimeAndDecimal[];
optimizedMoneyManagement: MoneyManagement; optimizedMoneyManagement: MoneyManagement;
moneyManagement: MoneyManagement;
user: User; user: User;
strategiesValues: { [key in keyof typeof StrategyType]?: StrategiesResultBase; }; strategiesValues: { [key in keyof typeof StrategyType]?: StrategiesResultBase; };
score: number; score: number;
} }
export interface TradingBotConfig {
accountName: string;
moneyManagement: MoneyManagement;
ticker: Ticker;
scenarioName: string;
timeframe: Timeframe;
isForWatchingOnly: boolean;
botTradingBalance: number;
botType: BotType;
isForBacktest: boolean;
cooldownPeriod: number;
maxLossStreak: number;
flipPosition: boolean;
name: string;
}
export interface MoneyManagement {
name: string;
timeframe: Timeframe;
stopLoss: number;
takeProfit: number;
leverage: number;
user?: User | null;
}
export enum Timeframe {
FiveMinutes = "FiveMinutes",
FifteenMinutes = "FifteenMinutes",
ThirtyMinutes = "ThirtyMinutes",
OneHour = "OneHour",
FourHour = "FourHour",
OneDay = "OneDay",
OneMinute = "OneMinute",
}
export enum Ticker { export enum Ticker {
AAVE = "AAVE", AAVE = "AAVE",
ADA = "ADA", ADA = "ADA",
@@ -2673,6 +2703,12 @@ export enum Ticker {
Unknown = "Unknown", Unknown = "Unknown",
} }
export enum BotType {
SimpleBot = "SimpleBot",
ScalpingBot = "ScalpingBot",
FlippingBot = "FlippingBot",
}
export interface Position { export interface Position {
accountName: string; accountName: string;
date: Date; date: Date;
@@ -2697,25 +2733,6 @@ export enum TradeDirection {
Long = "Long", Long = "Long",
} }
export interface MoneyManagement {
name: string;
timeframe: Timeframe;
stopLoss: number;
takeProfit: number;
leverage: number;
user?: User | null;
}
export enum Timeframe {
FiveMinutes = "FiveMinutes",
FifteenMinutes = "FifteenMinutes",
ThirtyMinutes = "ThirtyMinutes",
OneHour = "OneHour",
FourHour = "FourHour",
OneDay = "OneDay",
OneMinute = "OneMinute",
}
export interface Trade { export interface Trade {
fee?: number; fee?: number;
date: Date; date: Date;
@@ -2850,12 +2867,6 @@ export enum SignalType {
Context = "Context", Context = "Context",
} }
export enum BotType {
SimpleBot = "SimpleBot",
ScalpingBot = "ScalpingBot",
FlippingBot = "FlippingBot",
}
export interface PerformanceMetrics { export interface PerformanceMetrics {
count?: number; count?: number;
sharpeRatio?: number; sharpeRatio?: number;
@@ -2970,6 +2981,9 @@ export interface StartBotRequest {
moneyManagementName?: string | null; moneyManagementName?: string | null;
isForWatchOnly?: boolean; isForWatchOnly?: boolean;
initialTradingBalance?: number; initialTradingBalance?: number;
cooldownPeriod?: number;
maxLossStreak?: number;
name?: string | null;
} }
export interface TradingBot { export interface TradingBot {

View File

@@ -1,4 +1,4 @@
import { ColorSwatchIcon, TrashIcon, XIcon } from '@heroicons/react/solid' import {ColorSwatchIcon, TrashIcon} from '@heroicons/react/solid'
import {useQuery} from '@tanstack/react-query' import {useQuery} from '@tanstack/react-query'
import React, {useEffect, useState} from 'react' import React, {useEffect, useState} from 'react'
@@ -28,19 +28,6 @@ const BacktestScanner: React.FC = () => {
} }
}, [backtests]) }, [backtests])
function deleteAllBacktests() {
const t = new Toast('Deleting all backtests')
client
.backtest_DeleteBacktests()
.then(() => {
t.update('success', 'Backtest Succeeded')
refetch()
})
.catch((err) => {
t.update('error', 'Error :' + err)
})
}
const openModalRemoveBacktests = () => { const openModalRemoveBacktests = () => {
setShowModalRemoveBacktest(true) setShowModalRemoveBacktest(true)
} }
@@ -111,11 +98,6 @@ const BacktestScanner: React.FC = () => {
<TrashIcon width="20"></TrashIcon> <TrashIcon width="20"></TrashIcon>
</button> </button>
</div> </div>
<div className="tooltip" data-tip="Delete all backtests">
<button className="btn btn-error text-xs" onClick={deleteAllBacktests}>
<XIcon width="20"></XIcon>
</button>
</div>
<BacktestTable list={backtestingResult} isFetching={isLoading} setBacktests={setBacktest} /> <BacktestTable list={backtestingResult} isFetching={isLoading} setBacktests={setBacktest} />

View File

@@ -2,46 +2,11 @@ import React, { useState } from 'react'
import {toast} from 'react-toastify' import {toast} from 'react-toastify'
import {SettingsClient} from '../../../generated/ManagingApi' import {SettingsClient} from '../../../generated/ManagingApi'
import useApiUrlStore from '../../../app/store/apiStore' import useApiUrlStore from '../../../app/store/apiStore'
import { GmxSdk } from '@gmx-io/sdk'
import { createClient, createTestClient, createWalletClient, http, publicActions, walletActions } from 'viem'
import { getClient, getConnectorClient } from '@wagmi/core'
import { privyWagmiConfig } from '../../../config/privy'
import { arbitrum } from 'viem/chains'
import { GmxSdkConfig } from '@gmx-io/sdk/build/src/types/sdk'
const DefaultConfig: React.FC = () => { const DefaultConfig: React.FC = () => {
const [isCreating, setIsCreating] = useState(false) const [isCreating, setIsCreating] = useState(false)
const { apiUrl } = useApiUrlStore() const { apiUrl } = useApiUrlStore()
const client = createWalletClient({
account: "0x9f7198eb1b9Ccc0Eb7A07eD228d8FbC12963ea33",
chain: arbitrum,
transport: http(),
})
const testClient = createTestClient({
chain: arbitrum,
mode: "hardhat",
transport: http(),
})
.extend(publicActions)
.extend(walletActions);
const arbitrumSdkConfig: GmxSdkConfig = {
chainId: arbitrum.id,
account: "0x9f7198eb1b9Ccc0Eb7A07eD228d8FbC12963ea33",
oracleUrl: "https://arbitrum-api.gmxinfra.io",
rpcUrl: "https://arb1.arbitrum.io/rpc",
walletClient: client,
subsquidUrl: "https://gmx.squids.live/gmx-synthetics-arbitrum:live/api/graphql",
subgraphUrl: "https://subgraph.satsuma-prod.com/3b2ced13c8d9/gmx/synthetics-arbitrum-stats/api",
};
const sdk = new GmxSdk(arbitrumSdkConfig)
console.log(sdk)
const createDefaultConfig = async () => { const createDefaultConfig = async () => {
try { try {
const client = new SettingsClient({}, apiUrl) const client = new SettingsClient({}, apiUrl)