From 6a634eafaa958abc62efb29f449bdb456a47503c Mon Sep 17 00:00:00 2001 From: cryptooda Date: Thu, 17 Jul 2025 04:40:18 +0700 Subject: [PATCH] Update get backtests --- .../BacktestRepository.cs | 2 +- .../Services/KaigenService.cs | 46 +++++++++++-------- .../organism/Backtest/backtestRowDetails.tsx | 33 +++++++++---- 3 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/Managing.Infrastructure.Database/BacktestRepository.cs b/src/Managing.Infrastructure.Database/BacktestRepository.cs index 42209bb..732b25e 100644 --- a/src/Managing.Infrastructure.Database/BacktestRepository.cs +++ b/src/Managing.Infrastructure.Database/BacktestRepository.cs @@ -153,7 +153,7 @@ public class BacktestRepository : IBacktestRepository public Backtest GetBacktestByIdForUser(User user, string id) { - var backtest = _backtestRepository.FindById(id); + var backtest = _backtestRepository.FindOne(b => b.Identifier == id); // Check if backtest exists and belongs to the user if (backtest != null && backtest.User != null && backtest.User.Name == user.Name) diff --git a/src/Managing.Infrastructure.Web3/Services/KaigenService.cs b/src/Managing.Infrastructure.Web3/Services/KaigenService.cs index 140c036..76ce875 100644 --- a/src/Managing.Infrastructure.Web3/Services/KaigenService.cs +++ b/src/Managing.Infrastructure.Web3/Services/KaigenService.cs @@ -40,8 +40,8 @@ public class KaigenService : IKaigenService // Check if credits are enabled via environment variable var creditsEnabledEnv = Environment.GetEnvironmentVariable("KAIGEN_CREDITS_ENABLED"); - _creditsEnabled = string.IsNullOrEmpty(creditsEnabledEnv) || creditsEnabledEnv.ToLower() == "true"; - + _creditsEnabled = !string.IsNullOrEmpty(creditsEnabledEnv) && creditsEnabledEnv.ToLower() == "true"; + if (!_creditsEnabled) { _logger.LogInformation("Kaigen credits are disabled via KAIGEN_CREDITS_ENABLED environment variable"); @@ -59,7 +59,8 @@ public class KaigenService : IKaigenService // Validate required settings only if credits are enabled if (string.IsNullOrEmpty(_settings.PrivateKey)) { - throw new InvalidOperationException("Kaigen PrivateKey is not configured. Please set the KAIGEN_PRIVATE_KEY environment variable."); + throw new InvalidOperationException( + "Kaigen PrivateKey is not configured. Please set the KAIGEN_PRIVATE_KEY environment variable."); } if (string.IsNullOrEmpty(_settings.BaseUrl)) @@ -74,7 +75,8 @@ public class KaigenService : IKaigenService if (!_creditsEnabled) { var dummyRequestId = Guid.NewGuid().ToString(); - _logger.LogInformation("Credits disabled - skipping debit for user {UserName}. Returning dummy request ID {RequestId}", + _logger.LogInformation( + "Credits disabled - skipping debit for user {UserName}. Returning dummy request ID {RequestId}", user.Name, dummyRequestId); return dummyRequestId; } @@ -83,10 +85,10 @@ public class KaigenService : IKaigenService { var walletAddress = GetUserWalletAddress(user); var requestId = Guid.NewGuid().ToString(); - + // Create the message to sign (concatenate the values) var message = $"{requestId}{walletAddress}{debitAmount}"; - + // Sign the message var signature = SignMessage(message, _settings.PrivateKey); @@ -99,24 +101,26 @@ public class KaigenService : IKaigenService signature = signature }; - _logger.LogInformation("Debiting {Amount} credits for user {UserName} (wallet: {WalletAddress}) with request ID {RequestId}", + _logger.LogInformation( + "Debiting {Amount} credits for user {UserName} (wallet: {WalletAddress}) with request ID {RequestId}", debitAmount, user.Name, walletAddress, requestId); var response = await _httpClient.PutAsJsonAsync( - $"{_settings.BaseUrl}{_settings.DebitEndpoint}", - requestPayload, + $"{_settings.BaseUrl}{_settings.DebitEndpoint}", + requestPayload, _jsonOptions); if (!response.IsSuccessStatusCode) { var errorContent = await response.Content.ReadAsStringAsync(); - _logger.LogError("Failed to debit credits. Status: {StatusCode}, Error: {Error}", + _logger.LogError("Failed to debit credits. Status: {StatusCode}, Error: {Error}", response.StatusCode, errorContent); throw new Exception($"Failed to debit credits: {response.StatusCode} - {errorContent}"); } var result = await response.Content.ReadFromJsonAsync(_jsonOptions); - _logger.LogInformation("Successfully debited {Amount} credits for user {UserName} (wallet: {WalletAddress})", + _logger.LogInformation( + "Successfully debited {Amount} credits for user {UserName} (wallet: {WalletAddress})", debitAmount, user.Name, walletAddress); return requestId; @@ -133,7 +137,7 @@ public class KaigenService : IKaigenService // If credits are disabled, return true (success) immediately if (!_creditsEnabled) { - _logger.LogInformation("Credits disabled - skipping refund for user {UserName} with request ID {RequestId}", + _logger.LogInformation("Credits disabled - skipping refund for user {UserName} with request ID {RequestId}", user.Name, requestId); return true; } @@ -141,10 +145,10 @@ public class KaigenService : IKaigenService try { var walletAddress = GetUserWalletAddress(user); - + // Create the message to sign (concatenate the values) var message = $"{requestId}{walletAddress}"; - + // Sign the message var signature = SignMessage(message, _settings.PrivateKey); @@ -156,23 +160,25 @@ public class KaigenService : IKaigenService signature = signature }; - _logger.LogInformation("Refunding credits for user {UserName} (wallet: {WalletAddress}) with request ID {RequestId}", + _logger.LogInformation( + "Refunding credits for user {UserName} (wallet: {WalletAddress}) with request ID {RequestId}", user.Name, walletAddress, requestId); var response = await _httpClient.PutAsJsonAsync( - $"{_settings.BaseUrl}{_settings.RefundEndpoint}", - requestPayload, + $"{_settings.BaseUrl}{_settings.RefundEndpoint}", + requestPayload, _jsonOptions); if (!response.IsSuccessStatusCode) { var errorContent = await response.Content.ReadAsStringAsync(); - _logger.LogError("Failed to refund credits. Status: {StatusCode}, Error: {Error}", + _logger.LogError("Failed to refund credits. Status: {StatusCode}, Error: {Error}", response.StatusCode, errorContent); return false; } - _logger.LogInformation("Successfully refunded credits for user {UserName} (wallet: {WalletAddress})", user.Name, walletAddress); + _logger.LogInformation("Successfully refunded credits for user {UserName} (wallet: {WalletAddress})", + user.Name, walletAddress); return true; } catch (Exception ex) @@ -191,7 +197,7 @@ public class KaigenService : IKaigenService // Use the first account's key as the wallet address var walletAddress = user.Accounts[0].Key; - + if (string.IsNullOrEmpty(walletAddress)) { throw new InvalidOperationException($"No wallet address found for user {user.Name}"); diff --git a/src/Managing.WebApp/src/components/organism/Backtest/backtestRowDetails.tsx b/src/Managing.WebApp/src/components/organism/Backtest/backtestRowDetails.tsx index ac2e8a1..dbe7f79 100644 --- a/src/Managing.WebApp/src/components/organism/Backtest/backtestRowDetails.tsx +++ b/src/Managing.WebApp/src/components/organism/Backtest/backtestRowDetails.tsx @@ -1,6 +1,7 @@ import {CardPositionItem, TradeChart} from '..' import { Backtest, + BacktestClient, CandlesWithIndicatorsResponse, DataClient, GetCandlesWithIndicatorsRequest, @@ -20,6 +21,17 @@ const BacktestRowDetails: React.FC = ({ }) => { const {apiUrl} = useApiUrlStore(); const dataClient = new DataClient({}, apiUrl); + const backtestClient = new BacktestClient({}, apiUrl); + + // Use TanStack Query to load full backtest data + const {data: fullBacktestData, isLoading: isLoadingFullBacktest, error: fullBacktestError} = useQuery({ + queryKey: ['fullBacktest', backtest.id], + queryFn: async (): Promise => { + return await backtestClient.backtest_Backtest(backtest.id); + }, + staleTime: 5 * 60 * 1000, // 5 minutes + gcTime: 10 * 60 * 1000, // 10 minutes (formerly cacheTime) + }); // Use TanStack Query to load candles with indicators const {data: candlesData, isLoading: isLoadingCandles, error} = useQuery({ @@ -65,9 +77,12 @@ const BacktestRowDetails: React.FC = ({ gcTime: 10 * 60 * 1000, // 10 minutes (formerly cacheTime) }); + // Use the full backtest data if available, otherwise fallback to the original backtest + const currentBacktest = fullBacktestData || backtest; + // Use the data from query or fallback to backtest data - const candles = candlesData?.candles || backtest.candles || []; - const indicatorsValues = candlesData?.indicatorsValues || backtest.indicatorsValues || {}; + const candles = candlesData?.candles || currentBacktest.candles || []; + const indicatorsValues = candlesData?.indicatorsValues || currentBacktest.indicatorsValues || {}; const { positions, @@ -75,7 +90,7 @@ const BacktestRowDetails: React.FC = ({ signals, statistics, config - } = backtest; + } = currentBacktest; // Helper function to calculate position open time in hours const calculateOpenTimeInHours = (position: any) => { @@ -301,10 +316,12 @@ const BacktestRowDetails: React.FC = ({ return ( <>
- {isLoadingCandles && ( + {(isLoadingCandles || isLoadingFullBacktest) && (
- Loading candles with indicators... + + {isLoadingFullBacktest ? "Loading backtest data..." : "Loading candles with indicators..."} +
)}
@@ -358,7 +375,7 @@ const BacktestRowDetails: React.FC = ({ = ({ > = ({ content={getAverageTradesPerDay() + " trades/day"} >
- {!isLoadingCandles && ( + {!isLoadingCandles && !isLoadingFullBacktest && (