程序库: MT4Orders - 页 16

 

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

mql4语言的特点、精妙之处和工作技巧

fxsaber, 2017.09.11 20:29

下面将触及的主题,不仅涉及 MT4,还涉及 MT5 与其他平台。但为了便于理解,逻辑将在 MQL4 中编写,因此在本主题中。

与库直接相关的讨论。

 

在 MQL5 中出现 "原因 "标志之前,论坛上未结头寸的 SL/TP/SO 水平时,就会生成相应的市场订单,该订单在 MT5 的未结订单表中,直到执行为止。


因此,在 MT5 中,即使是纯 MQL5,也不可能修改/删除此类订单,MT5 交易逻辑要求检查未结订单是否实际冻结。


以下是在 MT4Orders 上编写交易逻辑时识别此类订单的条件及其触发示例

// 触发 SL/TP/SO
void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest &Request, const MqlTradeResult &Result )
{ 
  if ((Trans.type == TRADE_TRANSACTION_ORDER_ADD) && OrderSelect(Trans.order))
  {
    const ENUM_ORDER_REASON Reason = (ENUM_ORDER_REASON)OrderGetInteger(ORDER_REASON);
    
    if (Reason == ORDER_REASON_TP)
      Print("Position #" + (string)Trans.position + " - triggered TP.");    
    else if (Reason == ORDER_REASON_SL)
      Print("Position #" + (string)Trans.position + " - triggered SL.");    
    else if (Reason == ORDER_REASON_SO)
      Print("Position #" + (string)Trans.position + " - triggered StopOut.");    
  }
}

#include <MT4Orders.mqh>

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnInit()
{
  EventSetMillisecondTimer(1);
  
  OrderSend(_Symbol, OP_BUY, 1, Ask, 100, Bid - _Point, Ask + _Point);    
}

// 显示当前 MT5 未结订单表中存在 SL/TP/SO 订单
void OnTimer()
{
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) &&
        (OrderCloseReason() >= (int)ORDER_REASON_SL)) // 如果触发此条件,则无法修改/删除订单!
    {
      OrderPrint();
      
      const long Position = OrderGetInteger(ORDER_POSITION_ID); // 有可能,因为 MT4Orders 已配置为与 MQL5 交易应用程序接口并行工作
      
      const ENUM_ORDER_REASON Reason = (ENUM_ORDER_REASON)OrderCloseReason();
      
      if (Reason == ORDER_REASON_TP)
        Print("Position #" + (string)Position + " - in the process of execution TP.");    
      else if (Reason == ORDER_REASON_SL)
        Print("Position #" + (string)Position + " - in the process of execution SL.");    
      else if (Reason == ORDER_REASON_SO)
        Print("Position #" + (string)Position + " - in the process of execution StopOut.");
    }
}


结果

2017.09.14 09:35:11.565 Position #1060283 - triggered TP.
2017.09.14 09:35:11.575 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.575 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.595 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.595 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.607 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.607 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.617 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.617 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.637 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.637 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.657 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.657 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.667 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.667 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.680 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.680 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.700 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.700 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.710 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.710 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.730 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.730 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.757 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.757 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.760 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.760 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.780 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.780 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.790 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.790 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.810 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.810 Position #1060283 - in the process of execution TP.
2017.09.14 09:35:11.820 #1060284 2017.09.14 09:36:14 sell 1.00 EURUSD 1.18838 0.00000 0.00000 1.18838 0.00 0.00 0.00 [tp 1.18838] 0
2017.09.14 09:35:11.820 Position #1060283 - in the process of execution TP.


您可以看到,TP 订单在未结订单中悬挂超过四分之一秒。任何修改/删除该订单的尝试都会导致错误。

请考虑 MT5 的这一功能(不仅在使用 MT4Orders 时)。

 
fxsaber:

在 MQL5 中出现 "原因 "标志之前,论坛上未结头寸的 SL/TP/SO 水平时,就会生成相应的市场订单,该订单在 MT5 的未结订单表中,直到执行为止。


因此,在 MT5 中,即使是纯 MQL5,也不可能修改/删除此类订单,MT5 交易逻辑要求检查未结订单是否实际冻结。

以下是在 MT4Orders 上编写交易逻辑时识别此类订单的条件 及其触发示例

您可以看到 TP 订单在未结订单中悬挂了超过四分之一秒。任何修改/删除的尝试都会导致错误。

请将 MT5 的这一功能考虑在内(不仅是在使用 MT4Orders 时)。

现在库中已内置此条件检查功能,您可以像在 MT4 中一样工作

// 更改列表:
// 14.09.2017:
// 修复:现在,程序库无法查看当前未处于 ORDER_STATE_PLACED 状态的 MT5 订单。.
// 为了让程序库看到所有 MT5 未结订单,必须在程序库之前写入以下一行
//
// #define MT4ORDERS_SELECTFILTER_OFF // 使 MT4Orders.mqh 查看当前所有 MT5 订单
 
有必要在 mt5 中创建如此多的仓位/订单,在其他任何平台中,我都没有遇到过如此多的仓位/订单 )
 
Maxim Dmitrievsky:
我从未在任何其他平台上见过这样的多样性)。

ORDER_STATE 参数的作用更大。对于 SL/TP 订单,它是ORDER_STATE_STARTED。但绝不能忽略所有 ORDER_STATE_STARTED(解释起来需要很长时间)。这就是为什么依赖 ORDER_STATE 是错误的,而需要 ORDER_REASON。

ORDER_STATE 是另一回事。假设一个仓位部分由挂单开立,而其余订单仍挂着。那么历史记录中就会出现一笔交易,但订单本身还没有出现。如果该订单随后完全成交,那么要了解它所产生的第一笔交易是部分开仓,就不能查看该订单的 ORDER_STATE。


总之,有很多情况下都会出现这种 STATE 实际上.....我们必须引入人性化的 OrderOpenState() 和 OrderCloseSate(),但这很头疼(而且只有少数人会用)。当然,这还是一个简单的谜题。它们有很多,有些甚至没有被怀疑过。总而言之,能够在几乎不降低工作效率的情况下,将部分谜题解出工作状态和人类形态,已经很不错了。我认为,图书馆满足了一半以上的需求。

 
fxsaber:

ORDER_STATE 参数的作用更大。对于 SL/TP 订单,它是ORDER_STATE_STARTED。但绝不能忽略所有 ORDER_STATE_STARTED(解释起来需要很长时间)。这就是为什么依赖 ORDER_STATE 是错误的,而需要 ORDER_REASON。

ORDER_STATE 是另一回事。假设一个仓位部分由挂单开立,而其余订单仍挂着。那么历史记录中就会出现一笔交易,但订单本身还没有出现。如果该订单随后完全成交,那么要了解它所产生的第一笔交易是部分开仓,就不能查看该订单的 ORDER_STATE。


总之,有很多情况下都会出现这种 STATE 实际上.....。有必要引入人性化的 OrderOpenState() 和 OrderCloseSate(),但这是个麻烦事(只有少数人会用)。当然,这还是一个简单的谜题。谜题有很多,其中有些甚至没有被怀疑过。总而言之,能够在几乎不降低工作效率的情况下,将部分谜题解出工作状态和人类形态,这是件好事。我认为这个程序库满足了我一半以上的需求。

我在机器人中使用它,无论是在测试器中还是在实际操作中,都没有出现过错误。有一个问题是,当 dts 突然开始缓慢执行订单时(针对套利的插件),我不记得了,我不记得了,我想是 liba 没有时间计算仓位是否已经在市场上(历史同步问题,据我记忆),并在一排中盖章了很多订单,但随后您进行了更新,它就变得像时钟一样了。所以至少超过了一半:)
 

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

智能交易系统:量子 103

fxsaber, 2017.09.26 09:55 pm.

智能交易系统的跨平台变体
// MQL4&5 代码

#ifdef __MQL5__

