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

 

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

Особенности языка 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 за предложение такого решения!

 
fxsaber:

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

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

Для чего этот хак?

 
Rashid Umarov:

Для чего этот хак?

В примере закомментированы long-типы. Если их оставить, то в MQL5 и NoStrict-MQL4 не будет предупреждений. Но в strict-MQL4  - возникнут.

Чтобы можно было писать кроссплатформенные библиотеки без соответствующих Warnings, и добавлен данный функционал.

Пользоваться им совершенно не требуется. Это дополнительное удобство для тех, перед кем может встать кроссплатформенная задача подобного рода.

 

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

Робот из МТ4 на МТ5

fxsaber, 2018.03.08 09:27

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

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

int Minute( void )
{
  return((int)((TimeCurrent() % 3600) / 60));
}

#include "super-signals-channel.mq4" // https://www.mql5.com/ru/forum/231135#comment_6751304
 

Я пытаюсь реализовать стратегию (которая, очевидно, прекрасно работает в MT4), но уперся в кирпичную стену.

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

У каждой сделки есть SL и TP, и советнику необходимо отслеживать, что произошло (SL или TP) с самой последней сделкой в каждой последовательности, проверяя историю ордеров.

К сожалению, это не представляется возможным, судя по заметкам в библиотеке (см. ниже) и различным попыткам заставить систему работать:

// В MT4 OrderSelect в режиме SELECT_BY_TICKET выбирает тикет независимо от MODE_TRADES / MODE_HISTORY,
// так как "Номер тикета является уникальным идентификатором ордера".
// В MT5 номер билета НЕ является уникальным,
// поэтому OrderSelect в режиме SELECT_BY_TICKET имеет следующие приоритеты выбора для сопоставления билетов:
// MODE_TRADES: существующая позиция> существующий ордер> сделка> отмененный ордер
// MODE_HISTORY: сделка> отмененный ордер> существующая позиция> существующий ордер

Экспериментируя, я убедился, что номер тикета всегда меняется после события SL/TP, и что единственной общей информацией является магический номер - даже комментарий к ордеру не сохраняется.

При тестировании размещение первоначального ордера с SL, TP, магическим номером и торговым комментарием возвращает тикет №2 и отображает всю ожидаемую информацию.

Однако, когда SL или TP достигается, тикет №2 исчезает, и его нельзя извлечь ни с помощью SELECT_BY_POS, ни с помощью SELECT_BY_TICKET.

Вместо этого (при условии отсутствия другой торговой активности) появляется тикет №3, в котором не установлен комментарий к ордеру.

При отсутствии последовательности в отношении номера билета и комментария к ордеру, на который можно было бы сослаться, похоже, нет простого способа определить последний ордер в данной последовательности :(

Надеюсь, @fxsaber найдет решение или предложит обходной путь :)

 
SysFX:

К сожалению, я не понял суть проблемы.

 

Извините за поздний ответ :(

Проблема в том, что торговая информация 'MODE_HISTORY' в принципе непригодна для использования, потому что:

1) когда сделка закрывается, номер тикета меняется ... вы можете легко проверить это, открыв сделку на покупку / продажу с TP и SL - если сделка открывается как тикет #2, то после срабатывания SL или TP она станет тикетом #3 в пуле истории

2) магическое число потеряно

3) теряется комментарий к билету

Таким образом, если в коде эксперта нужно проверить, закрылась ли сделка с прибылью или убытком, это невозможно, поскольку нет информации, позволяющей идентифицировать сделку.

Я надеюсь, что вы сможете изменить ситуацию, чтобы сохранить магическое число и сделать так, чтобы комментарий к сделке вел себя как в MT4 - возможно, вы найдете способ сохранить и номер тикета.

 
SysFX:

Извините за поздний ответ :(

Проблема в том, что торговая информация 'MODE_HISTORY' в основном непригодна для использования, потому что:

1) когда сделка закрывается, номер тикета меняется ... вы можете легко проверить это, открыв сделку на покупку / продажу с TP и SL - если сделка открывается как тикет #2, то после срабатывания SL или TP она станет тикетом #3 в пуле истории.

2) магическое число теряется

3) комментарий к билету потерян

Таким образом, если в коде эксперта нужно проверить, закрылась ли сделка с прибылью или убытком, это невозможно, поскольку нет информации, позволяющей идентифицировать сделку.

Я надеюсь, что вы сможете изменить ситуацию, чтобы сохранить магическое число и заставить торговый комментарий вести себя как в MT4 - возможно, вы сможете найти способ сохранить и номер тикета.

Пример

#include <MT4Orders.mqh>

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

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

void OnInit()
{
  long Ticket;
  
  PRINT((Ticket = OrderSend(_Symbol, OP_BUY, 1, Ask, 0, Bid - 100 * _Point, Bid + 100 * _Point, "Hello World!", 12345)));
  
  if (OrderSelect(Ticket, SELECT_BY_TICKET))
    PRINT(OrderClose(OrderTicket(), 0.3, OrderClosePrice(), 0));
}

void OnDeinit( const int )
{
  const int Total = OrdersHistoryTotal();
  
  for (int i = 1; i < Total; i++)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
    {
      OrderPrint();
      
      PRINT(OrderTicket());
      PRINT(OrderMagicNumber());
      PRINT(OrderComment());
      PRINT(OrderTicketOpen());
    }
}


Результат

2018.03.25 00:00:00   instant buy 1.00 EURUSD at 1.23527 sl: 1.23414 tp: 1.23614 (1.23514 / 1.23527)
2018.03.25 00:00:00   deal #2  buy 1.00 EURUSD at 1.23527 done (based on order #2)
2018.03.25 00:00:00   deal performed [#2  buy 1.00 EURUSD at 1.23527]
2018.03.25 00:00:00   order performed buy 1.00 at 1.23527 [#2  buy 1.00 EURUSD at 1.23527]
2018.03.25 00:00:00   (Ticket=OrderSend(_Symbol,OP_BUY,1,Ask,0,Bid-100*_Point,Bid+100*_Point,Hello World!,12345)) = 2
2018.03.25 00:00:00   instant sell 0.30 EURUSD at 1.23514, close #2 (1.23514 / 1.23527)
2018.03.25 00:00:00   deal #3  sell 0.30 EURUSD at 1.23514 done (based on order #3)
2018.03.25 00:00:00   deal performed [#3  sell 0.30 EURUSD at 1.23514]
2018.03.25 00:00:00   order performed sell 0.30 at 1.23514 [#3  sell 0.30 EURUSD at 1.23514]
2018.03.25 00:00:00   OrderClose(OrderTicket(),0.3,OrderClosePrice(),0) = true
2018.03.26 01:04:40   take profit triggered #2  buy 0.70 EURUSD 1.23527 sl: 1.23414 tp: 1.23614 [#4  sell 0.70 EURUSD at 1.23614]
2018.03.26 01:04:40   deal #4  sell 0.70 EURUSD at 1.23614 done (based on order #4)
2018.03.26 01:04:40   deal performed [#4  sell 0.70 EURUSD at 1.23614]
2018.03.26 01:04:40   order performed sell 0.70 at 1.23614 [#4  sell 0.70 EURUSD at 1.23614]
final balance 10000046.11 EUR
2018.03.26 23:59:59   #3 2018.03.25 00:00:00 buy 0.30 EURUSD 1.23527 1.23414 1.23614 2018.03.25 00:00:00 1.23514 0.00 0.00 -3.16 Hello World! 12345
2018.03.26 23:59:59   OrderTicket() = 3
2018.03.26 23:59:59   OrderMagicNumber() = 12345
2018.03.26 23:59:59   OrderComment() = Hello World!
2018.03.26 23:59:59   OrderTicketOpen() = 2
2018.03.26 23:59:59   #4 2018.03.25 00:00:00 buy 0.70 EURUSD 1.23527 0.00000 1.23614 2018.03.26 01:04:40 1.23614 0.00 0.00 49.27 tp 1.23614 12345
2018.03.26 23:59:59   OrderTicket() = 4
2018.03.26 23:59:59   OrderMagicNumber() = 12345
2018.03.26 23:59:59   OrderComment() = tp 1.23614
2018.03.26 23:59:59   OrderTicketOpen() = 2

stop loss!!!


PS Русская ветка обсуждения.