diff --git a/backend/app/crypto_agent/llm_signal_analyzer.py b/backend/app/crypto_agent/llm_signal_analyzer.py index 9086869..b28db86 100644 --- a/backend/app/crypto_agent/llm_signal_analyzer.py +++ b/backend/app/crypto_agent/llm_signal_analyzer.py @@ -56,10 +56,16 @@ class LLMSignalAnalyzer: - **旗形整理**:趋势中的健康回调 ## 三、技术指标分析 -### RSI(相对强弱指标) -- RSI < 30:超卖区,关注反弹机会 -- RSI > 70:超买区,关注回落风险 -- RSI 背离:价格与 RSI 走势相反 = 重要反转信号 +### RSI(相对强弱指标)- 使用 Wilder's Smoothing 标准算法 +**RSI 是最重要的超买超卖指标,请注意细节:** +- **RSI < 30**:超卖区,关注反弹机会 + - RSI 从 30 以下回升,交叉上穿 30:买入信号 + - RSI 底背离(价格新低但 RSI 未创新低):强买入信号 +- **RSI > 70**:超买区,关注回落风险 + - RSI 从 70 以上回落,交叉下穿 70:卖出信号 + - RSI 顶背离(价格新高但 RSI 未创新高):强卖出信号 +- **RSI 40-60**:震荡区,观望为主 +- **RSI 趋势**:RSI 自身的趋势变化比单一数值更重要 ### MACD - 金叉(DIF 上穿 DEA):做多信号 @@ -74,11 +80,20 @@ class LLMSignalAnalyzer: - 布林带收口:即将变盘 - 布林带开口:趋势启动 -### 均线系统 -- 多头排列(MA5>MA10>MA20):上涨趋势 -- 空头排列(MA5 MA10 > MA20 > MA50):强势上涨趋势,回调做多 +- **空头排列**(MA5 < MA10 < MA20 < MA50):强势下跌趋势,反弹做空 +- **价格与 MA 的关系**: + - 价格站稳 MA5/MA10 上方:短线上涨 + - 价格突破 MA20:中线转多 + - 价格跌破 MA20:中线转空 + - MA50 是中期趋势的分水岭 +- **均线金叉死叉**: + - MA5 上穿 MA10:短线买入信号 + - MA5 下穿 MA10:短线卖出信号 + - MA10 上穿 MA20:中线买入信号 + - MA10 下穿 MA20:中线卖出信号 ## 四、新闻舆情分析 结合最新市场新闻判断: @@ -87,10 +102,33 @@ class LLMSignalAnalyzer: - **市场情绪**:恐慌指数、社交媒体热度 - **大户动向**:鲸鱼转账、交易所流入流出 -## 五、多周期共振 -- 4H + 1H 同向 = 中线信号更可靠 -- 1H + 15M 同向 = 短线信号更可靠 -- 多周期 RSI 同时超买/超卖 = 强反转信号 +## 五、多周期共振(关键分析框架) +**多周期共振是提高信号质量的核心方法:** + +### 周期层级关系 +- **4h(趋势层)**:决定中期大方向 +- **1h(主周期)**:主要交易周期 +- **15m(入场层)**:寻找入场时机 +- **5m(精确入场)**:确认最佳入场点 + +### 共振判断标准 +**强共振(A级信号)**: +- 所有周期趋势同向(如 4h多 + 1h多 + 15m多) +- 多周期 RSI 同时超买/超卖后出现背离 +- 多周期 MA 同时金叉/死叉 + +**中等共振(B级信号)**: +- 大周期(4h+1h)同向 +- 主周期(1h)技术指标明确 + +**弱共振(C级信号)**: +- 只有单一周期信号 +- 多周期方向不一致 + +### 实战策略 +- **顺势交易**:4h 和 1h 同向时,在 15m/5m 寻找入场点 +- **逆势谨慎**:只有 1h 信号但 4h 反向时,降低置信度 +- **突破交易**:多周期同时突破关键位,信号最强 ## 六、入场方式 - **market**:现价立即入场 - 信号已经触发,建议立即开仓 @@ -247,10 +285,16 @@ class LLMSignalAnalyzer: - **箱体震荡**:震荡区间,突破后选择方向 ## 三、技术指标分析 -### RSI(相对强弱指标) -- RSI < 30:超卖区,关注反弹机会 -- RSI > 70:超买区,关注回落风险 -- RSI 背离:价格与 RSI 走势相反 = 重要反转信号 +### RSI(相对强弱指标)- 使用 Wilder's Smoothing 标准算法 +**RSI 是最重要的超买超卖指标,请注意细节:** +- **RSI < 30**:超卖区,关注反弹机会 + - RSI 从 30 以下回升,交叉上穿 30:买入信号 + - RSI 底背离(价格新低但 RSI 未创新低):强买入信号 +- **RSI > 70**:超买区,关注回落风险 + - RSI 从 70 以上回落,交叉下穿 70:卖出信号 + - RSI 顶背离(价格新高但 RSI 未创新高):强卖出信号 +- **RSI 40-60**:震荡区,观望为主 +- **RSI 趋势**:RSI 自身的趋势变化比单一数值更重要 - 股票市场中 RSI 极端值比加密货币更可靠 ### MACD @@ -267,21 +311,51 @@ class LLMSignalAnalyzer: - 布林带开口:趋势启动 ### 均线系统(重要) -- 多头排列(MA5>MA10>MA20>MA50):上涨趋势 -- 空头排列(MA5 MA10 > MA20 > MA50):强势上涨趋势,回调做多 +- **空头排列**(MA5 < MA10 < MA20 < MA50):强势下跌趋势,反弹做空 +- **价格与 MA 的关系**: + - 价格站稳 MA5/MA10 上方:短线上涨 + - 价格突破 MA20:中线转多 + - 价格跌破 MA20:中线转空 + - MA20/MA50 是中期趋势的分水岭 +- **均线金叉死叉**: + - MA5 上穿 MA10:短线买入信号 + - MA5 下穿 MA10:短线卖出信号 + - MA10 上穿 MA20:中线买入信号 + - MA10 下穿 MA20:中线卖出信号 ### 成交量分析 - **量价配合**:价格上涨+放量或下跌+缩量是健康的 - **量价背离**:价格上涨+缩量或下跌+放量要警惕 - **换手率**:换手率过低说明关注度不够,换手率过高可能是投机 -## 四、多周期共振 -- 日线 + 周线同向 = 中长线信号更可靠 -- 日线 + 4小时同向 = 短线信号更可靠 -- 多周期 RSI 同时超买/超卖 = 强反转信号 +## 四、多周期共振(关键分析框架) +**多周期共振是提高信号质量的核心方法:** + +### 周期层级关系 +- **日线(趋势层)**:决定中长期大方向 +- **4h/1h(主周期)**:主要交易周期 +- **15m/5m(入场层)**:寻找最佳入场时机 + +### 共振判断标准 +**强共振(A级信号)**: +- 所有周期趋势同向(如日线多 + 4h多 + 1h多) +- 多周期 RSI 同时超买/超卖后出现背离 +- 多周期 MA 同时金叉/死叉 + +**中等共振(B级信号)**: +- 大周期(日线+4h)同向 +- 主周期技术指标明确 + +**弱共振(C级信号)**: +- 只有单一周期信号 +- 多周期方向不一致 + +### 实战策略 +- **顺势交易**:大周期和小周期同向时,信号最强 +- **逆势谨慎**:只有小周期信号但大周期反向时,降低置信度 +- **突破交易**:多周期同时突破关键位,信号最可靠 - 大周期决定方向,小周期决定入场时机 ## 五、股票市场特殊性 diff --git a/backend/app/services/binance_service.py b/backend/app/services/binance_service.py index 4619e07..63bbba7 100644 --- a/backend/app/services/binance_service.py +++ b/backend/app/services/binance_service.py @@ -93,7 +93,7 @@ class BinanceService: for interval in ['5m', '15m', '1h', '4h']: df = self.get_klines(symbol, interval, limit=limits.get(interval, 100)) if not df.empty: - df = self.calculate_indicators(df) + df = self.calculate_indicators(df, interval) # 传递 interval 参数 data[interval] = df logger.info(f"获取 {symbol} 多周期数据完成") @@ -124,12 +124,13 @@ class BinanceService: return df - def calculate_indicators(self, df: pd.DataFrame) -> pd.DataFrame: + def calculate_indicators(self, df: pd.DataFrame, interval: str = '1h') -> pd.DataFrame: """ 计算技术指标 Args: df: K线数据 DataFrame + interval: K线周期,用于调整 MA 参数 Returns: 添加了技术指标的 DataFrame @@ -137,17 +138,28 @@ class BinanceService: if df.empty: return df - # 移动平均线 - df['ma5'] = self._calculate_ma(df['close'], 5) - df['ma10'] = self._calculate_ma(df['close'], 10) - df['ma20'] = self._calculate_ma(df['close'], 20) - df['ma50'] = self._calculate_ma(df['close'], 50) + # 根据周期调整 MA 参数 + # 短周期(5m, 15m)使用较短的 MA,长周期使用较长的 MA + ma_config = { + '5m': {'ma_short': 5, 'ma_mid': 10, 'ma_long': 20, 'ma_extra': 50}, + '15m': {'ma_short': 5, 'ma_mid': 10, 'ma_long': 20, 'ma_extra': 50}, + '1h': {'ma_short': 5, 'ma_mid': 10, 'ma_long': 20, 'ma_extra': 50}, + '4h': {'ma_short': 5, 'ma_mid': 10, 'ma_long': 20, 'ma_extra': 50}, + } + + config = ma_config.get(interval, ma_config['1h']) + + # 移动平均线(统一命名,便于 LLM 分析) + df['ma5'] = self._calculate_ma(df['close'], config['ma_short']) + df['ma10'] = self._calculate_ma(df['close'], config['ma_mid']) + df['ma20'] = self._calculate_ma(df['close'], config['ma_long']) + df['ma50'] = self._calculate_ma(df['close'], config['ma_extra']) # EMA df['ema12'] = self._calculate_ema(df['close'], 12) df['ema26'] = self._calculate_ema(df['close'], 26) - # RSI + # RSI(使用 Wilder's Smoothing) df['rsi'] = self._calculate_rsi(df['close'], 14) # MACD @@ -181,12 +193,25 @@ class BinanceService: @staticmethod def _calculate_rsi(data: pd.Series, period: int = 14) -> pd.Series: - """RSI 指标""" + """ + RSI 指标 - 使用 Wilder's Smoothing 方法 + 这是标准 RSI 计算方法,比简单平均更准确 + """ delta = data.diff() - gain = (delta.where(delta > 0, 0)).rolling(window=period).mean() - loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean() - rs = gain / loss + + # 分离涨跌 + gain = delta.where(delta > 0, 0) + loss = -delta.where(delta < 0, 0) + + # 使用 Wilder's Smoothing (EMA) 而不是简单平均 + # alpha = 1/period + avg_gain = gain.ewm(alpha=1/period, adjust=False).mean() + avg_loss = loss.ewm(alpha=1/period, adjust=False).mean() + + # 计算 RS 和 RSI + rs = avg_gain / avg_loss rsi = 100 - (100 / (1 + rs)) + return rsi @staticmethod diff --git a/backend/app/services/us_stock_service.py b/backend/app/services/us_stock_service.py index 082c44f..d26eaae 100644 --- a/backend/app/services/us_stock_service.py +++ b/backend/app/services/us_stock_service.py @@ -171,11 +171,14 @@ class USStockService: ma20 = close.rolling(window=20).mean().iloc[-1] if len(close) >= 20 else None ma60 = close.rolling(window=60).mean().iloc[-1] if len(close) >= 60 else None - # 计算RSI + # 计算RSI(使用 Wilder's Smoothing 方法) delta = close.diff() - gain = (delta.where(delta > 0, 0)).rolling(window=14).mean() - loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean() - rs = gain / loss + gain = delta.where(delta > 0, 0) + loss = -delta.where(delta < 0, 0) + # 使用 EMA (Wilder's Smoothing) 而不是简单平均 + avg_gain = gain.ewm(alpha=1/14, adjust=False).mean() + avg_loss = loss.ewm(alpha=1/14, adjust=False).mean() + rs = avg_gain / avg_loss rsi = 100 - (100 / (1 + rs)) rsi_value = rsi.iloc[-1] if len(rsi) >= 14 else None diff --git a/backend/app/services/yfinance_service.py b/backend/app/services/yfinance_service.py index e851a64..543dc23 100644 --- a/backend/app/services/yfinance_service.py +++ b/backend/app/services/yfinance_service.py @@ -196,11 +196,14 @@ class YFinanceService: df['ma20'] = df['close'].rolling(window=20).mean() df['ma50'] = df['close'].rolling(window=50).mean() - # RSI + # RSI(使用 Wilder's Smoothing 方法) delta = df['close'].diff() - gain = (delta.where(delta > 0, 0)).rolling(window=14).mean() - loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean() - rs = gain / loss + gain = delta.where(delta > 0, 0) + loss = -delta.where(delta < 0, 0) + # 使用 EMA (Wilder's Smoothing) 而不是简单平均 + avg_gain = gain.ewm(alpha=1/14, adjust=False).mean() + avg_loss = loss.ewm(alpha=1/14, adjust=False).mean() + rs = avg_gain / avg_loss df['rsi'] = 100 - (100 / (1 + rs)) # MACD (使用与 binance_service 相同的计算方法)