13 KiB
13 KiB
交易策略与盈亏平仓处理分析报告
一、当前策略架构
1.1 策略核心逻辑
多周期共振策略
- 4H周期定方向:使用EMA20判断大趋势(up/down/neutral)
- 1H周期找信号:使用RSI、MACD、布林带、均线系统
- 15min周期入场:精细点位选择
市场状态识别
-
震荡市场(ranging):均值回归策略
- RSI超卖(<30)→ 做多信号
- RSI超买(>70)→ 做空信号
- 布林带下轨 → 做多信号
- 布林带上轨 → 做空信号
-
趋势市场(trending):趋势跟踪策略
- MACD金叉 → 做多信号
- MACD死叉 → 做空信号
- 价格在均线之上(EMA20 > EMA50)→ 做多信号
- 价格在均线之下(EMA20 < EMA50)→ 做空信号
信号强度计算
-
基础分数:
- RSI超买/超卖:+4分
- 布林带触及:+3分
- MACD金叉/死叉:+3分
- 均线系统:+2分
- 多指标确认(≥2个):+2分
- 4H周期共振:+2分
-
扣分项:
- 逆4H趋势:-3分
- 信号强度不足:拒绝交易
-
交易阈值:信号强度 ≥ 7(可配置
MIN_SIGNAL_STRENGTH)
开仓条件检查流程
1. 市场扫描 → 找出涨跌幅最大的前N个交易对
2. 技术指标分析 → 计算信号强度和方向
3. 风险检查:
- 最小涨跌幅阈值(MIN_CHANGE_PERCENT)
- 是否已有持仓(避免重复开仓)
- 成交量确认(MIN_VOLUME_24H)
4. 仓位计算:
- 单笔仓位限制(MAX_POSITION_PERCENT)
- 总仓位限制(MAX_TOTAL_POSITION_PERCENT)
- 最小保证金要求(MIN_MARGIN_USDT)
5. 动态杠杆计算(根据信号强度)
6. 开仓执行
1.2 风险管理
仓位管理
- 单笔仓位:账户余额的 1%-5%(可配置)
- 总仓位上限:账户余额的 30%(可配置)
- 最小保证金:0.5 USDT(可配置)
- 动态杠杆:10x-20x(根据信号强度调整)
止损止盈机制
止损计算(混合策略):
-
基于保证金的止损:
- 止损金额 = 保证金 × STOP_LOSS_PERCENT(默认8%)
- 止损价 = 入场价 ± (止损金额 / 数量)
-
基于价格百分比的保护:
- 最小价格变动 = 入场价 × MIN_STOP_LOSS_PRICE_PCT(默认2%)
- 最终止损价 = max(基于保证金的止损, 基于价格的止损) [取更宽松的]
-
技术止损(可选):
- 使用支撑/阻力位、布林带
- 如果技术止损更紧,使用技术止损
止盈计算(混合策略):
-
基于保证金的止盈:
- 止盈金额 = 保证金 × TAKE_PROFIT_PERCENT(默认15%)
- 止盈价 = 入场价 ± (止盈金额 / 数量)
-
基于价格百分比的保护:
- 最小价格变动 = 入场价 × MIN_TAKE_PROFIT_PRICE_PCT(默认3%)
- 最终止盈价 = max(基于保证金的止盈, 基于价格的止盈) [取更宽松的]
分步止盈策略:
- 第一目标:盈亏比 1:1,平仓 50%
- 第二目标:原始止盈价,平仓剩余 50%
- 部分止盈后,止损移至成本价(保本)
移动止损(Trailing Stop):
- 激活条件:盈利达到保证金的 1%(TRAILING_STOP_ACTIVATION)
- 保护机制:止损价跟随价格移动,保护保证金的 1%利润(TRAILING_STOP_PROTECT)
1.3 监控机制
实时监控(WebSocket)
- 每个持仓独立WebSocket连接
- 实时接收价格更新
- 立即检查止损止盈条件
- 自动重连机制(最多5次)
定时检查(备用)
- 扫描间隔:可配置(默认3600秒)
- 持仓同步:每5分钟(POSITION_SYNC_INTERVAL)
- 作为WebSocket的备用方案
二、发现的问题
2.1 代码问题
问题1:部分止盈逻辑重复
位置:position_manager.py 第829-851行
# 代码重复:做多和做空的处理逻辑几乎相同,但写了两遍
# 第一段(第808-828行):处理做多
# 第二段(第829-851行):处理做空,但逻辑相同
影响:代码冗余,维护困难,容易出错
问题2:止损检查逻辑重复
位置:position_manager.py 第744-782行
# 第744行:检查止损价是否设置
# 第747行:再次检查止损价(重复)
影响:代码冗余,逻辑不清晰
问题3:移动止损计算可能有问题
位置:position_manager.py 第718-740行
# 移动止损的计算方式:
# new_stop_loss = entry_price + (pnl_amount - protect_amount) / quantity
# 这个公式可能不正确,因为:
# 1. pnl_amount 是当前总盈亏,但应该基于剩余仓位
# 2. 如果已经部分止盈,应该基于剩余仓位计算
影响:移动止损可能不准确
问题4:分步止盈后剩余仓位计算
位置:position_manager.py 第854-894行
# 第二目标止盈时,使用 remaining_quantity 计算盈亏
# 但 pnl_amount 仍然是基于原始 quantity 计算的
# 这可能导致盈亏计算不准确
影响:盈亏统计可能不准确
2.2 策略问题
问题1:信号强度计算不够清晰
- 多个指标同时触发时,分数可能过高
- 没有考虑指标之间的冲突(如RSI超买但MACD死叉)
- 4H趋势判断过于简单(只用EMA20)
问题2:缺少策略回测
- 没有历史数据回测功能
- 无法验证策略有效性
- 无法优化参数
问题3:缺少交易统计
- 没有胜率统计
- 没有盈亏比统计
- 没有按策略类型统计(均值回归 vs 趋势跟踪)
问题4:移动止损激活条件可能太早
- 激活条件:盈利1% of margin
- 保护金额:1% of margin
- 这意味着一旦激活,就保护1%利润,但可能被正常波动触发
2.3 性能问题
问题1:WebSocket连接过多
- 每个持仓一个WebSocket连接
- 如果有10个持仓,就有10个连接
- 可能达到币安连接数限制
问题2:定时检查与WebSocket重复
- WebSocket实时监控 + 定时检查
- 可能造成重复计算
三、优化建议
3.1 代码优化
建议1:重构部分止盈逻辑
# 统一处理做多和做空
async def _partial_take_profit(self, symbol: str, position_info: Dict, target_pct: float):
"""统一的部分止盈逻辑"""
side = position_info['side']
quantity = position_info['quantity']
partial_quantity = quantity * 0.5
# 确定平仓方向
close_side = 'SELL' if side == 'BUY' else 'BUY'
# 执行部分平仓
partial_order = await self.client.place_order(
symbol=symbol,
side=close_side,
quantity=partial_quantity,
order_type='MARKET'
)
if partial_order:
position_info['partialProfitTaken'] = True
position_info['remainingQuantity'] = quantity - partial_quantity
position_info['stopLoss'] = position_info['entryPrice'] # 移至成本价
position_info['trailingStopActivated'] = True
建议2:修复移动止损计算
# 修复移动止损计算,基于剩余仓位
if position_info.get('partialProfitTaken', False):
remaining_quantity = position_info.get('remainingQuantity', quantity)
remaining_margin = (entry_price * remaining_quantity) / leverage
protect_amount = remaining_margin * trailing_protect
# 基于剩余仓位计算盈亏
if side == 'BUY':
remaining_pnl = (current_price - entry_price) * remaining_quantity
else:
remaining_pnl = (entry_price - current_price) * remaining_quantity
# 计算新的止损价
if side == 'BUY':
new_stop_loss = entry_price + (remaining_pnl - protect_amount) / remaining_quantity
else:
new_stop_loss = entry_price - (remaining_pnl - protect_amount) / remaining_quantity
else:
# 未部分止盈,使用原始逻辑
...
建议3:统一止损止盈检查
async def _check_sl_tp(self, symbol: str, current_price: float) -> Optional[str]:
"""
统一的止损止盈检查
返回:None(不触发)或 'stop_loss'/'take_profit'/'trailing_stop'
"""
position_info = self.active_positions.get(symbol)
if not position_info:
return None
# 计算盈亏
pnl_data = self._calculate_pnl(position_info, current_price)
# 检查止损
if self._check_stop_loss(position_info, pnl_data):
return 'stop_loss'
# 检查移动止损
if self._check_trailing_stop(position_info, pnl_data):
return 'trailing_stop'
# 检查止盈
if self._check_take_profit(position_info, pnl_data):
return 'take_profit'
return None
3.2 策略优化
建议1:改进信号强度计算
# 添加指标冲突检测
def _check_indicator_conflict(self, indicators: Dict) -> int:
"""检测指标冲突,返回冲突分数"""
conflict_score = 0
# RSI与MACD冲突
if indicators.get('rsi', 50) > 70 and indicators.get('macd_histogram', 0) < 0:
conflict_score += 2 # RSI超买但MACD死叉
if indicators.get('rsi', 50) < 30 and indicators.get('macd_histogram', 0) > 0:
conflict_score += 2 # RSI超卖但MACD金叉
return conflict_score
# 在信号强度计算中减去冲突分数
signal_strength -= conflict_score
建议2:改进4H趋势判断
# 使用多个指标判断4H趋势
def _judge_trend_4h(self, symbol_info: Dict) -> str:
"""使用多个指标判断4H趋势"""
price_4h = symbol_info.get('price_4h')
ema20_4h = symbol_info.get('ema20_4h')
ema50_4h = symbol_info.get('ema50_4h')
macd_4h = symbol_info.get('macd_4h')
signals = []
# EMA20 vs 价格
if price_4h > ema20_4h:
signals.append('up')
elif price_4h < ema20_4h:
signals.append('down')
# EMA20 vs EMA50
if ema20_4h > ema50_4h:
signals.append('up')
elif ema20_4h < ema50_4h:
signals.append('down')
# MACD
if macd_4h and macd_4h.get('histogram', 0) > 0:
signals.append('up')
elif macd_4h and macd_4h.get('histogram', 0) < 0:
signals.append('down')
# 多数投票
up_count = signals.count('up')
down_count = signals.count('down')
if up_count > down_count:
return 'up'
elif down_count > up_count:
return 'down'
else:
return 'neutral'
建议3:调整移动止损参数
# 建议的移动止损参数
TRAILING_STOP_ACTIVATION = 0.05 # 盈利5% of margin后激活(更保守)
TRAILING_STOP_PROTECT = 0.03 # 保护3% of margin利润(更合理)
3.3 性能优化
建议1:使用组合流(Combined Stream)
# 使用币安组合流,一个连接监控多个交易对
# wss://fstream.binance.com/stream?streams=btcusdt@ticker/ethusdt@ticker/...
ws_url = f"wss://fstream.binance.com/stream?streams={'/'.join([f'{s.lower()}@ticker' for s in symbols])}"
建议2:减少定时检查频率
# 如果WebSocket正常工作,减少定时检查频率
# 或者只在WebSocket断开时启用定时检查
if not self._websocket_connected:
await self.check_stop_loss_take_profit()
3.4 功能增强
建议1:添加策略回测
class StrategyBacktester:
"""策略回测器"""
async def backtest(self, start_date: str, end_date: str, initial_balance: float):
"""回测策略"""
# 加载历史数据
# 模拟交易
# 计算收益、胜率、最大回撤等
pass
建议2:添加交易统计
class TradeStatistics:
"""交易统计"""
def get_statistics(self, start_date: str, end_date: str):
"""获取交易统计"""
return {
'total_trades': 0,
'win_rate': 0.0,
'profit_factor': 0.0,
'avg_win': 0.0,
'avg_loss': 0.0,
'max_drawdown': 0.0,
'by_strategy': {
'mean_reversion': {...},
'trend_following': {...}
}
}
四、优先级建议
高优先级(立即修复)
- ✅ 修复部分止盈逻辑重复 - 代码质量问题
- ✅ 修复移动止损计算 - 可能影响盈亏
- ✅ 修复分步止盈后盈亏计算 - 统计准确性
中优先级(近期优化)
- ⚠️ 改进信号强度计算 - 提高策略质量
- ⚠️ 改进4H趋势判断 - 提高策略质量
- ⚠️ 调整移动止损参数 - 优化风险控制
低优先级(长期优化)
- 📝 添加策略回测 - 功能增强
- 📝 添加交易统计 - 功能增强
- 📝 优化WebSocket连接 - 性能优化
五、总结
当前策略架构整体合理,采用了多周期共振、技术指标确认、风险管理等成熟方法。但存在一些代码质量和逻辑问题需要修复。
核心优势:
- 多周期共振策略,提高胜率
- 基于保证金的止损止盈,更合理
- WebSocket实时监控,响应及时
- 分步止盈策略,平衡风险收益
主要问题:
- 代码重复和逻辑错误
- 移动止损计算可能不准确
- 缺少策略验证和统计
建议行动:
- 先修复高优先级问题(代码质量)
- 然后优化策略逻辑(提高胜率)
- 最后添加回测和统计功能(长期优化)