From 098132bda62f00ccaebcfcc64bbceba481f1bb9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=96=87=E8=96=87=E5=AE=89?= Date: Sat, 17 Jan 2026 21:16:37 +0800 Subject: [PATCH] a --- frontend/src/components/Recommendations.css | 131 +++++++++++++++ frontend/src/components/Recommendations.jsx | 50 +++++- trading_system/trade_recommender.py | 171 +++++++++++++++++++- 3 files changed, 348 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/Recommendations.css b/frontend/src/components/Recommendations.css index 849662b..df55e66 100644 --- a/frontend/src/components/Recommendations.css +++ b/frontend/src/components/Recommendations.css @@ -261,6 +261,137 @@ line-height: 1.6; } +/* 推荐分类和风险标签 */ +.recommendation-tags { + display: flex; + gap: 8px; + flex-wrap: wrap; + margin-bottom: 10px; +} + +.category-tag, +.risk-tag { + padding: 4px 10px; + border-radius: 4px; + font-size: 12px; + font-weight: bold; +} + +.category-tag { + background-color: #2196F3; + color: white; +} + +.category-tag.category-逆势反弹高风险 { + background-color: #f44336; +} + +.category-tag.category-震荡区间操作 { + background-color: #FF9800; +} + +.risk-tag { + background-color: #9E9E9E; + color: white; +} + +.risk-tag.risk-高 { + background-color: #f44336; +} + +.risk-tag.risk-中高 { + background-color: #FF5722; +} + +.risk-tag.risk-中等 { + background-color: #FF9800; +} + +.risk-tag.risk-低中 { + background-color: #4CAF50; +} + +/* 用户指南 */ +.user-guide { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 15px; + border-radius: 8px; + margin: 10px 0; +} + +.user-guide strong { + display: block; + margin-bottom: 10px; + font-size: 16px; +} + +.user-guide-content { + margin: 0; + white-space: pre-wrap; + font-family: 'Courier New', monospace; + font-size: 13px; + line-height: 1.8; + background: rgba(255, 255, 255, 0.1); + padding: 12px; + border-radius: 4px; + overflow-x: auto; +} + +/* 交易教程 */ +.trading-tutorial { + background-color: #fff3cd; + border-left: 4px solid #ffc107; + padding: 12px 15px; + border-radius: 4px; + margin: 10px 0; +} + +.trading-tutorial strong { + display: block; + margin-bottom: 8px; + color: #856404; +} + +.trading-tutorial p { + margin: 0; + color: #856404; + line-height: 1.6; +} + +/* 预期持仓时间和退出提醒 */ +.expected-hold-time, +.max-hold-warning { + background-color: #e3f2fd; + border-left: 4px solid #2196F3; + padding: 10px 15px; + border-radius: 4px; + margin: 10px 0; +} + +.expected-hold-time strong, +.max-hold-warning strong { + display: inline-block; + margin-right: 8px; + color: #1976d2; +} + +.expected-hold-time span, +.max-hold-warning span { + color: #1976d2; + line-height: 1.6; +} + +.max-hold-warning { + background-color: #fff3e0; + border-left-color: #ff9800; +} + +.max-hold-warning strong, +.max-hold-warning span { + color: #e65100; +} + .suggested-params { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); diff --git a/frontend/src/components/Recommendations.jsx b/frontend/src/components/Recommendations.jsx index 0b6dcca..f8fc2b7 100644 --- a/frontend/src/components/Recommendations.jsx +++ b/frontend/src/components/Recommendations.jsx @@ -317,6 +317,22 @@ function Recommendations() {
+ {/* 推荐分类和风险等级标签 */} + {(rec.recommendation_category || rec.risk_level) && ( +
+ {rec.recommendation_category && ( + + {rec.recommendation_category} + + )} + {rec.risk_level && ( + + 风险: {rec.risk_level} + + )} +
+ )} +
@@ -337,8 +353,24 @@ function Recommendations() { )}
+ {/* 用户指南(人话版计划) */} + {rec.user_guide && ( +
+ 📋 操作计划: +
{rec.user_guide}
+
+ )} + + {/* 交易教程(如果存在) */} + {rec.trading_tutorial && ( +
+ 💡 交易提示: +

{rec.trading_tutorial}

+
+ )} +
- 推荐原因: + 技术分析原因:

