Files
Predictalytics/src/Predictalytics.Worker/Services/TraderAnalyticsWorker.cs
T

73 lines
2.2 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Predictalytics.Infrastructure.Data;
using Predictalytics.Application.Interfaces;
namespace Predictalytics.Worker.Services;
public class TraderAnalyticsWorker : BackgroundService
{
private readonly IServiceProvider _services;
private readonly ILogger<TraderAnalyticsWorker> _logger;
public TraderAnalyticsWorker(IServiceProvider services, ILogger<TraderAnalyticsWorker> _logger)
{
_services = services;
this._logger = _logger;
}
protected override async Task ExecuteAsync(CancellationToken ct)
{
_logger.LogInformation("TraderAnalyticsWorker starting...");
while (!ct.IsCancellationRequested)
{
try
{
await RunAnalyticsAsync(ct);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in TraderAnalyticsWorker");
}
_logger.LogInformation("TraderAnalyticsWorker sleeping for 12 hours...");
await Task.Delay(TimeSpan.FromHours(12), ct);
}
}
private async Task RunAnalyticsAsync(CancellationToken ct)
{
using var scope = _services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var pnlEngine = scope.ServiceProvider.GetRequiredService<IPositionPnLEngine>();
var cutoff30d = DateTime.UtcNow.AddDays(-30);
// Find traders active in the last 30 days
var traderIds = await db.Trades
.Where(t => t.ExecutedAt >= cutoff30d)
.Select(t => t.TraderId)
.Distinct()
.ToListAsync(ct);
_logger.LogInformation("Found {Count} active traders to analyze", traderIds.Count);
foreach (var id in traderIds)
{
try
{
await pnlEngine.RecalculateTraderPositionsAsync(id, ct);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error recalculating positions/PnL for trader {TraderId}", id);
}
}
_logger.LogInformation("Trader analytics update complete.");
}
}