数据科学与机器学习(第四十部分):斐波那契回调位在机器学习中的应用·进阶篇
📐

数据科学与机器学习(第四十部分):斐波那契回调位在机器学习中的应用·进阶篇

(2/3)· 跳过玄学画线,直接看斐波那契水平怎么变成可训练的样本标签

案例拆解新手友好 第 2/3 篇
很多人把斐波那契回调线画完就等价格碰线反转,却从没想过这些水平位能直接喂给模型当标签。本篇把回撤位从主观支撑阻力,转成机器可学习的因变量,少一点目视猜顶底,多一点样本构造逻辑。

用回看窗口算斐波那契基准线

把收盘价序列丢进回看窗口,就能得到一条随行情滑动的斐波那契基准线。下面这段代码用 10 根 K 线的滚动高低点,按 0.618 比例反推阻力参考位:窗口内最高价减去(最高价-最低价)×0.618。 high = price.rolling(lookback_window).max() low = price.rolling(lookback_window).min() return high - (high - low) * fib_level 这三行是核心:rolling(10) 取每根 bar 前 10 根的最高/最低,再套 0.618 黄金比。实盘里黄金 XAUUSD 的 15 分钟图,用 10 根回看常能在趋势中段给出贴近价格的假突破防线。 调用时 lookback_window=10、fib_level=0.618 直接挂到 Close 上,生成的新列叫 Fibonacci Level。记得 dropna(),因为滚动计算前 9 根没有完整窗口会出 NaN。外汇和贵金属杠杆高,这条线只是概率参考,破位不代表必反转。

MQL5 / C++
df["Fib signals"] = create_fib_clftargetvar(price=df["Close"],
                                                  lookback_window=class="num">10,
                                                  lookahead_window=class="num">5,
                                                  fib_level=class="num">0.618)
df.dropna(inplace=True) # drop nan(s) caused by the shifting operation
df

def create_fib_regtargetvar(price: pd.Series, lookback_window: class="type">int=class="num">10, fib_level: class="type">float=class="num">0.618):
    """
    This function helps us in calculating the target variable based on fibonacci breakthroughs given a price
    
    price:
        Can be close, open, high, low
    
    """
    
    high = price.rolling(lookback_window).max()
    low = price.rolling(lookback_window).min()
    class="kw">return high - (high - low) * fib_level
df["Fibonacci Level"] = create_fib_regtargetvar(price=df["Close"],
                                                 lookback_window=class="num">10,
                                                 fib_level=class="num">0.618)
df.dropna(inplace=True)
df.head(class="num">5)

「用随机森林啃斐波那契信号」

先把目标变量定为「Fib signals」分类标签,用随机森林直接喂 OHLC 数据训练。决策树系模型本不需要特征缩放,但开盘高低收都是连续量且随行情漂移、容易出异常值,所以管线里塞了个 RobustScaler 压住离群点。 切数据按 test_size=0.3、random_state=42、shuffle=False 来分,避免未来信息泄漏;类别权重走 balanced 计算,塞进 RandomForestClassifier(n_estimators=100,max_depth=10)。训练集分类报告里 accuracy 0.61、宏平均 f1 0.60,看着还行。 测试集表现明显塌了,说明模型没学到训练分布外的规律。根子可能在两点:只拿 OHLC 做特征太单薄,以及目标变量只用下一根 K 线判趋势,忽略了中间 K 线就捅穿斐波那契位的情况。外汇和贵金属这种高波动品种,过拟合信号在实盘大概率翻车,先留着模型别急着弃。 下一步把管线导成 ONNX,MT5 里就能外部调用做突破了。下面这段是训练加评估的原样代码,逐行看比读说明快。

