a
This commit is contained in:
parent
209a5cd376
commit
9983a892bd
231
CURRENT_STRATEGY.md
Normal file
231
CURRENT_STRATEGY.md
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
# 当前交易策略方案文档
|
||||
|
||||
## 一、策略概述
|
||||
|
||||
当前系统采用基于技术指标的自适应交易策略,结合均值回归和趋势跟踪两种模式,根据市场状态自动切换。
|
||||
|
||||
### 核心特点
|
||||
- **自适应策略**:根据市场状态(趋势/震荡)自动选择策略
|
||||
- **技术指标过滤**:使用RSI、MACD、布林带、EMA等多指标确认
|
||||
- **信号强度要求**:信号强度 >= 5/10 才执行交易
|
||||
- **时间段差异化**:晚间激进,白天平衡
|
||||
|
||||
## 二、当前配置参数
|
||||
|
||||
### 仓位控制
|
||||
- **单笔最大仓位**:5% (MAX_POSITION_PERCENT: 0.05)
|
||||
- **总仓位上限**:30% (MAX_TOTAL_POSITION_PERCENT: 0.30)
|
||||
- **单笔最小仓位**:1% (MIN_POSITION_PERCENT: 0.01)
|
||||
|
||||
### 市场扫描
|
||||
- **扫描间隔**:1小时 (SCAN_INTERVAL: 3600秒)
|
||||
- **扫描交易对数量**:500个 (MAX_SCAN_SYMBOLS: 500)
|
||||
- **处理交易对数量**:10个 (TOP_N_SYMBOLS: 10)
|
||||
- **最小涨跌幅阈值**:2% (MIN_CHANGE_PERCENT: 2.0)
|
||||
- **最小24小时成交量**:1000万USDT (MIN_VOLUME_24H: 10000000)
|
||||
|
||||
### 风险控制
|
||||
- **止损**:3% (STOP_LOSS_PERCENT: 0.03)
|
||||
- **止盈**:5% (TAKE_PROFIT_PERCENT: 0.05)
|
||||
- **杠杆倍数**:10倍 (LEVERAGE: 10)
|
||||
- **移动止损**:启用 (USE_TRAILING_STOP: True)
|
||||
- **移动止损激活阈值**:1% (TRAILING_STOP_ACTIVATION: 0.01)
|
||||
- **移动止损保护利润**:1% (TRAILING_STOP_PROTECT: 0.01)
|
||||
|
||||
### 策略参数
|
||||
- **最小信号强度**:5/10 (MIN_SIGNAL_STRENGTH: 5)
|
||||
- **K线周期**:1小时 (KLINE_INTERVAL: 1h)
|
||||
- **主周期**:1小时 (PRIMARY_INTERVAL: 1h)
|
||||
- **确认周期**:4小时 (CONFIRM_INTERVAL: 4h)
|
||||
- **入场周期**:15分钟 (ENTRY_INTERVAL: 15m)
|
||||
|
||||
## 三、策略逻辑
|
||||
|
||||
### 1. 市场扫描
|
||||
- 每小时扫描500个USDT交易对
|
||||
- 筛选涨跌幅 >= 2% 且成交量 >= 1000万USDT的交易对
|
||||
- 计算技术指标(RSI、MACD、布林带、EMA等)
|
||||
- 按信号得分排序,选择前10个进行详细分析
|
||||
|
||||
### 2. 市场状态判断
|
||||
- **震荡市场 (ranging)**:使用均值回归策略
|
||||
- **趋势市场 (trending)**:使用趋势跟踪策略
|
||||
|
||||
### 3. 交易信号生成
|
||||
|
||||
#### 均值回归策略(震荡市场)
|
||||
- **做多信号**:
|
||||
- RSI < 30(超卖)
|
||||
- 价格触及布林带下轨
|
||||
- **做空信号**:
|
||||
- RSI > 70(超买)
|
||||
- 价格触及布林带上轨
|
||||
|
||||
#### 趋势跟踪策略(趋势市场)
|
||||
- **做多信号**:
|
||||
- MACD金叉(MACD > Signal 且 Histogram > 0)
|
||||
- 价格 > EMA20 > EMA50(上升趋势)
|
||||
- **做空信号**:
|
||||
- MACD死叉(MACD < Signal 且 Histogram < 0)
|
||||
- 价格 < EMA20 < EMA50(下降趋势)
|
||||
|
||||
#### 信号强度计算
|
||||
- 基础信号:2-4分
|
||||
- 多指标确认:+2分
|
||||
- 要求信号强度 >= 5/10 才执行交易
|
||||
|
||||
### 4. 风险控制
|
||||
- 仓位大小:根据账户余额和涨跌幅动态计算
|
||||
- 止损止盈:固定百分比(止损3%,止盈5%)
|
||||
- 移动止损:盈利1%后激活,保护1%利润
|
||||
- 持仓监控:WebSocket实时监控 + 定时检查(5分钟)
|
||||
|
||||
## 四、时间段策略
|
||||
|
||||
### 晚间激进策略(20:00-02:00 UTC+8)
|
||||
- **特点**:市场波动大,机会多
|
||||
- **建议配置**:
|
||||
- MAX_SCAN_SYMBOLS: 350-400(增加扫描范围)
|
||||
- TOP_N_SYMBOLS: 15-20(处理更多交易对)
|
||||
- MIN_SIGNAL_STRENGTH: 3-4(降低信号强度要求,捕捉更多机会)
|
||||
- SCAN_INTERVAL: 1800-3600秒(30分钟-1小时)
|
||||
|
||||
### 白天平衡策略(02:00-20:00 UTC+8)
|
||||
- **特点**:市场相对平稳,注重信号质量
|
||||
- **建议配置**:
|
||||
- MAX_SCAN_SYMBOLS: 250-300(平衡扫描范围)
|
||||
- TOP_N_SYMBOLS: 10-12(选择优质机会)
|
||||
- MIN_SIGNAL_STRENGTH: 5-6(提高信号强度要求)
|
||||
- SCAN_INTERVAL: 3600秒(1小时)
|
||||
|
||||
## 五、运行情况分析
|
||||
|
||||
### 统计数据
|
||||
- **总交易单数**:53单
|
||||
- **当前胜率**:40%
|
||||
- **目标胜率**:50-60%
|
||||
|
||||
### 胜率分析
|
||||
|
||||
#### 当前胜率偏低的原因
|
||||
1. **信号强度要求可能偏低**
|
||||
- 当前MIN_SIGNAL_STRENGTH: 5
|
||||
- 可能接受了过多中等强度的信号
|
||||
|
||||
2. **时间段策略未完全实现**
|
||||
- 晚间激进策略可能增加了低质量交易
|
||||
- 白天平衡策略的信号强度要求可能还不够严格
|
||||
|
||||
3. **市场环境判断可能不准确**
|
||||
- 震荡市场和趋势市场的判断可能不够准确
|
||||
- 导致使用了错误的策略
|
||||
|
||||
4. **止损止盈比例**
|
||||
- 止损3%,止盈5%,盈亏比约1.67:1
|
||||
- 如果胜率低于37.5%,整体会亏损
|
||||
|
||||
## 六、改进建议
|
||||
|
||||
### 1. 提高信号强度要求
|
||||
**建议**:将MIN_SIGNAL_STRENGTH从5提高到6-7
|
||||
- **理由**:减少假信号,提高入场质量
|
||||
- **预期效果**:胜率提升5-10%,但交易频率可能下降
|
||||
|
||||
### 2. 优化时间段策略
|
||||
**建议**:实现自动时间段切换
|
||||
- **晚间(20:00-02:00)**:
|
||||
- MIN_SIGNAL_STRENGTH: 4(激进)
|
||||
- TOP_N_SYMBOLS: 15-18
|
||||
- **白天(02:00-20:00)**:
|
||||
- MIN_SIGNAL_STRENGTH: 6-7(保守)
|
||||
- TOP_N_SYMBOLS: 8-10
|
||||
|
||||
### 3. 优化止损止盈比例
|
||||
**建议**:调整止损止盈比例,提高盈亏比
|
||||
- **方案A**:止损2.5%,止盈5%(盈亏比2:1)
|
||||
- **方案B**:止损3%,止盈6%(盈亏比2:1)
|
||||
- **预期效果**:即使胜率40%,盈亏比2:1也能盈利
|
||||
|
||||
### 4. 加强市场状态判断
|
||||
**建议**:
|
||||
- 使用更多指标判断市场状态
|
||||
- 增加市场状态的确认机制
|
||||
- 在不确定的市场状态下降低仓位或暂停交易
|
||||
|
||||
### 5. 增加过滤条件
|
||||
**建议**:
|
||||
- 增加成交量确认(确保有足够的流动性)
|
||||
- 增加波动率过滤(避免在极端波动时交易)
|
||||
- 增加相关性检查(避免同时持有高度相关的币种)
|
||||
|
||||
### 6. 优化移动止损
|
||||
**建议**:
|
||||
- 提高移动止损激活阈值到2%
|
||||
- 增加移动止损保护利润到1.5-2%
|
||||
- **预期效果**:更好地保护利润,减少盈利变亏损
|
||||
|
||||
## 七、预期改进效果
|
||||
|
||||
### 短期目标(1-2周)
|
||||
- **胜率目标**:45-50%
|
||||
- **改进措施**:
|
||||
- 提高MIN_SIGNAL_STRENGTH到6
|
||||
- 优化止损止盈比例到2:1
|
||||
- 加强市场状态判断
|
||||
|
||||
### 中期目标(1个月)
|
||||
- **胜率目标**:50-55%
|
||||
- **改进措施**:
|
||||
- 实现时间段自动切换
|
||||
- 优化移动止损参数
|
||||
- 增加更多过滤条件
|
||||
|
||||
### 长期目标(3个月)
|
||||
- **胜率目标**:55-60%
|
||||
- **改进措施**:
|
||||
- 建立回测系统
|
||||
- 使用机器学习优化信号权重
|
||||
- 多时间周期确认
|
||||
|
||||
## 八、监控指标
|
||||
|
||||
### 关键指标
|
||||
1. **胜率**:目标 > 50%
|
||||
2. **盈亏比**:目标 > 1.5:1
|
||||
3. **平均盈利/亏损**:确保平均盈利 > 平均亏损
|
||||
4. **交易频率**:每天3-10单(根据市场情况)
|
||||
5. **持仓数量**:同时持仓3-8个
|
||||
|
||||
### 需要关注的日志
|
||||
- 信号强度分布
|
||||
- 市场状态分布(趋势/震荡)
|
||||
- 移动止损激活情况
|
||||
- 止损/止盈触发比例
|
||||
|
||||
## 九、风险提示
|
||||
|
||||
1. **胜率40%偏低**:如果盈亏比不够高,整体可能亏损
|
||||
2. **时间段策略**:需要根据实际市场情况调整,不能盲目激进
|
||||
3. **市场环境变化**:策略需要适应不同的市场环境
|
||||
4. **参数调整**:不要频繁大幅调整参数,建议渐进式优化
|
||||
|
||||
## 十、下一步行动
|
||||
|
||||
1. **立即执行**:
|
||||
- 提高MIN_SIGNAL_STRENGTH到6
|
||||
- 调整止损止盈比例到2:1(止损2.5%,止盈5%)
|
||||
|
||||
2. **本周完成**:
|
||||
- 实现时间段自动切换功能
|
||||
- 优化移动止损参数
|
||||
|
||||
3. **本月完成**:
|
||||
- 加强市场状态判断
|
||||
- 增加更多过滤条件
|
||||
- 建立数据分析和回测系统
|
||||
|
||||
---
|
||||
|
||||
**文档更新时间**:2024年
|
||||
**策略版本**:v1.0
|
||||
**下次评估时间**:运行100单后重新评估
|
||||
|
|
@ -65,7 +65,7 @@ async def get_trades(
|
|||
如果同时提供了 period 和 start_date/end_date,period 优先级更高
|
||||
"""
|
||||
try:
|
||||
logger.info(f"获取交易记录请求: start_date={start_date}, end_date={end_date}, period={period}, symbol={symbol}, status={status}, limit={limit}")
|
||||
logger.info(f"获取交易记录请求: start_date={start_date}, end_date={end_date}, period={period}, symbol={symbol}, status={status}, limit={limit}, trade_type={trade_type}, exit_reason={exit_reason}")
|
||||
# 如果提供了 period,使用快速时间段筛选
|
||||
if period:
|
||||
period_start, period_end = get_date_range(period)
|
||||
|
|
@ -80,7 +80,7 @@ async def get_trades(
|
|||
if end_date and len(end_date) == 10: # YYYY-MM-DD
|
||||
end_date = f"{end_date} 23:59:59"
|
||||
|
||||
trades = Trade.get_all(start_date, end_date, symbol, status)
|
||||
trades = Trade.get_all(start_date, end_date, symbol, status, trade_type, exit_reason)
|
||||
logger.info(f"查询到 {len(trades)} 条交易记录")
|
||||
|
||||
# 格式化交易记录,添加平仓类型的中文显示
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ CREATE TABLE IF NOT EXISTS `trading_signals` (
|
|||
INDEX `idx_executed` (`executed`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='交易信号表';
|
||||
|
||||
|
||||
|
||||
-- 初始化默认配置
|
||||
INSERT INTO `trading_config` (`config_key`, `config_value`, `config_type`, `category`, `description`) VALUES
|
||||
-- 仓位控制
|
||||
|
|
@ -108,7 +110,7 @@ INSERT INTO `trading_config` (`config_key`, `config_value`, `config_type`, `cate
|
|||
('MIN_VOLATILITY', '0.02', 'number', 'scan', '最小波动率:2%'),
|
||||
|
||||
-- 高胜率策略参数
|
||||
('MIN_SIGNAL_STRENGTH', '5', 'number', 'strategy', '最小信号强度(0-10)'),
|
||||
('MIN_SIGNAL_STRENGTH', '7', 'number', 'strategy', '最小信号强度(0-10),已提升至7以提高入场质量'),
|
||||
('LEVERAGE', '10', 'number', 'strategy', '杠杆倍数'),
|
||||
('USE_TRAILING_STOP', 'true', 'boolean', 'strategy', '是否使用移动止损'),
|
||||
('TRAILING_STOP_ACTIVATION', '0.01', 'number', 'strategy', '移动止损激活阈值(盈利1%后激活)'),
|
||||
|
|
|
|||
138
newplan20260115.md
Normal file
138
newplan20260115.md
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
核心诊断:盈利公式与当前瓶颈
|
||||
盈利的核心公式是:期望收益 = 胜率 × 平均盈利 - (1-胜率) × 平均亏损。
|
||||
您当前配置是:胜率40%,盈亏比约1.67:1(止损3%,止盈5%)。
|
||||
代入公式:0.4*5 - 0.6*3 = 2 - 1.8 = 0.2%(每笔交易的期望收益为正,但非常微薄,易被滑点、手续费侵蚀)。
|
||||
|
||||
主要瓶颈在于:
|
||||
|
||||
胜率偏低:40%的胜率对策略的容错率要求极高。
|
||||
|
||||
盈亏比不具优势:1.67:1的盈亏比在40%胜率下仅能勉强保本。
|
||||
|
||||
“激进”与“平衡”时段的定义可能过于时间驱动,而非市场驱动。
|
||||
|
||||
系统性优化方案(从高优先级到低优先级)
|
||||
第一阶段:立即实施(提高单笔交易质量)
|
||||
严格强化入场信号(提升胜率最直接的方法)
|
||||
|
||||
多时间周期共振:您已有主周期(1h)和确认周期(4h)。应严格执行 “大周期定方向,小周期找点位”。
|
||||
|
||||
做多:4H趋势向上(如价格 > 4H EMA20)时,仅在1H和15min上寻找做多信号。绝对禁止在4H下跌趋势中做1H级别的“反弹多”。
|
||||
|
||||
做空:同理。这能极大过滤逆势交易,提升胜率。
|
||||
|
||||
增加量价确认:
|
||||
|
||||
买入信号时,要求入场K线(或前一根)的成交量显著高于近期均量,确认买盘力量。
|
||||
|
||||
突破布林带时,要求K线实体饱满,而非长影线触及。
|
||||
|
||||
将 MIN_SIGNAL_STRENGTH 从5提升至7。这看似激进,但结合多周期共振,能确保只有最强、最清晰的信号才被执行。预期牺牲20-30%的交易机会,但目标是提升单笔交易胜率10%以上。
|
||||
|
||||
优化风险回报结构(提升盈亏比)
|
||||
|
||||
放弃固定止盈止损,采用 基于技术结构的动态风控。
|
||||
|
||||
止损:设置在关键支撑/阻力位、布林带外轨或前高/前低之外 + 一定缓冲。例如,做多时,止损放在近期波段低点下方0.5-1%。这通常比固定的3%更合理。
|
||||
|
||||
止盈:采用 分步止盈。
|
||||
|
||||
第一目标(保守):近期阻力位或盈亏比1:1的位置,了结50%仓位。
|
||||
|
||||
第二目标(激进):更远的技术位(如趋势线、前高),让剩余仓位配合移动止损博取更大利润。
|
||||
|
||||
此举目标:将平均盈亏比提升至 2.5:1 甚至 3:1。
|
||||
|
||||
第二阶段:近期优化(提升系统适应性与仓位效率)
|
||||
重构“时间段策略”为“市场波动率策略”
|
||||
|
||||
时间本身不产生机会,波动率才是。建议根据平均真实波幅(ATR)或布林带带宽来定义“激进”与“保守”模式。
|
||||
|
||||
高波动率模式(激进):当波动率高于近期均值时。
|
||||
|
||||
仓位系数 = 0.5 (降低标准仓位的一半,以应对更大风险)。
|
||||
|
||||
MIN_SIGNAL_STRENGTH 可适当降低至6,但必须配合更宽的止损(如基于ATR的2倍)。
|
||||
|
||||
低波动率模式(保守):当波动率低于近期均值时。
|
||||
|
||||
仓位系数 = 1.0 (标准仓位)。
|
||||
|
||||
MIN_SIGNAL_STRENGTH = 7 (信号要求最高)。
|
||||
|
||||
极度波动模式(暂停):当波动率突破极端阈值(如+3标准差),暂停开新仓,仅管理现有持仓。
|
||||
|
||||
实施基于凯利公式或固定分数法的动态仓位管理
|
||||
|
||||
当前固定的5%仓位过于僵化。应根据交易信号的强度和账户当前状态动态调整。
|
||||
|
||||
简化版:单笔风险 = 账户总资金的0.5% - 1%。
|
||||
|
||||
假设止损距离是2%,那么仓位大小就是 (账户资金 * 0.5%) / (入场价 * 2%)。
|
||||
|
||||
优势:无论交易什么币种,每笔交易的最大亏损是固定的,真正控制了风险。
|
||||
|
||||
第三阶段:中长期建设(构建护城河)
|
||||
增加“策略失效”监控与熔断机制
|
||||
|
||||
设定一个连续亏损次数(如5次) 或单日最大回撤比例(如3%) 的阈值。一旦触发,系统自动切换至“观察模式”或“极小仓位模式”,防止情绪化决策下的恶性循环。
|
||||
|
||||
建立简易但必须的回测与统计分析框架
|
||||
|
||||
记录每一笔交易的:入场理由(趋势/震荡)、信号强度、使用指标、持仓时间、结果。
|
||||
|
||||
定期(如每周)分析:
|
||||
|
||||
哪种市场状态下胜率高?(趋势强?震荡市?)
|
||||
|
||||
哪个技术指标组合的预测力最强?(是MACD金叉+放量,还是RSI超卖+布林带下轨?)
|
||||
|
||||
据此动态调整信号权重,让策略自我进化。
|
||||
|
||||
优化后的预期与监控重点
|
||||
预期效果:
|
||||
|
||||
短期(1-2周):通过强化信号(多周期共振,强度7) 和动态风控,目标将胜率稳定至45%-50%,盈亏比提升至2.5:1。
|
||||
|
||||
中期(1个月):引入波动率仓位管理和分步止盈,目标使策略在不同市场环境下回撤可控,月化收益率曲线更加平滑。
|
||||
|
||||
长期:通过数据分析驱动策略微调,形成稳定正期望的交易系统。
|
||||
|
||||
新的关键监控指标:
|
||||
|
||||
期望收益:核心中的核心,必须为正且大于0.5%。
|
||||
|
||||
风险调整后收益:如夏普比率。
|
||||
|
||||
最大连续亏损次数/金额:衡量策略的逆境承受力。
|
||||
|
||||
不同市场状态下的胜率与盈亏比:检验策略的适应性。
|
||||
|
||||
信号强度与胜率的相关性:验证信号系统的有效性。
|
||||
|
||||
总结:行动路线图
|
||||
本周:
|
||||
|
||||
立即:将 MIN_SIGNAL_STRENGTH 提升至 7。
|
||||
|
||||
立即:实施 多时间周期共振入场规则(4H定方向)。
|
||||
|
||||
立即:将止损改为 基于支撑/阻力的动态止损。
|
||||
|
||||
设计:分步止盈和移动止损逻辑。
|
||||
|
||||
下周:
|
||||
|
||||
引入 基于ATR的波动率仓位管理。
|
||||
|
||||
实施 基于固定百分比风险的仓位计算。
|
||||
|
||||
本月内:
|
||||
|
||||
建立交易日志数据库。
|
||||
|
||||
建立 策略熔断机制(连续亏损5次暂停)。
|
||||
|
||||
完成首次数据分析报告。
|
||||
|
||||
交易系统的优化是一场“精益求精”的工程。您的文档已有一个极好的起点。请务必记住:每一次调整最好只改变1-2个变量,并观察足够样本(至少20-30笔交易)后再做下一次调整,这样才能清晰归因。
|
||||
|
|
@ -176,7 +176,7 @@ def _get_trading_config():
|
|||
'ENTRY_INTERVAL': '15m',
|
||||
'MIN_VOLUME_24H': 10000000,
|
||||
'MIN_VOLATILITY': 0.02,
|
||||
'MIN_SIGNAL_STRENGTH': 5,
|
||||
'MIN_SIGNAL_STRENGTH': 7, # 提升至7以提高入场质量,减少假信号
|
||||
'LEVERAGE': 10,
|
||||
'USE_TRAILING_STOP': True,
|
||||
'TRAILING_STOP_ACTIVATION': 0.01,
|
||||
|
|
|
|||
|
|
@ -194,11 +194,22 @@ class MarketScanner:
|
|||
if len(klines) < 2:
|
||||
return None
|
||||
|
||||
# 提取价格数据
|
||||
# 获取4H周期数据用于多周期共振检查
|
||||
confirm_interval = config.TRADING_CONFIG.get('CONFIRM_INTERVAL', '4h')
|
||||
klines_4h = await self.client.get_klines(
|
||||
symbol=symbol,
|
||||
interval=confirm_interval,
|
||||
limit=50 # 获取4H周期数据
|
||||
)
|
||||
|
||||
# 提取价格数据(主周期)
|
||||
close_prices = [float(k[4]) for k in klines] # 收盘价
|
||||
high_prices = [float(k[2]) for k in klines] # 最高价
|
||||
low_prices = [float(k[3]) for k in klines] # 最低价
|
||||
|
||||
# 提取4H周期价格数据
|
||||
close_prices_4h = [float(k[4]) for k in klines_4h] if len(klines_4h) >= 2 else close_prices
|
||||
|
||||
# 计算涨跌幅(基于主周期)
|
||||
current_price = close_prices[-1]
|
||||
prev_price = close_prices[-2] if len(close_prices) >= 2 else close_prices[0]
|
||||
|
|
@ -216,6 +227,9 @@ class MarketScanner:
|
|||
ema20 = TechnicalIndicators.calculate_ema(close_prices, period=20)
|
||||
ema50 = TechnicalIndicators.calculate_ema(close_prices, period=50)
|
||||
|
||||
# 计算4H周期的EMA20用于多周期共振检查
|
||||
ema20_4h = TechnicalIndicators.calculate_ema(close_prices_4h, period=20) if len(close_prices_4h) >= 20 else None
|
||||
|
||||
# 判断市场状态
|
||||
market_regime = TechnicalIndicators.detect_market_regime(close_prices)
|
||||
|
||||
|
|
@ -267,9 +281,12 @@ class MarketScanner:
|
|||
'atr': atr,
|
||||
'ema20': ema20,
|
||||
'ema50': ema50,
|
||||
'ema20_4h': ema20_4h, # 4H周期EMA20,用于多周期共振
|
||||
'price_4h': close_prices_4h[-1] if len(close_prices_4h) > 0 else current_price, # 4H周期当前价格
|
||||
'marketRegime': market_regime,
|
||||
'signalScore': signal_score,
|
||||
'klines': klines[-10:] # 保留最近10根K线
|
||||
'klines': klines[-10:], # 保留最近10根K线
|
||||
'klines_4h': klines_4h[-10:] if len(klines_4h) >= 10 else klines_4h # 保留最近10根4H K线
|
||||
}
|
||||
except Exception as e:
|
||||
logger.debug(f"获取 {symbol} 数据失败: {e}")
|
||||
|
|
|
|||
|
|
@ -67,7 +67,9 @@ class PositionManager:
|
|||
leverage: int = 10,
|
||||
trade_direction: Optional[str] = None,
|
||||
entry_reason: str = '',
|
||||
atr: Optional[float] = None
|
||||
atr: Optional[float] = None,
|
||||
klines: Optional[List] = None,
|
||||
bollinger: Optional[Dict] = None
|
||||
) -> Optional[Dict]:
|
||||
"""
|
||||
开仓
|
||||
|
|
@ -118,22 +120,52 @@ class PositionManager:
|
|||
|
||||
entry_price = ticker['price']
|
||||
|
||||
# 计算动态止损止盈(使用ATR或固定比例)
|
||||
if atr and atr > 0:
|
||||
# 使用ATR计算动态止损(2倍ATR)
|
||||
atr_stop_loss_pct = (atr * 2) / entry_price
|
||||
# 限制在合理范围内(1%-5%)
|
||||
atr_stop_loss_pct = max(0.01, min(0.05, atr_stop_loss_pct))
|
||||
stop_loss_price = self.risk_manager.get_stop_loss_price(
|
||||
entry_price, side, stop_loss_pct=atr_stop_loss_pct
|
||||
# 获取K线数据用于动态止损计算(从symbol_info中获取,如果可用)
|
||||
klines = None
|
||||
bollinger = None
|
||||
if 'klines' in locals() or 'symbol_info' in locals():
|
||||
# 尝试从外部传入的symbol_info获取
|
||||
pass
|
||||
|
||||
# 计算基于支撑/阻力的动态止损
|
||||
# 优先使用技术结构(支撑/阻力位、布林带)
|
||||
# 如果无法获取K线数据,回退到ATR或固定止损
|
||||
if not klines:
|
||||
# 如果没有传入K线数据,尝试获取
|
||||
try:
|
||||
primary_interval = config.TRADING_CONFIG.get('PRIMARY_INTERVAL', '1h')
|
||||
klines_data = await self.client.get_klines(
|
||||
symbol=symbol,
|
||||
interval=primary_interval,
|
||||
limit=20 # 获取最近20根K线用于计算支撑/阻力
|
||||
)
|
||||
# 止盈为止损的1.5-2倍
|
||||
take_profit_pct = atr_stop_loss_pct * 1.8
|
||||
klines = klines_data if len(klines_data) >= 10 else None
|
||||
except Exception as e:
|
||||
logger.debug(f"获取K线数据失败,使用固定止损: {e}")
|
||||
klines = None
|
||||
|
||||
# 使用基于支撑/阻力的动态止损
|
||||
if klines or bollinger or atr:
|
||||
stop_loss_price = self.risk_manager.get_stop_loss_price(
|
||||
entry_price, side,
|
||||
klines=klines,
|
||||
bollinger=bollinger,
|
||||
atr=atr
|
||||
)
|
||||
|
||||
# 计算动态止损百分比(用于计算止盈)
|
||||
if side == 'BUY':
|
||||
stop_loss_pct = (entry_price - stop_loss_price) / entry_price
|
||||
else:
|
||||
stop_loss_pct = (stop_loss_price - entry_price) / entry_price
|
||||
|
||||
# 止盈为止损的2-2.5倍(提高盈亏比)
|
||||
take_profit_pct = stop_loss_pct * 2.5
|
||||
take_profit_price = self.risk_manager.get_take_profit_price(
|
||||
entry_price, side, take_profit_pct=take_profit_pct
|
||||
)
|
||||
else:
|
||||
# 使用固定止损止盈
|
||||
# 回退到固定止损止盈
|
||||
stop_loss_price = self.risk_manager.get_stop_loss_price(entry_price, side)
|
||||
take_profit_price = self.risk_manager.get_take_profit_price(entry_price, side)
|
||||
|
||||
|
|
@ -170,7 +202,17 @@ class PositionManager:
|
|||
elif not Trade:
|
||||
logger.warning(f"Trade模型未导入,无法保存 {symbol} 交易记录")
|
||||
|
||||
# 记录持仓信息(包含动态止损止盈)
|
||||
# 计算分步止盈价格
|
||||
# 第一目标:盈亏比1:1(保守,了结50%仓位)
|
||||
if side == 'BUY':
|
||||
take_profit_1 = entry_price + (entry_price - stop_loss_price) # 盈亏比1:1
|
||||
else:
|
||||
take_profit_1 = entry_price - (stop_loss_price - entry_price) # 盈亏比1:1
|
||||
|
||||
# 第二目标:原始止盈价(激进,剩余50%仓位)
|
||||
take_profit_2 = take_profit_price
|
||||
|
||||
# 记录持仓信息(包含动态止损止盈和分步止盈)
|
||||
position_info = {
|
||||
'symbol': symbol,
|
||||
'side': side,
|
||||
|
|
@ -180,7 +222,11 @@ class PositionManager:
|
|||
'orderId': order.get('orderId'),
|
||||
'tradeId': trade_id, # 数据库交易ID
|
||||
'stopLoss': stop_loss_price,
|
||||
'takeProfit': take_profit_price,
|
||||
'takeProfit': take_profit_price, # 保留原始止盈价(第二目标)
|
||||
'takeProfit1': take_profit_1, # 第一目标(盈亏比1:1,了结50%)
|
||||
'takeProfit2': take_profit_2, # 第二目标(原始止盈价,剩余50%)
|
||||
'partialProfitTaken': False, # 是否已部分止盈
|
||||
'remainingQuantity': quantity, # 剩余仓位数量
|
||||
'initialStopLoss': stop_loss_price, # 初始止损(用于移动止损)
|
||||
'leverage': leverage,
|
||||
'entryReason': entry_reason,
|
||||
|
|
@ -537,14 +583,126 @@ class PositionManager:
|
|||
closed_positions.append(symbol)
|
||||
continue
|
||||
|
||||
# 检查止盈
|
||||
take_profit = position_info['takeProfit']
|
||||
# 检查分步止盈
|
||||
take_profit_1 = position_info.get('takeProfit1') # 第一目标(盈亏比1:1)
|
||||
take_profit_2 = position_info.get('takeProfit2', position_info.get('takeProfit')) # 第二目标
|
||||
partial_profit_taken = position_info.get('partialProfitTaken', False)
|
||||
remaining_quantity = position_info.get('remainingQuantity', quantity)
|
||||
|
||||
# 第一目标:盈亏比1:1,了结50%仓位
|
||||
if not partial_profit_taken:
|
||||
if position_info['side'] == 'BUY' and current_price >= take_profit_1:
|
||||
logger.info(
|
||||
f"{symbol} 触发第一目标止盈(盈亏比1:1): {current_price:.4f} >= {take_profit_1:.4f} "
|
||||
f"(盈亏: {pnl_percent:.2f}%)"
|
||||
)
|
||||
# 部分平仓50%
|
||||
partial_quantity = quantity * 0.5
|
||||
try:
|
||||
# 部分平仓
|
||||
close_side = 'SELL' if position_info['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'] = remaining_quantity - partial_quantity
|
||||
logger.info(
|
||||
f"{symbol} 部分止盈成功: 平仓{partial_quantity:.4f},剩余{position_info['remainingQuantity']:.4f}"
|
||||
)
|
||||
# 更新止损为成本价(保护剩余仓位)
|
||||
position_info['stopLoss'] = entry_price
|
||||
position_info['trailingStopActivated'] = True
|
||||
logger.info(f"{symbol} 剩余仓位止损移至成本价,配合移动止损博取更大利润")
|
||||
except Exception as e:
|
||||
logger.error(f"{symbol} 部分止盈失败: {e}")
|
||||
elif position_info['side'] == 'SELL' and current_price <= take_profit_1:
|
||||
logger.info(
|
||||
f"{symbol} 触发第一目标止盈(盈亏比1:1): {current_price:.4f} <= {take_profit_1:.4f} "
|
||||
f"(盈亏: {pnl_percent:.2f}%)"
|
||||
)
|
||||
# 部分平仓50%
|
||||
partial_quantity = quantity * 0.5
|
||||
try:
|
||||
# 部分平仓
|
||||
partial_order = await self.client.place_order(
|
||||
symbol=symbol,
|
||||
side='BUY', # 做空平仓用买入
|
||||
quantity=partial_quantity,
|
||||
order_type='MARKET'
|
||||
)
|
||||
if partial_order:
|
||||
position_info['partialProfitTaken'] = True
|
||||
position_info['remainingQuantity'] = remaining_quantity - partial_quantity
|
||||
logger.info(
|
||||
f"{symbol} 部分止盈成功: 平仓{partial_quantity:.4f},剩余{position_info['remainingQuantity']:.4f}"
|
||||
)
|
||||
# 更新止损为成本价(保护剩余仓位)
|
||||
position_info['stopLoss'] = entry_price
|
||||
position_info['trailingStopActivated'] = True
|
||||
logger.info(f"{symbol} 剩余仓位止损移至成本价,配合移动止损博取更大利润")
|
||||
except Exception as e:
|
||||
logger.error(f"{symbol} 部分止盈失败: {e}")
|
||||
|
||||
# 第二目标:原始止盈价,平掉剩余仓位
|
||||
if partial_profit_taken:
|
||||
if position_info['side'] == 'BUY' and current_price >= take_profit_2:
|
||||
logger.info(
|
||||
f"{symbol} 触发第二目标止盈: {current_price:.4f} >= {take_profit_2:.4f} "
|
||||
f"(盈亏: {pnl_percent:.2f}%)"
|
||||
)
|
||||
exit_reason = 'take_profit'
|
||||
# 更新数据库
|
||||
if DB_AVAILABLE:
|
||||
trade_id = position_info.get('tradeId')
|
||||
if trade_id:
|
||||
try:
|
||||
Trade.update_exit(
|
||||
trade_id=trade_id,
|
||||
exit_price=current_price,
|
||||
exit_reason=exit_reason,
|
||||
pnl=pnl_percent * entry_price * quantity / 100,
|
||||
pnl_percent=pnl_percent
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(f"更新止盈记录失败: {e}")
|
||||
if await self.close_position(symbol, reason=exit_reason):
|
||||
closed_positions.append(symbol)
|
||||
continue
|
||||
elif position_info['side'] == 'SELL' and current_price <= take_profit_2:
|
||||
logger.info(
|
||||
f"{symbol} 触发第二目标止盈: {current_price:.4f} <= {take_profit_2:.4f} "
|
||||
f"(盈亏: {pnl_percent:.2f}%)"
|
||||
)
|
||||
exit_reason = 'take_profit'
|
||||
# 更新数据库
|
||||
if DB_AVAILABLE:
|
||||
trade_id = position_info.get('tradeId')
|
||||
if trade_id:
|
||||
try:
|
||||
Trade.update_exit(
|
||||
trade_id=trade_id,
|
||||
exit_price=current_price,
|
||||
exit_reason=exit_reason,
|
||||
pnl=pnl_percent * entry_price * quantity / 100,
|
||||
pnl_percent=pnl_percent
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(f"更新止盈记录失败: {e}")
|
||||
if await self.close_position(symbol, reason=exit_reason):
|
||||
closed_positions.append(symbol)
|
||||
continue
|
||||
else:
|
||||
# 如果未部分止盈,但达到第二目标,直接全部平仓
|
||||
take_profit = position_info.get('takeProfit')
|
||||
if position_info['side'] == 'BUY' and current_price >= take_profit:
|
||||
logger.info(
|
||||
f"{symbol} 触发止盈: {current_price:.4f} >= {take_profit:.4f} "
|
||||
f"(盈亏: {pnl_percent:.2f}%)"
|
||||
)
|
||||
# 确定平仓原因
|
||||
exit_reason = 'take_profit'
|
||||
# 更新数据库
|
||||
if DB_AVAILABLE:
|
||||
|
|
@ -569,7 +727,6 @@ class PositionManager:
|
|||
f"{symbol} 触发止盈: {current_price:.4f} <= {take_profit:.4f} "
|
||||
f"(盈亏: {pnl_percent:.2f}%)"
|
||||
)
|
||||
# 确定平仓原因
|
||||
exit_reason = 'take_profit'
|
||||
# 更新数据库
|
||||
if DB_AVAILABLE:
|
||||
|
|
|
|||
|
|
@ -347,19 +347,83 @@ class RiskManager:
|
|||
self,
|
||||
entry_price: float,
|
||||
side: str,
|
||||
stop_loss_pct: Optional[float] = None
|
||||
stop_loss_pct: Optional[float] = None,
|
||||
klines: Optional[List] = None,
|
||||
bollinger: Optional[Dict] = None,
|
||||
atr: Optional[float] = None
|
||||
) -> float:
|
||||
"""
|
||||
计算止损价格
|
||||
计算止损价格(基于支撑/阻力的动态止损)
|
||||
|
||||
Args:
|
||||
entry_price: 入场价格
|
||||
side: 方向 'BUY' 或 'SELL'
|
||||
stop_loss_pct: 止损百分比,如果为None则使用配置值
|
||||
klines: K线数据,用于计算支撑/阻力位
|
||||
bollinger: 布林带数据,用于计算动态止损
|
||||
atr: 平均真实波幅,用于计算动态止损
|
||||
|
||||
Returns:
|
||||
止损价格
|
||||
"""
|
||||
# 优先使用基于技术结构的动态止损
|
||||
if klines and len(klines) >= 10:
|
||||
# 计算支撑/阻力位
|
||||
low_prices = [float(k[3]) for k in klines[-20:]] # 最近20根K线的最低价
|
||||
high_prices = [float(k[2]) for k in klines[-20:]] # 最近20根K线的最高价
|
||||
|
||||
if side == 'BUY': # 做多,止损放在支撑位下方
|
||||
# 找到近期波段低点
|
||||
recent_low = min(low_prices)
|
||||
# 止损放在低点下方0.5-1%
|
||||
buffer = entry_price * 0.005 # 0.5%缓冲
|
||||
dynamic_stop = recent_low - buffer
|
||||
|
||||
# 如果布林带可用,也可以考虑布林带下轨
|
||||
if bollinger and bollinger.get('lower'):
|
||||
bollinger_stop = bollinger['lower'] * 0.995 # 布林带下轨下方0.5%
|
||||
dynamic_stop = max(dynamic_stop, bollinger_stop)
|
||||
|
||||
# 确保止损不超过固定止损范围(1%-5%)
|
||||
fixed_stop_pct = stop_loss_pct or self.config['STOP_LOSS_PERCENT']
|
||||
max_stop = entry_price * (1 - 0.01) # 最多1%止损
|
||||
min_stop = entry_price * (1 - 0.05) # 最少5%止损(极端情况)
|
||||
|
||||
dynamic_stop = max(min_stop, min(max_stop, dynamic_stop))
|
||||
|
||||
logger.info(
|
||||
f"动态止损计算 (BUY): 入场价={entry_price:.4f}, "
|
||||
f"近期低点={recent_low:.4f}, 动态止损={dynamic_stop:.4f}, "
|
||||
f"止损比例={((entry_price - dynamic_stop) / entry_price * 100):.2f}%"
|
||||
)
|
||||
return dynamic_stop
|
||||
else: # 做空,止损放在阻力位上方
|
||||
# 找到近期波段高点
|
||||
recent_high = max(high_prices)
|
||||
# 止损放在高点上方0.5-1%
|
||||
buffer = entry_price * 0.005 # 0.5%缓冲
|
||||
dynamic_stop = recent_high + buffer
|
||||
|
||||
# 如果布林带可用,也可以考虑布林带上轨
|
||||
if bollinger and bollinger.get('upper'):
|
||||
bollinger_stop = bollinger['upper'] * 1.005 # 布林带上轨上方0.5%
|
||||
dynamic_stop = min(dynamic_stop, bollinger_stop)
|
||||
|
||||
# 确保止损不超过固定止损范围(1%-5%)
|
||||
fixed_stop_pct = stop_loss_pct or self.config['STOP_LOSS_PERCENT']
|
||||
min_stop = entry_price * (1 + 0.01) # 最少1%止损
|
||||
max_stop = entry_price * (1 + 0.05) # 最多5%止损(极端情况)
|
||||
|
||||
dynamic_stop = min(max_stop, max(min_stop, dynamic_stop))
|
||||
|
||||
logger.info(
|
||||
f"动态止损计算 (SELL): 入场价={entry_price:.4f}, "
|
||||
f"近期高点={recent_high:.4f}, 动态止损={dynamic_stop:.4f}, "
|
||||
f"止损比例={((dynamic_stop - entry_price) / entry_price * 100):.2f}%"
|
||||
)
|
||||
return dynamic_stop
|
||||
|
||||
# 回退到固定百分比止损
|
||||
stop_loss_percent = stop_loss_pct or self.config['STOP_LOSS_PERCENT']
|
||||
|
||||
if side == 'BUY': # 做多,止损价低于入场价
|
||||
|
|
|
|||
|
|
@ -149,7 +149,9 @@ class TradingStrategy:
|
|||
leverage=config.TRADING_CONFIG.get('LEVERAGE', 10),
|
||||
trade_direction=trade_direction,
|
||||
entry_reason=entry_reason,
|
||||
atr=symbol_info.get('atr')
|
||||
atr=symbol_info.get('atr'),
|
||||
klines=symbol_info.get('klines'), # 传递K线数据用于动态止损
|
||||
bollinger=symbol_info.get('bollinger') # 传递布林带数据用于动态止损
|
||||
)
|
||||
|
||||
if position:
|
||||
|
|
@ -261,6 +263,7 @@ class TradingStrategy:
|
|||
async def _analyze_trade_signal(self, symbol_info: Dict) -> Dict:
|
||||
"""
|
||||
使用技术指标分析交易信号(高胜率策略)
|
||||
实施多周期共振:4H定方向,1H和15min找点位
|
||||
|
||||
Args:
|
||||
symbol_info: 交易对信息(包含技术指标)
|
||||
|
|
@ -277,68 +280,117 @@ class TradingStrategy:
|
|||
ema20 = symbol_info.get('ema20')
|
||||
ema50 = symbol_info.get('ema50')
|
||||
|
||||
# 多周期共振检查:4H定方向
|
||||
price_4h = symbol_info.get('price_4h', current_price)
|
||||
ema20_4h = symbol_info.get('ema20_4h')
|
||||
|
||||
# 判断4H周期趋势方向
|
||||
trend_4h = None # 'up', 'down', 'neutral'
|
||||
if ema20_4h is not None:
|
||||
if price_4h > ema20_4h:
|
||||
trend_4h = 'up'
|
||||
elif price_4h < ema20_4h:
|
||||
trend_4h = 'down'
|
||||
else:
|
||||
trend_4h = 'neutral'
|
||||
|
||||
signal_strength = 0
|
||||
reasons = []
|
||||
direction = None
|
||||
|
||||
# 多周期共振检查:4H定方向,禁止逆势交易
|
||||
if trend_4h == 'up':
|
||||
# 4H趋势向上,只允许做多信号
|
||||
logger.debug(f"{symbol} 4H趋势向上,只允许做多信号")
|
||||
elif trend_4h == 'down':
|
||||
# 4H趋势向下,只允许做空信号
|
||||
logger.debug(f"{symbol} 4H趋势向下,只允许做空信号")
|
||||
elif trend_4h is None:
|
||||
# 无法判断4H趋势,记录警告
|
||||
logger.warning(f"{symbol} 无法判断4H趋势,可能影响信号质量")
|
||||
|
||||
# 策略1:均值回归(震荡市场,高胜率)
|
||||
if market_regime == 'ranging':
|
||||
# RSI超卖,做多信号
|
||||
# RSI超卖,做多信号(需4H趋势向上或中性)
|
||||
if rsi and rsi < 30:
|
||||
if trend_4h in ('up', 'neutral', None):
|
||||
signal_strength += 4
|
||||
reasons.append(f"RSI超卖({rsi:.1f})")
|
||||
if direction is None:
|
||||
direction = 'BUY'
|
||||
else:
|
||||
reasons.append(f"RSI超卖但4H趋势向下,禁止逆势做多")
|
||||
|
||||
# RSI超买,做空信号
|
||||
# RSI超买,做空信号(需4H趋势向下或中性)
|
||||
elif rsi and rsi > 70:
|
||||
if trend_4h in ('down', 'neutral', None):
|
||||
signal_strength += 4
|
||||
reasons.append(f"RSI超买({rsi:.1f})")
|
||||
if direction is None:
|
||||
direction = 'SELL'
|
||||
else:
|
||||
reasons.append(f"RSI超买但4H趋势向上,禁止逆势做空")
|
||||
|
||||
# 布林带下轨,做多信号
|
||||
# 布林带下轨,做多信号(需4H趋势向上或中性)
|
||||
if bollinger and current_price <= bollinger['lower']:
|
||||
if trend_4h in ('up', 'neutral', None):
|
||||
signal_strength += 3
|
||||
reasons.append("触及布林带下轨")
|
||||
if direction is None:
|
||||
direction = 'BUY'
|
||||
else:
|
||||
reasons.append("触及布林带下轨但4H趋势向下,禁止逆势做多")
|
||||
|
||||
# 布林带上轨,做空信号
|
||||
# 布林带上轨,做空信号(需4H趋势向下或中性)
|
||||
elif bollinger and current_price >= bollinger['upper']:
|
||||
if trend_4h in ('down', 'neutral', None):
|
||||
signal_strength += 3
|
||||
reasons.append("触及布林带上轨")
|
||||
if direction is None:
|
||||
direction = 'SELL'
|
||||
else:
|
||||
reasons.append("触及布林带上轨但4H趋势向上,禁止逆势做空")
|
||||
|
||||
# 策略2:趋势跟踪(趋势市场)
|
||||
elif market_regime == 'trending':
|
||||
# MACD金叉,做多信号
|
||||
# MACD金叉,做多信号(需4H趋势向上或中性)
|
||||
if macd and macd['macd'] > macd['signal'] and macd['histogram'] > 0:
|
||||
if trend_4h in ('up', 'neutral', None):
|
||||
signal_strength += 3
|
||||
reasons.append("MACD金叉")
|
||||
if direction is None:
|
||||
direction = 'BUY'
|
||||
else:
|
||||
reasons.append("MACD金叉但4H趋势向下,禁止逆势做多")
|
||||
|
||||
# MACD死叉,做空信号
|
||||
# MACD死叉,做空信号(需4H趋势向下或中性)
|
||||
elif macd and macd['macd'] < macd['signal'] and macd['histogram'] < 0:
|
||||
if trend_4h in ('down', 'neutral', None):
|
||||
signal_strength += 3
|
||||
reasons.append("MACD死叉")
|
||||
if direction is None:
|
||||
direction = 'SELL'
|
||||
else:
|
||||
reasons.append("MACD死叉但4H趋势向上,禁止逆势做空")
|
||||
|
||||
# 均线系统
|
||||
if ema20 and ema50:
|
||||
if current_price > ema20 > ema50: # 上升趋势
|
||||
if trend_4h in ('up', 'neutral', None):
|
||||
signal_strength += 2
|
||||
reasons.append("价格在均线之上")
|
||||
if direction is None:
|
||||
direction = 'BUY'
|
||||
else:
|
||||
reasons.append("1H均线向上但4H趋势向下,禁止逆势做多")
|
||||
elif current_price < ema20 < ema50: # 下降趋势
|
||||
if trend_4h in ('down', 'neutral', None):
|
||||
signal_strength += 2
|
||||
reasons.append("价格在均线之下")
|
||||
if direction is None:
|
||||
direction = 'SELL'
|
||||
else:
|
||||
reasons.append("1H均线向下但4H趋势向上,禁止逆势做空")
|
||||
|
||||
# 策略3:综合信号(提高胜率)
|
||||
# 多个指标同时确认时,信号更强
|
||||
|
|
@ -370,8 +422,25 @@ class TradingStrategy:
|
|||
signal_strength += 2
|
||||
reasons.append(f"{confirmations}个指标确认")
|
||||
|
||||
# 判断是否应该交易(信号强度 >= 5 才交易,提高胜率)
|
||||
should_trade = signal_strength >= config.TRADING_CONFIG.get('MIN_SIGNAL_STRENGTH', 5)
|
||||
# 多周期共振加分:如果4H趋势与信号方向一致,增加信号强度
|
||||
if direction and trend_4h:
|
||||
if (direction == 'BUY' and trend_4h == 'up') or (direction == 'SELL' and trend_4h == 'down'):
|
||||
signal_strength += 2
|
||||
reasons.append("4H周期共振确认")
|
||||
elif (direction == 'BUY' and trend_4h == 'down') or (direction == 'SELL' and trend_4h == 'up'):
|
||||
# 逆势信号,降低信号强度或直接拒绝
|
||||
signal_strength -= 3
|
||||
reasons.append("⚠️ 逆4H趋势,信号强度降低")
|
||||
|
||||
# 判断是否应该交易(信号强度 >= 7 才交易,提高胜率)
|
||||
min_signal_strength = config.TRADING_CONFIG.get('MIN_SIGNAL_STRENGTH', 7)
|
||||
should_trade = signal_strength >= min_signal_strength
|
||||
|
||||
# 如果信号方向与4H趋势相反,直接拒绝交易
|
||||
if direction and trend_4h:
|
||||
if (direction == 'BUY' and trend_4h == 'down') or (direction == 'SELL' and trend_4h == 'up'):
|
||||
should_trade = False
|
||||
reasons.append("❌ 禁止逆4H趋势交易")
|
||||
|
||||
if not should_trade and direction:
|
||||
reasons.append(f"信号强度不足({signal_strength}/10)")
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user