Библиотеки: MT4Orders - страница 16

 

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

Особенности языка mql4, тонкости и приёмы работы

fxsaber, 2017.09.11 20:29

Ниже будет затронута тема, которая касается не только MT4, но и MT5 с другими платформами. Но для удобного восприятия логика будет написана на MQL4, поэтому в этой ветке.

Дискуссия, напрямую касающаяся библиотеки.

 

На форуме еще до появления в MQL5 Reason-флагов был выложен триггер SL/TP. Его логика четко показывала, что при акцептировании 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);    
}

// Показываем, что SL/TP/SO-ордера присутствуют в текущей таблице открытых MT5-ордеров
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 настроен на параллельную работу с торговым API 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 Reason-флагов был выложен триггер SL/TP. Его логика четко показывала, что при акцептировании SL/TP/SO уровней открытой позиции торговым сервером порождается соответствующий маркет-ордер, который находится в MT5-таблице открытых ордеров до тех пор, пока не исполнится.


Поэтому в MT5 даже на чистом MQL5 модификация/удаление таких ордеров невозможна и торговая логика в MT5 требует проверки, является ли открытый ордер фактически замороженным или нет.

Ниже показано условие идентификации таких ордеров при написании торговой логики на MT4Orders и пример его срабатывания

Видно, что больше четверти секунды TP-ордер висел среди открытых. Любые попытки его модификации/удаления вызывали бы ошибки.

Учитывайте данную особенность MT5 (не только при работе с MT4Orders).

Проверка данного условия теперь встроена в библиотеку, работать можно, как и в MT4

// Список изменений:
// 14.09.2017:
//   Fix: Теперь библиотека не видит текущие MT5-ордера, которые не имеют состояние ORDER_STATE_PLACED.
//        Чтобы библиотека видела все открытые MT5-ордера нужно ДО библиотеки прописать строку
//
//        #define MT4ORDERS_SELECTFILTER_OFF // Обязываем MT4Orders.mqh видеть все текущие MT5-ордера
[Удален]  
Этож надо было столько понаворотить с этими позициями\ордерами в мт5, ни в одной другой платформе не встречал такого многообразия )
 
Maxim Dmitrievsky:
Этож надо было столько понаворотить с этими позициями\ордерами в мт5, ни в одной другой платформе не встречал такого многообразия )

Еще большУю роль играет 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(), но это голову сломать (да и единицы использовать будут). И, конечно, это еще простая головоломка. Там их много и позаковырестей, а о некоторых даже нет подозрений. В общем, хорошо, что удалось частично распутать до рабочего состояния и человеческого вида почти без потерь в производительности. Больше половины потребностей, думаю, библиотека удовлетворяет.

Использую в ботах, ни в тестере ни на реале ни одной ошибки пока не возникало вроде как, на Фортс в окрытии и на форексе. Была проблема когда дц вдруг начал медленно приказы исполнять (воткнул плагин против арбитража), уже не помню, по моему не успевала либа посчитать есиь ли позиция уже в рынке или нет, (проблема с синхронизацией истории, насколько помню) и подряд наштамповал много ордеров, но потом вы сделали обновление и стало как часы. Так что больше половины как минимум :)
 

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

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

fxsaber, 2017.09.26 09:55

Кроссплатформенный вариант советника
// MQL4&5-code

#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/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-бэктеста, потому как стандартный отчет читается с трудом - см. оба в прицепе.

Хорошо видно величины влияния на результат 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

Результат бэктеста на реальных тиках на МТ5

Стандартный отчет MT5

Пользовательский отчет (стиль МТ4)


Прикрепил отчет MT4-стиля MT5-backtest, так как стандартный отчет читается с трудом - смотрите оба в аттаче.

Вы можете наглядно увидеть влияние на результат MT5-бэктеста проскальзывания и комиссии этого советника.

 

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

Советники: Display orders

fxsaber, 2017.10.09 13:22

Кроссплатформенный вариант
// MQL4&5-code

#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/ru/code/16006

#endif // __MQL5__

#include "Display orders.mq4"
 

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

Советники: Xarax

fxsaber, 2017.10.11 13:44

Кроссплатформенный вариант

// MQL4&5-code

#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/ru/code/16006

#endif // __MQL5__

#include "Xarax.mq4"