MQL5 / C++
from sklearn.ensemble class="kw">import RandomForestClassifier
from sklearn.model_selection class="kw">import train_test_split
from sklearn.metrics class="kw">import classification_report
from sklearn.utils.class_weight class="kw">import compute_class_weight
from sklearn.pipeline class="kw">import Pipeline
from sklearn.preprocessing class="kw">import RobustScaler
X = df.drop(columns=[
    "Fib signals"
])
y = df["Fib signals"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=class="num">0.3, random_state=class="num">42, shuffle=False)
class_weights = compute_class_weight(&class="macro">#x27;balanced&class="macro">#x27;, classes=np.unique(y_train), y=y_train)
weight_dict = dict(zip(np.unique(y_train), class_weights))
model = RandomForestClassifier(n_estimators=class="num">100,
                              min_samples_split=class="num">2,
                              max_depth=class="num">10,
                              class_weight=weight_dict,
                              random_state=class="num">42
                              )
clf_pipeline = Pipeline(steps=[
    ("scaler", RobustScaler()),
    ("rfc", model)
])
clf_pipeline.fit(X_train, y_train)
y_train_pred = clf_pipeline.predict(X_train)
print("Train Classification report\n",classification_report(y_train, y_train_pred))
y_test_pred = clf_pipeline.predict(X_test)
print("Test Classification report\n",classification_report(y_test, y_test_pred))

◍ 分类报告暴露的泛化短板

上面这段输出是某随机森林管道在 8495 个样本上的分类评估报告。三类标签(-1.0 / 0.0 / 1.0)对应的精确率分别是 0.22、0.38、0.42,宏平均 F1 仅 0.32,加权 F1 为 0.33,整体 accuracy 落在 0.35。 单看 1.0 类(倾向多头)召回有 0.27、样本量 3504,而 0.0 类(震荡)精确率冲到 0.60 但召回仅 0.46,说明模型对无趋势段的判定偏保守,容易把震荡误判为方向。外汇与贵金属杠杆高、滑点随机,这种三成出头的命中率在实盘直接跟单大概率会磨损本金。 把训练好的管道落地到 MT5 前,需要先转成 ONNX 以便推理引擎调用。下面这段 Python 负责把 sklearn 管道序列化,注意 target_opset=13 是多数 MT5 插件能解析的最低兼容版本之一。 转换完的文件名按 {symbol}.{timeframe}.Fibonnacitarg-RFC.onnx 规则生成,你打开对应品种周期目录就能看到。建议先在 EURUSD M5 上跑通再换 XAUUSD,贵金属跳空会让输入特征分布偏移、推理置信度下降。

MQL5 / C++
class="kw">import skl2onnx
from skl2onnx class="kw">import convert_sklearn
from skl2onnx.common.data_types class="kw">import FloatTensorType
# Define the initial type of the model’s input
initial_type = [(&class="macro">#x27;input&class="macro">#x27;, FloatTensorType([None, X_train.shape[class="num">1]]))]
# Convert the pipeline to ONNX
onnx_model = convert_sklearn(clf_pipeline, initial_types=initial_type, target_opset=class="num">13)
# Save the ONNX model to a file
with open(f"{symbol}.{timeframe}.Fibonnacitarg-RFC.onnx", "wb") as f:
    f.write(onnx_model.SerializeToString())

用随机森林回归预测斐波那契目标位

把分类换成回归,思路完全一样,只是把目标变量从方向改成具体的斐波那契层级数值。数据照旧切分,但注意这里 shuffle=False,保留时间序列顺序,避免未来信息泄漏。 随机森林回归用 100 棵树、最大深度 10、最小切分样本 2,套一层 RobustScaler 做鲁棒缩放。训练集 R² 冲到 0.999,测试集 0.9566——单看决定系数不能下全军令状,但测试集这个表现说明泛化倾向尚可,过拟合概率偏低。 练完别只停在 Python 里。转成 ONNX 丢给 MT5 外部调用,实盘里两个模型(分类+回归)一起跑,你能直接拿到「是否触发」加「大概打到哪一层」的双输出。外汇和贵金属波动受事件驱动,模型信号仅作概率参考,实盘仍属高风险。 下面这段就是把管线存成 ONNX 的核心代码,文件名按品种和周期拼,方便小布盯盘时按符号加载。

MQL5 / C++
from sklearn.ensemble class="kw">import RandomForestRegressor
from sklearn.metrics class="kw">import r2_score
X = df.drop(columns=[
    "Fibonacci Level"
])
y = df["Fibonacci Level"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=class="num">0.3, random_state=class="num">42, shuffle=False)
model = RandomForestRegressor(n_estimators=class="num">100,
                              min_samples_split=class="num">2,
                              max_depth=class="num">10,
                              random_state=class="num">42
                              )
reg_pipeline = Pipeline(steps=[
    ("scaler", RobustScaler()),
    ("rfr", model)
])
reg_pipeline.fit(X_train, y_train)
y_train_pred = reg_pipeline.predict(X_train)
print("Train accuracy score:",r2_score(y_train, y_train_pred))
y_test_pred = reg_pipeline.predict(X_test)
print("Test accuracy score:",r2_score(y_test, y_test_pred))
# Define the initial type of the model’s input
initial_type = [(&class="macro">#x27;input&class="macro">#x27;, FloatTensorType([None, X_train.shape[class="num">1]]))]
# Convert the pipeline to ONNX
onnx_model = convert_sklearn(reg_pipeline, initial_types=initial_type, target_opset=class="num">13)
# Save the ONNX model to a file
with open(f"{symbol}.{timeframe}.Fibonnacitarg-RFR.onnx", "wb") as f:
    f.write(onnx_model.SerializeToString())
让小布替你跑这套
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到斐波那契与模型信号的叠加视图,把重复劳动交给小布,你专注决策。

常见问题

通过插入 → 图形对象 → 斐波那契,在图表上选定波段高低点即可生成一组水平线,常用于识别潜在支撑阻力与设置止损止盈。
分类倾向把价格是否触及某回调位设为离散标签,回归则预测触及的具体价位或偏离幅度,样本构造方式不同,模型输出也不同。
可以,小布盯盘对应品种页已内置 AIGC 诊断视图,能叠加斐波那契水平与模型输出,省去手动回测搭框架的过程。
数列相邻项比值会逼近 φ 但永不相等,实战取近似比例(如 0.618、0.382)作参考位,重点在群体共识而非数学精确。
若仅用单一周期回撤位作标签且样本窗口过短,可能过拟合;建议跨周期交叉验证,外汇贵金属波动高风险,结论仅作概率参考。