From e6560b340d79da79be43783c4808f610b9f76cfa Mon Sep 17 00:00:00 2001 From: aaron <> Date: Sat, 28 Feb 2026 19:38:00 +0800 Subject: [PATCH] update --- .../crypto_agent/market_signal_analyzer.py | 226 +++++++++++++++++- 1 file changed, 222 insertions(+), 4 deletions(-) diff --git a/backend/app/crypto_agent/market_signal_analyzer.py b/backend/app/crypto_agent/market_signal_analyzer.py index 7389ed3..e47fad9 100644 --- a/backend/app/crypto_agent/market_signal_analyzer.py +++ b/backend/app/crypto_agent/market_signal_analyzer.py @@ -32,10 +32,11 @@ class MarketSignalAnalyzer: ### 🚨 铁律(必须遵守) 1. **先判断趋势,再寻找信号** - 趋势方向错误,信号再强也不做 -2. **顺势交易为主** - 上涨趋势只做多或观望,下跌趋势只做空或观望 -3. **逆势交易极其谨慎** - 必须有多重反转信号才能考虑逆势 -4. **单边行情不逆势** - 强趋势中(连续3根以上同向K线)严禁逆势开仓 -5. **严禁重复信号** - 如果上一轮已经给出了相同方向的交易信号,绝对不要重复输出!只有在以下情况才能给出新信号: +2. **判断趋势位置,避免盲目追涨杀跌** - 趋势到了晚期,要警惕反转 +3. **顺势交易为主,但要考虑反转机会** - 上涨趋势只做多或观望,下跌趋势只做空或观望 +4. **逆势交易极其谨慎** - 必须有多重反转信号才能考虑逆势 +5. **单边行情不逆势** - 强趋势中(连续3根以上同向K线)严禁逆势开仓 +6. **严禁重复信号** - 如果上一轮已经给出了相同方向的交易信号,绝对不要重复输出!只有在以下情况才能给出新信号: - 趋势发生了**明确的反转**(从多头转为空头,或反之) - 上一轮是观望,现在出现了**新的明确交易机会** - 上一轮信号已失效(价格已触及止损或止盈) @@ -95,6 +96,100 @@ class MarketSignalAnalyzer: **如果不符合上述条件,即使有买入/卖出信号,也必须选择 hold(观望)。** +## 零点五、趋势位置判断和左侧交易(短线交易核心) + +### 🚨 避免盲目追涨杀跌 +**顺势交易不等于追涨杀跌!趋势到了晚期,要警惕反转。** + +### 趋势三阶段判断 +**上升趋势的三个阶段**: +1. **早期**(启动阶段): + - 均线刚开始多头排列 + - 价格刚刚站上所有均线 + - 成交量温和放大 + - ✅ 可以积极做多 + +2. **中期**(加速阶段): + - 均线完美排列,价格远离均线 + - 成交量持续放大 + - RSI 在 50-70 之间 + - ✅ 可以顺势做多,但警惕超买 + +3. **晚期**(过度延伸): + - 价格严重偏离均线(> 5%) + - RSI > 75(超买区) + - 布林带开口极大,价格在上轨之外 + - 出现顶背离信号 + - ❌ 不要追多,警惕反转 + +**下降趋势的三个阶段**: +1. **早期**:均线刚开始空头排列,刚刚破位 → ✅ 可以积极做空 +2. **中期**:均线完美空头排列,加速下跌 → ✅ 可以顺势做空,警惕超卖 +3. **晚期**:价格严重偏离均线,RSI < 25 → ❌ 不要追空,警惕反弹 + +### 过度延伸的信号(必须警惕) + +**上涨过度延伸的信号**: +- RSI > 75 且出现顶背离 +- 价格偏离 MA5 > 5% +- 布林带上轨之外,且开口极大 +- 连续 3 根以上大阳线 +- 极端放量后价格滞涨 +- ⚠️ 这时不要追多,考虑减仓或做空 + +**下跌过度延伸的信号**: +- RSI < 25 且出现底背离 +- 价格偏离 MA5 > 5% +- 布林带下轨之外,且开口极大 +- 连续 3 根以上大阴线 +- 极端放量后价格企稳 +- ⚠️ 这时不要追空,考虑平仓或做多 + +### 左侧交易规则(特定条件下可尝试) + +**什么时候可以尝试左侧交易?** + +1. **上升趋势晚期,出现明确反转信号**: + - RSI 顶背离 + 价格触及布林带上轨外 + - 放量滞涨 + 出现大阴线 + - 关键阻力位出现明显反转形态(十字星、吞没) + - ✅ 可以尝试做空,小仓位(light 或 micro) + +2. **下降趋势晚期,出现明确反转信号**: + - RSI 底背离 + 价格触及布林带下轨外 + - 地量后企稳 + 出现大阳线 + - 关键支撑位出现明显反转形态(锤子线、早晨之星) + - ✅ 可以尝试做多,小仓位(light 或 micro) + +3. **小级别反转信号**: + - 5m/15m 周期出现明显的背离信号 + - 4h/1h 大周期仍在趋势中,但小级别开始反转 + - ✅ 可以尝试小仓位反向,但严格止损 + +**左侧交易必须满足的条件**: +- 至少 2 个反转信号同时出现 +- 有明确的关键点位支撑/阻力 +- 严格止损(不超过保证金的 1%) +- 小仓位(light 或 micro) + +### 实战示例 + +**❌ 错误:盲目追涨** +``` +场景:BTC 多头排列,连续上涨 5% +MA 完美多头排列,RSI = 68 +错误分析:趋势仍在延续,追多 +正确分析:价格已偏离 MA5 > 3%,接近过度延伸,观望或小仓位做空 +``` + +**✅ 正确:等待反转信号** +``` +场景:BTC 多头排列,但出现顶背离 +4h 多头排列,但 RSI 出现顶背离 +15m 价格创新高但 RSI 未创新高 +正确分析:趋势可能反转,小仓位尝试做空 +``` + ## 一、量价分析(重要) 量价关系是判断趋势真假的核心: @@ -303,6 +398,25 @@ class MarketSignalAnalyzer: - 短线信号:同一方向信号间隔至少1小时 - 波段信号:同一方向信号间隔至少4小时 +### 🎯 趋势位置考虑(重要!) +**在给出信号之前,先判断趋势所处的阶段:** + +**上升趋势中**: +- 如果价格严重偏离均线(> 5%),RSI > 75,布林带开口极大 + → 趋势可能到晚期,不要追多,考虑反向信号 +- 如果价格在均线上方,但开始出现顶背离 + → 警惕反转,考虑做空或观望 +- 如果价格刚刚突破,均线刚开始多头排列 + → 趋势早期,可以积极做多 + +**下降趋势中**: +- 如果价格严重偏离均线(> 5%),RSI < 25,布林带开口极大 + → 趋势可能到晚期,不要追空,考虑反向信号 +- 如果价格在均线下方,但开始出现底背离 + → 警惕反弹,考虑做多或观望 +- 如果价格刚刚跌破,均线刚开始空头排列 + → 趋势早期,可以积极做空 + **记住:宁可错过,不要噪音。重复信号只会导致过度交易!** 记住:你只负责分析市场,输出客观的交易信号,不需要考虑仓位管理和风险控制! @@ -435,6 +549,12 @@ class MarketSignalAnalyzer: context_parts.append(f"\n## 波动率分析") context_parts.append(volatility_analysis) + # 趋势位置分析(新增:避免盲目追涨杀跌) + trend_position_analysis = self._analyze_trend_position(data) + if trend_position_analysis: + context_parts.append(f"\n## 趋势位置分析") + context_parts.append(trend_position_analysis) + return "\n".join(context_parts) async def _get_news_context(self, symbol: str) -> str: @@ -462,6 +582,104 @@ class MarketSignalAnalyzer: logger.warning(f"获取新闻失败: {e}") return "新闻获取失败" + def _analyze_trend_position(self, data: Dict[str, pd.DataFrame]) -> str: + """分析趋势所处的位置(早期、中期、晚期)""" + try: + df_1h = data.get('1h') + if df_1h is None or len(df_1h) < 50: + return "" + + latest = df_1h.iloc[-1] + current_price = float(latest['close']) + + # 获取均线 + ma5 = latest.get('ma5') + ma10 = latest.get('ma10') + ma20 = latest.get('ma20') + + if not all([ma5, ma10, ma20]): + return "" + + # 计算价格偏离度 + deviation_ma5 = abs(current_price - ma5) / ma5 * 100 + deviation_ma20 = abs(current_price - ma20) / ma20 * 100 + + # 获取 RSI + rsi = latest.get('rsi', 50) + + # 获取布林带 + bb_upper = latest.get('bb_upper') + bb_lower = latest.get('bb_lower') + + analysis = [] + + # 判断趋势方向 + if ma5 > ma10 > ma20: + trend = "上涨" + # 判断是否过度延伸 + overextended_signals = [] + + if deviation_ma5 > 5: + overextended_signals.append(f"价格偏离 MA5 > 5% ({deviation_ma5:.1f}%)") + + if rsi > 75: + overextended_signals.append(f"RSI 超买 ({rsi:.0f})") + + if bb_upper and current_price > bb_upper: + overextended_signals.append("价格突破布林带上轨") + + if overextended_signals: + analysis.append(f"⚠️ 警告:{trend}趋势可能过度延伸") + for signal in overextended_signals: + analysis.append(f" - {signal}") + analysis.append(f" → 不要追{trend},警惕反转") + + elif deviation_ma5 > 3 or rsi > 65: + analysis.append(f"📍 位置:{trend}趋势中期") + analysis.append(f" → 价格偏离 MA5 {deviation_ma5:.1f}%,RSI {rsi:.0f}") + analysis.append(f" → 可以顺势{trend},但警惕超买") + + else: + analysis.append(f"✅ 位置:{trend}趋势早期") + analysis.append(f" → 可以积极{trend}") + + elif ma5 < ma10 < ma20: + trend = "下跌" + overextended_signals = [] + + if deviation_ma5 > 5: + overextended_signals.append(f"价格偏离 MA5 > 5% ({deviation_ma5:.1f}%)") + + if rsi < 25: + overextended_signals.append(f"RSI 超卖 ({rsi:.0f})") + + if bb_lower and current_price < bb_lower: + overextended_signals.append("价格跌破布林带下轨") + + if overextended_signals: + analysis.append(f"⚠️ 警告:{trend}趋势可能过度延伸") + for signal in overextended_signals: + analysis.append(f" - {signal}") + analysis.append(f" → 不要追{trend},警惕反弹") + + elif deviation_ma5 > 3 or rsi < 35: + analysis.append(f"📍 位置:{trend}趋势中期") + analysis.append(f" → 价格偏离 MA5 {deviation_ma5:.1f}%,RSI {rsi:.0f}") + analysis.append(f" → 可以顺势{trend},但警惕超卖") + + else: + analysis.append(f"✅ 位置:{trend}趋势早期") + analysis.append(f" → 可以积极{trend}") + + else: + analysis.append("➖ 位置:震荡市") + + return "\n".join(analysis) if analysis else "" + + except Exception as e: + logger.warning(f"趋势位置分析失败: {e}") + return "" + def _build_analysis_prompt(self, symbol: str, market_context: str, news_context: str, previous_signal: Dict[str, Any] = None) -> str: