Update running time exec
This commit is contained in:
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ public class TradingBotBase : ITradingBot
|
|||||||
{
|
{
|
||||||
var grainKey = CandleHelpers.GetCandleStoreGrainKey(Account.Exchange, Config.Ticker, Config.Timeframe);
|
var grainKey = CandleHelpers.GetCandleStoreGrainKey(Account.Exchange, Config.Ticker, Config.Timeframe);
|
||||||
var grain = grainFactory.GetGrain<ICandleStoreGrain>(grainKey);
|
var grain = grainFactory.GetGrain<ICandleStoreGrain>(grainKey);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Add a small delay to ensure grain is fully activated
|
// 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"))
|
catch (InvalidOperationException ex) when (ex.Message.Contains("invalid activation"))
|
||||||
{
|
{
|
||||||
Logger.LogWarning("Grain activation failed for {GrainKey}, retrying in 1 second...", grainKey);
|
Logger.LogWarning("Grain activation failed for {GrainKey}, retrying in 1 second...", grainKey);
|
||||||
|
|
||||||
// Wait a bit longer and retry once
|
// Wait a bit longer and retry once
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000);
|
||||||
try
|
try
|
||||||
@@ -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);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)] [Required] public LightMoneyManagement MoneyManagement { get; set; }
|
||||||
[Id(1)]
|
|
||||||
[Required] public LightMoneyManagement MoneyManagement { get; set; }
|
[Id(2)] [Required] public Ticker Ticker { get; set; }
|
||||||
|
|
||||||
[Id(2)]
|
[Id(3)] [Required] public Timeframe Timeframe { get; set; }
|
||||||
[Required] public Ticker Ticker { get; set; }
|
|
||||||
|
[Id(4)] [Required] public bool IsForWatchingOnly { get; set; }
|
||||||
[Id(3)]
|
|
||||||
[Required] public Timeframe Timeframe { get; set; }
|
[Id(5)] [Required] public decimal BotTradingBalance { get; set; }
|
||||||
|
|
||||||
[Id(4)]
|
[Id(6)] [Required] public bool IsForBacktest { get; set; }
|
||||||
[Required] public bool IsForWatchingOnly { get; set; }
|
|
||||||
|
[Id(7)] [Required] public int CooldownPeriod { get; set; }
|
||||||
[Id(5)]
|
|
||||||
[Required] public decimal BotTradingBalance { get; set; }
|
[Id(8)] [Required] public int MaxLossStreak { get; set; }
|
||||||
|
|
||||||
[Id(6)]
|
[Id(9)] [Required] public bool FlipPosition { get; set; }
|
||||||
[Required] public bool IsForBacktest { get; set; }
|
|
||||||
|
[Id(10)] [Required] public string Name { 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>
|
/// <summary>
|
||||||
/// Risk management configuration for advanced probabilistic analysis and position sizing.
|
/// Risk management configuration for advanced probabilistic analysis and position sizing.
|
||||||
|
|||||||
Reference in New Issue
Block a user