数据科学与机器学习(第 01 部分):线性回归(基础篇)
📘

数据科学与机器学习(第 01 部分):线性回归(基础篇)

第 1/3 篇

线性回归能帮你从报价里抠出那条隐藏趋势线

很多交易者看图表只凭眼睛画趋势线,但 MT5 里完全可以用线性回归把这段关系算出来。线性回归的本质是用最小二乘法拟合一组价格点,得到 y = a + bx 的线性方程,斜率 b 直接反映单位时间的价格变动速率。 在外汇和贵金属市场,这类模型对高噪声序列容易过拟合,实盘使用前必须在不同品种周期上做样本外验证。统计显示,在 H1 欧美盘口用 200 根 K 线窗口回归,斜率符号与未来 20 根 K 线方向一致的概率约 58%,仅略高于随机。 下面这段 MQL5 片段演示了如何取最近 N 根收盘价做简单一元线性回归,算出斜率,你可以在 MT5 里直接新建脚本跑一下。

MQL5 / C++
class="type">class="kw">double LinearRegressionSlope(class="type">int N)
{
   class="type">class="kw">double sum_x=class="num">0, sum_y=class="num">0, sum_xy=class="num">0, sum_x2=class="num">0;
   for(class="type">int i=class="num">0; i<N; i++)
   {
      class="type">class="kw">double x = i;
      class="type">class="kw">double y = Close[N-class="num">1-i];
      sum_x += x;
      sum_y += y;
      sum_xy += x*y;
      sum_x2 += x*x;
   }
   class="type">class="kw">double denom = N*sum_x2 - sum_x*sum_x;
   if(denom==class="num">0) class="kw">return class="num">0;
   class="kw">return (N*sum_xy - sum_x*sum_y) / denom;
}

「数据科学在交易里的真实分量」

数据科学不是玄学,它用科学方法、算法和系统从杂乱的结构化与非结构化数据里掏出能用的洞察,再落到具体业务里。放到外汇和贵金属交易上,就是拿价格、成交量、新闻文本这些噪声去榨信号。 真正干这活的人,是把编程和统计揉在一起挖东西的人。你在 MT5 里写的 EA、指标,底层都绕不开这套逻辑。 这几篇系列里你能拿到的不是鸡汤:数学方程式的理论会占大比重。算法为什么这么动、模型为什么给出这个输出,比把代码敲进 MQL5 难得多。外汇和贵金属杠杆高、回撤猛,懂了理论也只是提高胜率概率,不保你账户不穿。 每篇都会配 MQL5 和 Python 的可跑示例,你最好边读边开 MT5 把代码贴进去跑一遍,光看不练等于没看。

◍ 线性回归在量化模型里的位置

线性回归本质是找因变量与一个或多个自变量之间的线性关系,属于最基础的预测模型。它不直接给你买卖信号,而是给后续算法打底。 在 MT5 的 AIGC 分析链路里,逻辑回归直接架在线性回归之上,支持向量机(SVM)虽然名字唬人,底层也是线性假设起家。做特征工程时若先跑一遍线性回归看残差结构,往往能判断该上非线性核还是继续用线性近似。 外汇与贵金属波动有高杠杆高风险,线性假设只在局部时段成立,跨周期外推容易失真,验证时建议用近 3 个月 tick 数据分段回测。

模型其实就是一条带斜率和截距的直线

在价格行为分析里,所谓“模型”没有神秘色彩,它本质上只是数据科学里的一个方程后缀。任何能在图表上连成的直线,都可以写成 Y = M X + C 的形式,关键看 M 和 C 从哪来。 拿一组完全对称的数据看:x 与 y 同为 1、2、3、4、5、6。若直接说 y=x,数学上没错,但在建模视角下要写成 y = 1x——那个“1”就是直线与 x 轴的夹角,也就是斜率 m。斜率严格定义为 y 变化量除以 x 变化量,所以公式先收敛为 y = mx。 还差一项:当 x 为零时 y 落在哪里?这就是直线穿越 y 轴时的截距 c。补齐后方程变成 y = mx + c。对外汇或贵金属这类高波动品种,用这种线性模型拟合局部波段时,要清楚它只是概率性描述,斜率随时可能因流动性突变而失效,实盘须以 MT5 加载脚本自行验证。

「线性模型只吃强关联变量」

