![在 MetaTrader 5 中测试和优化二元期权策略](https://c.mql5.com/2/0/binary-strategy-tester_600x314.jpg)
在 MetaTrader 5 中测试和优化二元期权策略
概述
最近,我对二元期权产生了兴趣。 在网上冲浪,并查看了一些经纪商之后,发现几乎大多人都在他们的平台进行交易。 这些平台没有测试策略的能力,充其量只有一套浅薄的标准指标。 在审查了大量不同的二元期权策略后,我开始琢磨如何验证这些策略及其优化。 和往常一样,我们心爱的 MetaTrader 5 来拯救我了。 与往常一样,我将尝试尽可能简单地与您分享我的实验,在没有复杂方程和代码的情况下贡献真材实料。 但首先,关于二元期权是否值得深入研究,,极其理论尚存争论。
理论
二元期权是一种数字合约,其主题是预测选定时间段内资产价格的方向。 任务是正确判定市场形势发展的两种可能情景之一:资产是上涨还是下跌。 今天,我们有广泛的货币、证券和商品可在线选择。 实践中几乎任何东西(包括天气预报)都可以成为一种资产。 交易不需要在市场交易过程领域进行巨额投资,以及深厚的金融和经济知识。
二元期权的类型
最高价/最低价是最简单的二元期权类型,因为交易者只需要判定价格将朝哪个方向发展。 在看涨趋势中,建议买入最高价(看涨期权)。 如果预计资产将向下移动,则按最低价购买(看跌期权)。 最高价/最低价期权的利润从赌注的 10% 到 80% 不等。
“一次式触及”代表一个协议,其中需要判定所期望价位的达到。 平仓期间的价位无关紧要。 触及给定水平就足够了。 “一次式触及”的盈利能力高于平时,可能达到 95%,由于在大多数情况下很难预测它们,故您也可能会 100% 亏掉所有。
范围判定一个价格走廊,资产的价值将在到期时位于该走廊之内。 这也很难理解和预测。 盈利能力高达 95%。
下面我将测试和优化最高价/最低价期权的策略,因为我认为这是最受欢迎的。
优点和缺点
优点如下:
- 简单 — 您可以把潜在损失或利润维持在固定数额,避免进行止损和止盈价位的复杂计算,如果您是初学者,这尤其实用。
- 在期权经纪商的网站上简单注册 — 不需要一揽子文件。
- 最广泛的资源 — 公司股票、股票指数、石油、黄金、加密货币,初始本金从 100 美元甚至更低。 而在股票或期货市场上交易需要更多金额的初始本金。
缺点:
- 高风险和负面期望。 需要两场取胜才能弥补一场的损失。 盈利效率高达 80%。 亏损操作的成本将高于取胜操作。
- “赌博”模式从长远来看终会带来损失。 有些人试图在交易时应用来赌场的技巧,如马丁格尔(译者按:逆势翻倍加仓)等方法,这违反了正确交易的规则,最终导致资金爆仓。
- 大笔佣金。
货币对。 优化和前向验证测试范围。 设置
以下是所有优化和测试参数:
- 外汇;
- EURUSD;
- M5, M15, M30, H1;
- 到期时间 5, 15, 30 分钟和 1 小时。
- 优化范围 1 年。 2021.01.28 - 2022.01.28.
- 前向验证测试范围 1 年。 2022.01.28 - 2023.01.28;
- 初始本金 10,000;
- 比率 10;
- 利率 80%。
技术方面
我们需要用于测试和优化的输入:
- StartDepo - 启动资金;
- OptionRate - 比率;
- ExpirationTime - 到期时间;
- ProfitPercent - 盈利百分比;
- TimeFrame - 指标时间帧;
- Optimization - 优化开关;
- OptimizationFileName – 存储优化结果的文件名。
input string N0 = "------------Open settings----------------"; input double StartDepo = 10000; input int OptionRate = 10; input string N1 = "------------Close settings---------------"; input int ExpirationTime = 1; //ExpirationTime 1=5 min, 2=15 min, 3=30 min, 4=60 min input double ProfitPercent = 80; input string N2 = "------------Optimization settings--------"; input int TimeFrame = 1; //TimeFrame 1=5 min, 2=15 min, 3=30 min, 4=60 min input bool Optimization = false; input string OptimizationFileName = "Optimization.csv"; input string N3 = "------------Other settings---------------"; input int Slippage = 10; input int Magic = 111111; input string EAComment = "2Ma+RSI+Stochastic Oscillator";
我们还需要变量来存储和跟踪资金,以及可盈利和无盈利期权购买数量的变化:
- XStartDepo - 存储当前资金;
- Profit - 存储可盈利期权购买数量;
- Loss - 存储无盈利期权购买数量;
double XStartDepo = StartDepo; int Profit=0; int Loss=0;
为了在 MetaTrader 5 中跟踪开仓时间,并在时间到期后平仓,我们将调用返回开仓时间的函数。
//+------------------------------------------------------------------+ //| Get open time in positions | //+------------------------------------------------------------------+ datetime GetTime(string symb="0", int type=-1, int mg=-1,int index=0) { datetime p[]; int c=-1, pr=0; if(symb=="0") { symb=Symbol();} for(int i=PositionsTotal()-1;i>=0;i--){ if(position.SelectByIndex(i)) { if(position.PositionType()==POSITION_TYPE_BUY || position.PositionType()==POSITION_TYPE_SELL) { if((position.Symbol()==symb||symb=="")&&(type<0||position.PositionType()==type)&&(mg<0||position.Magic()==mg)) { c++; ArrayResize(p, c+1); p[c]=position.Time(); pr=c>=index?index:c; }}}} return(c==-1?0:p[pr]); }
为了跟踪持仓的盈利能力,并决定我们是否赢得了赌注,我们将调用一个函数来返回持仓于当前时间的利润。 佣金和掉期利率此刻不被考虑在内。
//+------------------------------------------------------------------+ //| Get profit in positions | //+------------------------------------------------------------------+ double GetProfit(string symb="0", int type=-1, int mg=-1,int index=0) { double p[]; int c=-1, pr=0; if(symb=="0") { symb=Symbol();} for(int i=PositionsTotal()-1;i>=0;i--){ if(position.SelectByIndex(i)) { if(position.PositionType()==POSITION_TYPE_BUY || position.PositionType()==POSITION_TYPE_SELL) { if((position.Symbol()==symb||symb=="")&&(type<0||position.PositionType()==type)&&(mg<0||position.Magic()==mg)) { c++; ArrayResize(p, c+1); p[c]=position.Profit(); pr=c>=index?index:c; }}}} return(c==-1?0:p[pr]); }
应用若干个触发器,以便仅处理新传入的信号。 换言之,只有当有新信号时,才允许入场。 在同一信号上的重复入场将被忽略:
- TrigerSell - 买入看跌期权;
- TrigerBuy - 买入看涨期权;
int TrigerSell=0; int TrigerBuy=0;
持仓离场、在初始资金基础上增/减资金,以及计算所购期权的盈亏,均通过跟踪持仓的当前时间至和到期时间来贯彻。
//Sell (Put) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
为了进行优化,使用变量来判定所需的时间帧和到期时间。 优化模式依据 Optimization 变量启用。 优化的本质来自 CSV 等文件的运用。 在 OnDeinit 中完成测试后,将所有必要的变量写入文件。优化时,EA 创建一个存储结果的 CSV 文件,位于 “C:\Users\您的登录名\AppData\Roaming\MetaQuotes\Terminal\Common\Files”。
- 最终资金;
- 盈利交易数量;
- 亏损交易数量;
- 时间帧·;
- 到期时间。
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if (Optimization==true){ if (FileIsExist(OptimizationFileName)==false){ filehandle = FileOpen(OptimizationFileName,FILE_WRITE|FILE_READ|FILE_CSV|FILE_COMMON|FILE_ANSI, ";"); if(filehandle!=INVALID_HANDLE) { FileSeek(filehandle, 0, SEEK_END); FileWrite(filehandle,DoubleToString(XStartDepo),IntegerToString(Profit),IntegerToString(Loss),IntegerToString(XTimeFrame),IntegerToString(XExpirationTime)); FileClose(filehandle); } } } }
您可以在可视化模式下观查测试。 为简单起见,我们调用 Comment() 显示当前结果。
策略
2Ma+RSI+Stochastic 振荡器策略
该策略由一家知名经纪商提供,作为二元期权的剥头皮策略。 策略的建议时间帧为 5 分钟。 过期时间为 5 分钟。
指标:
- 一对周期为 5 和 10 的指数移动平均线;
- RSI,默认设置;
- Stochastic 振荡器,设置参数值 14, 3, 3。
满足多个条件时的“上涨”信号(或买入看涨期权):
- 红色移动平均线向上穿过蓝色移动平均线;
- RSI 高于 50;
- Stochastic 的快速指标线向上穿过慢速指标线(虚线)。
- 红色 MA 向下穿过蓝色 MA;;
- RSI 指数位于 50 以下;
- Stochastic 振荡器的快速线向下穿过慢速线。
//Sell (Put) if((ind_In1S1[1]>ind_In2S1[1]) && (ind_In1S1[2]>ind_In2S1[2])){TrigerSell=1;} if ((TrigerSell==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (ind_In1S1[1]<ind_In2S1[1]) && (ind_In1S1[0]<ind_In2S1[0]) && (ind_In4S1[1]<50) && (ind_In4S1[0]<50) && (ind_In3S1_1[1]<ind_In3S1_2[1])){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerSell=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if((ind_In1S1[1]<ind_In2S1[1]) && (ind_In1S1[2]<ind_In2S1[2])){TrigerBuy=1;} if ((TrigerBuy==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (ind_In1S1[1]>ind_In2S1[1]) && (ind_In1S1[0]>ind_In2S1[0]) && (ind_In4S1[1]>50) && (ind_In4S1[0]>50) && (ind_In3S1_1[1]>ind_In3S1_2[1])){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerBuy=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
该测试产生以下结果:
- 最终资金 1964;
- 盈利交易 1273;
- 亏损交易 1822。
优化后,我们得到结果。 正如我们所见,我们的资金在任何时间帧和到期时间都没有增加。
Maverick 策略
这是一个有趣而简单的期权策略,名为 Maverick。 它基于两个技术分析指标。 据说可以非常准确地判定入场和离场交易点。 交易的时间帧为 1-5 分钟。 为了接收更多信号,我们可以同时打开多个含有不同资产的图表。
指标:
- 布林带 20 和 StDev(标准偏差)2;
- RSI 指标。 RSI 参数 – 周期 4,边界为 80 和 20。
增长预测。 买入看涨期权:
一旦 RSI 指标线进入 20 以下的超卖区域,而价格线触及或超过布林带,等待第一根看涨蜡烛,并入场进行向上交易。
下跌预测。 买入看跌期权:
在 RSI 指标线进入 80 以上的超买区域,并且价格线已经超过布林指标的上限后,等待第一根看跌蜡烛,并进行向下交易。
我选择在布林指标通道内收盘前一根蜡烛作为新的信号触发器。 策略代码如下所示。
//Sell (Put) if(iClose(symbolS1.Name(),XTimeFrame,1)<ind_In1S1_1[1]){TrigerSell=1;} if ((TrigerSell==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (iClose(symbolS1.Name(),XTimeFrame,2)>ind_In1S1_1[2]) && (ind_In2S1[2]>80) && (iClose(symbolS1.Name(),XTimeFrame,1)<iOpen(symbolS1.Name(),XTimeFrame,1))){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerSell=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if(iClose(symbolS1.Name(),XTimeFrame,1)>ind_In1S1_2[1]){TrigerBuy=1;} if ((TrigerBuy==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (iClose(symbolS1.Name(),XTimeFrame,2)<ind_In1S1_2[2]) && (ind_In2S1[2]<20) && (iClose(symbolS1.Name(),XTimeFrame,1)>iOpen(symbolS1.Name(),XTimeFrame,1))){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerBuy=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
我们开始检查。 我们先在 M5 上进行测试。 得到的结果:
- 最终资金 3312;
- 盈利交易 1589;
- 亏损交易 1940。
我们经历了亏损。 虽然结果比以前的策略略好。 我们执行优化,希望能赚取正数值的金额。 唉,该策略未起作用:
Vortex+TSI 策略
二元期权的策略被称为 Vortex,这是因为选用了同名指标。 事实上,该策略涉及两个指标 — 主要指标,以及作为过滤器的第二个指标。 建议的时间帧是 1-5 分钟。
指标:
- Vortex 14;
- 真实强度指标 (TSI) 25, 13, 5, 指数。
对于购买看涨期权:
- 等待两个指标线同时彼此相交,当蓝线在顶部,红色线下降时;
- Vortex 指标线应发散。
对于购买看跌期权:
- 等待两个指标的线同时彼此相交,当红线在顶部,蓝色线下降;
- Vortex 指标线应发散。
//Sell (Put) if(ind_In1S1_1[1]>ind_In1S1_2[1]){TrigerSell=1;} if ((TrigerSell==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (ind_In1S1_1[0]<ind_In1S1_2[0]) && (ind_In1S1_1[1]<ind_In1S1_2[1]) && (ind_In2S1_1[0]<ind_In2S1_2[0]) && (ind_In2S1_1[1]<ind_In2S1_2[1]) && (ind_In2S1_1[0]<ind_In2S1_1[1]) && (ind_In2S1_2[0]>ind_In2S1_2[1]) && (ind_In2S1_1[1]<ind_In2S1_1[2]) && (ind_In2S1_2[1]>ind_In2S1_2[2])){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerSell=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if(ind_In1S1_1[1]<ind_In1S1_2[1]){TrigerBuy=1;} if ((TrigerBuy==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (ind_In1S1_1[0]>ind_In1S1_2[0]) && (ind_In1S1_1[1]>ind_In1S1_2[1]) && (ind_In2S1_1[0]>ind_In2S1_2[0]) && (ind_In2S1_1[1]>ind_In2S1_2[1]) && (ind_In2S1_1[0]>ind_In2S1_1[1]) && (ind_In2S1_2[0]<ind_In2S1_2[1]) && (ind_In2S1_1[1]>ind_In2S1_1[2]) && (ind_In2S1_2[1]<ind_In2S1_2[2])){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerBuy=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
是时候开始测试我们的指标策略了。 我们先在 M5 上进行测试。 得到的结果:
- 最终资金 -3118;
- 盈利交易 1914;
- 亏损交易 2843。
亏损交易的数量更多。 最终资金额为负数。 或许优化会有所帮助。
优化结果不言自明:
在测试了大约 10 种不同的策略,但均未得到满意的预期结果后,我决定开发自己的策略。 根据获得的经验,我决定尝试一种不同的方法。 该策略名为“新建”。
新建 策略
我将利用超卖和超买状况作为策略的核心部分。 我还决定添加摊平操作。 虽然我反对这样的决策,但看看结果仍然很有趣。
指标:
轨道线 14, 0, 0,1 简单平均 方法应用于 收盘价.
“向上”信号或买入看涨期权:
- 要价(Ask)小于轨道线指标的下边线;
- 从轨道线指标的底线到要价(Ask)的距离(以点为单位)大于 Distance 参数值。
“向下”信号或买入看跌期权:
- 出价(Bid)高于轨道线指标的上边线;
- 从轨道线指标的底线到出价(Bid)的距离(以点为单位)大于 Distance 参数值。
策略中不使用触发器。 如果满足条件,且无持仓,则会持续监控新的入场信号。 以下是未采用摊平操作的策略代码
//Sell (Put) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (BidS1>(ind_In1S1_1[0]+(Distance*PointS1)))){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (AskS1<(ind_In1S1_2[0]-(Distance*PointS1)))){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
我们在 M5 上进行测试。 Distance=150。 下面的屏幕截图中是未采用摊平操作的测试结果
亏损交易 804。
可盈利的项目比无盈利的项目多,但我们仍损失了部分资金。 这是负面的期望。 采用这种方法时,连续输掉的最大项目序列是两次,那么我认为运用摊平方式会对我们有利。在下面的屏幕截图中是未采用摊平方式的优化结果。 为了方便和清晰起见,决定在报告中仅包括有盈利的情况:
我们来加入摊平操作。 我决定限制摊平操作的项目数量。 为此,我引入了一个新参数 Averageaging,默认情况下为 4。 摊平策略代码如下:
//Sell (Put) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (BidS1>(ind_In1S1_1[0]+(Distance*PointS1)))){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); Print(((XOptionRate*LossIn)*LossIn)); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+(((XOptionRate*LossIn)*ProfitPercent)/100); Profit++; LossIn=1; } else{ XStartDepo=XStartDepo-(XOptionRate*LossIn); Loss++; LossIn++; if(LossIn>Averaging){LossIn=1;} } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (AskS1<(ind_In1S1_2[0]-(Distance*PointS1)))){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); Print(((XOptionRate*LossIn)*LossIn)); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+(((XOptionRate*LossIn)*ProfitPercent)/100); Profit++; LossIn=1; } else{ XStartDepo=XStartDepo-(XOptionRate*LossIn); Loss++; LossIn++; if(LossIn>Averaging){LossIn=1;} } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
摊平操作测试结果。 最终,成功。
摊平操作优化结果:
一个更有趣的选择的结果,在亏损交易后乘以倍增率。 代码提供如下:
//Sell (Put) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (BidS1>(ind_In1S1_1[0]+(Distance*PointS1)))){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); Print(((XOptionRate*LossIn)*LossIn)); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((((XOptionRate*LossIn)*LossIn)*ProfitPercent)/100); Profit++; LossIn=1; } else{ XStartDepo=XStartDepo-((XOptionRate*LossIn)*LossIn); Loss++; LossIn++; if(LossIn>Averaging){LossIn=1;} } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (AskS1<(ind_In1S1_2[0]-(Distance*PointS1)))){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); Print(((XOptionRate*LossIn)*LossIn)); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((((XOptionRate*LossIn)*LossIn)*ProfitPercent)/100); Profit++; LossIn=1; } else{ XStartDepo=XStartDepo-((XOptionRate*LossIn)*LossIn); Loss++; LossIn++; if(LossIn>Averaging){LossIn=1;} } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
经优化的有趣变体的结果:
结束语
从所做的所有工作中可以得出什么结论? 99% 的指标策略实际上不起作用。 通过稍微改变方法,可以制定良好的盈利策略。 有必要在入场之前检查所有东西。 与往常一样,MetaTrader 5 将帮助我们解决这个问题。顺便说一句,已有了 100% 盈利能力的选项,这可作为额外思考的养料。您可从附件中下载以智能系统形式实现的所有研究过的策略。
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/12103
![MQL5 中的范畴论 (第 2 部分)](https://c.mql5.com/2/51/Category-Theory-avatar-002.png)
![如何选择智能系统:拒绝一款交易机器人的 20 条强大准则](https://c.mql5.com/2/0/Avatar_Twenty_strong_criteria_to_reject_a_trading_bot.png)
![MQL5 酷宝书 — 宏观经济事件数据库](https://c.mql5.com/2/51/mql5-recipes-database.png)