Update running time exec

This commit is contained in:
2025-09-14 23:02:42 +07:00
parent c60bc4123a
commit 37d57a1bb8
8 changed files with 47 additions and 59 deletions

View File

@@ -14,7 +14,7 @@ public interface ICandleStoreGrain : IGrainWithStringKey
/// Gets the current list of historical candles (up to 500 most recent) /// Gets the current list of historical candles (up to 500 most recent)
/// </summary> /// </summary>
/// <returns>List of candles ordered by date</returns> /// <returns>List of candles ordered by date</returns>
Task<List<Candle>> GetCandlesAsync(); Task<HashSet<Candle>> GetCandlesAsync();
Task<Candle> GetLastCandle(); Task<Candle> GetLastCandle();
} }

View File

@@ -1,3 +1,4 @@
using Managing.Common;
using Managing.Domain.Bots; using Managing.Domain.Bots;
using Managing.Domain.Candles; using Managing.Domain.Candles;
using Managing.Domain.Indicators; using Managing.Domain.Indicators;
@@ -15,8 +16,9 @@ public interface IScenarioRunnerGrain : IGrainWithGuidKey
/// </summary> /// </summary>
/// <param name="config">The trading bot configuration</param> /// <param name="config">The trading bot configuration</param>
/// <param name="previousSignals">Previous signals to consider</param> /// <param name="previousSignals">Previous signals to consider</param>
/// <param name="startDate">Start date</param> /// <param name="tradingExchange">Trading Exchange</param>
/// <returns>The generated signal or null if no signal</returns> /// <returns>The generated signal or null if no signal</returns>
Task<LightSignal> GetSignals(TradingBotConfig config, Dictionary<string, LightSignal> previousSignals, DateTime startDate, Task<LightSignal> GetSignals(TradingBotConfig config, Dictionary<string, LightSignal> previousSignals,
Candle candle); Enums.TradingExchanges tradingExchange,
Candle lastCandle);
} }

View File

@@ -215,7 +215,7 @@ public class TradingBotBase : ITradingBot
await ServiceScopeHelpers.WithScopedService<IGrainFactory>(_scopeFactory, async grainFactory => await ServiceScopeHelpers.WithScopedService<IGrainFactory>(_scopeFactory, async grainFactory =>
{ {
var scenarioRunnerGrain = grainFactory.GetGrain<IScenarioRunnerGrain>(Guid.NewGuid()); var scenarioRunnerGrain = grainFactory.GetGrain<IScenarioRunnerGrain>(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; if (signal == null) return;
await AddSignal(signal); await AddSignal(signal);
}); });

View File

@@ -77,7 +77,7 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
await base.OnDeactivateAsync(reason, cancellationToken); await base.OnDeactivateAsync(reason, cancellationToken);
} }
public Task<List<Candle>> GetCandlesAsync() public Task<HashSet<Candle>> GetCandlesAsync()
{ {
try try
{ {
@@ -86,15 +86,15 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
{ {
_logger.LogWarning("State not initialized for grain {GrainKey}, returning empty list", _logger.LogWarning("State not initialized for grain {GrainKey}, returning empty list",
this.GetPrimaryKeyString()); this.GetPrimaryKeyString());
return Task.FromResult(new List<Candle>()); return Task.FromResult(new HashSet<Candle>());
} }
return Task.FromResult(_state.State.Candles.ToList()); return Task.FromResult(_state.State.Candles.ToHashSet());
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Error retrieving candles for grain {GrainKey}", this.GetPrimaryKeyString()); _logger.LogError(ex, "Error retrieving candles for grain {GrainKey}", this.GetPrimaryKeyString());
return Task.FromResult(new List<Candle>()); return Task.FromResult(new HashSet<Candle>());
} }
} }
@@ -205,7 +205,7 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
{ {
try try
{ {
var streamProvider = this.GetStreamProvider("DefaultStreamProvider"); var streamProvider = this.GetStreamProvider("ManagingStreamProvider");
_priceStream = streamProvider.GetStream<Candle>(streamKey); _priceStream = streamProvider.GetStream<Candle>(streamKey);
_streamSubscription = await _priceStream.SubscribeAsync(this); _streamSubscription = await _priceStream.SubscribeAsync(this);

View File

@@ -171,8 +171,8 @@ public class PriceFetcherGrain : Grain, IPriceFetcherGrain, IRemindable
processedCandles.Count, streamKey); processedCandles.Count, streamKey);
} }
var streamProvider = this.GetStreamProvider("DefaultStreamProvider"); var streamProvider = this.GetStreamProvider("ManagingStreamProvider");
var stream = streamProvider.GetStream<Candle>(streamKey); var stream = streamProvider.GetStream<Candle>("Candles", streamKey);
// Publish to stream (if needed) // Publish to stream (if needed)
foreach (var candle in processedCandles) foreach (var candle in processedCandles)

View File

@@ -1,5 +1,4 @@
using Managing.Application.Abstractions.Grains; using Managing.Application.Abstractions.Grains;
using Managing.Application.Abstractions.Services;
using Managing.Core; using Managing.Core;
using Managing.Domain.Bots; using Managing.Domain.Bots;
using Managing.Domain.Candles; using Managing.Domain.Candles;
@@ -30,19 +29,17 @@ public class ScenarioRunnerGrain : Grain, IScenarioRunnerGrain
_scopeFactory = scopeFactory; _scopeFactory = scopeFactory;
} }
private async Task<HashSet<Candle>> GetCandlesAsync(TradingBotConfig config, DateTime startDate) private async Task<HashSet<Candle>> GetCandlesAsync(TradingExchanges tradingExchange, TradingBotConfig config)
{ {
try try
{ {
var newCandles = await ServiceScopeHelpers.WithScopedService<IExchangeService, HashSet<Candle>>( var newCandles = await ServiceScopeHelpers.WithScopedService<IGrainFactory, HashSet<Candle>>(
_scopeFactory, async exchangeService => _scopeFactory, async grainFactory =>
{ {
return await exchangeService.GetCandlesInflux( var priceGrainKey =
TradingExchanges.Evm, CandleHelpers.GetCandleStoreGrainKey(tradingExchange, config.Ticker, config.Timeframe);
config.Ticker, var grain = grainFactory.GetGrain<ICandleStoreGrain>(priceGrainKey);
startDate, return await grain.GetCandlesAsync();
config.Timeframe,
500);
}); });
_logger.LogInformation($"Updated {newCandles.Count} candles for {config.Ticker}"); _logger.LogInformation($"Updated {newCandles.Count} candles for {config.Ticker}");
@@ -56,7 +53,7 @@ public class ScenarioRunnerGrain : Grain, IScenarioRunnerGrain
} }
public async Task<LightSignal> GetSignals(TradingBotConfig config, Dictionary<string, LightSignal> previousSignals, public async Task<LightSignal> GetSignals(TradingBotConfig config, Dictionary<string, LightSignal> previousSignals,
DateTime startDate, Candle candle) TradingExchanges tradingExchanges, Candle candle)
{ {
try try
{ {
@@ -64,7 +61,7 @@ public class ScenarioRunnerGrain : Grain, IScenarioRunnerGrain
// candle, candle.Date, TradingExchanges.Evm, IndicatorType.Composite, // candle, candle.Date, TradingExchanges.Evm, IndicatorType.Composite,
// SignalType.Signal, "Generated Signal"); // SignalType.Signal, "Generated Signal");
var candlesHashSet = await GetCandlesAsync(config, startDate); var candlesHashSet = await GetCandlesAsync(tradingExchanges, config);
if (candlesHashSet.LastOrDefault()!.Date <= candle.Date) if (candlesHashSet.LastOrDefault()!.Date <= candle.Date)
{ {
return null; // No new candles, no need to generate a signal return null; // No new candles, no need to generate a signal

View File

@@ -321,7 +321,7 @@ public static class ApiBootstrap
} }
// Configure Orleans Streams for price data distribution // Configure Orleans Streams for price data distribution
siloBuilder.AddMemoryStreams("DefaultStreamProvider") siloBuilder.AddMemoryStreams("ManagingStreamProvider")
.AddMemoryGrainStorage("PubSubStore"); .AddMemoryGrainStorage("PubSubStore");
siloBuilder siloBuilder

View File

@@ -9,38 +9,27 @@ namespace Managing.Domain.Bots;
[GenerateSerializer] [GenerateSerializer]
public class TradingBotConfig public class TradingBotConfig
{ {
[Id(0)] [Id(0)] [Required] public string AccountName { get; set; }
[Required] public string AccountName { get; set; }
[Id(1)] [Id(1)] [Required] public LightMoneyManagement MoneyManagement { get; set; }
[Required] public LightMoneyManagement MoneyManagement { get; set; }
[Id(2)] [Id(2)] [Required] public Ticker Ticker { get; set; }
[Required] public Ticker Ticker { get; set; }
[Id(3)] [Id(3)] [Required] public Timeframe Timeframe { get; set; }
[Required] public Timeframe Timeframe { get; set; }
[Id(4)] [Id(4)] [Required] public bool IsForWatchingOnly { get; set; }
[Required] public bool IsForWatchingOnly { get; set; }
[Id(5)] [Id(5)] [Required] public decimal BotTradingBalance { get; set; }
[Required] public decimal BotTradingBalance { get; set; }
[Id(6)] [Id(6)] [Required] public bool IsForBacktest { get; set; }
[Required] public bool IsForBacktest { get; set; }
[Id(7)] [Id(7)] [Required] public int CooldownPeriod { get; set; }
[Required] public int CooldownPeriod { get; set; }
[Id(8)] [Id(8)] [Required] public int MaxLossStreak { get; set; }
[Required] public int MaxLossStreak { get; set; }
[Id(9)] [Id(9)] [Required] public bool FlipPosition { get; set; }
[Required] public bool FlipPosition { get; set; }
[Id(10)] [Id(10)] [Required] public string Name { get; set; }
[Required] public string Name { get; set; }
/// <summary> /// <summary>
/// Risk management configuration for advanced probabilistic analysis and position sizing. /// Risk management configuration for advanced probabilistic analysis and position sizing.