bool RefreshRates( void ) { return(true); }

double MarketInfo( const string Symb, const ENUM_SYMBOL_INFO_DOUBLE Property )  { return(SymbolInfoDouble(Symb, Property)); }
int    MarketInfo( const string Symb, const ENUM_SYMBOL_INFO_INTEGER Property ) { return((int)SymbolInfoInteger(Symb, Property)); }

bool IsTesting(void)            { return(MQLInfoInteger(MQL_TESTER) || MQLInfoInteger(MQL_OPTIMIZATION)); }
bool IsTradeContextBusy( void ) { return(false); }
bool IsTradeAllowed(void)       { return(MQLInfoInteger(MQL_TRADE_ALLOWED)); }
bool IsExpertEnabled(void)      { return(AccountInfoInteger(ACCOUNT_TRADE_EXPERT)); }

int    ObjectFind( const string Name )   { return(ObjectFind(0, Name)); }
int    ObjectsTotal( void )              { return(ObjectsTotal(0)); }
bool   ObjectDelete( const string Name ) { return(ObjectDelete(0, Name)); }
string ObjectName( const int Pos )       { return(ObjectName(0, Pos)); }

double AccountFreeMarginCheck(const string Symb,const int Cmd,const double dVolume)
{
 double Margin;

 return(OrderCalcMargin((ENUM_ORDER_TYPE)Cmd, Symb, dVolume,
        SymbolInfoDouble(Symb, (Cmd == ORDER_TYPE_BUY) ? SYMBOL_ASK : SYMBOL_BID), Margin) ?
        AccountInfoDouble(ACCOUNT_MARGIN_FREE) - Margin : -1);
}

#define False false
#define True  true

#define Digits _Digits
#define Point  _Point

#define MODE_BID       SYMBOL_BID
#define MODE_ASK       SYMBOL_ASK
#define MODE_POINT     SYMBOL_POINT
#define MODE_DIGITS    SYMBOL_DIGITS
#define MODE_STOPLEVEL SYMBOL_TRADE_STOPS_LEVEL
#define MODE_SPREAD    SYMBOL_SPREAD

#define StrToTime    StringToTime
#define StrToInteger StringToInteger
#define TimeToStr    TimeToString
#define DoubleToStr  DoubleToString

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

#define   MT4_TICKET_TYPE // 命令发送(OrderSend)和订单票据(OrderTicket)必须返回与 MT4 相同类型的值 - int。
#include <MT4Orders.mqh> //https://www.mql5.com/zh/code/16006

// 报告中的图表需要
// #include <TypeToBytes.mqh> //https://www.mql5.com/zh/code/16280

#define  REPORT_TESTER // 测试仪将自动记录报告
#include <Report.mqh> //https://www.mql5.com/zh/code/18801

#endif // __MQL5__

#include "Quantum 103.mq4" //https://www.mql5.com/zh/code/19133

MT5 真实点差回溯测试结果

标准 MT5 报告

自定义报告(MT4 风格)


我附上了 MT4 风格的 MT5 回溯测试报告,因为标准报告难以阅读--请参见预告片中的两种报告。

您可以清楚地看到滑点和佣金对该 EA MT5 回溯测试结果的影响。

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Советники:量子 103

fxsaber, 2017.09.26 09:55

跨平台版智能交易系统
// MQL4&5 代码

#ifdef __MQL5__

bool RefreshRates( void ) { return(true); }

double MarketInfo( const string Symb, const ENUM_SYMBOL_INFO_DOUBLE Property )  { return(SymbolInfoDouble(Symb, Property)); }
int    MarketInfo( const string Symb, const ENUM_SYMBOL_INFO_INTEGER Property ) { return((int)SymbolInfoInteger(Symb, Property)); }

bool IsTesting(void)            { return(MQLInfoInteger(MQL_TESTER) || MQLInfoInteger(MQL_OPTIMIZATION)); }
bool IsTradeContextBusy( void ) { return(false); }
bool IsTradeAllowed(void)       { return(MQLInfoInteger(MQL_TRADE_ALLOWED)); }
bool IsExpertEnabled(void)      { return(AccountInfoInteger(ACCOUNT_TRADE_EXPERT)); }

