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

 
// Список изменений:
// 29.12.2021
//   Fix: Улучшена синхронизация в ByPass-режиме.
 

В MT4 при переборе ордеров возможны задвоения (двойной учет) из-за перетряхивания таблицы ордеров.


В MT4Orders в определенной ситуации меняется индексация таблицы ордеров. Это происходит, когда MT5-марет-ордер превращается в MT5-позицию. Если постараться нарваться на такую ситуацию на некоторых серверах, то возможен сбой в учете. Написал демонстрацию для этого.

#define MT4ORDERS_BYPASS_MAXTIME 1000000 // Максимальное время (в мкс.) на ожидание синхронизации торгового окружения
#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define MinLot SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)

double GetLots()
{
  double Lots = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--) // Бежим по всем ордерам - здесь может быть сбой.
    if (OrderSelect(i, SELECT_BY_POS))
      Lots += OrderLots();
      
  return(NormalizeDouble(Lots, 2));
}

void OnStart()
{
  MT4ORDERS::OrderSend_MaxPause = 0; // Отказываемся от встроенной коррекции результата MT5-OrderSend.

  const double NewLots = 0.11;
  
  while (!IsStopped())
  {
    const double Lots = NormalizeDouble(GetLots() + NewLots, 2); // Сколько должно быть лотов суммарно после выставления ордера.
    const TICKET_TYPE Ticket = OrderSend(_Symbol, OP_BUY, NewLots, Ask, 0, 0 ,0); // Выставили маркет-ордер.
    
    if (Ticket != -1)
    {
      while (!PositionSelectByTicket(Ticket)) // Ждем, пока маркет-ордер не превратился в позицию.
      {
        const double Lots2 = GetLots(); // Вычисляем суммарный объем.
        
        if (Lots2 != Lots) // Суммарный объем не совпадает с предварительным расчетом - выводим.
          Alert((string)Lots + " " + (string)Lots2);                        
      }
    }
          
    if (OrderSelect(Ticket, SELECT_BY_TICKET) &&
        OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0)) // Отправляем маркет-ордер на закрытие позиции.
      while (PositionSelectByTicket(Ticket))                          // Ждем закрытия позиции.
        ;      
  }
    
  Print(MT4ORDERS::ByPass.ToString()); // Распечатываем статистику синхронизаций.
}


Такой советник будет Алерить на некоторых конфигурациях. ByPass-режим делает значения Алертов стабильными, но все равно не избавляет от них.


Сам не торгую без ByPass-режима, т.к. это очень сильная штука по обходу MT5-сюрпризов. А еще не торгую без снепшотов. Именно снепшот-механизм позволяет исцелиться от переиндексации.


Вот так это выглядит на том же примере.

#define VIRTUAL_SNAPSHOT_REFRESHTIME 1000 // Время жизни снепшота для обновления. В MT5 требует подключенной MT4Orders.mqh
#define VIRTUAL_SNAPSHOT_WITHOUT_HISTORY // Отказ от снепшота истории для повышения производительности
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577

double GetLots()
{
  double Lots = 0;

  VIRTUAL::Snapshot(0, -1, false, ""); // Заснепшотили реальное торговое окружение.
  
  for (int i = OrdersTotal() - 1; i >= 0; i--) // За счет снепшот-механизма бежим по всем ордерам безопасно.
    if (OrderSelect(i, SELECT_BY_POS))
      Lots += OrderLots();

  VIRTUAL::SnapshotDelete(); // Удалили снепшот.
      
  return(NormalizeDouble(Lots, 2));
}


Рекомендую связку ByPass+Snapshot. Помогает не только обходить подводные камни, но и значительно уменьшает потребление вычислительных ресурсов. Особенно, когда много мультивалютных ордеров/советников.

 

Часть объявления из Фриланса.

Конвертация должна быть выполнена в родном MQL5 без использования сторонних библиотек типа MT4Orders.

Разработчик должен предоставить исходный код до закрытия работы чтобы была возможность убедиться как сделана конвертация.

Видимо, где-то что-то плохо работает.

 
fxsaber #:

Файл битый

---

В архиве последняя версия

// 01.06.2021
//   Fix: Compatibility with the compiler build 2449 and higher.
//   Fix: Improved synchronization. ByPass.mqh must be of the latest version.
//   Add: OrderLots(true) - synchronized size of the selected position, taking into account all orders which close this position.
 
Vitaly Muzichenko #:

Файл битый

