在 MetaTrader 5 中测试和优化二元期权策略

文章介绍了二元期权的基本概念、类型及优缺点,并探讨了如何使用MetaTrader5平台进行策略测试和优化。作者提供了两个具体的交易策略——2Ma+RSI+Stochastic振荡器策略和Maverick策略,并分享了测试结果和优化过程。
摘要由CSDN通过智能技术生成

概述

最近,我对二元期权产生了兴趣。 在网上冲浪,并查看了一些经纪商之后,发现几乎大多人都在他们的平台进行交易。 这些平台没有测试策略的能力,充其量只有一套浅薄的标准指标。 在审查了大量不同的二元期权策略后,我开始琢磨如何验证这些策略及其优化。 和往常一样,我们心爱的 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%。

技术方面

我们需要用于测试和优化的输入:

  1. StartDepo  - 启动资金;
  2. OptionRate - 比率;
  3. ExpirationTime - 到期时间;
  4. ProfitPercent - 盈利百分比;
  5. TimeFrame - 指标时间帧;
  6. Optimization - 优化开关;
  7. 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";

我们还需要变量来存储和跟踪资金,以及可盈利和无盈利期权购买数量的变化:

  1. XStartDepo - 存储当前资金;
  2. Profit - 存储可盈利期权购买数量;
  3. 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]);
 }

应用若干个触发器,以便仅处理新传入的信号。 换言之,只有当有新信号时,才允许入场。 在同一信号上的重复入场将被忽略:

  1. TrigerSell - 买入看跌期权;
  2. 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”。

  1. 最终资金;
  2. 盈利交易数量;
  3. 亏损交易数量;
  4. 时间帧·;
  5. 到期时间。
//+------------------------------------------------------------------+
//| 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 分钟。

指标:

  1. 一对周期为 5 和 10 的指数移动平均线;
  2. RSI,默认设置;
  3. Stochastic 振荡器,设置参数值 14, 3, 3。

满足多个条件时的“上涨”信号(或买入看涨期权):

  1. 红色移动平均线向上穿过蓝色移动平均线;
  2. RSI 高于 50;
  3. Stochastic 的快速指标线向上穿过慢速指标线(虚线)。

如果存在某些因素,则形成“下降”信号(买入看跌期权):

  1. 红色 MA 向下穿过蓝色 MA;;
  2. RSI 指数位于 50 以下;
  3. Stochastic 振荡器的快速线向下穿过慢速线。

我选择了相反方向的 MA 交点作为这个新信号策略的触发器。 策略代码如下所示。

//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 分钟。 为了接收更多信号,我们可以同时打开多个含有不同资产的图表。

指标:

  1. 布林带 20 和 StDev(标准偏差)2;
  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 分钟。

指标:

  1. Vortex 14;
  2. 真实强度指标 (TSI) 25, 13, 5, 指数。

对于购买看涨期权:

  1. 等待两个指标线同时彼此相交,当蓝线在顶部,红色线下降时;
  2. Vortex 指标线应发散。

对于购买看跌期权:

  1. 等待两个指标的线同时彼此相交,当红线在顶部,蓝色线下降;
  2. Vortex 指标线应发散。

真实强度指示器的反向交叉用作新的信号触发。 策略代码如下所示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值