Типичные ошибки и способы их устранения при работе с торговым окружением

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Artyom Trishkin
Модератор
52443
Artyom Trishkin  
В данной теме будем обсуждать часто встречающиеся ошибки при работе с торговым окружением терминала в тех или иных алгоритмах, методы их устранения и избегания в дальнейшем.
Andrei Fandeev
35937
Andrei Fandeev  
Ок.
Для затравки:
Советник анализирует направление (или профит, ... ) последнего закрывшегося ордера. Последний закрылся 2 суток назад.
А трейдер выставил глубину истории 1 день.
OrdersHistoryTotal() не видит уже тот ордер.
Решение?
Artyom Trishkin
Модератор
52443
Artyom Trishkin  
Andrei Fandeev:
Ок.
Для затравки:
Советник анализирует направление (или профит, ... ) последнего закрывшегося ордера. Последний закрылся 2 суток назад.
А трейдер выставил глубину истории 1 день.
OrdersHistoryTotal() не видит уже тот ордер.
Решение?

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

МТ5 позволяет загрузить историю на нужную глубину.

Andrei Fandeev
35937
Andrei Fandeev  
Artyom Trishkin:

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

Полагаться на пользователя - плохая затея. Нужна проверка.
Артём, в МТ4 не нашёл Get для получения значения установленной глубины истории.
Её действительно невозможно получить программно?

Artyom Trishkin
Модератор
52443
Artyom Trishkin  
Andrei Fandeev:

Полагаться на пользователя - плохая затея. Нужна проверка.
Артём, в МТ4 не нашёл Get для получения значения установленной глубины истории.
Её действительно невозможно получить программно?

Действительно.

fxsaber
16746
fxsaber  

Есть две парадигмы работы с торговым окружением, написания советников.

  1. Событийные входы (OnTick, OnTimer и т.д.) зависят друг от друга. Есть информация, которую ОБЯЗАТЕЛЬНО (не для ускорения, вроде кеша, а для работоспособности) нужно иметь между событиями. Например, нужно сохранить результат OrderSendAsync и использовать его в OnTradeTransaction. Кеши - это НЕ обязательная информация и используются только для ускорения. Поэтому их не учитываем сразу.
  2. Событийные входы (OnTick, OnTimer и т.д.) НЕ зависят друг от друга. Каждый вход с чистого листа. Примерно, как Скрипт, который Вы запускаете самостоятельно на каждое событие.
В MT4, наверное, все можно было решить через второй вариант. MT5 - не так однозначно.


Преимущества второго варианта перед первым

  • Можно в любом месте (штатно и нештатно) завершить работу алгоритма.
  • В любом месте запустить/продолжить.
  • Высокая надежность.


Недостатки

  • В Тестере будет уступать по производительности первому варианту.
  • Логика "с чистого листа" заставляет писать несколько "нелогичный" код, что требует привычки на первом этапе.

fxsaber
16746
fxsaber  

Как сравнить API торговых окружений? Представим большое количество разнообразных ТС. И представим свой идеальный виртуальный API, который бы позволял минимальными усилиями воплощать ТС в надежном коде.

Если из реального API возможно создать в виде обертки этот самый идеальный виртуальный API, то исходный API отличный. Несмотря даже на то, сколько требуется сил и времени на создание обертки.


MT4 и MT5 по этому критерию являются отличными API. Сложны только исходные API, но они позволяют (нет архитектурных/технических ограничений) написать великолепную обертку, а значит хороши.

Поэтому, когда говорят, что MT5 сложнее MT4 - имеют в виду, что не встретили еще MT5-обертки (возможно, она еще не написана), которая настолько же удобна, как используемая ими обертка в MT4.


В общем, обе платформы позволяют из низкоуровневых API создать единый высокоуровневый API (обертка). Так что сложности API торговых окружений у них равны!

fxsaber
16746
fxsaber  

У MT4 исходный API довольно высокоуровневый, поэтому мало кто пытается написать универсальную более удобную обертку. Но с MT5 дела обстоят иначе - исходный низкоуровневый API просто ТРЕБУЕТ написания хоть какой-то обертки. Поэтому в данной теме не много смысла обсуждать особенности каждой из оберток. Скорее, важно показать, что обертка все же потребуется. Какие особенности низкоуровневого API все же нужно учитывать при написании высокоуровневого API.

В общем, обе платформы позволяют из низкоуровневых API создать единый высокоуровневый API (обертка). Так что сложности API торговых окружений у них равны!

Исходя из этого утверждения нужно научиться писать MT5-код, ничем не уступающий по удобству MT4-коду. API обертки могут быть разными (как правило, это синтаксис), но архитектурно MT5 не должен уступать MT4, иначе теряется смысл выделенного утверждения. Поэтому более громоздкий MT5-код следует воспринимать, не как повод для критики, а как помощь для зашивания его в не менее удобную в работе обертку, чем MT4.

fxsaber
16746
fxsaber  
Возьмем простой MT4-шаблон ТС

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

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

fxsaber, 2018.02.15 23:19

// Шаблон большинства ТС

#property strict // обязательно

// Сигнал на покупку
bool BuySignal( const string Symb ) { return(true); }

// Сигнал на продажу
bool SellSignal( const string Symb ) { return(false); }

// Находит ордер соответствующего типа
bool OrdersScan( const string Symb, const int Type )
{
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() == Type) && (OrderSymbol() == Symb))
      return(true);    
    
  return(false);  
}

// Торговое действие на сигнал
bool Action( const string Symb, const int Type, const double Lots = 1 )
{
  bool Res = true;    
  
  // Закрыли противоположные сигналу позиции
  while ((OrdersScan(Symb, 1 - Type)) && (Res = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100)));

  // Открыли позицию по сигналу
  return(Res && !OrdersScan(Symb, Type) && OrderSend(Symb, Type, Lots, SymbolInfoDouble(Symb, Type ? SYMBOL_BID : SYMBOL_ASK), 100, 0, 0));
}

// Шаблон торговой стратегии
void Strategy( const string Symb )
{
  if (BuySignal(Symb))
    Action(Symb, OP_BUY);
  else if (SellSignal(Symb))
    Action(Symb, OP_SELL);
}

void OnTick()
{
  Strategy(_Symbol);
}

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


Казалось бы, пишем то же самое на MT5

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

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

fxsaber, 2018.02.15 22:30

// Шаблон большинства ТС

#include <Trade/Trade.mqh>

// Сигнал на покупку
bool BuySignal( const string Symb ) { return(true); }

// Сигнал на продажу
bool SellSignal( const string Symb ) { return(false); }

// Находит позицию соответствующего типа
bool PositionsScan( const string Symb, const ENUM_POSITION_TYPE Type )
{
  for (int i = PositionsTotal() - 1; i >= 0; i--)
    if ((PositionGetSymbol(i) == Symb) && (PositionGetInteger(POSITION_TYPE) == Type))
      return(true);    
    
  return(false);  
}

// Торговое действие на сигнал
bool Action( const string Symb, const ENUM_POSITION_TYPE Type, const double Lots = 1 )
{
  static CTrade Trade;    
  bool Res = true;    
  
  // Закрыли противоположные сигналу позиции
  while ((PositionsScan(Symb, (ENUM_POSITION_TYPE)(1 - Type))) && (Res = Trade.PositionClose(PositionGetInteger(POSITION_TICKET))));

  // Открыли позицию по сигналу
  return(Res && !PositionsScan(Symb, Type) && (Type ? Trade.Sell(Lots, Symb) : Trade.Buy(Lots, Symb)));
}

// Шаблон торговой стратегии
void Strategy( const string Symb )
{
  if (BuySignal(Symb))
    Action(Symb, POSITION_TYPE_BUY);
  else if (SellSignal(Symb))
    Action(Symb, POSITION_TYPE_SELL);
}

void OnTick()
{
  Strategy(_Symbol);
}

По какой-то причине некоторые пишут больше кода для таких же ТС. Но на самом деле этот код справляется не хуже. Большинство ТС требуют написания только BuySignal и SellSignal. Больше ничего не нужно.

Пример шаблона специально написан с помощью СБ. Поэтому вопрос к спецам по MT5, код правильный?


Красным помечена функция, которая показывает необходимость обертки. Ее проблема описана здесь. Кто-то вспомнит, что это древняя проблема повторных открытий позиций, которую еще в древности решали через Sleep, дожидаясь, когда же после OrderSend откроется позиция. Но на самом деле данная проблема никак не касается OrderSend. Нужно уметь правильно считывать торговое окружение.

fxsaber
16746
fxsaber  
fxsaber:

Нужно уметь правильно считывать торговое окружение.

Правильный вариант на простом примере

// Возвращает количество позиций по символу
int GetAmountPositions( const string Symb )
{
  int Res = 0;
  
  for (int i = PositionsTotal() - 1; i >= 0; i--)
    if (PositionGetSymbol(i) == Symb)
      Res++;
      
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderGetTicket(i) && (OrderGetInteger(ORDER_TYPE) <= ORDER_TYPE_SELL) &&
        !OrderGetInteger(ORDER_POSITION_ID) && (OrderGetString(ORDER_SYMBOL) == Symb))
      Res++;  

/*
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (OrderSymbol() == Symb))
      Res++;
*/      
  return(Res);
}

Смысл вкратце таков: если стоит маркет-ордер, считай, что и это "позиция". В кавычках, потому что это оберточная позиция. Выделенный код, как правило, нигде не фигурирует. Но он позволяет избегать повторных открытий позиций. Самое интересное здесь - выделенное красным. Необходимость этой фишки не сразу осознать.

Дело в том, что есть так называемые закрывающие маркет-ордера. Те же SL/TP. Очевидно, что такие маркет-ордера видеть в виде "позиций" не хотелось бы. Да и те ордера, которые сам выставил для закрытия - аналогично. Вот выделенное условие и является соответствующим фильтром.


ЗЫ Вставьте этот код сюда и проверьте результат на демо-сервере.

Artyom Trishkin
Модератор
52443
Artyom Trishkin  
fxsaber:

Правильный вариант на простом примере

Смысл вкратце таков: если стоит маркет-ордер, считай, что и это "позиция". В кавычках, потому что это оберточная позиция. Выделенный код, как правило, нигде не фигурирует. Но он позволяет избегать повторных открытий позиций. Самое интересное здесь - выделенное красным. Необходимость этой фишки не сразу осознать.

Дело в том, что есть так называемые закрывающие маркет-ордера. Те же SL/TP. Очевидно, что такие маркет-ордера видеть в виде "позиций" не хотелось бы. Да и те ордера, которые сам выставил для закрытия - аналогично. Вот выделенное условие и является соответствующим фильтром.


ЗЫ Вставьте этот код сюда и проверьте результат на демо-сервере.

Вопрос: что будет, если после отсылки торгового приказа до следующего тика маркет-ордер не будет выставлен сервером?

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий