Ускорение работы советника и усовершенствованная система торговли

 

Здравствуйте уважаемые профессионалы MQL. Как Вы считаете ускорит ли работу советника создание внутренней базы данных ордеров, которая копирует внешнюю,и используется для сложных расчетов и привязки доп. параметров. На сколько сильно время обращение к переменной объекта, отличается от получения данных SL или PRICE_OPEN позиции? Например:

1) Каждому ордеру нужно привязать тикет локирующего ордера

2) Связать ордера в сетку и открывать ордера не по одному а созданием объектов класса Setka, которые при помощи внутренних ф-й исходя из внешних параметров сами будет ставить ордера и управлять ими. Цель: выставлять сетки ордеров с входными параметрами начало сетки (цена), конец сетки (цена), % от баланса не опускаясь до постановки конкретного ордера. Как бы Вы реализовали выполнение этой задачи? Заранее спасибо.

 

скажем так - исполнение это не замедлит, а создание роботов упростит :-)

конечно пишутся классы

 
Ekaterina Belova:

Здравствуйте уважаемые профессионалы MQL. Как Вы считаете ускорит ли работу советника создание внутренней базы данных ордеров, которая копирует внешнюю,и используется для сложных расчетов и привязки доп. параметров. На сколько сильно время обращение к переменной объекта, отличается от получения данных SL или PRICE_OPEN позиции?

Ускорение нужно только в Тестере при Оптимизации.  Сетка ордеров тормозит не из-за обращения советника, а из-за соответствующей архитектуры самого Тестера. Производительность просто проваливается.

Вот воспроизводимое исследование на эту тему

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

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

fxsaber, 2018.11.16 01:33

Пока не в состоянии что-то серьезное написать, решил сделать замеры.

Тестовый советник

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

//#define VIRTUAL_ON // Тестер или Virtual

#ifdef VIRTUAL_ON
  #include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577
  
  const int Init = VIRTUAL::Select(VIRTUAL::Create());
  
  void OnTick()
  {
    VIRTUAL::NewTick();
  }
/*  
  double OnTester()
  {
    return(AccountEquity());
  } */
#endif // VIRTUAL_ON

input int inRange = 0;          // 1 .. 5
input int inAmount = 1;         // Amount of positions
input int iTakeProfit  = 10000; // TakeProfit in pips

uint iStartTime;

void OnInit()
{  
  iStartTime = GetTickCount(); // Начинается замер специально в OnInit, а не снаружи
  
  const double Price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
  
  for (int i = 0; i < inAmount; i++)
    OrderSend(_Symbol, OP_BUY, 0.1, Price, 100, 0, Price + iTakeProfit * _Point);
}

double OnTester()
{
  return(GetTickCount() - iStartTime);
}


22 млн тиков в режиме по всем тикам. Терминалы запускались с RAMDrive. Только одно ядро задействовано. Выбран лучший результат из Оптимизации в 5 прогонов. Кросс-перерасчет выключен. Время указано в секундах. Hedge, Forex, MaxCustom. Исходный баланс 10 млн. В MT5 кастомный символ (свопы и комиссия отсутствуют).

AmountMT5-TesterMT4-TesterMT5-Virtual (x64) MT4-Virtual (x32) (w/o strict)
002.88603.43203.86906.209
108.23711.24704.08706.677
214.36713.08904.19708.159
317.58117.03604.49310.998
420.90522.21504.69610.296
523.11925.61604.94513.558
2061.21568.85807.59735.568


С увеличением одновременно открытых позиций (Amount) заметно растет время выполнения. MT4 проигрывает MT5 по скорости в режиме Тестера и в режиме Virtual.

Virtual значительно быстрее MT5-тестера и слабо зависит от Amount.


Любители сеточных ТС могут увеличить скорость оптимизации почти на порядок, если будут использовать Virtual.

