文章 "轻松快捷开发 MetaTrader 程序的函数库(第二十六部分):处理延后交易请求 - 首次实现(开仓)"

 

新文章 轻松快捷开发 MetaTrader 程序的函数库(第二十六部分):处理延后交易请求 - 首次实现(开仓)已发布:

在本文中,我们将在订单和仓位的魔幻数字中存储一些数据,并开始实现延后请求。 为了验证这一概念,我们在收到服务器错误并需要等待与重复发送请求时,创建第一个测试延后请求来开仓。

编译并启动 EA。 断开互联网,然后等待以下图像出现在终端的右下角:



禁用互联网并单击“卖出”后,交易服务器返回错误,且日志中显示以下记录:

2019.11.26 15:34:48.661 CTrading::OpenPosition<uint,uint>: Invalid request:
2019.11.26 15:34:48.661 No connection with the trade server
2019.11.26 15:34:48.661 Correction of trade request parameters ...
2019.11.26 15:34:48.661 Trading attempt #1. Error: No connection with the trade server


收到错误后,函数库会采用未成功开立空头持仓的参数集合来创建延后请求。
延后请求还具有尝试次数和 20 秒的等待时间。

然后启用互联网,恢复与交易服务器的连接:


连接一旦恢复后,函数库将立即处理延后请求,并将其发送到服务器。 结果则为,我们成功开仓,且日志里也有记录:

2019.11.26 15:35:00.853 CTrading::OpenPosition<double,double>: Invalid request:
2019.11.26 15:35:00.853 Trading is prohibited for the current account
2019.11.26 15:35:00.853 Correction of trade request parameters ...
2019.11.26 15:35:00.853 Trading operation aborted
2019.11.26 15:35:01.192 CTrading::OpenPosition<double,double>: Invalid request:
2019.11.26 15:35:01.192 Trading is prohibited for the current account
2019.11.26 15:35:01.192 Correction of trade request parameters ...
2019.11.26 15:35:01.192 Trading operation aborted
2019.11.26 15:35:01.942 - Position is open: 2019.11.26 10:35:01.660 -
2019.11.26 15:35:01.942 EURUSD Opened 0.10 Sell #486405595 [0.10 Market-order Sell #486405595] at price 1.10126, sl 1.10285, tp 1.09985, Magic number 17629307 (123), G1: 13
2019.11.26 15:35:01.942 OnDoEasyEvent: Position is open


如我们所见,在交易服务器恢复连接后,当前帐户能够延迟交易
但无论如何,延后请求只是玩了把戏
...

此外,我们可以在日志中看到实际的魔幻数字 17629307,然后在括号(123)中是 EA 设置中定义的魔幻数字,再加上另一个记录 G1: 13 表示第一个组 ID 等于13,而第二个组 ID 缺失 — 其值实际上为零,因此没有第二个含有 G2: XX 的记录。

请注意:

作者:Artyom Trishkin

 
您好!我下载了最新版本的库和 Expert Part_26,在测试仪上设置了可视模式,市场订单已打开,但所有挂单均未打开。

市场订单已打开,但所有挂单均未打开。

交换符号,经纪人 Otkritie,版本 5.00 建 2190。

 
Alexander:
您好!我下载了最新版本的库和 Expert Part_26,在测试仪上设置了可视模式和市场模式。

订单已打开,但所有挂单均未打开。

交易所符号,经纪人 Otkritie,版本 5.00 build 2190。

交易、自动交易系统和交易策略测试论坛

讨论文章 "方便快捷地创建 MetaTrader 程序库(第二十五部分):处理交易服务器返回的错误"

Artyom Trishkin, 2019.11.28 09:39 AM

在这个版本的程序库中,以及在下一个版本中,我漏掉了对订单成交类型和订单到期类型的检查。在下一篇(27)文章中会有更正。

目前,我建议在发送交易请求时,应明确指定到期类型。例如,要下限价卖出挂单,需要在测试智能交易系统中添加该 挂单:

//--- 如果按下 BUTT_SELL_LIMIT 按钮: 设置卖出上限
else if(button==EnumToString(BUTT_SELL_LIMIT))
  {
   //--- 设置限价卖出订单
   engine.PlaceSellLimit(lot,Symbol(),distance_pending,stoploss,takeprofit,magic,TextByLanguage("待沽限额","Pending order SellLimit"),0,ORDER_TIME_DAY);
  }

并在所有包含设置挂单 方法调用的行中执行相同操作。


 
是的,谢谢,就是这样。
 
