From 37d57a1bb87ae5714e659fb42b875dfe758ecb60 Mon Sep 17 00:00:00 2001 From: cryptooda Date: Sun, 14 Sep 2025 23:02:42 +0700 Subject: [PATCH] Update running time exec --- .../Grains/ICandleStoreGrain.cs | 2 +- .../Grains/IScenarioRunnerGrain.cs | 8 +-- .../Bots/TradingBotBase.cs | 6 +-- .../Grains/CandleStoreGrain.cs | 10 ++-- .../Grains/PriceFetcherGrain.cs | 4 +- .../Scenarios/ScenarioRunnerGrain.cs | 21 ++++---- src/Managing.Bootstrap/ApiBootstrap.cs | 2 +- src/Managing.Domain/Bots/TradingBotConfig.cs | 53 ++++++++----------- 8 files changed, 47 insertions(+), 59 deletions(-) diff --git a/src/Managing.Application.Abstractions/Grains/ICandleStoreGrain.cs b/src/Managing.Application.Abstractions/Grains/ICandleStoreGrain.cs index b417a6a0..d42306b9 100644 --- a/src/Managing.Application.Abstractions/Grains/ICandleStoreGrain.cs +++ b/src/Managing.Application.Abstractions/Grains/ICandleStoreGrain.cs @@ -14,7 +14,7 @@ public interface ICandleStoreGrain : IGrainWithStringKey /// Gets the current list of historical candles (up to 500 most recent) /// /// List of candles ordered by date - Task> GetCandlesAsync(); + Task> GetCandlesAsync(); Task GetLastCandle(); } diff --git a/src/Managing.Application/Abstractions/Grains/IScenarioRunnerGrain.cs b/src/Managing.Application/Abstractions/Grains/IScenarioRunnerGrain.cs index 20d7dd36..2f05300a 100644 --- a/src/Managing.Application/Abstractions/Grains/IScenarioRunnerGrain.cs +++ b/src/Managing.Application/Abstractions/Grains/IScenarioRunnerGrain.cs @@ -1,3 +1,4 @@ +using Managing.Common; using Managing.Domain.Bots; using Managing.Domain.Candles; using Managing.Domain.Indicators; @@ -15,8 +16,9 @@ public interface IScenarioRunnerGrain : IGrainWithGuidKey /// /// The trading bot configuration /// Previous signals to consider - /// Start date + /// Trading Exchange /// The generated signal or null if no signal - Task GetSignals(TradingBotConfig config, Dictionary previousSignals, DateTime startDate, - Candle candle); + Task GetSignals(TradingBotConfig config, Dictionary previousSignals, + Enums.TradingExchanges tradingExchange, + Candle lastCandle); } \ No newline at end of file diff --git a/src/Managing.Application/Bots/TradingBotBase.cs b/src/Managing.Application/Bots/TradingBotBase.cs index 954434f0..fdce0cce 100644 --- a/src/Managing.Application/Bots/TradingBotBase.cs +++ b/src/Managing.Application/Bots/TradingBotBase.cs @@ -123,7 +123,7 @@ public class TradingBotBase : ITradingBot { var grainKey = CandleHelpers.GetCandleStoreGrainKey(Account.Exchange, Config.Ticker, Config.Timeframe); var grain = grainFactory.GetGrain(grainKey); - + try { // Add a small delay to ensure grain is fully activated @@ -133,7 +133,7 @@ public class TradingBotBase : ITradingBot catch (InvalidOperationException ex) when (ex.Message.Contains("invalid activation")) { Logger.LogWarning("Grain activation failed for {GrainKey}, retrying in 1 second...", grainKey); - + // Wait a bit longer and retry once await Task.Delay(1000); try @@ -215,7 +215,7 @@ public class TradingBotBase : ITradingBot await ServiceScopeHelpers.WithScopedService(_scopeFactory, async grainFactory => { var scenarioRunnerGrain = grainFactory.GetGrain(Guid.NewGuid()); - var signal = await scenarioRunnerGrain.GetSignals(Config, Signals, PreloadSince, LastCandle); + var signal = await scenarioRunnerGrain.GetSignals(Config, Signals, Account.Exchange, LastCandle); if (signal == null) return; await AddSignal(signal); }); diff --git a/src/Managing.Application/Grains/CandleStoreGrain.cs b/src/Managing.Application/Grains/CandleStoreGrain.cs index a7554491..f914ca96 100644 --- a/src/Managing.Application/Grains/CandleStoreGrain.cs +++ b/src/Managing.Application/Grains/CandleStoreGrain.cs @@ -77,7 +77,7 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver await base.OnDeactivateAsync(reason, cancellationToken); } - public Task> GetCandlesAsync() + public Task> GetCandlesAsync() { try { @@ -86,15 +86,15 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver { _logger.LogWarning("State not initialized for grain {GrainKey}, returning empty list", this.GetPrimaryKeyString()); - return Task.FromResult(new List()); + return Task.FromResult(new HashSet()); } - return Task.FromResult(_state.State.Candles.ToList()); + return Task.FromResult(_state.State.Candles.ToHashSet()); } catch (Exception ex) { _logger.LogError(ex, "Error retrieving candles for grain {GrainKey}", this.GetPrimaryKeyString()); - return Task.FromResult(new List()); + return Task.FromResult(new HashSet()); } } @@ -205,7 +205,7 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver { try { - var streamProvider = this.GetStreamProvider("DefaultStreamProvider"); + var streamProvider = this.GetStreamProvider("ManagingStreamProvider"); _priceStream = streamProvider.GetStream(streamKey); _streamSubscription = await _priceStream.SubscribeAsync(this); diff --git a/src/Managing.Application/Grains/PriceFetcherGrain.cs b/src/Managing.Application/Grains/PriceFetcherGrain.cs index 7a05bdc3..a1af9523 100644 --- a/src/Managing.Application/Grains/PriceFetcherGrain.cs +++ b/src/Managing.Application/Grains/PriceFetcherGrain.cs @@ -171,8 +171,8 @@ public class PriceFetcherGrain : Grain, IPriceFetcherGrain, IRemindable processedCandles.Count, streamKey); } - var streamProvider = this.GetStreamProvider("DefaultStreamProvider"); - var stream = streamProvider.GetStream(streamKey); + var streamProvider = this.GetStreamProvider("ManagingStreamProvider"); + var stream = streamProvider.GetStream("Candles", streamKey); // Publish to stream (if needed) foreach (var candle in processedCandles) diff --git a/src/Managing.Application/Scenarios/ScenarioRunnerGrain.cs b/src/Managing.Application/Scenarios/ScenarioRunnerGrain.cs index 2bf41d36..3f3f163c 100644 --- a/src/Managing.Application/Scenarios/ScenarioRunnerGrain.cs +++ b/src/Managing.Application/Scenarios/ScenarioRunnerGrain.cs @@ -1,5 +1,4 @@ using Managing.Application.Abstractions.Grains; -using Managing.Application.Abstractions.Services; using Managing.Core; using Managing.Domain.Bots; using Managing.Domain.Candles; @@ -30,19 +29,17 @@ public class ScenarioRunnerGrain : Grain, IScenarioRunnerGrain _scopeFactory = scopeFactory; } - private async Task> GetCandlesAsync(TradingBotConfig config, DateTime startDate) + private async Task> GetCandlesAsync(TradingExchanges tradingExchange, TradingBotConfig config) { try { - var newCandles = await ServiceScopeHelpers.WithScopedService>( - _scopeFactory, async exchangeService => + var newCandles = await ServiceScopeHelpers.WithScopedService>( + _scopeFactory, async grainFactory => { - return await exchangeService.GetCandlesInflux( - TradingExchanges.Evm, - config.Ticker, - startDate, - config.Timeframe, - 500); + var priceGrainKey = + CandleHelpers.GetCandleStoreGrainKey(tradingExchange, config.Ticker, config.Timeframe); + var grain = grainFactory.GetGrain(priceGrainKey); + return await grain.GetCandlesAsync(); }); _logger.LogInformation($"Updated {newCandles.Count} candles for {config.Ticker}"); @@ -56,7 +53,7 @@ public class ScenarioRunnerGrain : Grain, IScenarioRunnerGrain } public async Task GetSignals(TradingBotConfig config, Dictionary previousSignals, - DateTime startDate, Candle candle) + TradingExchanges tradingExchanges, Candle candle) { try { @@ -64,7 +61,7 @@ public class ScenarioRunnerGrain : Grain, IScenarioRunnerGrain // candle, candle.Date, TradingExchanges.Evm, IndicatorType.Composite, // SignalType.Signal, "Generated Signal"); - var candlesHashSet = await GetCandlesAsync(config, startDate); + var candlesHashSet = await GetCandlesAsync(tradingExchanges, config); if (candlesHashSet.LastOrDefault()!.Date <= candle.Date) { return null; // No new candles, no need to generate a signal diff --git a/src/Managing.Bootstrap/ApiBootstrap.cs b/src/Managing.Bootstrap/ApiBootstrap.cs index c384f87d..af864de0 100644 --- a/src/Managing.Bootstrap/ApiBootstrap.cs +++ b/src/Managing.Bootstrap/ApiBootstrap.cs @@ -321,7 +321,7 @@ public static class ApiBootstrap } // Configure Orleans Streams for price data distribution - siloBuilder.AddMemoryStreams("DefaultStreamProvider") + siloBuilder.AddMemoryStreams("ManagingStreamProvider") .AddMemoryGrainStorage("PubSubStore"); siloBuilder diff --git a/src/Managing.Domain/Bots/TradingBotConfig.cs b/src/Managing.Domain/Bots/TradingBotConfig.cs index ad0fc4ae..bb6417db 100644 --- a/src/Managing.Domain/Bots/TradingBotConfig.cs +++ b/src/Managing.Domain/Bots/TradingBotConfig.cs @@ -9,38 +9,27 @@ namespace Managing.Domain.Bots; [GenerateSerializer] public class TradingBotConfig { - [Id(0)] - [Required] public string AccountName { get; set; } - - [Id(1)] - [Required] public LightMoneyManagement MoneyManagement { get; set; } - - [Id(2)] - [Required] public Ticker Ticker { get; set; } - - [Id(3)] - [Required] public Timeframe Timeframe { get; set; } - - [Id(4)] - [Required] public bool IsForWatchingOnly { get; set; } - - [Id(5)] - [Required] public decimal BotTradingBalance { get; set; } - - [Id(6)] - [Required] public bool IsForBacktest { get; set; } - - [Id(7)] - [Required] public int CooldownPeriod { get; set; } - - [Id(8)] - [Required] public int MaxLossStreak { get; set; } - - [Id(9)] - [Required] public bool FlipPosition { get; set; } - - [Id(10)] - [Required] public string Name { get; set; } + [Id(0)] [Required] public string AccountName { get; set; } + + [Id(1)] [Required] public LightMoneyManagement MoneyManagement { get; set; } + + [Id(2)] [Required] public Ticker Ticker { get; set; } + + [Id(3)] [Required] public Timeframe Timeframe { get; set; } + + [Id(4)] [Required] public bool IsForWatchingOnly { get; set; } + + [Id(5)] [Required] public decimal BotTradingBalance { get; set; } + + [Id(6)] [Required] public bool IsForBacktest { get; set; } + + [Id(7)] [Required] public int CooldownPeriod { get; set; } + + [Id(8)] [Required] public int MaxLossStreak { get; set; } + + [Id(9)] [Required] public bool FlipPosition { get; set; } + + [Id(10)] [Required] public string Name { get; set; } /// /// Risk management configuration for advanced probabilistic analysis and position sizing.