-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Task 003: 市场状态识别
概述
实现 detect_market_regime() 方法,通过复用现有技术指标框架来识别当前市场状态(震荡、趋势、过渡)。该方法将为后续的仓位管理和网格调整提供决策依据,帮助策略在不同市场环境中选择最优的交易参数。
需求描述
功能需求
-
三种市场状态识别
- 震荡市:ADX < 25,价格在布林带中轨附近波动
- 趋势市:ADX > 40,价格突破布林带边界
- 过渡期:25 ≤ ADX ≤ 40,市场方向不明确
-
多指标综合判断
- 主要指标:ADX(趋势强度)
- 辅助指标:布林带、RSI、成交量
- 价格行为:突破、回调、整理
-
状态稳定性验证
- 连续 3 个周期确认状态变化
- 防止频繁切换导致的策略不稳定
- 实施状态切换的最小时间间隔
-
历史状态记录
- 记录状态切换历史
- 统计各状态持续时间
- 为策略优化提供数据支持
技术要求
- 完全复用现有的 TA-Lib 指标计算
- 保持计算高效性,避免重复计算
- 提供清晰的状态输出和切换日志
验收标准
功能验收
- 准确识别三种市场状态
- 状态切换逻辑稳定可靠
- 多指标综合判断合理
- 历史记录功能完整
技术验收
- 状态判断延迟 < 100ms
- 指标计算复用率 100%
- 状态切换频率 < 每小时 2 次
- 单元测试覆盖率 > 90%
业务验收
- 震荡市识别准确率 > 85%
- 趋势市识别准确率 > 80%
- 状态预测稳定性良好
- 与历史人工标记对比误差 < 15%
实现方案
核心算法
- ADX 趋势强度分析
def calculate_trend_strength(self, dataframe: DataFrame) -> float:
"""
计算趋势强度
返回 ADX 值和趋势方向
"""
# 复用现有 ADX 计算
adx = ta.ADX(dataframe, timeperiod=14)
plus_di = ta.PLUS_DI(dataframe, timeperiod=14)
minus_di = ta.MINUS_DI(dataframe, timeperiod=14)
current_adx = adx.iloc[-1]
current_plus_di = plus_di.iloc[-1]
current_minus_di = minus_di.iloc[-1]
# 趋势方向判断
trend_direction = 1 if current_plus_di > current_minus_di else -1
return current_adx, trend_direction- 布林带位置分析
def analyze_bollinger_position(self, dataframe: DataFrame) -> dict:
"""
分析价格在布林带中的位置
返回位置信息和挤压状态
"""
bb_upper, bb_middle, bb_lower = ta.BBANDS(
dataframe['close'],
timeperiod=20,
nbdevup=2,
nbdevdn=2
)
current_price = dataframe['close'].iloc[-1]
current_upper = bb_upper.iloc[-1]
current_middle = bb_middle.iloc[-1]
current_lower = bb_lower.iloc[-1]
# 计算位置百分比
bb_position = (current_price - current_lower) / (current_upper - current_lower)
# 布林带挤压检测
bb_width = (current_upper - current_lower) / current_middle
bb_squeeze = bb_width < self.bb_squeeze_threshold.value
return {
'position': bb_position,
'width': bb_width,
'squeeze': bb_squeeze,
'breakout': bb_position < 0.1 or bb_position > 0.9
}- 市场状态综合判断
def detect_market_regime(self, dataframe: DataFrame) -> str:
"""
综合判断当前市场状态
返回: 'ranging', 'trending', 'transitioning'
"""
# 获取技术指标
adx_value, trend_direction = self.calculate_trend_strength(dataframe)
bb_analysis = self.analyze_bollinger_position(dataframe)
rsi = ta.RSI(dataframe, timeperiod=14).iloc[-1]
# 辅助判断因子
volume_sma = ta.SMA(dataframe['volume'], timeperiod=20)
volume_ratio = dataframe['volume'].iloc[-1] / volume_sma.iloc[-1]
# 状态判断逻辑
if adx_value < self.adx_ranging_threshold.value:
if bb_analysis['squeeze'] and 30 < rsi < 70:
regime = 'ranging'
else:
regime = 'transitioning'
elif adx_value > self.adx_trending_threshold.value:
if bb_analysis['breakout'] and volume_ratio > 1.2:
regime = 'trending'
else:
regime = 'transitioning'
else:
regime = 'transitioning'
# 状态稳定性验证
confirmed_regime = self.confirm_regime_change(regime)
return confirmed_regime- 状态稳定性验证
def confirm_regime_change(self, new_regime: str) -> str:
"""
验证状态变化的稳定性
需要连续确认才能切换状态
"""
if not hasattr(self, 'regime_history'):
self.regime_history = ['ranging'] * 5 # 初始状态
self.current_regime = 'ranging'
# 添加新的判断结果
self.regime_history.append(new_regime)
if len(self.regime_history) > 5:
self.regime_history.pop(0)
# 连续确认逻辑
recent_regimes = self.regime_history[-3:] # 最近3个周期
if len(set(recent_regimes)) == 1 and recent_regimes[0] != self.current_regime:
# 状态切换确认
old_regime = self.current_regime
self.current_regime = recent_regimes[0]
# 记录切换日志
logger.info(f"Market regime changed: {old_regime} -> {self.current_regime}")
return self.current_regime参数配置
# ADX 阈值参数
adx_ranging_threshold = DecimalParameter(15, 30, default=25, space="buy")
adx_trending_threshold = DecimalParameter(35, 50, default=40, space="buy")
# 布林带参数
bb_squeeze_threshold = DecimalParameter(0.1, 0.3, default=0.2, space="buy")
bb_breakout_threshold = DecimalParameter(0.05, 0.15, default=0.1, space="buy")
# RSI 辅助参数
rsi_overbought = IntParameter(65, 80, default=70, space="buy")
rsi_oversold = IntParameter(20, 35, default=30, space="buy")
# 确认参数
confirmation_periods = IntParameter(2, 5, default=3, space="buy")
min_regime_duration = IntParameter(5, 20, default=10, space="buy") # 最小持续周期状态管理
class MarketRegimeTracker:
"""市场状态追踪器"""
def __init__(self):
self.current_regime = 'ranging'
self.regime_start_time = None
self.regime_history = []
self.state_transitions = []
def update_regime(self, new_regime: str, timestamp: datetime):
"""更新市场状态"""
if new_regime != self.current_regime:
self.state_transitions.append({
'from': self.current_regime,
'to': new_regime,
'timestamp': timestamp,
'duration': self._calculate_duration()
})
self.current_regime = new_regime
self.regime_start_time = timestamp
def get_regime_stats(self) -> dict:
"""获取状态统计信息"""
return {
'current': self.current_regime,
'duration': self._calculate_duration(),
'transitions': len(self.state_transitions),
'stability': self._calculate_stability()
}测试计划
单元测试
- 指标计算测试
def test_trend_strength_calculation():
# 测试 ADX 计算准确性
# 验证趋势方向判断
# 测试边界情况
def test_bollinger_analysis():
# 测试布林带位置计算
# 验证挤压检测逻辑
# 测试突破识别
def test_regime_detection():
# 测试各种市场状态识别
# 验证综合判断逻辑
# 测试参数敏感性- 状态稳定性测试
def test_regime_confirmation():
# 测试状态切换确认机制
# 验证最小持续时间
# 测试频繁切换防护
def test_regime_history():
# 测试历史记录功能
# 验证统计信息准确性
# 测试内存使用控制历史数据验证
-
人工标记对比
- 选择典型的震荡和趋势行情片段
- 人工标记市场状态作为基准
- 计算算法识别的准确率
-
多时间框架验证
- 在不同时间框架下测试识别效果
- 验证状态一致性
- 分析最优参数组合
-
不同市场环境
- 牛市、熊市、震荡市
- 高波动、低波动环境
- 突发事件影响期间
性能测试
-
计算性能
- 大量历史数据处理速度
- 实时计算延迟测试
- 内存使用情况监控
-
准确性测试
- 状态识别准确率统计
- 假阳性/假阴性分析
- 不同参数下的效果对比
风险评估
算法风险
- 中等风险:复杂的多指标综合判断可能存在偏差
- 缓解措施:
- 充分的历史数据验证
- 保守的状态切换确认机制
- 提供手动状态覆盖选项
性能风险
- 低风险:额外的指标计算和状态管理开销
- 缓解措施:
- 复用现有指标计算结果
- 优化状态更新频率
- 实施智能缓存机制
业务风险
- 中等风险:状态误判可能影响策略收益
- 缓解措施:
- 渐进式部署和验证
- 保留状态识别功能的开关
- 记录详细的状态切换日志
完成定义
代码完成标准
-
detect_market_regime()方法完整实现 - 多指标综合判断逻辑正确
- 状态稳定性验证机制完善
- 历史记录和统计功能完整
测试完成标准
- 单元测试覆盖率 > 90%
- 历史数据验证通过
- 性能测试达标
- 准确率满足业务要求
部署标准
- 配置参数文档完整
- 状态切换日志清晰
- 监控指标完善
- 回退机制可用
时间估算
- 算法设计: 1.5小时
- 核心编码: 2.5小时
- 状态管理: 1小时
- 测试编写: 1小时
总计: 6小时
依赖关系
前置依赖
- Task 001: EnhancedGridStrategy 基础框架
- 需要基础类结构
- 需要指标计算接口
影响范围
- 为仓位管理模块提供市场状态信息
- 为网格调整提供环境依据
- 为风险控制提供市场判断
性能目标
识别准确率
- 震荡市识别: > 85%
- 趋势市识别: > 80%
- 过渡期识别: > 75%
系统性能
- 状态判断延迟: < 100ms
- 内存增量: < 20MB
- 状态切换频率: 合理范围内
输出格式
regime_info = {
'regime': 'ranging', # ranging/trending/transitioning
'confidence': 0.85, # 置信度 (0-1)
'duration': 120, # 当前状态持续分钟数
'indicators': {
'adx': 18.5,
'bb_position': 0.45,
'rsi': 52.3,
'volume_ratio': 0.95
},
'next_review': '2025-09-06T06:00:00Z' # 下次评估时间
}备注
- 算法设计兼顾准确性和稳定性
- 所有指标计算复用现有框架
- 状态切换采用保守策略,避免过度敏感
- 提供丰富的调试信息和状态历史
Metadata
Metadata
Assignees
Labels
No labels