//--- 数据在神奇数字ber int 值中的位置
      //-----------------------------------------------------------
      // 位 32|31 24|2316|15 8|7 0|
      //-----------------------------------------------------------
      // byte | 3 | 2| 1 | 0 |
      //-----------------------------------------------------------
      // data | uchar | uchar| ushort
      //-----------------------------------------------------------
      // descr |pend req id| id2 | id1 | magic |
      //----------------------------------------------------------- 
//--- 返回(1)指定的魔术号码器、(2)第一组的 ID、(3)第二组的 ID、(4)魔术号码器的待处理请求值
   ushort            GetMagicID(void)                                const { return ushort(this.Magic() & 0xFFFF);                                 }
   uchar             GetGroupID1(void)                               const { return uchar(this.Magic()>>16) & 0x0F;                                }
   uchar             GetGroupID2(void)                               const { return uchar((this.Magic()>>16) & 0xF0)>>4;                           }
   uchar             GetPendReqID(void)                              const { return uchar(this.Magic()>>24) & 0xFF;                                }

有一个从数字中提取比特的便捷函数

//--- 提取第 k 个比特位置上的 cnt 比特
   uint              _getBits(const uint number,uint pos,uint cnt=1) const { return (number >> pos) & ((1 << cnt) - 1);                            }
      
   ushort            GetMagicID(void)                                const { return ushort(_getBits(this.Magic(),0,16));                           }
   uchar             GetGroupID1(void)                               const { return uchar(_getBits(this.Magic(),16,4));                            }
   uchar             GetGroupID2(void)                               const { return uchar(_getBits(this.Magic(),20,4));                            }
   uchar             GetPendReqID(void)                              const { return uchar(_getBits(this.Magic(),24,8));                            }
 
amrali:

有一个从数字中提取比特的便捷函数

谢谢
 
库中是否有打开即时市场执行 的实现方法?
 
iabbott:
库中是否有打开即时市场执行 的功能?
 

能否请您告诉我,您是通过哪种方法对挂单请求中的编码魔法进行解码的?

在开仓时出错(资金不足),然后触发挂单请求后,我创建了一个魔法完全不同的仓位(显然是编码的那个)。

在哪里解码?我想要一个原生的马吉克,而不是一个新的。

 
void CTradingControl::OnPReqByErrCodeHandler()

这里应该调用返回原始魔力的方法。那是什么方法? GetMagicID()?

 
//+------------------------------------------------------------------+
//| 以点为单位返回订单利润|
//+------------------------------------------------------------------+
int COrder::ProfitInPoints(void) const
  {
   MqlTick tick={0};
   string symbol=this.Symbol();
   if(!::SymbolInfoTick(symbol,tick))
      return 0;
   ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)this.TypeOrder();
   double point=::SymbolInfoDouble(symbol,SYMBOL_POINT);
   if(type==ORDER_TYPE_CLOSE_BY || point==0) return 0;
   if(this.Status()==ORDER_STATUS_HISTORY_ORDER)
      return int(type==ORDER_TYPE_BUY ? (this.PriceClose()-this.PriceOpen())/point : type==ORDER_TYPE_SELL ? (this.PriceOpen()-this.PriceClose())/point : 0);
   else if(this.Status()==ORDER_STATUS_MARKET_POSITION)
     {
      if(type==ORDER_TYPE_BUY)
         return int((tick.bid-this.PriceOpen())/point);
      else if(type==ORDER_TYPE_SELL)
         return int((this.PriceOpen()-tick.ask)/point);
     }
   else if(this.Status()==ORDER_STATUS_MARKET_PENDING)
     {
      if(type==ORDER_TYPE_BUY_LIMIT || type==ORDER_TYPE_BUY_STOP || type==ORDER_TYPE_BUY_STOP_LIMIT)
         return (int)fabs((tick.bid-this.PriceOpen())/point);
      else if(type==ORDER_TYPE_SELL_LIMIT || type==ORDER_TYPE_SELL_STOP || type==ORDER_TYPE_SELL_STOP_LIMIT)
         return (int)fabs((this.PriceOpen()-tick.ask)/point);
     }
   return 0;
  }

为什么没有计算 ORDER_STATUS_DEAL 类型?

一般来说,不清楚如何获得平仓交易或头寸的利润点数......
而且总是 0:

deal_profit_pts=(int)deal.GetProperty(ORDER_PROP_PROFIT_PT)