Bibliotecas: MT4Orders - página 16

 

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Recursos da linguagem mql4, sutilezas e técnicas de trabalho

fxsaber, 2017.09.11 20:29

Abaixo será abordado o tópico, que diz respeito não apenas ao MT4, mas também ao MT5 com outras plataformas. Mas para facilitar a percepção, a lógica será escrita em MQL4, portanto, neste tópico.

Discussão diretamente relacionada à biblioteca.

 

posição aberta são aceitos pelo servidor de negociação, é gerada a ordem de mercado correspondente, que fica na tabela de ordens abertas do MT5 até ser executada.


Portanto, no MT5, mesmo em MQL5 puro, a modificação/exclusão de tais ordens é impossível e a lógica de negociação do MT5 requer a verificação se uma ordem aberta está realmente congelada ou não.


A seguir, mostramos a condição para identificar essas ordens ao escrever a lógica de negociação no MT4Orders e um exemplo de seu acionamento

// Acionar 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);    
}

// Mostrar que as ordens SL/TP/SO estão presentes na tabela atual de ordens abertas do MT5
void OnTimer()
{
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) &&
        (OrderCloseReason() >= (int)ORDER_REASON_SL)) // Se essa condição for acionada, você não poderá modificar/excluir o pedido!
    {
      OrderPrint();
      
      const long Position = OrderGetInteger(ORDER_POSITION_ID); // Possivelmente, já que o MT4Orders está configurado para trabalhar em paralelo com a API de negociação 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.");
    }
}


Resultado

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.


Você pode ver que a ordem TP estava suspensa entre as ordens abertas por mais de um quarto de segundo. Qualquer tentativa de modificá-la/excluí-la causaria erros.

Leve em conta esse recurso do MT5 (não apenas quando estiver trabalhando com o MT4Orders).

 
fxsaber:

posição aberta são aceitos pelo servidor de negociação, é gerada a ordem de mercado correspondente, que fica na tabela de ordens abertas do MT5 até ser executada.


Portanto, no MT5, mesmo em MQL5 puro, a modificação/exclusão de tais ordens é impossível e a lógica de negociação do MT5 requer a verificação se uma ordem aberta está realmente congelada ou não.

Abaixo, você pode ver a condição para identificar essas ordens ao escrever a lógica de negociação no MT4Orders e um exemplo de seu acionamento

Você pode ver que a ordem TP ficou suspensa entre as ordens abertas por mais de um quarto de segundo. Qualquer tentativa de modificá-la/excluí-la causaria erros.

Leve em conta esse recurso do MT5 (não apenas quando estiver trabalhando com o MT4Orders).

A verificação dessa condição agora está incorporada à biblioteca, e você pode trabalhar como no MT4

// Lista de modificações:
// 14.09.2017:
// Correção: agora a biblioteca não vê as ordens atuais do MT5 que não têm o estado ORDER_STATE_PLACED..
// Para que a biblioteca veja todas as ordens MT5 abertas, a seguinte linha deve ser escrita ANTES da biblioteca
//
// #define MT4ORDERS_SELECTFILTER_OFF // Faz com que o MT4Orders.mqh veja todos os pedidos atuais do MT5
[Excluído]  
Foi necessário criar tanto com essas posições/ordens no mt5, pois em nenhuma outra plataforma encontrei tamanha variedade.)
 
Maxim Dmitrievsky:
Nunca vi essa variedade em nenhuma outra plataforma).

O parâmetro ORDER_STATE desempenha um papel ainda mais importante. Para ordens SL/TP, ele é ORDER_STATE_STARTED. Mas você nunca deve ignorar todos os ORDER_STATE_STARTED (leva muito tempo para explicar). É por isso que é errado confiar em ORDER_STATE, mas ORDER_REASON é necessário.

ORDER_STATE é uma história diferente. Suponha que uma posição seja aberta parcialmente a partir de uma ordem pendente, e o restante da ordem ainda esteja pendente. Então, há uma transação no histórico, mas a ordem em si ainda não está lá. Se a ordem for totalmente preenchida, para entender que a primeira transação gerada por ela foi aberta parcialmente, não será possível consultar o ORDER_STATE da ordem que a originou.