Нужно скачать.

 
fxsaber #:

Нужно скачать.

Да, действительно. Чудеса какие-то, разные файлы.

Спасибо!
 
// Список изменений:
// 06.01.2022
//   Fix: Точное определение данных открытия позиций и размера комиссии. Корректно работает только в ByPass-режиме.
//   Add: Добавлена OrderDealsAmount() - количество MT5-сделок, участвующих в формировании позиции. Корректно работает только в ByPass-режиме.

Кто имеет дело с частичными исполнениями и CloseBy-перекрытиями, рекомендую данное обновление.

 
fxsaber #:

Кто имеет дело с частичными исполнениями и CloseBy-перекрытиями, рекомендую данное обновление.

Проверочный скрипт точности вычислений.

#define MT4ORDERS_BYPASS_MAXTIME 1000000 // ByPass-режим для точных вычислений.
#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

// Суммирование всех денежных операций - MT5-style.
double GetProfitMT5( void )
{
  double Res = 0;
  
  if (HistorySelect(0, INT_MAX))
    for (int i = HistoryDealsTotal() - 1; i >= 0; i--)
    {
      const ulong Ticket = HistoryDealGetTicket(i);
      
      Res += HistoryDealGetDouble(Ticket, DEAL_PROFIT) +
             HistoryDealGetDouble(Ticket, DEAL_SWAP) +
             HistoryDealGetDouble(Ticket, DEAL_COMMISSION);
    }
    
  return(Res);
}

// Суммирование всех денежных операций - MT4-style.
double GetProfitMT4( void )
{
  double Res = 0;

  for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)  
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
      Res += OrderProfit() + OrderSwap() + OrderCommission();
    
  return(Res);
}

void OnStart()
{
  if (PositionsTotal())
    MessageBox("The script works only if there are no open positions."); // Проверяем только при отсутствии открытых позиций.
  else
  {
    const double ProfitMT5 = GetProfitMT5(); // Суммирование всех денежных операций - MT5-style.
    const double ProfitMT4 = GetProfitMT4(); // Суммирование всех денежных операций - MT4-style.
    
    // Сравниваем суммы денежных операций, посчитанные разными способами.
    Alert("MT5 (" + DoubleToString(ProfitMT5, 8) + ") == MT4 (" + DoubleToString(ProfitMT4, 8) + ") - " +
          (string)(bool)!NormalizeDouble(ProfitMT4 - ProfitMT5, 8));
    Print(__MT4ORDERS__);
  }  
}


Результат работы - одна строка.

Alert: MT5 (0.00000000) == MT4 (-0.00500000) - false
Alert: MT5 (0.00000000) == MT4 (0.00000000) - true

false - MT4Orders где-то допускает ошибку. Просьба проверить на заковыристых счетах. Если false - дайте знать.

 
fxsaber #:

Проверочный скрипт точности вычислений.

Просьба проверить на заковыристых счетах.

Проверка показала, что библиотека с очень сложной историей торгов отрабатывает идеально. Надежность 100%.

 

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

Библиотеки: MT4Orders

fxsaber, 2022.01.06 03:18

// Список изменений:
// 06.01.2022
//   Fix: Точное определение данных открытия позиций и размера комиссии. Корректно работает только в ByPass-режиме.
//   Add: Добавлена OrderDealsAmount() - количество MT5-сделок, участвующих в формировании позиции. Корректно работает только в ByPass-режиме.

На примере CustomReport покажу, как это выглядит

Слева-направо выделенные места.

  • OrderDealsAmount. Есть позиции, которые формировались соответствующим количеством сделок. В общем случае это могут быть не только ENTRY_IN-сделки, но и остальных типов.
  • По этой причине цены открытия могут быть столь дробными - средневзвешенная по объему цена всех сделок, что формировали позицию.
  • Размер комиссии в пипсах. Он не должен сильно разниться (если объем немалый) на одном символе. Иначе - баг MT4Orders.

На скрине довольно простой случай. Есть значительно заковыристей, где OrderDealsAmount измеряется десятками. Например, в MT5 могут быть непересекающиеся по времени жизни позиции с одним и тем же тикетом. При этом MT5-GUI покажет, что это одна позиция, со временем открытия первой. А MT4Orders покажет несколько позиций с разным временем (и ценой) открытия и OrderTicketOpen (тикет сделки открытия).


Короче говоря, все очень точно и в привычном MT4-Style. Только в ByPass-режиме.