""" 交易策略 - 趋势跟踪策略定义 """ from typing import Dict, List, Any from app.utils.logger import logger class TrendFollowingStrategy: """趋势跟踪策略""" # 趋势判断规则(1H + 4H) TREND_RULES = { 'bullish': { 'description': '看涨趋势', 'conditions': [ {'name': 'price_above_ma20', 'desc': '价格在MA20上方'}, {'name': 'ma5_above_ma20', 'desc': 'MA5在MA20上方'}, {'name': 'macd_positive', 'desc': 'MACD在信号线上方'}, {'name': 'rsi_above_50', 'desc': 'RSI大于50'} ] }, 'bearish': { 'description': '看跌趋势', 'conditions': [ {'name': 'price_below_ma20', 'desc': '价格在MA20下方'}, {'name': 'ma5_below_ma20', 'desc': 'MA5在MA20下方'}, {'name': 'macd_negative', 'desc': 'MACD在信号线下方'}, {'name': 'rsi_below_50', 'desc': 'RSI小于50'} ] } } # 进场规则(5M + 15M) ENTRY_RULES = { 'buy': { 'description': '做多进场', 'conditions': [ {'name': 'rsi_oversold_recovery', 'desc': 'RSI从超卖区回升', 'weight': 2}, {'name': 'macd_golden_cross', 'desc': 'MACD金叉', 'weight': 2}, {'name': 'price_break_bb_middle', 'desc': '价格突破布林中轨', 'weight': 1}, {'name': 'kdj_golden_cross', 'desc': 'KDJ低位金叉', 'weight': 1}, {'name': 'volume_increase', 'desc': '成交量放大', 'weight': 1} ], 'min_score': 3 # 最低触发分数 }, 'sell': { 'description': '做空进场', 'conditions': [ {'name': 'rsi_overbought_decline', 'desc': 'RSI从超买区回落', 'weight': 2}, {'name': 'macd_death_cross', 'desc': 'MACD死叉', 'weight': 2}, {'name': 'price_break_bb_middle_down', 'desc': '价格跌破布林中轨', 'weight': 1}, {'name': 'kdj_death_cross', 'desc': 'KDJ高位死叉', 'weight': 1}, {'name': 'volume_increase', 'desc': '成交量放大', 'weight': 1} ], 'min_score': 3 } } # 出场规则 EXIT_RULES = { 'take_profit': { 'description': '止盈', 'conditions': [ {'name': 'target_reached', 'desc': '达到目标价位'}, {'name': 'rsi_extreme', 'desc': 'RSI达到极值'}, {'name': 'trend_reversal', 'desc': '趋势反转信号'} ] }, 'stop_loss': { 'description': '止损', 'conditions': [ {'name': 'price_hit_stop', 'desc': '价格触及止损位'}, {'name': 'trend_break', 'desc': '趋势破坏'} ] } } # 风险管理参数 RISK_PARAMS = { 'max_position_size': 0.1, # 最大仓位比例 'stop_loss_atr_multiplier': 2.0, # 止损 ATR 倍数 'take_profit_atr_multiplier': 3.0, # 止盈 ATR 倍数 'max_daily_trades': 5, # 每日最大交易次数 'min_risk_reward_ratio': 1.5 # 最小风险收益比 } def __init__(self): """初始化策略""" logger.info("趋势跟踪策略初始化完成") def get_trend_rules(self, trend: str) -> Dict[str, Any]: """获取趋势判断规则""" return self.TREND_RULES.get(trend, {}) def get_entry_rules(self, action: str) -> Dict[str, Any]: """获取进场规则""" return self.ENTRY_RULES.get(action, {}) def get_exit_rules(self, exit_type: str) -> Dict[str, Any]: """获取出场规则""" return self.EXIT_RULES.get(exit_type, {}) def calculate_position_size(self, account_balance: float, risk_per_trade: float, entry_price: float, stop_loss: float) -> float: """ 计算仓位大小 Args: account_balance: 账户余额 risk_per_trade: 单笔风险比例(如 0.02 表示 2%) entry_price: 入场价格 stop_loss: 止损价格 Returns: 建议仓位大小 """ risk_amount = account_balance * risk_per_trade price_risk = abs(entry_price - stop_loss) if price_risk == 0: return 0 position_size = risk_amount / price_risk # 限制最大仓位 max_position = account_balance * self.RISK_PARAMS['max_position_size'] / entry_price position_size = min(position_size, max_position) return round(position_size, 6) def validate_trade(self, entry_price: float, stop_loss: float, take_profit: float) -> Dict[str, Any]: """ 验证交易是否符合风险管理规则 Args: entry_price: 入场价格 stop_loss: 止损价格 take_profit: 止盈价格 Returns: 验证结果 """ risk = abs(entry_price - stop_loss) reward = abs(take_profit - entry_price) if risk == 0: return { 'valid': False, 'reason': '止损距离为0', 'risk_reward_ratio': 0 } risk_reward_ratio = reward / risk if risk_reward_ratio < self.RISK_PARAMS['min_risk_reward_ratio']: return { 'valid': False, 'reason': f'风险收益比({risk_reward_ratio:.2f})低于最低要求({self.RISK_PARAMS["min_risk_reward_ratio"]})', 'risk_reward_ratio': risk_reward_ratio } return { 'valid': True, 'reason': '符合风险管理规则', 'risk_reward_ratio': risk_reward_ratio } def get_strategy_description(self) -> str: """获取策略描述""" return """ ## 趋势跟踪策略 ### 核心理念 顺势而为,在大周期确认趋势后,在小周期寻找最佳进场点。 ### 趋势判断(4H + 1H) - 看涨:价格在MA20上方,MA5>MA20,MACD>信号线,RSI>50 - 看跌:价格在MA20下方,MA5