针对交易的组合数学和概率论(第二部分):通用分形·进阶篇
🧩

针对交易的组合数学和概率论(第二部分):通用分形·进阶篇

(2/3)·对称、非对称与单边边界分形如何被一个通用函数收编,并落地到代码与性能评估

新手友好 第 2/3 篇
很多交易者把分形当成单纯的形态识别工具,却忽略了它背后的边界约束直接决定了存款底线与平均步阶数。用错边界类型,算出来的胜率与持仓时长会整体偏移,决策依据随之失真。

◍ 通用分形启动函数的落地写法

要让分形在 MT5 里正确跑起来,先得有一个准备函数:它负责在分形真正启动前算好所有前置变量,再按既定规则把分形交出去。下面这套 MQL5 实现把输入参数压得很短,m、n 对称相等,足够覆盖交易适用的目标,没必要堆砌高级扩展。 核心是一个 Container 结构体,装了上下边界各自的「概率×步数」累加值和总概率,并重载了 += 运算符,方便在主函数里合并同类结构。日志里能看到:首次即时报价时算完整个分形后不再重算,前六个数是容器原生字段,其余都是从它们派生的——比如「完整组」里两个非重叠假设概率之和恒为 1.0,代码可直接验证。 别把参数对称当摆设:设置函数里 m 和 n 相等且对称,Middle 的符号随大小关系翻转,Half 始终是 (m+n)/2.0。外汇与贵金属波动随机性强、杠杆风险高,这套逻辑只提供概率倾向,不预示必然方向。

MQL5 / C++
Container StartFractal(class="type">int m, class="type">int n, class="type">int s,class="type">class="kw">double p)class=class="str">"cmt">//preparing all variables and starting the fractal
  {
  class="type">int Minimum;
  if ( m <= n ) Minimum=m;
  else Minimum=n;
  class="type">class="kw">double Middle;
  if ( n >= m ) Middle = (m+n)/class="num">2.0 - Minimum;
  else Middle = -((m+n)/class="num">2.0 - Minimum);  
  class="type">class="kw">double Half = (m+n)/class="num">2.0;
  class="kw">return Fractal(Half,Middle,m,n,s,p,class="num">0,class="num">0,class="num">0,class="num">1.0);
  }
class="kw">struct Containerclass=class="str">"cmt">//a container for collecting all the necessary data about the fractal
  {
  class=class="str">"cmt">//values to be summed, for the upper bound
  class="type">class="kw">double UpperMidSUp;class=class="str">"cmt">//the sum of probabilities multiplied by the number of steps up of a specific chain(to cross the upper bound)
  class="type">class="kw">double UpperMidSDown;class=class="str">"cmt">//the sum of probabilities multiplied by the number of steps down of a specific chain(to cross the upper bound
  class="type">class="kw">double UpperSummProbability;class=class="str">"cmt">//the sum of the probabilities(to cross the upper border)
  class=class="str">"cmt">//values to be summed, for the lower border
  class="type">class="kw">double LowerMidSUp;class=class="str">"cmt">//the sum of probabilities multiplied by the number of steps up of a specific chain(to cross the lower border)
  class="type">class="kw">double LowerMidSDown;class=class="str">"cmt">//the sum of probabilities multiplied by the number of steps down of a specific chain(to cross the lower border)
  class="type">class="kw">double LowerSummProbability;class=class="str">"cmt">//the sum of the probabilities(to cross the lower border)

  Container()class=class="str">"cmt">//class="kw">default constructor
    {
    UpperMidSUp=class="num">0.0;
    UpperMidSDown=class="num">0.0;
    UpperSummProbability=class="num">0.0;    
    LowerMidSUp=class="num">0.0;
    LowerMidSDown=class="num">0.0;
    LowerSummProbability=class="num">0.0;
    }

  class=class="str">"cmt">//
  class="type">void Summ(Container &c0,class="kw">const Container &c1) class="kw">constclass=class="str">"cmt">//full sum for class="kw">operator overloading
    {
    c0.UpperMidSUp=c0.UpperMidSUp+c1.UpperMidSUp;
    c0.UpperMidSDown=c0.UpperMidSDown+c1.UpperMidSDown;
    c0.UpperSummProbability=c0.UpperSummProbability+c1.UpperSummProbability;      
    c0.LowerMidSUp=c0.LowerMidSUp+c1.LowerMidSUp;
    c0.LowerMidSDown=c0.LowerMidSDown+c1.LowerMidSDown;
    c0.LowerSummProbability=c0.LowerSummProbability+c1.LowerSummProbability;
    }         
  class="type">void class="kw">operator+=(Container &c) { Summ(this,c); }class=class="str">"cmt">//class="kw">operator += overload
  };
Container Fractal(class="type">class="kw">double Half, class="type">class="kw">double Middle, class="type">int m, class="type">int n, class="type">int s,class="type">class="kw">double p,class="type">int SU,class="type">int SD, class="type">int U, class="type">class="kw">double P)class=class="str">"cmt">//Fractal
  {
  Container C;
  class=class="str">"cmt">///to pass to the next fractal level

向上突破中轴的递归分形构造

当已出现上升笔数 U 大于中轴 Middle,且总步数 SU+SD 仍小于目标 s 时,进入 case 1 的分形展开。此时剩余可走步数为 (n-1)-U,若大于 0 就按二项式系数把后续每一步的上升/下降组合全部枚举进容器 C。 核心递推在 for 循环里:NewU 由 -(n-1)+2*u+2*U 给出,NewP 用 Factorial 算组合数再乘 pow(p,u)*pow(1-p,剩余) 得到该分支概率。NewSU、NewSD 同步累加,随后调用 Fractal 做下一层递归。 若剩余步数恰为 0,则不再循环,直接构造一个 Container ct:其 UpperMidSDown = P*p*SD,UpperMidSUp = P*p*(SU+1),UpperSummProbability = P*p,并将 ct 与递归结果一并加入 C。这段逻辑说明,在 U>Middle 的边界情形下,价格向上越过中轴后的概率质量会按 p 的次幂衰减分配。 外汇与贵金属市场杠杆高、波动剧烈,此类分形概率仅反映数学模型下的路径可能,实盘须以 MT5 回测验证,切勿直接用作仓位依据。

MQL5 / C++
class="type">int NewU;
class="type">int NewSU;
class="type">int NewSD;
class="type">class="kw">double NewP;
class=class="str">"cmt">///

if ( U > Middle && SU + SD < s )class=class="str">"cmt">//case class="num">1
    {
    if ( (n-class="num">1) - U > class="num">0 )
      {
       for ( class="type">int u=class="num">0 ; u <= (n-class="num">1) - U; u++ )
          {
          NewU = -(n-class="num">1) + class="num">2*u + class="num">2*U;
          NewP = P * (Factorial((n-class="num">1) - U)/(Factorial(u)*Factorial((n-class="num">1) - U - u))) * pow(p,u)*pow(class="num">1.0-p,(n-class="num">1) - U - u);
          NewSU = SU + u;
          NewSD = SD + ((n-class="num">1) - U - u);
          C+=Fractal(Half,Middle,m,n,s,p,NewSU,NewSD,NewU,NewP);
          }      
      }
    if ( (n-class="num">1) - U == class="num">0 )
      {
       NewU = U - class="num">1;
       NewP = P * (class="num">1.0 - p);
       NewSU = SU;
       NewSD = SD + class="num">1;
       Container ct;
       ct.UpperMidSDown=P*p*SD;
       ct.UpperMidSUp=P*p*(SU+class="num">1);
       ct.UpperSummProbability=P*p;
       
       C+=ct;
       C+=Fractal(Half,Middle,m,n,s,p,NewSU,NewSD,NewU,NewP);
      }     
    } 

if ( U < Middle && SU + SD < s )class=class="str">"cmt">//case class="num">2
    {
    if ( (m-class="num">1) + U > class="num">0 )
      {
       for ( class="type">int u=class="num">0 ; u <= (m-class="num">1) + U; u++ )
          {
          NewU = -(m-class="num">1) + class="num">2*u;
          NewP = P * (Factorial((m-class="num">1) + U)/(Factorial(u)*Factorial((m-class="num">1) + U - u))) * pow(p,u)*pow(class="num">1.0-p,(m-class="num">1) + U - u);
          NewSU = SU + u;
          NewSD = SD + ((m-class="num">1) + U - u);
          C+=Fractal(Half,Middle,m,n,s,p,NewSU,NewSD,NewU,NewP);
          }      
      }
    if ( (m-class="num">1) + U == class="num">0 )
      {

「递归分形里的向下分支与中间态展开」

这段逻辑处理的是价格路径在向下偏离后、以及恰好落在中间位置的两种递归情形。外汇与贵金属杠杆高、跳空频繁,这类分形概率计算仅作路径推演,实盘信号仍需结合结构确认。 先看 case 2 的向下分支:NewU 在原有 U 上加 1,代表向上步数增一;NewP 用 P 乘衰减系数 p,概率随层级递减。NewSU 加 1 而 NewSD 不变,说明累计向上成功次数增加但向下次数未动。 随后构造 Container 实例 ct,LowerMidSDown 用 P*(1.0-p)*(SD+1) 表达「本层向下、下层再向下」的联合概率质量;LowerMidSUp 与 LowerSummProbability 同理分别刻画另一种分支与边际概率。ct 被压入集合 C,再递归调用 Fractal 把新参数传下去,层数越深分支越多。 case 3 触发条件是 U==Middle 且 SU+SD<s,即走到中点但总步数未达标。循环上界取 MathFloor(Half)-1,若大于 0 才展开;NewU 用 -(Half-1)+2*u+U 对称映射左右偏移,NewP 套用组合数乘 p^u*(1-p)^(剩余) 的二项分布权重。每一轮把更新后的 SU、SD 传入 Fractal 继续向下拆,最后 return C 把整棵概率树交回上层。 在 MT5 里把 Factorial 和 pow 换成自写整型阶乘可避免浮点误差;调小 s 会让递归深度陡增,i7 上 s=20 时叶节点可能破万,先打印 C.Size() 看规模再决定要不要剪枝。

MQL5 / C++
      NewU = U + class="num">1;
      NewP = P * p;
      NewSU = SU + class="num">1;
      NewSD = SD;  
      Container ct;
      ct.LowerMidSDown=P*(class="num">1.0 - p)*(SD+class="num">1);
      ct.LowerMidSUp=P*(class="num">1.0 - p)*SU;
      ct.LowerSummProbability=P*(class="num">1.0 - p);
      
      C+=ct;
      C+=Fractal(Half,Middle,m,n,s,p,NewSU,NewSD,NewU,NewP);
      }      
   }
 
   if ( U == Middle && SU + SD < s )class=class="str">"cmt">//case class="num">3
   {
   if ( class="type">int(MathFloor(Half))-class="num">1 > class="num">0 )
      {
      for ( class="type">int u=class="num">0 ; u <= class="type">int(MathFloor(Half))-class="num">1; u++ )
         {
         NewU = -(class="type">int(MathFloor(Half))-class="num">1) + class="num">2*u + U;
         NewP = P * (Factorial(class="type">int(MathFloor(Half))-class="num">1)/(Factorial(u)*Factorial(class="type">int(MathFloor(Half))-class="num">1 - u))) * pow(p,u)*pow(class="num">1.0-p,class="type">int(MathFloor(Half))-class="num">1 - u);
         NewSU = SU + u;
         NewSD = SD + (class="type">int(MathFloor(Half))-class="num">1 - u);
         C+=Fractal(Half,Middle,m,n,s,p,NewSU,NewSD,NewU,NewP);
         }         
      }
   }
 
   class="kw">return C;
   }

◍ 用对称分形反推走廊步阶公式

日志跑出来的平均步阶数会收敛到一个整数:当走廊按单位步阶翻倍、n 和 m 都取 1 时,链经过的平均步阶数趋于 4。 这说明较小对称走廊拼成较大对称走廊时,宽度和步阶数各自有一条递推链。 宽度递推是 P[n] = P[n-1] * 2,步阶递推是 S[n] = S[n-1] * 4。 若令 P[0]=1、S[0]=1 并从 0 开始编号,就得到 P[n]=2^n 与 S[n]=4^n,而 4^n 可写成 (2^n)^2,也就是 S = P^2。 换一组参数验证:n=3、m=3 时平均步阶数趋于 9,对应 P[n]=3^n、S[n]=9^n,关系仍是 S=P^2。 外汇与贵金属价格走这种对称分形时波动剧烈、风险极高,但该关系不依赖具体 n 和 m,只要求走廊对称且宽度成整数倍放大。 由此可外推任意放大倍数 K 下的指标:新走廊平均步阶 S = S0 * K^2,平均生存期 T = T0 * K^2(设旧走廊 S0=1),其中 K = P/P0。 在 MT5 里把 n、m 和走廊倍数改掉跑一遍日志,就能确认这条二次依赖是否在你关心的品种上成立。

