diff --git a/backend/app/crypto_agent/market_signal_analyzer.py b/backend/app/crypto_agent/market_signal_analyzer.py index 7df447f..c8bf6a5 100644 --- a/backend/app/crypto_agent/market_signal_analyzer.py +++ b/backend/app/crypto_agent/market_signal_analyzer.py @@ -25,15 +25,72 @@ class MarketSignalAnalyzer: """市场信号分析器 - 只关注市场,输出客观信号""" # 纯市场分析系统提示词(与旧版 CRYPTO_SYSTEM_PROMPT 保持一致,只移除仓位管理) - MARKET_ANALYSIS_PROMPT = """你是一位专业的加密货币交易员和技术分析师。你的任务是综合分析**K线数据、量价关系、技术指标和新闻舆情**,给出交易信号。 + MARKET_ANALYSIS_PROMPT = """你是一位专业的加密货币交易员和技术分析师。你的任务是综合分析**趋势方向、K线数据、量价关系、技术指标和新闻舆情**,给出交易信号。 ## 核心理念 -加密货币市场波动大,每天都有交易机会。你的目标是: -- **主动寻找机会**,而不是被动等待完美信号 -- 短线交易重点关注:超跌反弹、超涨回落、关键位突破 -- 中线交易重点关注:趋势回调、形态突破、多周期共振 +**趋势是你的朋友,顺势交易是稳定盈利的关键。** -## 一、量价分析(最重要) +### 🚨 铁律(必须遵守) +1. **先判断趋势,再寻找信号** - 趋势方向错误,信号再强也不做 +2. **顺势交易为主** - 上涨趋势只做多或观望,下跌趋势只做空或观望 +3. **逆势交易极其谨慎** - 必须有多重反转信号才能考虑逆势 +4. **单边行情不逆势** - 强趋势中(连续3根以上同向K线)严禁逆势开仓 + +### 交易目标 +- **稳健为主**:宁可错过,不做错 +- **顺势而为**:在大趋势方向上寻找入场点 +- **严控风险**:每次交易风险不超过本金的2% + +## 零、趋势方向判断(第一步,最重要!) +**在分析任何信号之前,先判断当前趋势方向和强度。** + +### 趋势判断标准(使用 EMA 和 均线系统) +**上升趋势(多头市场)**: +- EMA20 > EMA50 > EMA200(短中长期均线多头排列) +- 价格站稳在 EMA20 之上 +- MA5 > MA10 > MA20 > MA50 +- 最近高点逐步抬高,低点也逐步抬高 + +**下降趋势(空头市场)**: +- EMA20 < EMA50 < EMA200(短中长期均线空头排列) +- 价格持续在 EMA20 之下 +- MA5 < MA10 < MA20 < MA50 +- 最近高点逐步降低,低点也逐步降低 + +**震荡市(无明确趋势)**: +- 均线纠缠,无明显排列 +- 价格在 EMA20 上下波动 +- 高点低点无规律 +- 此时可双向交易,但降低仓位 + +### 趋势强度判断 +- **强趋势**:均线完美排列 + 价格远离均线 + 成交量配合 +- **中等趋势**:均线有排列 + 价格偶尔回踩均线 +- **弱趋势/震荡**:均线纠缠 + 价格在均线上下反复 + +### 顺势交易规则(必须执行) +| 当前趋势 | 允许操作 | 条件 | +|---------|---------|------| +| **强上升趋势** | ✅ 只做多 | 回调到支撑位、RSI超卖区、金叉 | +| **强上升趋势** | ❌ 严禁做空 | 除非出现明确的顶背离+放量反转信号 | +| **强下降趋势** | ✅ 只做空 | 反弹到阻力位、RSI超买区、死叉 | +| **强下降趋势** | ❌ 严禁做多 | 除非出现明确的底背离+放量反转信号 | +| **震荡市** | ✅ 双向交易 | 但降低仓位(轻仓),提高止损要求 | +| **趋势不明确** | ⚠️ 观望为主 | 等待趋势明确后再入场 | + +### 逆势交易的条件(极其严格) +**只有在满足以下全部条件时,才允许考虑逆势交易:** +1. **多重反转信号**: + - 明确的背离(顶背离或底背离) + - 关键形态反转(头肩顶/底、双顶/底、吞没形态) + - 放量突破关键位 +2. **多周期确认**:4h、1h、15m 三个周期同时出现反转信号 +3. **风险收益比合理**:潜在盈利至少是风险的3倍以上 +4. **降低仓位**:逆势交易必须轻仓(不超过顺势仓位的50%) + +**如果不符合上述条件,即使有买入/卖出信号,也必须选择 hold(观望)。** + +## 一、量价分析(重要) 量价关系是判断趋势真假的核心: ### 1. 健康上涨信号 @@ -90,8 +147,7 @@ class MarketSignalAnalyzer: - 布林带收口:即将变盘 - 布林带开口:趋势启动 -### 均线系统(重要) -**均线系统是趋势判断的核心,请仔细分析:** +### 均线系统(趋势判断核心) - **多头排列**(MA5 > MA10 > MA20 > MA50):强势上涨趋势,回调做多 - **空头排列**(MA5 < MA10 < MA20 < MA50):强势下跌趋势,反弹做空 - **价格与 MA 的关系**: @@ -163,6 +219,8 @@ class MarketSignalAnalyzer: ```json { + "trend_direction": "uptrend/downtrend/neutral", + "trend_strength": "strong/medium/weak", "analysis_summary": "简要描述当前市场状态(50字以内)", "volume_analysis": "量价分析结论(30字以内)", "news_sentiment": "positive/negative/neutral", @@ -177,7 +235,7 @@ class MarketSignalAnalyzer: "entry_zone": 66000, "stop_loss": 65500, "take_profit": 67500, - "reasoning": "详细的入场理由(必须包含量价分析)", + "reasoning": "详细的入场理由(必须包含趋势判断和量价分析)", "key_factors": ["关键因素1", "关键因素2"] } ], @@ -435,34 +493,57 @@ class MarketSignalAnalyzer: else: sig['grade'] = 'D' - # 从信号中推断 market_state 和 trend + # 处理趋势字段 - 优先使用 LLM 返回的趋势字段,否则从信号推断 + if 'trend_direction' not in result or 'trend_strength' not in result: + # 从 signals 中推断趋势 + if 'signals' in result and result['signals']: + best_signal = max(result['signals'], key=lambda s: s.get('confidence', 0)) + action = best_signal.get('action', 'wait') + confidence = best_signal.get('confidence', 0) + + # 推断趋势方向(如果 LLM 没有提供) + if 'trend_direction' not in result: + if action == 'buy': + result['trend_direction'] = 'uptrend' + elif action == 'sell': + result['trend_direction'] = 'downtrend' + else: + result['trend_direction'] = 'neutral' + + # 推断趋势强度(如果 LLM 没有提供) + if 'trend_strength' not in result: + result['trend_strength'] = 'strong' if confidence >= 70 else 'medium' if confidence >= 50 else 'weak' + + # 从信号中推断 market_state(用于向后兼容) if 'signals' in result and result['signals']: - # 找出置信度最高的信号 best_signal = max(result['signals'], key=lambda s: s.get('confidence', 0)) action = best_signal.get('action', 'wait') confidence = best_signal.get('confidence', 0) + trend_direction = result.get('trend_direction', 'neutral') # 推断市场状态 - if confidence >= 70: - if action == 'buy': + if confidence >= 70 and trend_direction != 'neutral': + if trend_direction == 'uptrend': result['market_state'] = '强势上涨' - elif action == 'sell': + elif trend_direction == 'downtrend': result['market_state'] = '强势下跌' else: result['market_state'] = '震荡整理' else: result['market_state'] = '震荡整理' - # 推断趋势 - if action == 'buy': - result['trend'] = 'up' - elif action == 'sell': - result['trend'] = 'down' - else: - result['trend'] = 'sideways' + # 推断 trend(用于向后兼容,简化的趋势字段) + if 'trend' not in result: + if trend_direction == 'uptrend': + result['trend'] = 'up' + elif trend_direction == 'downtrend': + result['trend'] = 'down' + else: + result['trend'] = 'sideways' else: result['market_state'] = '无明确信号' - result['trend'] = 'sideways' + if 'trend' not in result: + result['trend'] = 'sideways' logger.info(f"✅ 市场信号分析完成: {symbol}") logger.debug(f"市场信号: {json.dumps(result, ensure_ascii=False, indent=2)}") @@ -540,6 +621,8 @@ class MarketSignalAnalyzer: """返回空信号""" return { 'symbol': symbol, + 'trend_direction': 'neutral', + 'trend_strength': 'weak', 'analysis_summary': 'unknown', 'volume_analysis': '分析失败', 'news_sentiment': 'neutral',