stock-ai-agent/backend/app/crypto_agent/strategy.py
2026-02-05 22:23:41 +08:00

190 lines
6.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
交易策略 - 趋势跟踪策略定义
"""
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>MA20MACD>信号线RSI>50
- 看跌价格在MA20下方MA5<MA20MACD<信号线RSI<50
### 进场信号15M + 5M
- 做多RSI超卖回升、MACD金叉、突破布林中轨、KDJ低位金叉
- 做空RSI超买回落、MACD死叉、跌破布林中轨、KDJ高位死叉
### 风险管理
- 止损2倍ATR
- 止盈3倍ATR
- 最小风险收益比1.5
"""