plug candle store and bot
This commit is contained in:
@@ -16,7 +16,7 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
|
||||
private readonly IPersistentState<CandleStoreGrainState> _state;
|
||||
private readonly ILogger<CandleStoreGrain> _logger;
|
||||
private readonly ICandleRepository _candleRepository;
|
||||
|
||||
|
||||
private const int MaxCandleCount = 500;
|
||||
private IAsyncStream<Candle> _priceStream;
|
||||
private StreamSubscriptionHandle<Candle> _streamSubscription;
|
||||
@@ -38,20 +38,7 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
|
||||
_logger.LogInformation("CandleStoreGrain activated for key: {GrainKey}", grainKey);
|
||||
|
||||
// Parse the grain key to extract exchange, ticker, and timeframe
|
||||
var parts = grainKey.Split('-');
|
||||
if (parts.Length != 3)
|
||||
{
|
||||
_logger.LogError("Invalid grain key format: {GrainKey}. Expected format: Exchange-Ticker-Timeframe", grainKey);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Enum.TryParse<TradingExchanges>(parts[0], out var exchange) ||
|
||||
!Enum.TryParse<Ticker>(parts[1], out var ticker) ||
|
||||
!Enum.TryParse<Timeframe>(parts[2], out var timeframe))
|
||||
{
|
||||
_logger.LogError("Failed to parse grain key components: {GrainKey}", grainKey);
|
||||
return;
|
||||
}
|
||||
var (exchange, ticker, timeframe) = CandleHelpers.ParseCandleStoreGrainKey(grainKey);
|
||||
|
||||
// Initialize state if empty
|
||||
if (_state.State.Candles == null || _state.State.Candles.Count == 0)
|
||||
@@ -95,7 +82,7 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogDebug("Received new candle for {GrainKey} at {Date}",
|
||||
_logger.LogDebug("Received new candle for {GrainKey} at {Date}",
|
||||
this.GetPrimaryKeyString(), candle.Date);
|
||||
|
||||
// Initialize state if needed
|
||||
@@ -120,7 +107,7 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
|
||||
// Persist the updated state
|
||||
await _state.WriteStateAsync();
|
||||
|
||||
_logger.LogTrace("Updated candle store for {GrainKey}, total candles: {Count}",
|
||||
_logger.LogTrace("Updated candle store for {GrainKey}, total candles: {Count}",
|
||||
this.GetPrimaryKeyString(), _state.State.Candles.Count);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -145,14 +132,17 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Loading initial candles for {Exchange}-{Ticker}-{Timeframe}",
|
||||
_logger.LogInformation("Loading initial candles for {Exchange}-{Ticker}-{Timeframe}",
|
||||
exchange, ticker, timeframe);
|
||||
|
||||
// Load the last 500 candles from the database
|
||||
var endDate = DateTime.UtcNow;
|
||||
var startDate = endDate.AddDays(-30); // Look back 30 days to ensure we get enough data
|
||||
var startDate =
|
||||
CandleHelpers
|
||||
.GetBotPreloadSinceFromTimeframe(timeframe); // Look back 30 days to ensure we get enough data
|
||||
|
||||
var candles = await _candleRepository.GetCandles(exchange, ticker, timeframe, startDate, endDate, MaxCandleCount);
|
||||
var candles =
|
||||
await _candleRepository.GetCandles(exchange, ticker, timeframe, startDate, endDate, MaxCandleCount);
|
||||
|
||||
if (candles?.Any() == true)
|
||||
{
|
||||
@@ -163,23 +153,23 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
|
||||
|
||||
await _state.WriteStateAsync();
|
||||
|
||||
_logger.LogInformation("Loaded {Count} initial candles for {Exchange}-{Ticker}-{Timeframe}",
|
||||
_logger.LogInformation("Loaded {Count} initial candles for {Exchange}-{Ticker}-{Timeframe}",
|
||||
_state.State.Candles.Count, exchange, ticker, timeframe);
|
||||
}
|
||||
else
|
||||
{
|
||||
_state.State.Candles = new List<Candle>();
|
||||
await _state.WriteStateAsync();
|
||||
|
||||
_logger.LogWarning("No initial candles found for {Exchange}-{Ticker}-{Timeframe}",
|
||||
|
||||
_logger.LogWarning("No initial candles found for {Exchange}-{Ticker}-{Timeframe}",
|
||||
exchange, ticker, timeframe);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error loading initial candles for {Exchange}-{Ticker}-{Timeframe}",
|
||||
_logger.LogError(ex, "Error loading initial candles for {Exchange}-{Ticker}-{Timeframe}",
|
||||
exchange, ticker, timeframe);
|
||||
|
||||
|
||||
// Initialize empty state on error
|
||||
_state.State.Candles = new List<Candle>();
|
||||
await _state.WriteStateAsync();
|
||||
@@ -192,9 +182,9 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
|
||||
{
|
||||
var streamProvider = this.GetStreamProvider("DefaultStreamProvider");
|
||||
_priceStream = streamProvider.GetStream<Candle>(streamKey);
|
||||
|
||||
|
||||
_streamSubscription = await _priceStream.SubscribeAsync(this);
|
||||
|
||||
|
||||
_logger.LogInformation("Subscribed to price stream for {StreamKey}", streamKey);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -202,6 +192,11 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
|
||||
_logger.LogError(ex, "Error subscribing to price stream for {StreamKey}", streamKey);
|
||||
}
|
||||
}
|
||||
|
||||
public Task<Candle> GetLastCandle()
|
||||
{
|
||||
return Task.FromResult(_state.State.Candles?.LastOrDefault());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -210,6 +205,5 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
|
||||
[GenerateSerializer]
|
||||
public class CandleStoreGrainState
|
||||
{
|
||||
[Id(0)]
|
||||
public List<Candle> Candles { get; set; } = new();
|
||||
[Id(0)] public List<Candle> Candles { get; set; } = new();
|
||||
}
|
||||
Reference in New Issue
Block a user