MQL5 中的范畴论 (第 15 部分):函子与图论·综合运用
🕸️

MQL5 中的范畴论 (第 15 部分):函子与图论·综合运用

(3/3)·把日历新闻连成图、用函子跨范畴配对标普波动,这套抽象框架到底能给交易带来什么

实战向进阶 第 3/3 篇
把财经日历只当事件列表刷,等于浪费了它内部的依赖结构。用图论把新闻项连成带环的网,再借函子投到波动率范畴,才可能看出线性排序抓不到的跨项传导。

◍ 负向投影的正向校准与相关性落差

在 SPX500 月线(MN1)上跑 morphs 预测,2023.05 给出的投影是 763492.32,而实际值是 28877.00;一个月后投影变成 -30298.31,实际 23306.00。两者相关性只有 0.034,morph 常数被设为 50000.00,说明这套形变模型在该品种月线尺度上几乎失去线性解释力。 为了不让负投影直接污染后续计算,代码里用 NormalizeForecast 把负值折回正域。逻辑是:以当前实际值为锚,按 (当前实际 - 负投影)/当前实际 的比例,去缩放上一期实际与上一期投影的绝对差,再加回当前实际。 换用 objects 预测后,相关性升到 0.46195608(morph 常数 0.00)。2023.05 投影 19185.80、实际 28877.00,2023.06 投影 11544.54、实际 23306.00——方向大致对,但绝对误差仍偏大。外汇与贵金属品种若套同逻辑,因杠杆与跳空风险高,月线投影失准可能放大仓位误判,建议先在 MT5 用历史数据复算 corr 再决定是否采信。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Normalizes negative projections to positive number.               |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">class="kw">double NormalizeForecast(class="type">class="kw">double NegativeValue,class="type">class="kw">double CurrentActual,class="type">class="kw">double PreviousActual,class="type">class="kw">double PreviousForecast)
  {
   class="kw">return(CurrentActual+(((CurrentActual-NegativeValue)/CurrentActual)*fabs(PreviousActual-PreviousForecast)));
  }

形态映射在标普月线样本上的偏差

把一段形态映射(Morphs)脚本挂在 SPX500 的月线周期上跑,日志直接暴露了预测与现实的裂口。2023.05.01 零点形态预测值约 257937.93,而当时实际报价仅 28877.00;次月预测值冲到 679078.56,实际却落在 23306.00。 更关键的是相关性输出:correlation 为 -0.03589660,morph constant 是 0.00000000。负向且接近零的相关,加上常数为零,说明这套映射在该样本里基本没有解释力。 外汇与贵金属市场波动结构不同,但这类零相关结果提醒我们:任何形态外推模型在换周期、换品种后都可能失效,开 MT5 把同一脚本挂到 XAUUSD 月线对比一下,比盲信预测值更实在。

MQL5 / C++
class="num">2023.07.class="num">30 class="num">14:class="num">45:class="num">57.449 ct_15_w_n(SPX500,MN1)   class="type">void OnStart() Morphs forecast is: class="num">257937.92970615, on: class="num">2023.05.class="num">01 class="num">00:class="num">00, with actual being: class="num">28877.00000000
class="num">2023.07.class="num">30 class="num">14:class="num">45:class="num">57.527 ct_15_w_n(SPX500,MN1)   class="type">void OnStart() Morphs forecast is: class="num">679078.55629755, on: class="num">2023.06.class="num">01 class="num">00:class="num">00, with actual being: class="num">23306.00000000
class="num">2023.07.class="num">30 class="num">14:class="num">45:class="num">57.527 ct_15_w_n(SPX500,MN1)   class="type">void OnStart() correlation is: -class="num">0.03589660 with morph constant as: class="num">0.00000000

「函子系数怎么挪到别的货币对去用」

范畴论在金融里最被低估的一点,是它能把一次 heavy 优化得到的映射系数直接搬到别的标的。上面测试里算出的对象函子映射和态射映射系数,若覆盖 MT5 策略测试器很长历史区间,计算开销极大;但系数一旦出来,套到欧元财经日历对 EURO-STOXX 波动率、或 FTSE 波动率对英镑的影响上,按假设可能比平均结果更好。 我们用德国范畴配 DAX30 波动率范畴跑了一遍,GER30 月线日志里 2022.09 预测 144734 实际 154697、2023.01 预测 440957 实际才 55544,末尾 correlation 只有 0.0226;UK100 那边 2023.01 预测 153576 实际 30453,correlation 0.1441。两个都低得离谱,说明策略测试器自带的日历数据太受限,假设根本立不住。 别把 0.46 当圣经 美元和 SP500 早先那 0.46 相关性只是极早期指标,真实可靠性取决于域与协域的线性系数。长远看,把财经日历手动导成 CSV 或塞进数据库,让智能系统读,才能在理想长区间里正经测。外汇和贵金属波动剧烈,这种迁移假设失效时亏损可能很快放大。 除了预测波动率定止损,持仓规模也能用同一套:把每笔交易结果当对象、结果随时间的演变当态射,通过函子映射到「理想仓位」范畴。亏了就按当时波动率等比缩仓,赚了等比放大,映射天然带滞后——这周期结果连下周期仓位。 映射别只写线性方程 基础做法是域值加常数乘系数得协域,但二次关系只需多一个平方项系数。更稳的是用人工神经网络同时学对象和态射的同态映射,多输入单输出天生合适,大量训练后可能比手拍系数准得多。

MQL5 / C++
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">25.655	ct_15_w_n(GER30,MN1)	class="type">void OnStart() Objects forecast is: class="num">75550.00000000, on: class="num">2020.01.class="num">01 class="num">00:class="num">00, with actual being: class="num">210640.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">25.727	ct_15_w_n(GER30,MN1)	class="type">void OnStart() Objects forecast is: class="num">210640.00000000, on: class="num">2020.02.class="num">01 class="num">00:class="num">00, with actual being: class="num">431320.00000000
...
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">28.445	ct_15_w_n(GER30,MN1)	class="type">void OnStart() Objects forecast is: class="num">144734.23693128, on: class="num">2022.09.class="num">01 class="num">00:class="num">00, with actual being: class="num">154697.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">28.539	ct_15_w_n(GER30,MN1)	class="type">void OnStart() Objects forecast is: class="num">171908.69769099, on: class="num">2022.10.class="num">01 class="num">00:class="num">00, with actual being: class="num">156643.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">28.648	ct_15_w_n(GER30,MN1)	class="type">void OnStart() Objects forecast is: class="num">298789.42486333, on: class="num">2022.11.class="num">01 class="num">00:class="num">00, with actual being: class="num">99044.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">28.753	ct_15_w_n(GER30,MN1)	class="type">void OnStart() Objects forecast is: class="num">178962.89317906, on: class="num">2022.12.class="num">01 class="num">00:class="num">00, with actual being: class="num">137604.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">28.901	ct_15_w_n(GER30,MN1)	class="type">void OnStart() Objects forecast is: class="num">440957.33259197, on: class="num">2023.01.class="num">01 class="num">00:class="num">00, with actual being: class="num">55544.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">29.032	ct_15_w_n(GER30,MN1)	class="type">void OnStart() Objects forecast is: class="num">143198.91357580, on: class="num">2023.02.class="num">01 class="num">00:class="num">00, with actual being: class="num">124659.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">29.151	ct_15_w_n(GER30,MN1)	class="type">void OnStart() Objects forecast is: class="num">24327.24201304, on: class="num">2023.03.class="num">01 class="num">00:class="num">00, with actual being: class="num">48737.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">29.267	ct_15_w_n(GER30,MN1)	class="type">void OnStart() Objects forecast is: class="num">167059.32862279, on: class="num">2023.04.class="num">01 class="num">00:class="num">00, with actual being: class="num">69888.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">29.357	ct_15_w_n(GER30,MN1)	class="type">void OnStart() Objects forecast is: class="num">67301.73632062, on: class="num">2023.05.class="num">01 class="num">00:class="num">00, with actual being: class="num">74073.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">29.470	ct_15_w_n(GER30,MN1)	class="type">void OnStart() Objects forecast is: class="num">87406.10063493, on: class="num">2023.06.class="num">01 class="num">00:class="num">00, with actual being: class="num">104992.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">29.470	ct_15_w_n(GER30,MN1)	class="type">void OnStart() correlation is: class="num">0.02260757 with morph constant as: class="num">0.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">45.341	ct_15_w_n(UK100,MN1)	class="type">void OnStart() Objects forecast is: class="num">45860.00000000, on: class="num">2020.01.class="num">01 class="num">00:class="num">00, with actual being: class="num">109780.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">45.381	ct_15_w_n(UK100,MN1)	class="type">void OnStart() Objects forecast is: class="num">109780.00000000, on: class="num">2020.02.class="num">01 class="num">00:class="num">00, with actual being: class="num">210420.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">45.420	ct_15_w_n(UK100,MN1)	class="type">void OnStart() Objects forecast is: class="num">210420.00000000, on: class="num">2020.03.class="num">01 class="num">00:class="num">00, with actual being: class="num">87250.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">45.466	ct_15_w_n(UK100,MN1)	class="type">void OnStart() Objects forecast is: class="num">87250.00000000, on: class="num">2020.04.class="num">01 class="num">00:class="num">00, with actual being: class="num">58380.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">45.508	ct_15_w_n(UK100,MN1)	class="type">void OnStart() Objects forecast is: class="num">1581489.63705309, on: class="num">2020.05.class="num">01 class="num">00:class="num">00, with actual being: class="num">58370.00000000
...
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">46.685	ct_15_w_n(UK100,MN1)	class="type">void OnStart() Objects forecast is: class="num">153576.16806574, on: class="num">2023.01.class="num">01 class="num">00:class="num">00, with actual being: class="num">30453.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">46.710	ct_15_w_n(UK100,MN1)	class="type">void OnStart() Objects forecast is: class="num">222058.94934174, on: class="num">2023.02.class="num">01 class="num">00:class="num">00, with actual being: class="num">77051.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">46.739	ct_15_w_n(UK100,MN1)	class="type">void OnStart() Objects forecast is: class="num">50993.02046828, on: class="num">2023.03.class="num">01 class="num">00:class="num">00, with actual being: class="num">30780.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">46.784	ct_15_w_n(UK100,MN1)	class="type">void OnStart() Objects forecast is: class="num">66795.26430874, on: class="num">2023.04.class="num">01 class="num">00:class="num">00, with actual being: class="num">45453.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">46.832	ct_15_w_n(UK100,MN1)	class="type">void OnStart() Objects forecast is: class="num">75492.86146563, on: class="num">2023.05.class="num">01 class="num">00:class="num">00, with actual being: class="num">28845.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">46.876	ct_15_w_n(UK100,MN1)	class="type">void OnStart() Objects forecast is: class="num">92298.50964858, on: class="num">2023.06.class="num">01 class="num">00:class="num">00, with actual being: class="num">49472.00000000
class="num">2023.07.class="num">30 class="num">15:class="num">12:class="num">46.876	ct_15_w_n(UK100,MN1)	class="type">void OnStart() correlation is: class="num">0.14415363 with morph constant as: class="num">0.00000000

◍ 把这条线请下神坛

用财经日历构图、把波动率曲面当范畴、再用滞后标普500的函子关系去推下一步波动,这套框架本质上只是把主观判断转成了可装配的映射。前几篇留的 ct_15_w.mq5(17.23 KB)和 ct_15_w_n.mq5(18.41 KB)已经把尾随止损的挪移写死在向导里,读者照着自己策略改阈值比照搬更实际。 我们一直用的增量近似是线性或二次关系,域到协域的粗糙映射能跑通,但人工神经网络定义同一映射在下一篇才展开,不在这收口。外汇与贵金属杠杆高、滑点突兀,函子推出来的信号只调仓位和止损,别当入场圣旨。 至此变形与函子两块拼图凑齐,下次直接拿网络替掉手调增量,看映射是不是更贴真实波动。

把图到波动的映射交给小布
这些把 MQL5 日历重构为图、再算函子配对标普波动的诊断,小布盯盘的 AIGC 已内置,打开对应品种页即可看到预计算的范畴映射,你只管判断信号可信度。

常见问题

线性序对象只能顺次连一个邻点,图论允许顶点连多个对象并形成环,更适合表达财经日历里零售销售、CPI、PMI 互导的网状关系。
标普按时间逐点排列,而图的多行顶点对被捆绑进单个波动数据点,域元素成组映射,结构不对等故只可能是函子而非同构。
小布已内置日历转图与函子配对标普波动的模块,不用自己写 MQL5 抓取与重构,打开品种页直接读映射结果即可。
本文不验证该环准确性,只示范构图法;真实交易前需用历史数据回测环内传导倾向,外汇贵金属高风险,结论仅作概率参考。
将图范畴顶点对行数与标普波动点配对,观察多新闻共振时的波动倾斜,具体实现见本篇第四节对交易者的影响与收束说明。