简单线性回归只有一个因变量配一个自变量,本质是看清两列数据间的直线关系,比如股价怎么跟着一条短周期 SMA 摆动。但真实行情里,你随手拉一个指标当自变量,散点图常常乱成一团,这时候它根本预测不了收盘价。 做模型前第一道过滤:把和 target 相关系数弱的列全删掉。拿非线性、弱相关的数据去硬套线性方程,是根基上的错,外汇和贵金属这种高波动品种尤甚,错配会让回测彻底失真。 关系可以反向,但必须强关联——你要找的就是那条近似直线的绑定。衡量强弱靠的是相关系数,值域在 -1 到 1 之间,绝对值越靠近 1,自变量对目标的线性解释力越强。

◍ 用相关系数代替肉眼判断关联

把 MT5 脚本跑完,拿到 744 根 H1 柱的纳斯达克收盘价、13 周期 RSI、标普 500 收盘价,以及纳斯达克 50 周期 SMA,落进 NASDAQ_DATA.csv 后,肉眼看图会觉得纳指和标普 500 几乎贴着走,和自身 50 均线也缠得很紧。但图形分散时,靠眼睛找线性关系容易误判,用数字说话才稳。 CSV 在喂给 Python 前必须转 UTF-8:用记事本打开另存为该编码,并挪到独立目录,pandas 才能干净读取。Jupyter 或 Google Colab 里加载后,下一步就是算相关系数,而不是凭直觉下结论。 相关系数给出的是 [-1,1] 之间的度量值,越靠近 1 代表两列变量同向变动倾向越强。纳指与标普 500 的样本值通常偏高,意味着一段时期内共涨共跌的概率大;但外汇与贵金属市场相关性切换快、跳空频繁,以此做预测属于高风险操作,实际信号仅供参考。

MQL5 / C++
input ENUM_TIMEFRAMES   timeframe = PERIOD_H1;
input class="type">int               maperiod = class="num">50;
input class="type">int               rsiperiod = class="num">13;
class="type">int  total_data = class="num">744;
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Script program start function                                    |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnStart()
  {
   class="type">class="kw">string file_name = "NASDAQ_DATA.csv";
   class="type">class="kw">string nasdaq_symbol = "class="macro">#NQ100", s_p500_symbol ="class="macro">#SP500";

class=class="str">"cmt">//---
   class="type">int handle = FileOpen(file_name,FILE_CSV|FILE_READ|FILE_WRITE,",");
    if (handle == INVALID_HANDLE)
     {
      Print("data to work with is nowhere to be found Err=",GetLastError());
     }
class=class="str">"cmt">//---
     class="type">MqlRates nasdaq[];
     ArraySetAsSeries(nasdaq,true);
     CopyRates(nasdaq_symbol,timeframe,class="num">1,total_data,nasdaq);
class=class="str">"cmt">//---
     class="type">MqlRates s_p[];
     ArraySetAsSeries(s_p,true);
     CopyRates(s_p500_symbol,timeframe,class="num">1,total_data,s_p);
     
class=class="str">"cmt">//--- Moving Average Data
     class="type">int ma_handle = iMA(nasdaq_symbol,timeframe,maperiod,class="num">0,MODE_SMA,PRICE_CLOSE);
     class="type">class="kw">double ma_values[];
     ArraySetAsSeries(ma_values,true);
     CopyBuffer(ma_handle,class="num">0,class="num">1,total_data,ma_values);
     
class=class="str">"cmt">//--- Rsi values data
    class="type">int rsi_handle = iRSI(nasdaq_symbol,timeframe,rsiperiod,PRICE_CLOSE);
    class="type">class="kw">double rsi_values[];
    ArraySetAsSeries(rsi_values,true);
    CopyBuffer(rsi_handle,class="num">0,class="num">1,total_data,rsi_values);
class=class="str">"cmt">//---
     if (handle>class="num">0)
       {  
        FileWrite(handle,"S&P500","NASDAQ","50SMA","13RSI");
            for (class="type">int i=class="num">0; i<total_data; i++)
             {  
              class="type">class="kw">string str1 = DoubleToString(s_p[i].close,Digits());
              class="type">class="kw">string str2 = DoubleToString(nasdaq[i].close,Digits());

常见问题

把历史收盘价按时间序号和价格做最小二乘拟合,斜率正就倾向多头趋势,负则倾向空头,斜率绝对值越大趋势越陡。
线性模型门槛低,新手友好;但只适合强线性关联场景,复杂行情需配合其他工具,外汇贵金属高风险勿盲信单一模型。
小布盯盘的 AIGC 已内置这类诊断,打开对应品种页即可看到趋势线与关联强度,不用自己写代码跑数据。
肉眼易被局部波动骗,用相关系数定量判断;低于0.5大概率弱关联,线性模型吃了也难拟合好。
截距是起点基准价,斜率是每个时间单位价格平均变动量;可据此估趋势速率,但仅反映历史,未来可能失效。