using AssetManager.Data; using AssetManager.Models.DTOs; using Microsoft.Extensions.Logging; namespace AssetManager.Infrastructure.StrategyEngine; /// /// 策略引擎实现 /// public class StrategyEngine : IStrategyEngine { private readonly Dictionary _calculators; private readonly ILogger _logger; public StrategyEngine( IEnumerable calculators, ILogger logger) { _calculators = calculators.ToDictionary(c => c.StrategyType, c => c); _logger = logger; } public async Task CalculateSignalAsync( Strategy strategy, List positions, CancellationToken cancellationToken = default) { _logger.LogInformation( "开始计算策略信号, 策略ID: {StrategyId}, 类型: {StrategyType}, 持仓数: {PositionCount}", strategy.Id, strategy.Type, positions.Count); if (positions.Count == 0) { return new StrategySignal { StrategyType = strategy.Type, Signal = "HOLD", Reason = "无持仓", GeneratedAt = DateTime.UtcNow }; } if (!_calculators.TryGetValue(strategy.Type, out var calculator)) { _logger.LogWarning("未找到策略类型 {StrategyType} 的计算器", strategy.Type); return new StrategySignal { StrategyType = strategy.Type, Signal = "HOLD", Reason = $"不支持的策略类型: {strategy.Type}", GeneratedAt = DateTime.UtcNow }; } try { var signal = await calculator.CalculateAsync( strategy.Config ?? "{}", positions, cancellationToken); _logger.LogInformation( "策略信号计算完成, 策略ID: {StrategyId}, 信号: {Signal}", strategy.Id, signal.Signal); return signal; } catch (OperationCanceledException) { _logger.LogInformation("策略信号计算被取消, 策略ID: {StrategyId}", strategy.Id); throw; } catch (Exception ex) { _logger.LogError(ex, "策略信号计算失败, 策略ID: {StrategyId}", strategy.Id); return new StrategySignal { StrategyType = strategy.Type, Signal = "HOLD", Reason = $"计算失败: {ex.Message}", GeneratedAt = DateTime.UtcNow }; } } }