{rec.recommendation_reason || '-'}

@@ -404,6 +436,22 @@ function Recommendations() {
+ {/* 预期持仓时间(如果存在) */} + {rec.expected_hold_time && ( +
+ ⏱️ 预期持仓时间: + {rec.expected_hold_time} +
+ )} + + {/* 最大持仓天数提醒 */} + {rec.max_hold_days && ( +
+ ⚠️ 退出提醒: + 若持仓超过{rec.max_hold_days}天仍未触及第一目标,建议平仓离场重新评估 +
+ )} + {showDetails[rec.id || rec.symbol] && (
diff --git a/trading_system/trade_recommender.py b/trading_system/trade_recommender.py index aa36509..2fa8685 100644 --- a/trading_system/trade_recommender.py +++ b/trading_system/trade_recommender.py @@ -455,6 +455,20 @@ class TradeRecommender: expected_pnl_1 = (estimated_win_rate / 100) * take_profit_1_usdt - ((100 - estimated_win_rate) / 100) * stop_loss_usdt expected_pnl_2 = (estimated_win_rate / 100) * take_profit_2_usdt - ((100 - estimated_win_rate) / 100) * stop_loss_usdt + # 分类推荐类型和风险等级 + recommendation_category, risk_level, simple_reason, risk_warning, trading_tutorial = self._classify_recommendation( + market_regime, trend_4h, direction, trade_signal, signal_strength + ) + + # 计算预期持仓时间(基于策略周期和市场状态) + expected_hold_time = self._estimate_hold_time(market_regime, trend_4h, direction, signal_strength) + + # 生成用户指南(人话版计划) + user_guide = self._generate_user_guide( + symbol, direction, suggested_limit_price, stop_loss_price, take_profit_1, take_profit_2, + simple_reason, expected_hold_time, risk_warning, recommendation_category + ) + # 基础推荐数据 base_data = { 'symbol': symbol, @@ -488,7 +502,14 @@ class TradeRecommender: 'take_profit_1_usdt': round(take_profit_1_usdt, 2), 'take_profit_2_usdt': round(take_profit_2_usdt, 2), 'recommendation_time': recommendation_time, - 'timestamp': timestamp + 'timestamp': timestamp, + # 新增字段:用户指南和分类 + 'user_guide': user_guide, + 'recommendation_category': recommendation_category, + 'risk_level': risk_level, + 'expected_hold_time': expected_hold_time, + 'trading_tutorial': trading_tutorial, + 'max_hold_days': 3 # 最大持仓天数(超过此天数建议平仓) } # 限价单推荐 @@ -507,15 +528,159 @@ class TradeRecommender: logger.debug( f"✓ 生成推荐: {symbol} {direction} " - f"(信号强度: {signal_strength}/10, 胜率预估: {estimated_win_rate:.1f}%)" + f"(信号强度: {signal_strength}/10, 胜率预估: {estimated_win_rate:.1f}%, " + f"分类: {recommendation_category}, 风险: {risk_level})" ) return [limit_recommendation, market_recommendation] except Exception as e: - logger.error(f"创建推荐失败 {symbol_info.get('symbol', 'unknown')}: {e}") + logger.error(f"创建推荐失败 {symbol_info.get('symbol', 'unknown')}: {e}", exc_info=True) return None + def _classify_recommendation( + self, + market_regime: str, + trend_4h: Optional[str], + direction: str, + trade_signal: Dict, + signal_strength: int + ) -> tuple: + """ + 分类推荐类型和风险等级 + + Returns: + (recommendation_category, risk_level, simple_reason, risk_warning, trading_tutorial) + """ + # 判断是否为逆趋势交易 + is_counter_trend = False + if trend_4h: + if (direction == 'BUY' and trend_4h == 'down') or (direction == 'SELL' and trend_4h == 'up'): + is_counter_trend = True + + # 分类推荐类型 + if market_regime == 'trending': + if not is_counter_trend: + # 顺趋势突破 + category = "顺趋势突破" + risk_level = "中等" + simple_reason = "趋势明确,顺势而为,胜率较高" + risk_warning = "趋势可能反转,注意止损保护" + tutorial = "此类交易适合跟随趋势,持仓时间可稍长,但需关注趋势是否持续" + else: + # 逆趋势反弹(高风险) + category = "逆势反弹(高风险)" + risk_level = "高" + simple_reason = "逆趋势操作,风险较高,适合快进快出" + risk_warning = "⚠️ 高风险:逆趋势交易胜率较低,务必严格止损,快进快出" + tutorial = "此类交易胜率较低,仅适合短线快进快出,务必严格止损。建议持仓不超过数小时,一旦触及止损立即离场" + elif market_regime == 'ranging': + # 震荡区间操作 + category = "震荡区间操作" + risk_level = "中等" + simple_reason = "市场震荡,在区间边界操作,适合高抛低吸" + risk_warning = "震荡可能转为趋势,注意突破风险" + tutorial = "此类交易适合在震荡区间边界操作,预期持仓时间较短(数小时至1天),到达目标及时止盈" + else: + # 未知市场状态 + category = "市场状态不明" + risk_level = "中高" + simple_reason = "市场状态不明确,谨慎操作" + risk_warning = "市场状态不明,建议降低仓位或等待更明确信号" + tutorial = "市场状态不明确,建议谨慎操作,降低仓位,严格止损" + + # 根据信号强度调整风险等级 + if signal_strength >= 7: + if risk_level == "高": + risk_level = "中高" + elif risk_level == "中等": + risk_level = "低中" + elif signal_strength < 5: + if risk_level == "中等": + risk_level = "中高" + elif risk_level == "低中": + risk_level = "中等" + + return category, risk_level, simple_reason, risk_warning, tutorial + + def _estimate_hold_time( + self, + market_regime: str, + trend_4h: Optional[str], + direction: str, + signal_strength: int + ) -> str: + """ + 估算预期持仓时间 + + Returns: + 预期持仓时间的文字描述 + """ + # 基于策略周期(1H/15min)和市场状态估算 + if market_regime == 'trending': + # 趋势市场,持仓时间可能较长 + if signal_strength >= 7: + return "预期持仓:数小时至2天(趋势明确,可适当延长持仓)" + else: + return "预期持仓:数小时至1天(趋势较弱,及时止盈)" + elif market_regime == 'ranging': + # 震荡市场,持仓时间较短 + return "预期持仓:数小时至半天(震荡市场,快进快出)" + else: + # 未知状态,保守估计 + return "预期持仓:数小时(市场状态不明,谨慎持仓)" + + def _generate_user_guide( + self, + symbol: str, + direction: str, + limit_price: float, + stop_loss: float, + tp1: float, + tp2: float, + simple_reason: str, + expected_hold_time: str, + risk_warning: str, + category: str + ) -> str: + """ + 生成用户指南(人话版计划) + + Args: + symbol: 交易对 + direction: 方向 + limit_price: 建议入场价(限价单) + stop_loss: 止损价 + tp1: 第一目标止盈价 + tp2: 第二目标止盈价 + simple_reason: 简单原因 + expected_hold_time: 预期持仓时间 + risk_warning: 风险警告 + category: 推荐分类 + + Returns: + 用户指南文本 + """ + direction_cn = "买入" if direction == 'BUY' else "卖出" + + user_guide = f"""【操作计划】{direction_cn} {symbol} +【推荐类型】{category} +【核心理由】{simple_reason} +【具体点位】 + • 入场价(限价单): {limit_price:.4f} USDT + • 止损价: {stop_loss:.4f} USDT + • 第一目标: {tp1:.4f} USDT(盈亏比1:1) + • 第二目标: {tp2:.4f} USDT(盈亏比2.5:1) +【持仓周期】{expected_hold_time} +【退出条件】 + • 触及止损:立即平仓 + • 触及第一目标:可部分止盈或全部止盈 + • 触及第二目标:建议全部止盈 + • 持仓超过3天未触及第一目标:建议平仓离场重新评估 +【关键提醒】{risk_warning}""" + + return user_guide + async def get_active_recommendations(self) -> List[Dict]: """获取当前有效的推荐""" if DB_AVAILABLE and TradeRecommendation: