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

 
Чем лучше написан MT4-советник, тем проще его сконвертировать в MT5. И размер/сложность оригинального советника не имеет никакого значения при конвертации.

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

Советники: Three Point Arbitrage

fxsaber, 2018.01.20 09:58

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

#define MODE_MARGINREQUIRED 0

// https://www.mql5.com/ru/forum/170952/page9#comment_4134898
// Размер свободных средств, необходимых для открытия 1 лота на покупку
double MarketInfo( const string Symb, const int )
{
  MqlTick Tick;
  double MarginInit, MarginMain;

  return((SymbolInfoTick(Symb, Tick) && SymbolInfoMarginRate(Symb, ORDER_TYPE_BUY, MarginInit, MarginMain)) ? MarginInit * Tick.ask *
          SymbolInfoDouble(Symb, SYMBOL_TRADE_TICK_VALUE) / (SymbolInfoDouble(Symb, SYMBOL_TRADE_TICK_SIZE) * AccountInfoInteger(ACCOUNT_LEVERAGE)) : 0);
}

int DayOfWeek( void )
{
  MqlDateTime sTime = {0};

  TimeToStruct(TimeCurrent(), sTime);

  return(sTime.day_of_week);
}

int Hour( void )
{
  return((int)((TimeCurrent() % (24 * 3600)) / 3600));
}

#include "ThreePoint.mq4"
 
Если появляется Алерт, посмотрите, а не запущен ли на счете (по невнимательности) один и тот же советник дважды. Например, один на локальной машине, а другой - VPS.

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

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

fxsaber, 2018.02.06 07:41

OnTradeTransaction позволяет написать неторговый советник (Сервис), отслеживающий наличие запущенного на счете торгового "клона"-советника.
 

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

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

fxsaber, 2018.02.08 08:16

В MT5 у позиций нет комиссии (в отличие от MT4). Из-за этого есть свои особенности

  • В MT5 комиссия за открытие позиции, как и за закрытие позиции списывается сразу с баланса.
  • По этой причине Equity до закрытия всех позиций не показывает, чему будет равен Balance после закрытия.
  • Это значит, что рассчитать безубыток просто не получится в MT5.

MT4Orders все же имеет комиссию для позиций. По этой причине получается такая ситуация

#include <MT4Orders.mqh>

#define PRINT(A) Print(#A + " = " + (string)(A))

void OnStart()
{
  double ProfitWithoutCommission = 0;
  double ProfitWithCommission = 0;  
  
  for (int i = OrdersTotal(); i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      OrderPrint();
      
      ProfitWithoutCommission += OrderProfit() + OrderSwap(); // Вычисляем текущий профит без учета комиссии
      
      ProfitWithCommission += OrderProfit() + OrderSwap() + OrderCommission(); // Вычисляем текущий профит с учетом комиссии
    }
        
  PRINT(AccountInfoDouble(ACCOUNT_EQUITY) - AccountInfoDouble(ACCOUNT_BALANCE));
  
  PRINT(ProfitWithoutCommission);
  PRINT(ProfitWithCommission);  
}


Результат

#895889 2018.02.08 09:08:26 sell 1.00 EURUSD 1.22807 0.00000 0.00000 1.22877 -6.14 0.00 -70.00 0
AccountInfoDouble(ACCOUNT_EQUITY)-AccountInfoDouble(ACCOUNT_BALANCE) = -70.0
ProfitWithoutCommission = -70.0
ProfitWithCommission = -76.14


Как видим, разница между Equity и Balance отличается на размер комиссии. И может показаться, что классическое для MT4 выражение

ProfitWithCommission += OrderProfit() + OrderSwap() + OrderCommission(); // Вычисляем текущий профит с учетом комиссии

теряет смысл в MT5. Но это не так. На самом деле когда Вы закроете позицию, то Balance изменится именно на эту величину, а не станет тем, что показывало перед этим Equity. Грубо говоря, значение Equity в MT5 врет, с точки зрения этого понятия в MT4.

Учитывайте эту особенность MT5. Библиотека в данном случае точнее. И рассчитать тот же безубыток не составит труда.

 

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

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

fxsaber, 2018.02.08 10:06

На неттинге элементарно потерять комментарий открытой позиции. Для этого достаточно совершить любую сделку без комментария по символу позиции.

Библиотека не потеряет комментарий в описанном случае - OrderComment() будет выдавать комментарий, который был при открытии позиции.

 
// Список изменений:
// 13.02.2018
//   Add: Добавлено логирование ошибочного выполнения MT5-OrderSend.
//   Fix: Теперь "невидимы" только закрывающие MT5-ордера (SL/TP/SO, partial/full close).
//   Fix: Механизм определения SL/TP закрытых позиций после OrderClose скорректирован - работает, если позволяет StopLevel.
 

Здесь подробно описана некоторая особенность работы MT5. Библиотека отрабатывала эту ситуацию правильно уже давно. Но ругалась (Алерт), что ситуация нестандартная.

Теперь ругаться не будет

// Список изменений:
// 15.02.2018
//   Fix: Проверка синхронизации MT5-OrderSend теперь учитывает возможные особенности реализации ECN/STP.


В качестве проверки можно запустить этот скрипт на непростом демо-счете FXOpen-MT5

#include <Debug.mqh> // https://c.mql5.com/3/173/Debug.mqh
#include <MT4Orders.mqh>

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

void OnStart()
{
  _P(OrderCloseBy(_P(OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0)), _P(OrderSend(_Symbol, OP_SELL, 1, Bid, 0, 0, 0))));
}


Результат

void OnStart(), Line = 9: OrderSend(_Symbol,OP_SELL,1,Bid,0,0,0) = 897247
void OnStart(), Line = 9: OrderSend(_Symbol,OP_BUY,1,Ask,0,0,0) = 897248
void OnStart(), Line = 9: OrderCloseBy(_P(OrderSend(_Symbol,OP_BUY,1,Ask,0,0,0)),_P(OrderSend(_Symbol,OP_SELL,1,Bid,0,0,0))) = true
Файлы:
Debug.mqh  1 kb
 

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

Организация цикла перебора ордеров

fxsaber, 2018.02.16 09:40

в MT5 все совсем не в порядке. Пример, показывающий проблему

// Пример неправильного считывания торгового окружения на каждом тике
// Скрипт эмулирует два тика ТС, которая должна открыть одну позицию, если ее нет.

#include <Trade/Trade.mqh>

// Возвращает количество позиций по символу
int GetAmountPositions( const string Symb )
{
  int Res = 0;
  
  // Этот MQL5-код с ошибкой
  for (int i = PositionsTotal() - 1; i >= 0; i--)
    if (PositionGetSymbol(i) == Symb)
      Res++;

/*
  // В MT4 такой код выполняется без ошибки
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (OrderSymbol() == Symb))
      Res++;
*/      
  return(Res);
}

// Пример OnTick
void ExampleOnTick()
{
  static CTrade Trade;
  
  // Если нет позиции, открываем
  if (!GetAmountPositions(_Symbol))
    Trade.Buy(1);    
}

// Эмуляция прихода двух Tick-событий
void OnStart()
{
  ExampleOnTick(); 
  
  Sleep(10); // Между двумя тиками ~10 мс.
  
  ExampleOnTick();
}

Как думаете, если запустить этот скрипт на символе без позиций, что будет в итоге?

Правильный ответ: будет открыта одна или две позиции.

Эта проблема обходится, если писать в MQL4-style хотя бы частично. Чтобы в этом убедиться, достаточно GetAmountPositions сделать в MQL4-style (закомментирован в исходнике), убрав MQL5-style.

Будьте особенно бдительны с MQL5-style.

 

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

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

fxsaber, 2018.02.19 08:39

На неттинге одновременно на одном и том же символе может быть открытая позиция и несколько маркет-ордеров любого направления. Например, BUY-позиция и BUY-ордер.

В библиотеке MT5-ордера и MT5-позиции являются одной сущностью - MT4-ордера. По этой причина в данной ситуации на неттинг-счете возможно получить на одном символе несколько BUY/SELL-MT4-ордеров. Это не ошибка и ни к чему нехорошему привести не может. Но пишу об этом, если кого-то такая ситуация удивит.

Правда, мне не удалось найти такой демо-счет.

Больше теоретическое предупреждение. На практике не встречал.

 
Вот такие (очень редкие) ордера в Истории торгов библиотека намеренно не видит. Более ранние версии библы видели их. Если есть мнение, что текущее поведение должно быть прежним, дайте знать.
 
// Список изменений:
// 06.03.2018
//   Add: Добавлены TICKET_TYPE и MAGIC_TYPE, чтобы можно было писать единый кроссплатформенный код
//        без предупреждений компиляторов (включая strict-режим MQL4).

Ниже код, который компилируется без предупреждений под MQL4/5

#property strict

#include <MT4Orders.mqh>

void OnStart()
{
//  long Ticket = 0;
//  long Magic = 0;
  TICKET_TYPE Ticket = 0;
  MAGIC_TYPE  Magic = 0;
  
  long Tmp = OrderSelect(Ticket, SELECT_BY_TICKET) + 
             OrderDelete(Ticket) +
             OrderCloseBy(Ticket, Ticket) +
             OrderClose(Ticket, 1, 0, 0) +    
             OrderSend(_Symbol, OP_BUY, 1, 0, 0, 0, 0, NULL, Magic);
}

Спасибо @Andrey Voytenko за предложение такого решения!

Причина обращения: