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)
/// </summary>
/// <returns>List of candles ordered by date</returns>
Task<List<Candle>> GetCandlesAsync();
Task<HashSet<Candle>> GetCandlesAsync();
Task<Candle> GetLastCandle();
}

View File

@@ -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
/// </summary>
/// <param name="config">The trading bot configuration</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>
Task<LightSignal> GetSignals(TradingBotConfig config, Dictionary<string, LightSignal> previousSignals, DateTime startDate,
Candle candle);
Task<LightSignal> GetSignals(TradingBotConfig config, Dictionary<string, LightSignal> previousSignals,
Enums.TradingExchanges tradingExchange,
Candle lastCandle);
}

View File

@@ -123,7 +123,7 @@ public class TradingBotBase : ITradingBot
{
var grainKey = CandleHelpers.GetCandleStoreGrainKey(Account.Exchange, Config.Ticker, Config.Timeframe);
var grain = grainFactory.GetGrain<ICandleStoreGrain>(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<IGrainFactory>(_scopeFactory, async grainFactory =>
{
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;
await AddSignal(signal);
});

View File

@@ -77,7 +77,7 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
await base.OnDeactivateAsync(reason, cancellationToken);
}
public Task<List<Candle>> GetCandlesAsync()
public Task<HashSet<Candle>> GetCandlesAsync()
{
try
{
@@ -86,15 +86,15 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
{
_logger.LogWarning("State not initialized for grain {GrainKey}, returning empty list",
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)
{
_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
{
var streamProvider = this.GetStreamProvider("DefaultStreamProvider");
var streamProvider = this.GetStreamProvider("ManagingStreamProvider");
_priceStream = streamProvider.GetStream<Candle>(streamKey);
_streamSubscription = await _priceStream.SubscribeAsync(this);

View File

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

View File

@@ -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<HashSet<Candle>> GetCandlesAsync(TradingBotConfig config, DateTime startDate)
private async Task<HashSet<Candle>> GetCandlesAsync(TradingExchanges tradingExchange, TradingBotConfig config)
{
try
{
var newCandles = await ServiceScopeHelpers.WithScopedService<IExchangeService, HashSet<Candle>>(
_scopeFactory, async exchangeService =>
var newCandles = await ServiceScopeHelpers.WithScopedService<IGrainFactory, HashSet<Candle>>(
_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<ICandleStoreGrain>(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<LightSignal> GetSignals(TradingBotConfig config, Dictionary<string, LightSignal> 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

View File

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

View File

@@ -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; }
/// <summary>
/// Risk management configuration for advanced probabilistic analysis and position sizing.