Virtual не затачивался на большое количество одновременных ордеров, но переваривает их неплохо. Чего не скажешь про MT-тестеры. Там, похоже, отсутствует совсем оптимизация в этом месте.


До теста пришла в голову идея, как ускорить Virtual, чтобы количество ордеров почти не влияло на производительность. Но полученные результаты, честно говоря, удивили. Сложно сказать, стоит ли этим заниматься в Virtual. Но 100% это нужно делать в MT5-Тестере.


ЗЫ После замеров понял, что в MT4 не использовал strict-режим. Перезамерять не стал


По коду видно, что никакого обращения к торговому окружению советник не делает, т.е. кешировать просто нечего. Однако, происходит огромный провал в производительности.

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

 
Ekaterina Belova:

Здравствуйте уважаемые профессионалы MQL. Как Вы считаете ускорит ли работу советника создание внутренней базы данных ордеров, которая копирует внешнюю,и используется для сложных расчетов и привязки доп. параметров. На сколько сильно время обращение к переменной объекта, отличается от получения данных SL или PRICE_OPEN позиции? Например:

1) Каждому ордеру нужно привязать тикет локирующего ордера

2) Связать ордера в сетку и открывать ордера не по одному а созданием объектов класса Setka, которые при помощи внутренних ф-й исходя из внешних параметров сами будет ставить ордера и управлять ими. Цель: выставлять сетки ордеров с входными параметрами начало сетки (цена), конец сетки (цена), % от баланса не опускаясь до постановки конкретного ордера. Как бы Вы реализовали выполнение этой задачи? Заранее спасибо.

Сам делаю так.

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

2. Далее, отслеживаем появление условия выставления ордера и COrder *order=new COrder(передаваемые параметры);

3. После чего, если выход по стопу, остается на каждом тике проверять условие того, что ордер благополучно закрылся: if (order.Control()==ORDER_CLOSED) delete order;

Общее направление такое. По поводу ускорения работы в тестере - скорее всего замедляется. Внутри класса все равно вызывать параметры ордера надо, правда не всегда все нужны, а обращение к куче затратнее по времени, чем к стеку. Зато удобство написания.

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

Как-то так.

 
Ekaterina Belova:

Здравствуйте уважаемые профессионалы MQL. Как Вы считаете ускорит ли работу советника создание внутренней базы данных ордеров, которая копирует внешнюю,и используется для сложных расчетов и привязки доп. параметров. На сколько сильно время обращение к переменной объекта, отличается от получения данных SL или PRICE_OPEN позиции? Например:

1) Каждому ордеру нужно привязать тикет локирующего ордера

2) Связать ордера в сетку и открывать ордера не по одному а созданием объектов класса Setka, которые при помощи внутренних ф-й исходя из внешних параметров сами будет ставить ордера и управлять ими. Цель: выставлять сетки ордеров с входными параметрами начало сетки (цена), конец сетки (цена), % от баланса не опускаясь до постановки конкретного ордера. Как бы Вы реализовали выполнение этой задачи? Заранее спасибо.

Для истории ордеров имеет смысл создать свою базу, точнее массив структур. Потому-что в истории параметры не меняются. При этом, работая с историей ордеров, освобождаешься от необходимости постоянно проверять успешность OrderSelect(). Давно собираются такое сделать, все руки не доходят. А вот с рыночными - нет смысла, все равно на каждом тике их надо будет перебирать. Впрочем, можно все в один массив, и историю и рыночные, отсортированный по времени открытия. Однако, иногда бывает нудна сортировка по времени закрытия - это второй массив, разумеется рыночные ордера в нем отсутствуют.

1. Это просто - через глобальную переменную терминала.

2. Тут всякие случаи бывают. Сетки разные бывают. Если количество ордеров в сетке четко определено, то используется переменная bool, если true, значит эксперт находится в процессе установки сетки. Тут важно в случае ошибки установки очередного ордера разобраться с причиной, что бы принять решение, продолжать попытки или закончить.  

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

 
Dmitry Fedoseev:

При этом, работая с историей ордеров, освобождаешься от необходимости постоянно проверять успешность OrderSelect().

Эта проверка мизерно влияет на производительность в целом. Историю кешировать имеет смысл в случае множественных SELECT_BY_TICKET. Это тот еще тормоз, т.к. он проверяет наличие тиков среди живых, а потом среди мертвых.

А вот с рыночными - нет смысла, все равно на каждом тике их надо будет перебирать.

Некоторые специально для ускорения используют OnTrade совместно с OnTick.

так же в Тестере желательно выбрасывать проверку OrderSymbol() и прочие ненужности. Т.е. специально создавать Тестерный вариант советника.

Но для сеточников все равно основные тормоза - сам Тестер.

 
Dmitry Fedoseev:

Для истории ордеров имеет смысл создать свою базу, точнее массив структур. Потому-что в истории параметры не меняются. При этом, работая с историей ордеров, освобождаешься от необходимости постоянно проверять успешность OrderSelect(). Давно собираются такое сделать, все руки не доходят. А вот с рыночными - нет смысла, все равно на каждом тике их надо будет перебирать. Впрочем, можно все в один массив, и историю и рыночные, отсортированный по времени открытия. Однако, иногда бывает нудна сортировка по времени закрытия - это второй массив, разумеется рыночные ордера в нем отсутствуют.

1. Это просто - через глобальную переменную терминала.

2. Тут всякие случаи бывают. Сетки разные бывают. Если количество ордеров в сетке четко определено, то используется переменная bool, если true, значит эксперт находится в процессе установки сетки. Тут важно в случае ошибки установки очередного ордера разобраться с причиной, что бы принять решение, продолжать попытки или закончить.  

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

Извиняюсь конечно не в тему но хотелось бы услышать мнение профессионала. Как организовывать стандартный шаблон при создании советника? так сказать каковы критерии хорошего начального набора для советника из шаблона?

 
BillionerClub:

Извиняюсь конечно не в тему но хотелось бы услышать мнение профессионала. Как организовывать стандартный шаблон при создании советника? так сказать каковы критерии хорошего начального набора для советника из шаблона?

Долго рассказывать, да и не пытался пока сформулировать так, что бы четко и лаконично, и в совершенной форме. Что бы появился шаблон, сначала должен сформироваться универсальный подход. А что бы сформировался универсальный подход, нужен опыт. Собственно и шаблона особо нет, есть коллекция функций. В коллекцию функция отправляется после того, как одну и ту же задачу пришлось решить раз 10, тогда получается универсальная функция, которая может пригодиться. Конечно можно сесть и наделать функций, которые будут казаться полезными пока их пишешь, а потом никаким боком они никуда не полезут.  

 
Ekaterina Belova:

Здравствуйте уважаемые профессионалы MQL. Как Вы считаете ускорит ли работу советника создание внутренней базы данных ордеров, которая копирует внешнюю,и используется для сложных расчетов и привязки доп. параметров. На сколько сильно время обращение к переменной объекта, отличается от получения данных SL или PRICE_OPEN позиции? Например:

1) Каждому ордеру нужно привязать тикет локирующего ордера

2) Связать ордера в сетку и открывать ордера не по одному а созданием объектов класса Setka, которые при помощи внутренних ф-й исходя из внешних параметров сами будет ставить ордера и управлять ими. Цель: выставлять сетки ордеров с входными параметрами начало сетки (цена), конец сетки (цена), % от баланса не опускаясь до постановки конкретного ордера. Как бы Вы реализовали выполнение этой задачи? Заранее спасибо.

Я с Чебурашками(туннелями) ордеров так делал. Хм... Типо сетка это "ордер" с суммарным лотом и виртуальной точкой нуля... Нагрузка будет очень высокой...
Причина обращения: