MQL5自优化智能交易系统(第十三部分):基于矩阵分解浅谈控制理论
金融市场往往难以提前规划和预判。投资者情绪十分脆弱,会随全球形势与当下热点事件快速转变。因此,在历史数据中看起来盈利的策略,放到实时市场中常常会失效。
交易领域存在多种理论可以解释这类现象。但核心一点:交易程序一旦开发部署完成,其运行逻辑就固定下来,若无人工干预则无法修改。这意味着策略会一再重复同样的错误,既无法从失败中获益,也无法从过往失误中学习。

图 1:金融市场中部署交易程序的常规交易架构
针对这个长期存在的难题,人们提出过许多解决方案。其中一个极具潜力的方案来自控制理论。控制理论主要研究如何校正动态、混沌环境下系统的运行行为,目标是让系统重新朝着设定目标运行。
我们周期性地把策略的绩效数据反馈至反馈控制器;控制器会记录并观测策略和市场之间的相互作用,以此估算策略行为与市场结果之间的关联关系。控制器会挖掘和盈利 / 亏损交易强相关的主导模式。如果能够找到这类规律并完成学习,理论上,即便面对混乱且持续变化的市场,反馈控制器也能调整、引导交易系统的运行状态,实现盈利。
这实际上会改变原有策略的部署架构,也就是图 1 里的原理图。在图 2 中,本文介绍控制理论文献里的常用符号表示法:市场输入信号记为 (M),策略输出记为 (S)。

图 2:我们可以用简化符号重新定义交易程序,M 代表市场输入,S 代表策略输出
在前面介绍矩阵分解的文章里,我们主要搭建回归与分类模型,用来预测未来价格水平或是技术指标的变化。而本文将聚焦控制理论,具体来说是闭环反馈控制器。数值驱动型交易程序的相关讨论中,这个方向常常被忽略,但它的基础理论完全可以适配交易者的需求。
本文目标:验证反馈控制器能够对交易系统实现精细调控。合理配置后,控制器可以校正系统,并使其持续朝着盈利交易的方向运行。
我们以基准版本交易策略作为起点:策略使用两条移动平均线,一条基于最高价、一条基于最低价。两条均线周期相同,构成一个均线通道。当价格向上突破通道,开多单;价格向下跌破通道,则开空单。这个基准版本作为盈利基准,我们期望加入反馈控制器后能够超越该基准。图 3 展示该策略在欧元兑美元(EURUSD)日线图上的运行效果。

图 3:交易策略在 EURUSD 日线图表上的可视化演示
反馈控制器会先观测 90 天的策略运行表现,之后才允许介入策略。也就是说,前 90 天控制器不会向系统输出任何指令,只采集观测数据。请注意:这个 90 天观测周期属于可调参数,合适的参数值无法预先确定。本文选取 90 天是人为设定,假设该周期契合主导外汇市场金融机构的业务周期。读者可以自行调试该参数。
在这 90 天内,控制器记录多项关键变量:市场报价、账户余额、账户净值、指标数值、开仓类型。这些观测数据存入一个矩阵,称为快照。之后训练线性模型,学习快照随时间演变的规律。简单来讲,用前 89 组快照映射后续 89 组快照,让系统学习策略状态随时间的演变过程。
90 天观测期结束后,这个线性系统整合全部系统状态,预测下一笔交易将盈利还是亏损。如果预测下一笔交易会亏损,系统直接暂停交易,直到预判市场环境转好再恢复。
所以,反馈控制器的任务是观测系统输出 (S),学习一个全新的控制函数 (F),通过它改变系统行为 (FS),引导系统重回盈利状态,让策略不再单纯由市场 (M) 直接驱动。90 天观测周期结束后,策略不再仅由市场输入(M)单独驱动,而是同时受到市场输入与反馈控制器调节信号的共同作用(FS + M)。

图 4:反馈控制器部署后,调控交易程序运行逻辑的示意图
我们用五年 EURUSD 日线数据对两套系统做回测。加入反馈控制器后,系统盈利能力提升 82%。基准策略原本盈利 134 美元;增加反馈控制器后,利润提升至 245 美元。除此之外,优化后的系统在获取更高利润的同时,开仓笔数减少:总开仓从 180 笔降至 152 笔,交易频次减少 15%。意味着新系统以更低风险换取更高收益,这是交易程序非常理想的特性。
同时整体风险得到降低。基准策略总亏损为 - 1092 美元;增加反馈控制器后总亏损降至 - 838 美元,而毛利润基本保持不变。这又是一项非常理想的结果。
基准策略的夏普比率为 0.34。接入反馈控制器后,夏普比率提升至 0.68,增幅 100%,在 EURUSD 这类高难度市场中,这个结果相当亮眼。盈利交易占比提升六个百分点,由 53.89% 升至 57.24%。相应的,亏损交易占比同步下降,证明反馈控制器成功学到了区分盈利、亏损交易的核心特征。最后,单笔交易期望收益由 0.75 提升至 1.61,提升幅度 114%。
显而易见,反馈控制器在数值型交易程序中起到关键作用。配置得当的前提下,它可以自主学习、适时干预,避免策略重复踩坑。直接基于快照观测数据搭建控制器的技术称为系统辨识。
这类算法最初由流体力学领域工程师研发。当年工程师需要为飞机机翼组件设计控制器,但是湍流效应没有显式公式可以预测与校正。自然而然,他们需要找到方法:通过观测系统行为以及产生该行为的输入,学习最优控制输入。
本文搭建的是系统的线性模型,所以该方法更精确的名称为线性系统辨识。本文展示的结果激励我们进一步拓展反馈控制器的任务范围,并在未来研究非线性系统辨识。下面正式开始。
在 MQL5 中实现
和我们之前绝大多数交易程序一样,首先定义重要的系统参数。对于这套基准策略,只需要一项系统定义:设置统一的均线周期。
//+------------------------------------------------------------------+ //| Closed Loop Feedback.mq5 | //| Gamuchirai Ndawana | //| https://www.mql5.com/en/users/gamuchiraindawa | //+------------------------------------------------------------------+ #property copyright "Gamuchirai Ndawana" #property link "https://www.mql5.com/en/users/gamuchiraindawa" #property version "1.00" //+------------------------------------------------------------------+ //| System definitions | //+------------------------------------------------------------------+ #define MA_PERIOD 10
系统设计的下一个重点是全局变量。这套基准策略仅需少量全局变量,关联我们用到的技术指标。具体来说,我们需要两个均线指标句柄,再加一个 ATR 指标句柄,ATR 用于设置止损。每个指标都需要独立的数据缓存数组。
//+------------------------------------------------------------------+ //| Global variables | //+------------------------------------------------------------------+ int ma_h_handler,ma_l_handler,atr_handler; double ma_h[],ma_l[],atr[];
本系列文章编写的几乎所有交易程序都会引入依赖库,我们不会从零手写全部代码。本程序调用交易库,外加两个自定义库:一个用于监测新 K 线生成,另一个用来获取买卖价等关键报价信息。
//+------------------------------------------------------------------+ //| Dependencies | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> #include <VolatilityDoctor\Time\Time.mqh> #include <VolatilityDoctor\Trade\TradeInfo.mqh> CTrade Trade; Time *DailyTimeHandler; TradeInfo *TradeInfoHandler;
系统初始化阶段,我们首先实例化自定义类。同时创建各个指标实例。
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- DailyTimeHandler = new Time(Symbol(),PERIOD_D1); TradeInfoHandler = new TradeInfo(Symbol(),PERIOD_D1); ma_h_handler = iMA(Symbol(),PERIOD_D1,MA_PERIOD,0,MODE_EMA,PRICE_HIGH); ma_l_handler = iMA(Symbol(),PERIOD_D1,MA_PERIOD,0,MODE_EMA,PRICE_LOW); atr_handler = iATR(Symbol(),PERIOD_D1,14); //--- return(INIT_SUCCEEDED); }
当程序不再运行时,我们会删除之前创建的动态对象,以此高效管理内存,同时释放不再使用的指标,安全地回收系统资源。
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- delete DailyTimeHandler; delete TradeInfoHandler; IndicatorRelease(ma_h_handler); IndicatorRelease(ma_l_handler); }
每当收到新报价时,就会触发 OnTick 事件函数。该函数借助自定义库判断是否生成了一根新的日线 K 线。如果检测到新 K 线,程序就会更新缓存数组里的指标数值,并保存当前收盘价。若当前没有持仓,就执行交易规则判断买卖信号:如果收盘价高于均线通道上沿,则开多单;如果收盘价低于均线通道下沿,则开空单。
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- if(DailyTimeHandler.NewCandle()) { CopyBuffer(ma_h_handler,0,0,1,ma_h); CopyBuffer(ma_l_handler,0,0,1,ma_l); CopyBuffer(atr_handler,0,0,1,atr); double c = iClose(Symbol(),PERIOD_D1,0); if(PositionsTotal() == 0) { if(c > ma_h[0]) Trade.Buy(TradeInfoHandler.MinVolume(),Symbol(),TradeInfoHandler.GetAsk(),(TradeInfoHandler.GetBid()-(atr[0]*2)),(TradeInfoHandler.GetBid()+(atr[0]*2)),""); if(c < ma_l[0]) Trade.Sell(TradeInfoHandler.MinVolume(),Symbol(),TradeInfoHandler.GetBid(),(TradeInfoHandler.GetAsk()+(atr[0]*2)),(TradeInfoHandler.GetAsk()-(atr[0]*2)),""); } } }
最后,所有逻辑执行完毕后,我们取消定义程序开头声明的系统常量,完成资源清理。以上就是这套基准交易系统的完整代码逻辑。
//+------------------------------------------------------------------+ //| Undefine system constants | //+------------------------------------------------------------------+ #undef MA_PERIOD //+------------------------------------------------------------------+
接下来我们就可以在历史数据上对程序进行回测。本次测试选取五年的欧元兑美元日线数据,运行这套基准策略。

图 5:基于五年欧元兑美元历史行情数据回测交易程序
为了让测试更加贴近真实场景,我们加入随机延迟。现实市场充满不确定性,引入延迟可以模拟这种不确定性。

图 6:为本轮分析设置贴近真实环境的回测参数
完成回测后,我们可以生成程序完整的绩效报告。本文开篇已经简要介绍了回测的总体结果。从详细报告可以看到,该系统夏普比率偏低,仅为 0.34;并且平均亏损单笔金额大于平均盈利单笔金额。公平来讲,即便后续优化版本,单笔平均亏损依旧略大于单笔盈利。但我们这套闭环反馈系统缩小了二者之间的差距。

图 7:汇总交易程序绩效的详细统计报表
另外,查看基准策略的净值曲线可以发现,整体虽然向上,但稳定性很差,常常连续数月在区间内震荡,盈亏循环往复,策略长时间陷入停滞。这种不稳定表现,正是我们希望引入反馈控制器、修改系统行为所要解决的问题。

图 8:交易程序生成的净值曲线形态不稳定,效果不尽如人意
优化初始回测结果
现在我们开始借助反馈控制器优化原始策略的回测表现。为避免代码冗余,原文省略了没有改动的代码段,重点展示相对于原始版本的修改部分。
可以明显看到,程序需要定义的系统常量变多了。原始版本只需要 1 个常量,升级后的版本一共 4 个。其中新增定义主要涉及三类内容:(1)反馈控制器正式启用前需要采集的总观测样本数量;(2)需要跟踪的特征数量,本例共 12 个特征,用于刻画交易策略运行表现;(3)记录当前持仓类型的向量。
//+------------------------------------------------------------------+ //| Closed Loop Feedback.mq5 | //| Gamuchirai Ndawana | //| https://www.mql5.com/en/users/gamuchiraindawa | //+------------------------------------------------------------------+ #property copyright "Gamuchirai Ndawana" #property link "https://www.mql5.com/en/users/gamuchiraindawa" #property version "1.00" //+------------------------------------------------------------------+ //| System definitions | //+------------------------------------------------------------------+ #define MA_PERIOD 10 #define OBSERVATIONS 90 #define FEATURES 12 #define ACCOUNT_STATES 3
随着程序功能扩展,全局变量也更加复杂。现在需要矩阵存储状态快照、向量保存线性模型的预测结果,还有布尔标记,用来判断系统何时从观测阶段切换到实盘预测交易阶段。
//+------------------------------------------------------------------+ //| Global variables | //+------------------------------------------------------------------+ int ma_h_handler,ma_l_handler,atr_handler,scenes,b_matrix_scenes; double ma_h[],ma_l[],atr[]; matrix snapshots,OB_SIGMA,OB_VT,OB_U,b_vector,b_matrix; vector S,prediction; vector account_state; bool predict,permission;
系统初始化阶段会执行多项预处理工作。前面几步和之前一致,完成技术指标的创建。之后初始化快照矩阵,12 行 90 列,矩阵所有元素初始置1。permission 标记初始值为 true,表示系统一开始被允许交易但当 90 天观测周期结束后,该标记会被置为 false,同时 predict 标记设为 true。自此系统不再无条件执行交易;每一笔操作,都必须先获取线性模型的授权。
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- DailyTimeHandler = new Time(Symbol(),PERIOD_D1); TradeInfoHandler = new TradeInfo(Symbol(),PERIOD_D1); ma_h_handler = iMA(Symbol(),PERIOD_D1,MA_PERIOD,0,MODE_EMA,PRICE_HIGH); ma_l_handler = iMA(Symbol(),PERIOD_D1,MA_PERIOD,0,MODE_EMA,PRICE_LOW); atr_handler = iATR(Symbol(),PERIOD_D1,14); snapshots = matrix::Ones(FEATURES,OBSERVATIONS); scenes = 0; b_matrix_scenes = 0; account_state = vector::Zeros(3); b_matrix = matrix::Zeros(1,1); prediction = vector::Zeros(2); predict = false; permission = true; //--- return(INIT_SUCCEEDED); }
OnTick 事件处理函数相较于基准系统做了大幅修改。一项核心改动:账户状态现在保存到一个包含 3 个元素的向量中。该向量采用独热编码(one-hot encoding):若持有多单,则第一个元素置 1;若持有空单,则第二个元素置 1;若无持仓,则第三个元素置 1。这种方式以结构化形式向线性模型提供分类信息。
交易逻辑本身保持不变:如果收盘价高于均线通道上沿,则考虑开多;如果收盘价低于均线通道下沿,则考虑开空。前 90 天内,predict 标记为 false,系统拥有无条件交易权限。90 天之后,所有交易决策都需要经过线性模型校验。一旦采集够所需数量的观测样本,快照矩阵会调整尺寸以容纳新数据;同时,我们构建好的线性辨识系统会在下单前对交易决策进行筛选过滤。
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- if(DailyTimeHandler.NewCandle()) { CopyBuffer(ma_h_handler,0,0,1,ma_h); CopyBuffer(ma_l_handler,0,0,1,ma_l); CopyBuffer(atr_handler,0,0,1,atr); double c = iClose(Symbol(),PERIOD_D1,0); if(PositionsTotal() == 0) { account_state = vector::Zeros(ACCOUNT_STATES); if(c > ma_h[0]) { if(!predict) { if(permission) Trade.Buy(TradeInfoHandler.MinVolume(),Symbol(),TradeInfoHandler.GetAsk(),(TradeInfoHandler.GetBid()-(atr[0]*2)),(TradeInfoHandler.GetBid()+(atr[0]*2)),""); } account_state[0] = 1; } else if(c < ma_l[0]) { if(!predict) { if(permission) Trade.Sell(TradeInfoHandler.MinVolume(),Symbol(),TradeInfoHandler.GetBid(),(TradeInfoHandler.GetAsk()+(atr[0]*2)),(TradeInfoHandler.GetAsk()-(atr[0]*2)),""); } account_state[1] = 1; } else { account_state[2] = 1; } } if(scenes < OBSERVATIONS) { take_snapshots(); } else { matrix temp; temp.Assign(snapshots); snapshots = matrix::Ones(FEATURES,scenes+1); //--- The first row is the intercept and must be full of ones for(int i=0;i<FEATURES;i++) snapshots.Row(temp.Row(i),i); take_snapshots(); fit_snapshots(); predict = true; permission = false; } scenes++; } }
在这一阶段,系统采集全部相关特征的状态快照:昨日开盘价、最高价、最低价、收盘价,各项技术指标数值、账户信息,以及经过独热编码的账户状态向量。纳入这些变量后,系统能够学习并建立策略与市场之间的映射模型。我们的目标不再仅仅局限于预测未来价格水平,而是想要预测交易账户未来的资金余额。倘若这种关联关系真实存在且能够被模型学到,那么反馈控制器就可以无需人工干预,自主调整策略的运行行为。
//+------------------------------------------------------------------+ //| Record the current state of our system | //+------------------------------------------------------------------+ void take_snapshots(void) { snapshots[1,scenes] = iOpen(Symbol(),PERIOD_D1,1); snapshots[2,scenes] = iHigh(Symbol(),PERIOD_D1,1); snapshots[3,scenes] = iLow(Symbol(),PERIOD_D1,1); snapshots[4,scenes] = iClose(Symbol(),PERIOD_D1,1); snapshots[5,scenes] = AccountInfoDouble(ACCOUNT_BALANCE); snapshots[6,scenes] = AccountInfoDouble(ACCOUNT_EQUITY); snapshots[7,scenes] = ma_h[0]; snapshots[8,scenes] = ma_l[0]; snapshots[9,scenes] = account_state[0]; snapshots[10,scenes] = account_state[1]; snapshots[11,scenes] = account_state[2]; } //+------------------------------------------------------------------+
接下来我们使用两个矩阵来拟合线性系统:矩阵 X 作为输入,矩阵 y 作为目标输出。这是一个多输出系统,可以同时预测多个结果。矩阵 y 在时间上向后偏移一个步长,也就是输入对应前 89 组快照,输出对应紧随其后的 89 组快照。随着采集到的观测样本不断增加,该循环会通过统计已完成的总场景数,自然适配持续增长的数据集。
一个场景代表两次连续快照之间的时间间隔。本文中我们每天采集一次系统快照,因此场景数量读者可根据自身需求自行调整。我们利用伪逆解法(MQL5 中的`PInv()`函数)求解从 X 映射到 y 的最优系数。本系列前面的文章已经详细讲解过这个函数。如果读者尚不了解 PInv() 函数的重要作用,可以点击此处链接阅读相关内容,PInv() 是我们使用的一个强大工具。
拟合完成后,系统输出快照数据、输入与目标集、学习得到的系数以及模型预测结果。之后我们实时解析这些预测值:如果模型预判账户余额将会增长,则授予交易许可;当考虑开多单,并且模型预判均线的上沿存在上涨动能时,同样授予交易许可;同理,若考虑开空单,且模型预判均线下沿存在下跌动能,也授予交易许可。其余所有情况,系统都禁止交易。
最后,当获得交易许可且当前无持仓时,系统执行对应的交易。该流程执行完毕后,程序打印当前账户余额、预测余额,以及是否获得交易许可。到这里,所有用来改善策略绩效的代码修改就全部完成。我们编写的代码没有直接告诉控制器何时做多、何时做空,而是为控制器定义一套它可以执行的动作集合,控制器根据自身从积累的观测数据中推导出的结论自主做出决策。
//+------------------------------------------------------------------+ //| Fit our linear model to our collected snapshots | //+------------------------------------------------------------------+ void fit_snapshots(void) { matrix X,y; X.Reshape(FEATURES,scenes); y.Reshape(FEATURES-1,scenes); for(int i=0;i<scenes;i++) { X[0,i] = snapshots[0,i]; X[1,i] = snapshots[1,i]; X[2,i] = snapshots[2,i]; X[3,i] = snapshots[3,i]; X[4,i] = snapshots[4,i]; X[5,i] = snapshots[5,i]; X[6,i] = snapshots[6,i]; X[7,i] = snapshots[7,i]; X[8,i] = snapshots[8,i]; X[9,i] = snapshots[9,i]; X[10,i] = snapshots[10,i]; X[11,i] = snapshots[11,i]; y[0,i] = snapshots[1,i+1]; y[1,i] = snapshots[2,i+1]; y[2,i] = snapshots[3,i+1]; y[3,i] = snapshots[4,i+1]; y[4,i] = snapshots[5,i+1]; y[5,i] = snapshots[6,i+1]; y[6,i] = snapshots[7,i+1]; y[7,i] = snapshots[8,i+1]; y[8,i] = snapshots[9,i+1]; y[9,i] = snapshots[10,i+1]; y[10,i] = snapshots[11,i+1]; } //--- Find optimal solutions b_vector = y.MatMul(X.PInv()); Print("Day Number: ",scenes+1); Print("Snapshot"); Print(snapshots); Print("Input"); Print(X); Print("Target"); Print(y); Print("Coefficients"); Print(b_vector); Print("Prediciton"); Print(y.Col(scenes-1)); prediction = b_vector.MatMul(snapshots.Col(scenes-1)); if(prediction[4] > AccountInfoDouble(ACCOUNT_BALANCE)) permission = true; else if((account_state[0] == 1) && (prediction[6] > ma_h[0])) permission = true; else if((account_state[1] == 1) && (prediction[7] < ma_l[0])) permission = true; else permission = false; if(permission) { if(PositionsTotal() == 0) { if(account_state[0] == 1) Trade.Buy(TradeInfoHandler.MinVolume(),Symbol(),TradeInfoHandler.GetAsk(),(TradeInfoHandler.GetBid()-(atr[0]*2)),(TradeInfoHandler.GetBid()+(atr[0]*2)),""); else if(account_state[1] == 1) Trade.Sell(TradeInfoHandler.MinVolume(),Symbol(),TradeInfoHandler.GetBid(),(TradeInfoHandler.GetAsk()+(atr[0]*2)),(TradeInfoHandler.GetAsk()-(atr[0]*2)),""); } } Print("Current Balabnce: ",AccountInfoDouble(ACCOUNT_BALANCE)," Predicted Balance: ",prediction[4]," Permission: ",permission); } //+------------------------------------------------------------------+
框架搭建完成后,我们就可以在和之前完全相同的历史行情条件下对程序开展回测。为避免重复,此处不再复述测试参数,但所有参数均与图 6 保持一致。

图 9:准备对优化后的交易策略开展测试
详细分析结果显示,基准策略与这套带反馈控制器的系统存在显著差异。净利润大幅提升,而总盈利几乎维持不变 —— 这说明控制器能够精准识别并拦截亏损交易,效果值得肯定。夏普比率得到明显提升,盈利单和亏损单的平均盈亏金额基本持平,相对基准策略而言,这是巨大的进步。

图 10:交易程序的详细回测结果,展示了我们实现的各项优化
净值曲线的波动率有所下降,上涨趋势更强、稳定性更高。这正是我们在交易策略中引入闭环反馈控制器,期望实现的目标。

图 11:优化后的交易策略生成的净值曲线,随时间波动更小,收益更加稳定
我还附上了回测过程中系统采集快照的截图。受截图尺寸限制,12 个特征无法一次性全部展示。但读者可以看到,快照矩阵最后一行显示初始资金为 500 美元,也就是模拟交易策略的启动本金,可参考图 6。程序会持续追踪账户净值与余额如何受市场环境、以及交易策略决策的影响。

图 12:持续采集系统运行快照,用来监测并校正策略
输出日志里的快照记录印证了这套运行机制。例如,在第 1645 个交易日,线性模型预判本次交易会发生亏损,于是将交易许可标记置为 false,拦截了这笔交易。

图 13:线性系统控制器判断市场环境不利,禁止策略开仓
到了第二天,模型预判这笔交易具备盈利潜力,系统便授予交易许可并执行下单。总而言之,这就是优化版程序从启动到运行的完整工作流程。这也说明,预测模型除了常规的价格预测之外,还有大量应用场景。我们可以利用训练得到的模型,挖掘盈利、亏损交易背后可学习的内在规律,以此避免重复犯下过去的错误。

图 14:当市场环境适配策略时,反馈控制器授予交易许可,继续交易
结论
综上,反馈控制器为我们提供了一种构建交易系统的思路,这类系统不仅可以盈利,还具备自适应能力。系统可以从自身的历史绩效中学习,帮助我们避免重复踩坑,即便市场环境持续变化,依然可以保持有效性。本次回测结果在盈利能力、交易效率与风险控制上都取得明显改善,证明控制理论在交易领域具备实际应用价值。展望未来,本次研究激励我们跳出线性模型的局限,探索非线性反馈控制器,以期捕捉市场行为中更复杂的规律。依托这些技术进展,面对充满不确定性的市场,我们可以持续提升交易系统的稳定性与盈利能力。
不过,在离开线性系统的研究之前,我们仍然可以对它做一些有价值的改进。在简单线性系统上衡量每一项潜在优化带来的收益,能够为后续搭建各类非线性系统,提供一套可靠的基准参照。
本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/19132
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
本文由网站的一位用户撰写,反映了他们的个人观点。MetaQuotes Ltd 不对所提供信息的准确性负责,也不对因使用所述解决方案、策略或建议而产生的任何后果负责。
市场模拟:MQL5 中的 SQL 入门(五)
新手在交易中的10个基本错误
基于协整股票的统计套利(第三部分):数据库搭建
您未附上 volatilityDoctor/Time..Trade 的头文件。如果没有这两个头文件,就无法对您的提交进行测试。