CoolFace
Apppublic

Qionk/a-share-quant

sourceHugging Faceupdated 4mo agoView on Hugging Face
0likes
fibonacci_wave.py353 linesDownload Raw Back to predict
1"""2波段斐波那契分析(替代短期斐波那契)3使用 scipy.signal.find_peaks 自动检测完整波段高低点4基于波段起点/终点计算标准黄金分割线5"""6 7import numpy as np8import pandas as pd9from scipy.signal import find_peaks10 11# 斐波那契比率12FIB_LEVELS = [0.0, 0.191, 0.236, 0.382, 0.5, 0.618, 0.786, 0.809, 1.0, 1.272, 1.618, 2.0]13FIB_NAMES = {14    0.0: "波段起点", 0.191: "19.1%", 0.236: "23.6%", 0.382: "38.2%",15    0.5: "50.0%(黄金)", 0.618: "61.8%", 0.786: "78.6%", 0.809: "80.9%",16    1.0: "波段终点", 1.272: "127.2%", 1.618: "161.8%", 2.0: "200.0%",17}18FIB_COLORS = {19    0.0: "blue", 0.191: "lightgreen", 0.236: "orange", 0.382: "green",20    0.5: "gold", 0.618: "darkgreen", 0.786: "darkgreen", 0.809: "green",21    1.0: "red", 1.272: "orange", 1.618: "darkorange", 2.0: "red",22}23 24 25def detect_wave_levels(df: pd.DataFrame, wave_window: int = 60,26                       min_wave_return: float = 0.05) -> dict:27    """28    自动检测最近完整波段的高低点。29 30    参数:31      wave_window: 检测窗口(交易日数)32      min_wave_return: 最小波段涨跌幅(默认5%,小于此幅度视为震荡)33 34    返回:35      trend: 趋势方向(上涨波段/下跌波段/震荡趋势)36      wave_start/wave_end: 波段起/终点价格37      start_date/end_date: 起/终点日期38      wave_return: 波段累计涨跌幅39      is_valid_wave: 是否为有效波段40    """41    recent_df = df.tail(wave_window).copy()42    close_prices = recent_df['close'].values43 44    if len(close_prices) < 30:45        recent_high = float(close_prices.max())46        recent_low = float(close_prices.min())47        return {48            'trend': '震荡趋势',49            'wave_start': recent_low,50            'wave_end': recent_high,51            'start_date': recent_df.index[recent_df['close'].idxmin()],52            'end_date': recent_df.index[recent_df['close'].idxmax()],53            'wave_return': (recent_high - recent_low) / recent_low if recent_low > 0 else 0,54            'is_valid_wave': False,55        }56 57    # 检测局部高低点(距离至少10天)58    peaks, _ = find_peaks(close_prices, distance=10)59    troughs, _ = find_peaks(-close_prices, distance=10)60 61    if len(peaks) == 0 or len(troughs) == 0:62        recent_high = float(close_prices.max())63        recent_low = float(close_prices.min())64        high_idx = close_prices.argmax()65        low_idx = close_prices.argmin()66        return {67            'trend': '震荡趋势',68            'wave_start': recent_low,69            'wave_end': recent_high,70            'start_date': recent_df.index[low_idx],71            'end_date': recent_df.index[high_idx],72            'wave_return': (recent_high - recent_low) / recent_low if recent_low > 0 else 0,73            'is_valid_wave': False,74        }75 76    last_peak_idx = peaks[-1]77    last_trough_idx = troughs[-1]78    last_peak_price = float(close_prices[last_peak_idx])79    last_trough_price = float(close_prices[last_trough_idx])80    last_peak_date = recent_df.index[last_peak_idx]81    last_trough_date = recent_df.index[last_trough_idx]82 83    if last_peak_date > last_trough_date:84        # 高点在低点之后 → 上涨波段85        wave_return = (last_peak_price - last_trough_price) / last_trough_price86        is_valid = wave_return >= min_wave_return87        return {88            'trend': '上涨波段' if is_valid else '震荡趋势',89            'wave_start': last_trough_price,90            'wave_end': last_peak_price,91            'start_date': last_trough_date,92            'end_date': last_peak_date,93            'wave_return': wave_return,94            'is_valid_wave': is_valid,95        }96    else:97        # 低点在高点之后 → 下跌波段98        wave_return = (last_peak_price - last_trough_price) / last_peak_price99        is_valid = abs(wave_return) >= min_wave_return100        return {101            'trend': '下跌波段' if is_valid else '震荡趋势',102            'wave_start': last_peak_price,103            'wave_end': last_trough_price,104            'start_date': last_peak_date,105            'end_date': last_trough_date,106            'wave_return': wave_return,107            'is_valid_wave': is_valid,108        }109 110 111def calculate_wave_fibonacci(wave_info: dict) -> list:112    """113    基于波段信息计算所有标准黄金分割价位。114 115    返回 list[dict]:116      name: 价位名称, price: 价格, type: 类型(支撑/阻力/目标), color: 显示颜色117    """118    trend = wave_info['trend']119    wave_start = wave_info['wave_start']120    wave_end = wave_info['wave_end']121    wave_range = abs(wave_end - wave_start)122    if wave_range < 0.01 * wave_start:123        wave_range = 0.01 * wave_start124 125    levels = []126 127    if trend == "上涨波段":128        # 回撤支撑位(上涨后回调)129        levels.append({'name': '0.191支撑', 'price': round(wave_end - wave_range * 0.191, 2),130                       'type': '弱支撑', 'color': 'lightgreen', 'level': 0.191})131        levels.append({'name': '0.382支撑', 'price': round(wave_end - wave_range * 0.382, 2),132                       'type': '强支撑', 'color': 'green', 'level': 0.382})133        levels.append({'name': '0.5支撑', 'price': round(wave_end - wave_range * 0.5, 2),134                       'type': '黄金支撑', 'color': 'gold', 'level': 0.5})135        levels.append({'name': '0.618支撑', 'price': round(wave_end - wave_range * 0.618, 2),136                       'type': '极强支撑', 'color': 'darkgreen', 'level': 0.618})137        levels.append({'name': '0.809支撑', 'price': round(wave_end - wave_range * 0.809, 2),138                       'type': '强支撑', 'color': 'green', 'level': 0.809})139        # 扩展目标位140        levels.append({'name': '1.272目标', 'price': round(wave_end + wave_range * 0.272, 2),141                       'type': '第一目标', 'color': 'orange', 'level': 1.272})142        levels.append({'name': '1.618目标', 'price': round(wave_end + wave_range * 0.618, 2),143                       'type': '第二目标', 'color': 'darkorange', 'level': 1.618})144        levels.append({'name': '2.0目标', 'price': round(wave_end + wave_range * 1.0, 2),145                       'type': '第三目标', 'color': 'red', 'level': 2.0})146        # 波段高低点147        levels.append({'name': '波段高点', 'price': round(wave_end, 2),148                       'type': '阻力位', 'color': 'red', 'level': 1.0})149        levels.append({'name': '波段低点', 'price': round(wave_start, 2),150                       'type': '强支撑', 'color': 'darkgreen', 'level': 0.0})151 152    elif trend == "下跌波段":153        # 反弹阻力位(下跌后反弹)154        levels.append({'name': '0.191阻力', 'price': round(wave_end + wave_range * 0.191, 2),155                       'type': '弱阻力', 'color': 'lightcoral', 'level': 0.191})156        levels.append({'name': '0.382阻力', 'price': round(wave_end + wave_range * 0.382, 2),157                       'type': '强阻力', 'color': 'red', 'level': 0.382})158        levels.append({'name': '0.5阻力', 'price': round(wave_end + wave_range * 0.5, 2),159                       'type': '黄金阻力', 'color': 'gold', 'level': 0.5})160        levels.append({'name': '0.618阻力', 'price': round(wave_end + wave_range * 0.618, 2),161                       'type': '极强阻力', 'color': 'darkred', 'level': 0.618})162        levels.append({'name': '0.809阻力', 'price': round(wave_end + wave_range * 0.809, 2),163                       'type': '强阻力', 'color': 'red', 'level': 0.809})164        # 扩展目标位(下跌延续)165        levels.append({'name': '1.272目标', 'price': round(wave_end - wave_range * 0.272, 2),166                       'type': '第一目标', 'color': 'orange', 'level': 1.272})167        levels.append({'name': '1.618目标', 'price': round(wave_end - wave_range * 0.618, 2),168                       'type': '第二目标', 'color': 'darkorange', 'level': 1.618})169        levels.append({'name': '2.0目标', 'price': round(wave_end - wave_range * 1.0, 2),170                       'type': '第三目标', 'color': 'green', 'level': 2.0})171        # 波段高低点172        levels.append({'name': '波段低点', 'price': round(wave_end, 2),173                       'type': '支撑位', 'color': 'green', 'level': 0.0})174        levels.append({'name': '波段高点', 'price': round(wave_start, 2),175                       'type': '强阻力', 'color': 'darkred', 'level': 1.0})176 177    else:178        # 震荡趋势179        low = min(wave_start, wave_end)180        high = max(wave_start, wave_end)181        levels.append({'name': '震荡下轨', 'price': round(low, 2),182                       'type': '支撑位', 'color': 'green', 'level': 0.0})183        levels.append({'name': '震荡中轨', 'price': round((low + high) / 2, 2),184                       'type': '中性位', 'color': 'gray', 'level': 0.5})185        levels.append({'name': '震荡上轨', 'price': round(high, 2),186                       'type': '阻力位', 'color': 'red', 'level': 1.0})187 188    levels.sort(key=lambda x: x['price'])189    return levels190 191 192def generate_wave_fib_signals(current_price: float, fib_levels: list,193                                wave_info: dict, model_prediction: float = 0,194                                relative_volume: float = 1.0,195                                sensitivity: float = 0.015) -> list:196    """197    基于波段斐波那契价位生成买卖信号。198 199    参数:200      current_price: 当前价格201      fib_levels: calculate_wave_fibonacci 返回的价位列表202      wave_info: detect_wave_levels 返回的波段信息203      model_prediction: 模型预测的收益率%(正=看涨,负=看跌)204      relative_volume: 相对成交量(与20日均值比)205      sensitivity: 信号灵敏度(默认1.5%,比短期分析更宽松)206 207    返回 list[dict]: 信号列表208    """209    trend = wave_info['trend']210    is_valid_wave = wave_info['is_valid_wave']211    signals = []212 213    if not is_valid_wave:214        signals.append({215            'type': '观望',216            'level': '无',217            'price': current_price,218            'reason': '未检测到有效的上涨/下跌波段,建议观望',219            'confidence': 1,220        })221        return signals222 223    for level_info in fib_levels:224        price_diff = abs(current_price - level_info['price']) / current_price if current_price > 0 else float('inf')225 226        if price_diff <= sensitivity:227            level_name = level_info['name']228            level_type = level_info['type']229            confidence = 3230 231            # 结合模型预测调整置信度232            if (trend == "上涨波段" and model_prediction > 0) or \233               (trend == "下跌波段" and model_prediction < 0):234                confidence += 1235            elif (trend == "上涨波段" and model_prediction < 0) or \236                 (trend == "下跌波段" and model_prediction > 0):237                confidence -= 1238 239            # 结合成交量调整240            if relative_volume > 1.5:241                confidence += 1242            elif relative_volume < 0.7:243                confidence -= 1244 245            confidence = max(1, min(5, confidence))246 247            if trend == "上涨波段":248                if "支撑" in level_type:249                    if model_prediction > 0:250                        if "黄金支撑" in level_type or "极强支撑" in level_type:251                            signal_type = '强买入'252                        else:253                            signal_type = '买入'254                        signals.append({255                            'type': signal_type,256                            'level': level_name,257                            'price': level_info['price'],258                            'reason': f'上涨波段回调至{level_name},量价配合,模型看涨',259                            'confidence': confidence,260                        })261                    else:262                        signals.append({263                            'type': '观望',264                            'level': level_name,265                            'price': level_info['price'],266                            'reason': f'上涨波段回调至{level_name},但模型看跌,建议观望',267                            'confidence': confidence,268                        })269                elif "目标" in level_type:270                    signals.append({271                        'type': '止盈',272                        'level': level_name,273                        'price': level_info['price'],274                        'reason': f'价格到达上涨波段{level_name},建议分批止盈',275                        'confidence': confidence,276                    })277                elif level_name == "波段高点":278                    if model_prediction > 0:279                        signals.append({280                            'type': '持有/加仓',281                            'level': level_name,282                            'price': level_info['price'],283                            'reason': '价格突破波段高点,趋势延续,目标看1.272扩展位',284                            'confidence': confidence,285                        })286                    else:287                        signals.append({288                            'type': '止盈',289                            'level': level_name,290                            'price': level_info['price'],291                            'reason': '价格触及波段高点阻力,模型看跌,建议止盈',292                            'confidence': confidence,293                        })294 295            elif trend == "下跌波段":296                if "阻力" in level_type:297                    if model_prediction < 0:298                        if "黄金阻力" in level_type or "极强阻力" in level_type:299                            signal_type = '强卖出'300                        else:301                            signal_type = '卖出'302                        signals.append({303                            'type': signal_type,304                            'level': level_name,305                            'price': level_info['price'],306                            'reason': f'下跌波段反弹至{level_name},量价配合,模型看跌',307                            'confidence': confidence,308                        })309                    else:310                        signals.append({311                            'type': '观望',312                            'level': level_name,313                            'price': level_info['price'],314                            'reason': f'下跌波段反弹至{level_name},但模型看涨,建议观望',315                            'confidence': confidence,316                        })317                elif "目标" in level_type:318                    signals.append({319                        'type': '轻仓抄底',320                        'level': level_name,321                        'price': level_info['price'],322                        'reason': f'价格到达下跌波段{level_name},可轻仓尝试抄底',323                        'confidence': confidence,324                    })325                elif level_name == "波段低点":326                    if model_prediction < 0:327                        signals.append({328                            'type': '止损/清仓',329                            'level': level_name,330                            'price': level_info['price'],331                            'reason': '价格跌穿波段低点,趋势延续,目标看1.272扩展位',332                            'confidence': confidence,333                        })334                    else:335                        signals.append({336                            'type': '轻仓抄底',337                            'level': level_name,338                            'price': level_info['price'],339                            'reason': '价格触及波段低点支撑,模型看涨,可轻仓抄底',340                            'confidence': confidence,341                        })342 343    # 如果没有匹配信号,给出默认建议344    if not signals:345        signals.append({346            'type': '持有/观望',347            'level': '无',348            'price': current_price,349            'reason': '当前价格未接近任何关键黄金分割位,继续持有或观望',350            'confidence': 2,351        })352 353    return signals