De qualquer forma, há muitas situações em que esse STATE realmente..... Temos que introduzir OrderOpenState() e OrderCloseSate() humanos, mas é uma dor de cabeça (e poucas pessoas os usarão). E, é claro, ainda é um simples quebra-cabeça. Há muitos deles, e alguns nem sequer são suspeitos. Em suma, é bom poder desvendar parcialmente o estado de funcionamento e a forma humana quase sem perda de produtividade. Acho que a biblioteca atende a mais da metade das necessidades.

[Excluído]  
fxsaber:

O parâmetro ORDER_STATE desempenha um papel ainda mais importante. Para ordens SL/TP, ele é ORDER_STATE_STARTED. Mas você nunca deve ignorar todos os ORDER_STATE_STARTED (leva muito tempo para explicar). É por isso que é errado confiar em ORDER_STATE, mas ORDER_REASON é necessário.

ORDER_STATE é uma história diferente. Suponha que uma posição seja aberta parcialmente a partir de uma ordem pendente, e o restante da ordem ainda esteja pendente. Então, há uma transação no histórico, mas a ordem em si ainda não está lá. Se a ordem for totalmente preenchida, para entender que a primeira transação gerada por ela foi aberta parcialmente, não será possível consultar o ORDER_STATE da ordem que a originou.


De qualquer forma, há muitas situações em que esse STATE realmente..... É necessário introduzir OrderOpenState() e OrderCloseSate() humanos, mas isso é um quebra-cabeça (e poucas pessoas o usarão). E, é claro, ainda é um quebra-cabeça simples. Há muitos deles, e alguns nem sequer são suspeitos. Em suma, é bom poder desvendar parcialmente o estado de funcionamento e a forma humana quase sem perda de produtividade. Acho que a biblioteca satisfaz mais da metade das minhas necessidades.

Eu a utilizo em bots, nem no testador nem no real, ainda não ocorreram erros, ao que parece, em Forts na abertura e no forex. Houve um problema quando o dts de repente começou a executar ordens lentamente (plugin contra arbitragem), não me lembro, não me lembro, acho que a liba não teve tempo de calcular se a posição já está no mercado ou não (um problema com a sincronização do histórico, pelo que me lembro) e carimbou muitas ordens seguidas, mas depois você fez uma atualização e ficou como um relógio. Portanto, mais da metade, pelo menos :)
 

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Expert Advisors: Quantum 103

fxsaber, 2017.09.26 09:55 pm.

Variante de plataforma cruzada do Expert Advisor
// Código 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 // Obrigar o OrderSend e o OrderTicket a retornar um valor do mesmo tipo que no MT4 - int.
#include <MT4Orders.mqh> // https://www.mql5.com/pt/code/16006

// Necessário para gráficos em relatórios
// #include <TypeToBytes.mqh> // https://www.mql5.com/pt/code/16280

#define  REPORT_TESTER // O testador registrará automaticamente os relatórios
#include <Report.mqh> // https://www.mql5.com/pt/code/18801

#endif // __MQL5__

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

Resultado do backtest em ticks reais no MT5

Relatório padrão do MT5

Relatório personalizado (estilo MT4)


Anexei o relatório de backtest do MT5 no estilo MT4 porque o relatório padrão é difícil de ler - veja ambos no trailer.

Você pode ver claramente o impacto das derrapagens e das comissões no resultado do backtest do MT5 desse EA.

 

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

Советники: Quantum 103

fxsaber, 2017.09.26 09:55

Versão multiplataforma do Expert Advisor
// Código 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

Resultado do backtest em ticks reais no MT5

Relatório padrão do MT5

Relatório personalizado (estilo MT4)


Relatório anexado no estilo MT4 MT5-backtest, porque o relatório padrão é lido com dificuldade - veja ambos no anexo.

Você pode ver claramente o impacto no resultado do backtest MT5 da derrapagem e da comissão desse consultor.

 

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Expert Advisors: Exibir ordens

fxsaber, 2017.10.09 13:22

Variante de plataforma cruzada
// Código 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 // Obrigar o OrderSend e o OrderTicket a retornar um valor do mesmo tipo que no MT4 - int.
#include <MT4Orders.mqh> // https://www.mql5.com/pt/code/16006

#endif // __MQL5__

#include "Display orders.mq4"
 

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Consultores especializados: Xarax

fxsaber, 2017.10.11 13:44

Variante de plataforma cruzada

// Código 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 // Obrigar o OrderSend e o OrderTicket a retornar um valor do mesmo tipo que no MT4 - int.
#include <MT4Orders.mqh> // https://www.mql5.com/pt/code/16006

#endif // __MQL5__

#include "Xarax.mq4"