实现策略引擎核心功能,包括三种策略计算器和相关DTO定义: 1. 添加双均线策略(ma_trend)计算器 2. 添加吊灯止损策略(chandelier_exit)计算器 3. 添加风险平价策略(risk_parity)计算器 4. 定义策略类型常量类和策略配置DTO 5. 实现策略引擎服务接口和扩展方法 6. 更新项目引用和README文档
85 lines
2.7 KiB
C#
85 lines
2.7 KiB
C#
using AssetManager.Data;
|
|
using AssetManager.Models.DTOs;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace AssetManager.Infrastructure.StrategyEngine;
|
|
|
|
/// <summary>
|
|
/// 策略引擎实现
|
|
/// </summary>
|
|
public class StrategyEngine : IStrategyEngine
|
|
{
|
|
private readonly Dictionary<string, IStrategyCalculator> _calculators;
|
|
private readonly ILogger<StrategyEngine> _logger;
|
|
|
|
public StrategyEngine(
|
|
IEnumerable<IStrategyCalculator> calculators,
|
|
ILogger<StrategyEngine> logger)
|
|
{
|
|
_calculators = calculators.ToDictionary(c => c.StrategyType, c => c);
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task<StrategySignal> CalculateSignalAsync(
|
|
Strategy strategy,
|
|
List<Position> 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
|
|
};
|
|
}
|
|
}
|
|
} |