int    ObjectFind( const string Name )   { return(ObjectFind(0, Name)); }
int    ObjectsTotal( void )              { return(ObjectsTotal(0)); }
bool   ObjectDelete( const string Name ) { return(ObjectDelete(0, Name)); }
string ObjectName( const int Pos )       { return(ObjectName(0, Pos)); }

double AccountFreeMarginCheck(const string Symb,const int Cmd,const double dVolume)
{
 double Margin;

 return(OrderCalcMargin((ENUM_ORDER_TYPE)Cmd, Symb, dVolume,
        SymbolInfoDouble(Symb, (Cmd == ORDER_TYPE_BUY) ? SYMBOL_ASK : SYMBOL_BID), Margin) ?
        AccountInfoDouble(ACCOUNT_MARGIN_FREE) - Margin : -1);
}

#define False false
#define True  true

#define Digits _Digits
#define Point  _Point

#define MODE_BID       SYMBOL_BID
#define MODE_ASK       SYMBOL_ASK
#define MODE_POINT     SYMBOL_POINT
#define MODE_DIGITS    SYMBOL_TRADE_STOPS_LEVEL
#define MODE_STOPLEVEL SYMBOL_TRADE_STOPS_LEVEL
#define MODE_SPREAD    SYMBOL_SPREAD

#define StrToTime    StringToTime
#define StrToInteger StringToInteger
#define TimeToStr    TimeToString
#define DoubleToStr  DoubleToString

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

#define   MT4_TICKET_TYPE // Обязываем OrderSend и OrderTicket возвращать значение такого же типа, как в MT4 - int.
#include <MT4Orders.mqh> //https://www.mql5.com/ru/code/16006

// Нужно для графиков в отчетах
// #include <TypeToBytes.mqh> //https://www.mql5.com/ru/code/16280

#define  REPORT_TESTER // В тестере будут автоматически записываться отчеты
#include <Report.mqh> //https://www.mql5.com/ru/code/18801

#endif // __MQL5__

#include "Quantum 103.mq4" //https://www.mql5.com/ru/code/19133

MT5 真实点差回溯测试结果

标准 MT5 报告

自定义报告(MT4 风格)


附上 MT4 风格报告 MT5-backtest,因为标准报告读取困难 - 在附件中查看两者。

您可以清楚地看到滑点和佣金对 MT5 回溯测试结果的影响。

 

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

专家顾问:显示订单

fxsaber, 2017.10.09 13:22

跨平台变体
// MQL4&5 代码

#ifdef __MQL5__

bool RefreshRates( void ) { return(true); }

double MarketInfo( const string Symb, const ENUM_SYMBOL_INFO_DOUBLE Property )  { return(SymbolInfoDouble(Symb, Property)); }

string AccountCurrency( void ) { return(AccountInfoString(ACCOUNT_CURRENCY)); }
double AccountProfit( void )   { return(AccountInfoDouble(ACCOUNT_PROFIT)); }
double AccountBalance( void )  { return(AccountInfoDouble(ACCOUNT_BALANCE)); }

bool ObjectSet( const string Name, const ENUM_OBJECT_PROPERTY_INTEGER Index, long Value ) { return(ObjectSetInteger(0, Name, Index, Value)); }
bool ObjectDelete( const string Name )   { return(ObjectDelete(0, Name)); }

bool ObjectCreate( const string Name, const ENUM_OBJECT Type, const int SubWindow, const datetime Time1, const double Price1 )
{
  return(ObjectCreate(0, Name, Type, SubWindow, Time1, Price1));
}

bool ObjectSetText( const string Name, const string Text, const int FontSize = 0, const string FontName = NULL, const color TextColor = clrNONE )
{
  return(ObjectSetString(0, Name, OBJPROP_TEXT, Text) && ObjectSetString(0, Name, OBJPROP_FONT, FontName) && ObjectSetInteger(0, Name, OBJPROP_COLOR, TextColor));
}

