Postgres (#30)
* Add postgres * Migrate users * Migrate geneticRequest * Try to fix Concurrent call * Fix asyncawait * Fix async and concurrent * Migrate backtests * Add cache for user by address * Fix backtest migration * Fix not open connection * Fix backtest command error * Fix concurrent * Fix all concurrency * Migrate TradingRepo * Fix scenarios * Migrate statistic repo * Save botbackup * Add settings et moneymanagement * Add bot postgres * fix a bit more backups * Fix bot model * Fix loading backup * Remove cache market for read positions * Add workers to postgre * Fix workers api * Reduce get Accounts for workers * Migrate synth to postgre * Fix backtest saved * Remove mongodb * botservice decorrelation * Fix tradingbot scope call * fix tradingbot * fix concurrent * Fix scope for genetics * Fix account over requesting * Fix bundle backtest worker * fix a lot of things * fix tab backtest * Remove optimized moneymanagement * Add light signal to not use User and too much property * Make money management lighter * insert indicators to awaitable * Migrate add strategies to await * Refactor scenario and indicator retrieval to use asynchronous methods throughout the application * add more async await * Add services * Fix and clean * Fix bot a bit * Fix bot and add message for cooldown * Remove fees * Add script to deploy db * Update dfeeploy script * fix script * Add idempotent script and backup * finish script migration * Fix did user and agent name on start bot
This commit is contained in:
@@ -121,6 +121,12 @@ namespace Managing.Application.Backtesting
|
||||
result.StartDate = startDate;
|
||||
result.EndDate = endDate;
|
||||
|
||||
// Ensure RequestId is set - required for PostgreSQL NOT NULL constraint
|
||||
if (string.IsNullOrEmpty(result.RequestId))
|
||||
{
|
||||
result.RequestId = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
if (save && user != null)
|
||||
{
|
||||
_backtestRepository.InsertBacktestForUser(user, result);
|
||||
@@ -138,8 +144,9 @@ namespace Managing.Application.Backtesting
|
||||
var refundSuccess = await _kaigenService.RefundUserCreditsAsync(creditRequestId, user);
|
||||
if (refundSuccess)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
"Successfully refunded credits for user {UserName} after backtest failure", user.Name);
|
||||
_logger.LogError(
|
||||
"Successfully refunded credits for user {UserName} after backtest failure: {message}",
|
||||
user.Name, ex.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -188,7 +195,7 @@ namespace Managing.Application.Backtesting
|
||||
string requestId = null,
|
||||
object metadata = null)
|
||||
{
|
||||
var tradingBot = _botFactory.CreateBacktestTradingBot(config);
|
||||
var tradingBot = await _botFactory.CreateBacktestTradingBot(config);
|
||||
|
||||
// Scenario and indicators should already be loaded in constructor by BotService
|
||||
// This is just a validation check to ensure everything loaded properly
|
||||
@@ -215,26 +222,7 @@ namespace Managing.Application.Backtesting
|
||||
|
||||
private async Task<Account> GetAccountFromConfig(TradingBotConfig config)
|
||||
{
|
||||
var accounts = _accountService.GetAccounts(false, false).ToArray();
|
||||
var account = accounts.FirstOrDefault(a =>
|
||||
a.Name.Equals(config.AccountName, StringComparison.OrdinalIgnoreCase) &&
|
||||
a.Exchange == TradingExchanges.GmxV2);
|
||||
|
||||
if (account == null && accounts.Any())
|
||||
{
|
||||
account = accounts.First();
|
||||
}
|
||||
|
||||
if (account != null)
|
||||
{
|
||||
return account;
|
||||
}
|
||||
|
||||
return new Account
|
||||
{
|
||||
Name = config.AccountName,
|
||||
Exchange = TradingExchanges.GmxV2
|
||||
};
|
||||
return await _accountService.GetAccountByAccountName(config.AccountName, false, false);
|
||||
}
|
||||
|
||||
private List<Candle> GetCandles(Ticker ticker, Timeframe timeframe,
|
||||
@@ -270,13 +258,13 @@ namespace Managing.Application.Backtesting
|
||||
_logger.LogInformation("Starting backtest with {TotalCandles} candles for {Ticker} on {Timeframe}",
|
||||
totalCandles, config.Ticker, config.Timeframe);
|
||||
|
||||
bot.WalletBalances.Add(candles.FirstOrDefault().Date, config.BotTradingBalance);
|
||||
bot.WalletBalances.Add(candles.FirstOrDefault()!.Date, config.BotTradingBalance);
|
||||
|
||||
foreach (var candle in candles)
|
||||
{
|
||||
bot.OptimizedCandles.Enqueue(candle);
|
||||
bot.Candles.Add(candle);
|
||||
bot.Run();
|
||||
await bot.Run();
|
||||
|
||||
currentCandle++;
|
||||
|
||||
@@ -318,8 +306,6 @@ namespace Managing.Application.Backtesting
|
||||
|
||||
var finalPnl = bot.GetProfitAndLoss();
|
||||
var winRate = bot.GetWinRate();
|
||||
var optimizedMoneyManagement =
|
||||
TradingBox.GetBestMoneyManagement(candles, bot.Positions, config.MoneyManagement);
|
||||
var stats = TradingHelpers.GetStatistics(bot.WalletBalances);
|
||||
var growthPercentage =
|
||||
TradingHelpers.GetGrowthFromInitalBalance(bot.WalletBalances.FirstOrDefault().Value, finalPnl);
|
||||
@@ -357,7 +343,6 @@ namespace Managing.Application.Backtesting
|
||||
Fees = fees,
|
||||
WalletBalances = bot.WalletBalances.ToList(),
|
||||
Statistics = stats,
|
||||
OptimizedMoneyManagement = optimizedMoneyManagement,
|
||||
IndicatorsValues = withCandles
|
||||
? AggregateValues(indicatorsValues, bot.IndicatorsValues)
|
||||
: new Dictionary<IndicatorType, IndicatorsResultBase>(),
|
||||
@@ -442,11 +427,11 @@ namespace Managing.Application.Backtesting
|
||||
return indicatorsValues;
|
||||
}
|
||||
|
||||
public bool DeleteBacktest(string id)
|
||||
public async Task<bool> DeleteBacktestAsync(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
_backtestRepository.DeleteBacktestByIdForUser(null, id);
|
||||
await _backtestRepository.DeleteBacktestByIdForUserAsync(null, id);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -476,12 +461,24 @@ namespace Managing.Application.Backtesting
|
||||
return backtests;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Backtest>> GetBacktestsByUserAsync(User user)
|
||||
{
|
||||
var backtests = await _backtestRepository.GetBacktestsByUserAsync(user);
|
||||
return backtests;
|
||||
}
|
||||
|
||||
public IEnumerable<Backtest> GetBacktestsByRequestId(string requestId)
|
||||
{
|
||||
var backtests = _backtestRepository.GetBacktestsByRequestId(requestId).ToList();
|
||||
return backtests;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Backtest>> GetBacktestsByRequestIdAsync(string requestId)
|
||||
{
|
||||
var backtests = await _backtestRepository.GetBacktestsByRequestIdAsync(requestId);
|
||||
return backtests;
|
||||
}
|
||||
|
||||
public (IEnumerable<LightBacktest> Backtests, int TotalCount) GetBacktestsByRequestIdPaginated(string requestId,
|
||||
int page, int pageSize, string sortBy = "score", string sortOrder = "desc")
|
||||
{
|
||||
@@ -490,9 +487,19 @@ namespace Managing.Application.Backtesting
|
||||
return (backtests, totalCount);
|
||||
}
|
||||
|
||||
public Backtest GetBacktestByIdForUser(User user, string id)
|
||||
public async Task<(IEnumerable<LightBacktest> Backtests, int TotalCount)> GetBacktestsByRequestIdPaginatedAsync(
|
||||
string requestId, int page, int pageSize, string sortBy = "score", string sortOrder = "desc")
|
||||
{
|
||||
var backtest = _backtestRepository.GetBacktestByIdForUser(user, id);
|
||||
var (backtests, totalCount) =
|
||||
await _backtestRepository.GetBacktestsByRequestIdPaginatedAsync(requestId, page, pageSize, sortBy,
|
||||
sortOrder);
|
||||
return (backtests, totalCount);
|
||||
}
|
||||
|
||||
|
||||
public async Task<Backtest> GetBacktestByIdForUserAsync(User user, string id)
|
||||
{
|
||||
var backtest = await _backtestRepository.GetBacktestByIdForUserAsync(user, id);
|
||||
|
||||
if (backtest == null)
|
||||
return null;
|
||||
@@ -504,12 +511,12 @@ namespace Managing.Application.Backtesting
|
||||
var account = new Account
|
||||
{ Name = backtest.Config.AccountName, Exchange = TradingExchanges.Evm };
|
||||
|
||||
var candles = _exchangeService.GetCandlesInflux(
|
||||
var candles = await _exchangeService.GetCandlesInflux(
|
||||
account.Exchange,
|
||||
backtest.Config.Ticker,
|
||||
backtest.StartDate,
|
||||
backtest.Config.Timeframe,
|
||||
backtest.EndDate).Result;
|
||||
backtest.EndDate);
|
||||
|
||||
if (candles != null && candles.Count > 0)
|
||||
{
|
||||
@@ -525,11 +532,11 @@ namespace Managing.Application.Backtesting
|
||||
return backtest;
|
||||
}
|
||||
|
||||
public bool DeleteBacktestByUser(User user, string id)
|
||||
public async Task<bool> DeleteBacktestByUserAsync(User user, string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
_backtestRepository.DeleteBacktestByIdForUser(user, id);
|
||||
await _backtestRepository.DeleteBacktestByIdForUserAsync(user, id);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -539,11 +546,11 @@ namespace Managing.Application.Backtesting
|
||||
}
|
||||
}
|
||||
|
||||
public bool DeleteBacktestsByIdsForUser(User user, IEnumerable<string> ids)
|
||||
public async Task<bool> DeleteBacktestsByIdsForUserAsync(User user, IEnumerable<string> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
_backtestRepository.DeleteBacktestsByIdsForUser(user, ids);
|
||||
await _backtestRepository.DeleteBacktestsByIdsForUserAsync(user, ids);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -567,11 +574,11 @@ namespace Managing.Application.Backtesting
|
||||
}
|
||||
}
|
||||
|
||||
public bool DeleteBacktestsByRequestId(string requestId)
|
||||
public async Task<bool> DeleteBacktestsByRequestIdAsync(string requestId)
|
||||
{
|
||||
try
|
||||
{
|
||||
_backtestRepository.DeleteBacktestsByRequestId(requestId);
|
||||
await _backtestRepository.DeleteBacktestsByRequestIdAsync(requestId);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -589,6 +596,14 @@ namespace Managing.Application.Backtesting
|
||||
return (backtests, totalCount);
|
||||
}
|
||||
|
||||
public async Task<(IEnumerable<LightBacktest> Backtests, int TotalCount)> GetBacktestsByUserPaginatedAsync(
|
||||
User user, int page, int pageSize, string sortBy = "score", string sortOrder = "desc")
|
||||
{
|
||||
var (backtests, totalCount) =
|
||||
await _backtestRepository.GetBacktestsByUserPaginatedAsync(user, page, pageSize, sortBy, sortOrder);
|
||||
return (backtests, totalCount);
|
||||
}
|
||||
|
||||
// Bundle backtest methods
|
||||
public void InsertBundleBacktestRequestForUser(User user, BundleBacktestRequest bundleRequest)
|
||||
{
|
||||
@@ -600,27 +615,53 @@ namespace Managing.Application.Backtesting
|
||||
return _backtestRepository.GetBundleBacktestRequestsByUser(user);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<BundleBacktestRequest>> GetBundleBacktestRequestsByUserAsync(User user)
|
||||
{
|
||||
return await _backtestRepository.GetBundleBacktestRequestsByUserAsync(user);
|
||||
}
|
||||
|
||||
public BundleBacktestRequest? GetBundleBacktestRequestByIdForUser(User user, string id)
|
||||
{
|
||||
return _backtestRepository.GetBundleBacktestRequestByIdForUser(user, id);
|
||||
}
|
||||
|
||||
public async Task<BundleBacktestRequest?> GetBundleBacktestRequestByIdForUserAsync(User user, string id)
|
||||
{
|
||||
return await _backtestRepository.GetBundleBacktestRequestByIdForUserAsync(user, id);
|
||||
}
|
||||
|
||||
public void UpdateBundleBacktestRequest(BundleBacktestRequest bundleRequest)
|
||||
{
|
||||
_backtestRepository.UpdateBundleBacktestRequest(bundleRequest);
|
||||
}
|
||||
|
||||
public async Task UpdateBundleBacktestRequestAsync(BundleBacktestRequest bundleRequest)
|
||||
{
|
||||
await _backtestRepository.UpdateBundleBacktestRequestAsync(bundleRequest);
|
||||
}
|
||||
|
||||
public void DeleteBundleBacktestRequestByIdForUser(User user, string id)
|
||||
{
|
||||
_backtestRepository.DeleteBundleBacktestRequestByIdForUser(user, id);
|
||||
}
|
||||
|
||||
public async Task DeleteBundleBacktestRequestByIdForUserAsync(User user, string id)
|
||||
{
|
||||
await _backtestRepository.DeleteBundleBacktestRequestByIdForUserAsync(user, id);
|
||||
}
|
||||
|
||||
public IEnumerable<BundleBacktestRequest> GetBundleBacktestRequestsByStatus(BundleBacktestRequestStatus status)
|
||||
{
|
||||
// Use the repository method to get all bundles, then filter by status
|
||||
return _backtestRepository.GetBundleBacktestRequestsByStatus(status);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<BundleBacktestRequest>> GetBundleBacktestRequestsByStatusAsync(
|
||||
BundleBacktestRequestStatus status)
|
||||
{
|
||||
return await _backtestRepository.GetBundleBacktestRequestsByStatusAsync(status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a LightBacktestResponse to all SignalR subscribers of a bundle request.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user