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
};
}
}
}