({rec.direction === 'BUY' ? '低于' : '高于'}当前价
@@ -430,15 +440,15 @@ function Recommendations() {
)}
- {parseFloat(rec.suggested_stop_loss || 0).toFixed(4)}
+ {fmtPrice(rec.suggested_stop_loss)}
- {parseFloat(rec.suggested_take_profit_1 || 0).toFixed(4)}
+ {fmtPrice(rec.suggested_take_profit_1)}
- {parseFloat(rec.suggested_take_profit_2 || 0).toFixed(4)}
+ {fmtPrice(rec.suggested_take_profit_2)}
diff --git a/trading_system/trade_recommender.py b/trading_system/trade_recommender.py
index 278c047..e0242b1 100644
--- a/trading_system/trade_recommender.py
+++ b/trading_system/trade_recommender.py
@@ -331,18 +331,23 @@ class TradeRecommender:
signal_strength += 2
reasons.append("4H周期共振确认")
- # 判断是否应该交易(使用传入的参数,如果没有则使用config中的值)
+ # 推荐系统:默认不再输出“逆4H趋势”的推荐(用户反馈方向不对的主要来源)
+ # 如果未来需要放开,可做成配置项 ALLOW_COUNTER_TREND_RECOMMENDATIONS。
+ if direction and trend_4h and trend_4h in ("up", "down"):
+ if (direction == 'BUY' and trend_4h == 'down') or (direction == 'SELL' and trend_4h == 'up'):
+ reasons.append("❌ 逆4H趋势,跳过推荐")
+ return {
+ 'should_trade': False,
+ 'direction': direction,
+ 'reason': ', '.join(reasons) if reasons else '逆趋势',
+ 'strength': max(0, signal_strength - 2),
+ 'trend_4h': trend_4h
+ }
+
+ # 判断是否应该推荐(使用传入的参数,如果没有则使用config中的值)
if min_signal_strength is None:
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'):
- # 推荐系统允许逆趋势,但降低信号强度(减2分)
- signal_strength = max(0, signal_strength - 2)
- reasons.append("⚠️ 逆4H趋势(高风险)")
- # 不禁止,但标记为高风险
+ should_trade = (direction is not None) and (signal_strength >= min_signal_strength)
return {
'should_trade': should_trade,
@@ -395,10 +400,20 @@ class TradeRecommender:
price_ts_ms = None
direction = trade_signal['direction']
+ if not direction:
+ return None
- # 计算建议的止损止盈(基于保证金)
- entry_price = current_price
-
+ # 先计算建议挂单价(限价单),然后用“挂单价”作为止损/止盈的基准入场价
+ # 否则会出现:止损按 current_price 算、但挂单按回调价算 → 止损/挂单价不匹配,甚至相等
+ limit_price_offset_pct = config.TRADING_CONFIG.get('LIMIT_ORDER_OFFSET_PCT', 0.5) # 默认0.5%
+ if direction == 'BUY':
+ suggested_limit_price = current_price * (1 - limit_price_offset_pct / 100)
+ else: # SELL
+ suggested_limit_price = current_price * (1 + limit_price_offset_pct / 100)
+
+ # 计算建议的止损止盈(基于保证金),以“计划入场价=挂单价”为基准
+ entry_price = suggested_limit_price
+
# 估算仓位数量和杠杆(用于计算止损止盈)
# 重要语义:suggested_position_pct 表示“保证金占用比例”
account_balance = symbol_info.get('account_balance', 1000)
@@ -453,15 +468,6 @@ class TradeRecommender:
position_multiplier = min(1.0 + (signal_strength - 5) * 0.1, 1.5)
suggested_position_pct = base_position_pct * position_multiplier
- # 计算建议的挂单价(使用限价单,而不是市价单)
- # 对于做多:建议价格略低于当前价格(当前价格的99.5%),以便在回调时买入
- # 对于做空:建议价格略高于当前价格(当前价格的100.5%),以便在反弹时卖出
- limit_price_offset_pct = config.TRADING_CONFIG.get('LIMIT_ORDER_OFFSET_PCT', 0.5) # 默认0.5%
- if direction == 'BUY':
- suggested_limit_price = current_price * (1 - limit_price_offset_pct / 100)
- else: # SELL
- suggested_limit_price = current_price * (1 + limit_price_offset_pct / 100)
-
# 添加时间戳
timestamp = time.time()
recommendation_time = datetime.now().isoformat()
@@ -533,6 +539,8 @@ class TradeRecommender:
'suggested_stop_loss': stop_loss_price,
'suggested_take_profit_1': take_profit_1,
'suggested_take_profit_2': take_profit_2,
+ # 计划入场价(限价挂单价)作为止损/止盈计算基准
+ 'planned_entry_price': entry_price,
'suggested_position_percent': suggested_position_pct,
'suggested_leverage': config.TRADING_CONFIG.get('LEVERAGE', 10),
'volume_24h': symbol_info.get('volume24h'),