用整数走廊逼近浮点因子的生存期

前面推导的生存期公式对整数 P 成立,但真实行情里加宽系数 K 往往是浮点。要让公式覆盖实数 K,得借一条已知平均生存期的价格走廊当基准。 假设手里有平均生存期 T 的走廊,它容纳了某个更小走廊的 N 倍宽度,但小走廊生存期未知。套原关系 T = T0 * N^2,反推 T0 = T / N^2,就拿到最小走廊的生存期。 小走廊以点数为单位的宽度 d = P / N。要塞进加宽到 K 倍的走廊,能容下的段数取下整:Smin = MathFloor(K * N)。极限 Lim(N→+∞)[K*N / MathFloor(K*N)] = 1,说明 N 越大,取整丢掉的小数越无关紧要。 若担心截断误差,再算 Smax = MathFloor(K*N)+1 = Smin+1,真实 K*N 必落在二者之间。N 趋于无穷时,这两套只差一段的走廊平均生存期几乎相等,于是用算术平均兜底:T1 = T0 * (Smin^2 + Smax^2) / 2。 拿 N=1000 做第一次验证,替代表达式算出的 T1 与整数公式 T*K^2 结果数字相同;逻辑上 N 更大二者更重合。极限 Lim(N→+∞)[T0*(Smin^2+Smax^2)/2 / (T*K^2)] = 1 从数学上坐实了这一点。 我写了个简单函数,把 N 从 1 扫到整千量级做全区间比对,输出证实:为整数 K 找到的生存期函数,对 0 到 +∞ 内任意正浮点 K 同样适用。这给后续把分形结构铺到实数系数上留了底。

把分形推演交给小布
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到通用分形在不同边界下的概率分布,你只需核对参数是否合理。

常见问题

m 与 n 通常表示分形上下方向的步阶计数边界,s 则对应存款或价格层面的止损底线阈值;具体映射依赖你定义的定价过程。
S 趋于无穷时单边约束消失,通用公式退化为无截尾的对称过程,能更干净地暴露链式反应本身的统计特征,但计算量会陡增。
可以,小布内置的 AIGC 模块已封装通用分形推导,选择品种后能看到不同参数下的分形性能估计,省去手写 MQL5 的重复劳动。
倾向用于存在明确下档存款保护、上档开放盈利的情形,例如固定止损加浮动止盈的贵金属短线策略,概率可能更贴合真实分布。
应主动限制递归深度或分段近似,外汇与贵金属属高风险市场,过度精细的推演并不必然带来更优决策。