欢迎光临散文网 会员登陆 & 注册

量化交易软件:交易机器人在市场发布前必须经过的检验

2023-07-25 13:59 作者:bili_45793681098  | 我要投稿

怎样快速捕捉和修复交易机器人中的错误

平台中集成的策略测试器不仅允许回测交易系统,而且可以用于发现交易机器人开发过程中的逻辑和算法错误,在测试中,所有有关交易操作的消息以及发现的错误都输出在测试器的日志(Journal)中。使用特别的记录阅读器就可以很方便地分析这些消息, 它可以使用上下文菜单的命令调用出来。

编辑搜图

在EA交易的测试之后,打开阅读器并启用"只显示错误(Error only)"模式,如上图所示。如果您的交易机器人包含错误,您就能立即看到它们。如果第一次没有侦测到错误,可以在不同的交易品种/时段/输入参数以及不同数量的初始存款情况下进行一系列的测试。使用这些简单的技巧可以发现 99% 的错误,并且赫兹量化会在本文中讨论它们。

赫兹量化可以使用在 MetaEditor 中的在历史数据上做调试的功能来仔细研究发现的错误,通过这个方法,赫兹量化可以使用可视化测试模式,不仅监控价格图表和使用的指标,也能跟踪程序在每个时刻的变量数值。这样,您就能够调试您的交易策略了,而不必在实时模式下花费很长时间。

资金不足以进行交易操作

在发送每个交易订单之前,需要检查账户是否有足够的资金,缺乏资金以进行未来的建仓或者订单会被认为是疏忽大意的。

请一定要记住就算设置一个挂单也可能会要求担保 — 保证金。

编辑搜图


赫兹量化推荐特意使用很小的初始存款来测试交易机器人,例如,1美元或者1欧元。

如果检查显示,资金不足以进行交易操作,就有必要在记录中输出一个错误消息而不是调用 OrderSend() 函数。检验实例:

MQL5

bool CheckMoneyForTrade(string symb,double lots,ENUM_ORDER_TYPE type)
  {//--- 取得建仓价格   MqlTick mqltick;
   SymbolInfoTick(symb,mqltick);
   double price=mqltick.ask;
   if(type==ORDER_TYPE_SELL)
      price=mqltick.bid;//--- 所需以及可用保证金的数值   double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
   //--- 调用检验函数   if(!OrderCalcMargin(type,symb,lots,price,margin))
     {
      //--- 出错了,发送报告并返回 false      Print("有错误出现在 ",__FUNCTION__," 编号=",GetLastError());
      return(false);
     }
   //--- 如果资金不够进行操作   if(margin>free_margin)
     {
      //--- 报告错误并返回 false      Print("资金不足以进行 ",EnumToString(type)," ",lots," ",symb," 错误编号=",GetLastError());
      return(false);
     }//--- 检验成功   return(true);
  }

MQL4

bool CheckMoneyForTrade(string symb, double lots,int type)
  {
   double free_margin=AccountFreeMarginCheck(symb,type, lots);
   //-- 如果资金不够   if(free_margin<0)
     {
      string oper=(type==OP_BUY)?"买入":"卖出";
      Print("资金不足以进行", oper," ",lots, " ", symb, " 错误编号",GetLastError());
      return(false);
     }
   //--- 检验成功   return(true);
  }


交易操作中的无效交易量

在发送交易订单之前,也有必要检查在订单中指定的交易量的正确性,EA交易中订单设置的手数必须在调用 OrderSend() 函数之前进行检查,交易品种所允许的最小和最大交易量,以及交易量之间的步长是在规格说明中指定的。在 MQL5 中, 这些数值可以通过ENUM_SYMBOL_INFO_DOUBLE 枚举,在SymbolInfoDouble()函数的帮助下获得。

SYMBOL_VOLUME_MIN

交易的最小交易量

SYMBOL_VOLUME_MAX

交易的最大交易量

SYMBOL_VOLUME_STEP

执行交易时最小的交易量变化步长

检查交易量正确性函数的实例

//+------------------------------------------------------------------+//| 检查订单交易量的正确性                                               |//+------------------------------------------------------------------+bool CheckVolumeValue(double volume,string &description)
  {//--- 交易操作允许的最小交易量   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
     {
      description=StringFormat("交易量小于允许的最小交易量,SYMBOL_VOLUME_MIN=%.2f",min_volume);
      return(false);
     }//--- 交易操作允许的最大交易量    double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
     {
      description=StringFormat("交易量大于允许的最大交易量,SYMBOL_VOLUME_MAX=%.2f",max_volume);
      return(false);
     }//--- 取得交易量变化的最小步长   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
     {
      description=StringFormat("交易量不是最小交易步长的整数倍,SYMBOL_VOLUME_STEP=%.2f, 最接近的正确交易量是 %.2f",
                               volume_step,ratio*volume_step);
      return(false);
     }
   description="正确的交易量数值";
   return(true);
  }


挂单的限制数量

账户中允许同时设置的活动挂单的数量可能也会有所限制。IsNewOrderAllowed() 函数的实例, 它用来检查是否还允许继续设置挂单。

//+------------------------------------------------------------------+//| 检查是否还允许设置订单                                               |//+------------------------------------------------------------------+bool IsNewOrderAllowed()
  {//--- 取得账户中允许设置的挂单数量   int max_allowed_orders=(int)AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);//--- 如果没有限制,返回 true; 您可以发送一个订单   if(max_allowed_orders==0) return(true);//--- 如果我们达到这一行,说明有限制; 找出已经设置了多少挂单   int orders=OrdersTotal();//--- 返回比较结果   return(orders<max_allowed_orders);
  }

这个函数很简单: 取得允许的最大订单数并赋予max_allowed_orders变量; 如果它不等于0,把它与当前订单数量做比较。但是,这个函数没有考虑到另外的可能的限制 - 对某一特定交易品种开启仓位总交易量的限制和挂单数量的限制。


某特定交易品种的手数限制

为了取得某一特定交易品种的开启仓位的总交易量,首先您需要使用PositionSelect()函数来选择一个仓位,之后您就可以使用PositionGetDouble()来得到已建仓位的交易量, 它可以返回双精度类型的所选仓位的各种属性。让我们写一个 PostionVolume() 函数来取得所需交易品种的仓位交易量。

//+------------------------------------------------------------------+//| 返回指定交易品种的仓位大小                                            |//+------------------------------------------------------------------+double PositionVolume(string symbol)
  {//--- 尝试根据交易品种选择仓位   bool selected=PositionSelect(symbol);//--- 有仓位   if(selected)
      //--- 返回仓位交易量      return(PositionGetDouble(POSITION_VOLUME));
   else     {
      //--- 选择仓位出错报告      Print(__FUNCTION__," 执行 PositionSelect() 失败,交易品种为 ",
           symbol," 错误编号 ",GetLastError());
      return(-1);
     }
  }

对于支持对冲的账户,还需要迭代当前交易品种所有的仓位。

在根据交易品种生成交易请求以设置挂单之前, 您应该检查在一个交易品种上的已开启仓位和挂单总交易量的限制 - SYMBOL_VOLUME_LIMIT,如果没有限制,那么挂单的总交易量不能超过使用SymbolInfoDouble()得到的最大交易量。



量化交易软件:交易机器人在市场发布前必须经过的检验的评论 (共 条)

分享到微博请遵守国家法律