void OnInit( void ) { init(); }
void OnDeinit( const int Reason ) { deinit(); }

#define extern input

#define MODE_BID       SYMBOL_BID
#define MODE_ASK       SYMBOL_ASK
#define MODE_POINT     SYMBOL_POINT
#define MODE_TICKVALUE SYMBOL_TRADE_TICK_VALUE

#define DoubleToStr DoubleToString

#define  DEFINE_TIMESERIE(NAME,FUNC,T)                                                                         \
  class CLASS##NAME                                                                                           \
  {                                                                                                           \
  public:                                                                                                     \
    static T Get(const string Symb,const int TimeFrame,const int iShift)                                      \
    {                                                                                                         \
      T tValue[];                                                                                             \
                                                                                                              \
      return((Copy##FUNC((Symb == NULL) ? _Symbol : Symb, _Period, iShift, 1, tValue) > 0) ? tValue[0] : -1); \
    }                                                                                                         \
                                                                                                              \
    T operator[](const int iPos) const                                                                        \
    {                                                                                                         \
      return(CLASS##NAME::Get(_Symbol, _Period, iPos));                                                       \
    }                                                                                                         \
  } NAME;                                                                                                     

DEFINE_TIMESERIE(Time,Time,datetime)

#define   MT4_TICKET_TYPE // 命令发送(OrderSend)和订单票据(OrderTicket)必须返回与 MT4 相同类型的值 - int。
#include <MT4Orders.mqh> //https://www.mql5.com/zh/code/16006

#endif // __MQL5__

#include "Display orders.mq4"
 

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

专家顾问:Xarax

fxsaber, 2017.10.11 13:44

跨平台变体

// MQL4&5 代码

#ifdef __MQL5__

bool RefreshRates( void ) { return(true); }

double MarketInfo( const string Symb, const ENUM_SYMBOL_INFO_DOUBLE Property )  { return(SymbolInfoDouble(Symb, Property)); }
int    MarketInfo( const string Symb, const ENUM_SYMBOL_INFO_INTEGER Property ) { return((int)SymbolInfoInteger(Symb, Property)); }

bool IsTesting(void)            { return(MQLInfoInteger(MQL_TESTER) || MQLInfoInteger(MQL_OPTIMIZATION)); }
bool IsTradeContextBusy( void ) { return(false); }
bool IsTradeAllowed(void)       { return(MQLInfoInteger(MQL_TRADE_ALLOWED)); }
bool IsExpertEnabled(void)      { return(AccountInfoInteger(ACCOUNT_TRADE_EXPERT)); }

double AccountFreeMarginCheck(const string Symb,const int Cmd,const double dVolume)
{
 double Margin;

 return(OrderCalcMargin((ENUM_ORDER_TYPE)Cmd, Symb, dVolume,
        SymbolInfoDouble(Symb, (Cmd == ORDER_TYPE_BUY) ? SYMBOL_ASK : SYMBOL_BID), Margin) ?
        AccountInfoDouble(ACCOUNT_MARGIN_FREE) - Margin : -1);
}

#define False false
#define True  true

#define Digits _Digits
#define Point  _Point

#define MODE_BID       SYMBOL_BID
#define MODE_ASK       SYMBOL_ASK
#define MODE_POINT     SYMBOL_POINT
#define MODE_DIGITS    SYMBOL_DIGITS
#define MODE_STOPLEVEL SYMBOL_TRADE_STOPS_LEVEL
#define MODE_LOTSTEP   SYMBOL_VOLUME_STEP

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

#define   MT4_TICKET_TYPE // 命令发送(OrderSend)和订单票据(OrderTicket)必须返回与 MT4 相同类型的值 - int。
#include <MT4Orders.mqh> //https://www.mql5.com/zh/code/16006

#endif // __MQL5__

#include "Xarax.mq4"