- www.mql5.com
Вы можете пропустить тики, если событие не поставлено в очередь. Бывает (в основном на VPS или медленном компьютере).
К сожалению, даже простые советники с одной только функцией OnTick пропускают тики. Для боевых советников используют CopyTicks-функции и другие ухищрения, чтобы работать без пропуска тиков.
Данная библиотека гарантировано не пропускает тики только в Тестере. Все точно также, как с OnTick.
/* // https://www.mql5.com/ru/blogs/post/755348 #define VIRTUAL_TESTER_MULTI // Запуск в виртуальном торговом окружении OnTickMulti #define VIRTUAL_LIMITS_TP_SLIPPAGE // Лимитники и TP исполняются по первой цене акцепта - положительные проскальзывания #define VIRTUAL_CLOSEALL_BYEND // Закрывает принудительно все ордера в конце тестирования // #define VIRTUAL_ALTERNATIVE // Альтернативная скорость расчетов */ #include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006 #include <fxsaber\OnTickMulti\OnTickMulti.mqh> // https://www.mql5.com/ru/code/47647 /* #define REPORT_TESTER // В тестере будут автоматически записываться отчеты #define REPORT_BROWSER // Создание отчета с запуском браузера - требует разрешения DLL. #include <Report.mqh> // https://www.mql5.com/ru/code/18801 */ input group "Trading" input double LotSize=0.01; input double TPdist=0.1; // TP (%) input double SLdist=0.2; // SL (%) input long MyMagic=123; input group "Benchmark: https://www.mql5.com/ru/forum/282062/page49#comment_50801337" input int inRange = 0; // Мультисимвольный OnTick. void OnTickMulti( const string &Symb, const int &Index ) { TradeStep(Symb, Index); } double OnTester() { return AccountInfoDouble(ACCOUNT_BALANCE); } int GetHour( const datetime time ) { return((int)(time / 3600) % 24); } void TradeStep( const string &symbol, const int &Index ) { if(GetHour(TimeTradeServer()) < 2) return; DoTrade(symbol, Index); } bool IsMySymbol( const string &Symb, const int &Index ) { return(OnTickMulti.IsOnlySymbolBase || ( #ifdef __VIRTUAL__ VIRTUAL::GetHandle() ? (OrderSymbolID() == Index) : // https://www.mql5.com/ru/forum/282062/page52#comment_51051261 #endif // #ifdef __VIRTUAL__ (OrderSymbol() == Symb))); } void DoTrade(const string &symbol, const int &Index ) { int total=OrdersTotal(); bool haveBuy=false; bool haveSell=false; for(int i=0; i<total; i++) { if(OrderSelect(i, SELECT_BY_POS) && OrderMagicNumber()==MyMagic && IsMySymbol(symbol, Index)) { int type=OrderType(); if(type==OP_BUY) haveBuy=true; if(type==OP_SELL) haveSell=true; } } if(!haveBuy) { double price=SymbolInfoDouble(symbol,SYMBOL_ASK); int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); double tp=NormalizeDouble(price*(1.0+TPdist/100.0), digits); double sl=NormalizeDouble(price*(1.0-SLdist/100.0), digits); OrderSend( symbol, OP_BUY, LotSize, price, 0, sl, tp, NULL, MyMagic); } if(!haveSell) { double price=SymbolInfoDouble(symbol,SYMBOL_BID); int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); double tp=NormalizeDouble(price*(1.0-TPdist/100.0), digits); double sl=NormalizeDouble(price*(1.0+SLdist/100.0), digits); OrderSend( symbol, OP_SELL, LotSize, price, 0, sl, tp, NULL, MyMagic); } }
Настройки Тестера.
Ускорение.
Можно ускорить, если раскомментировать вначале несколько строк.
Конфигурация | Результат |
---|---|
Without Virtual.mqh. | shortest pass 0:00:13.184, longest pass 0:00:15.031, average pass 0:00:13.633 |
With Virtual.mqh, inVirtualTester = false. | shortest pass 0:00:14.735, longest pass 0:00:16.384, average pass 0:00:15.081 |
With Virtual.mqh, inVirtualTester = true. | shortest pass 0:00:05.872, longest pass 0:00:05.964, average pass 0:00:05.919 |
With Virtual.mqh, inVirtualTester = true + VIRTUAL_ALTERNATIVE. | shortest pass 0:00:06.172, longest pass 0:00:07.791, average pass 0:00:06.524 |
Советник предельно простой (0-2 открытых позиций по каждому символу с фиксированными SL/TP, без отложенных ордеров), поэтому в таком варианте можно добиться ускорения лишь в 2.5 раза.
TickValue+Swap+Commission.
Выше тесты делались в режиме по пипсам (см. скрин настроек), чтобы не пересчитывать TickValue на каждом тике, подключая для этого другие символы. В этом режиме результаты идентичные.
Если нужно ускорение с полным фаршем, то надо использовать это решение.
- 2023.12.25
- www.mql5.com
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
fxsaber, 2024.03.18 18:36
void DoTrade(const string &symbol, const int &Index ) { int total=OrdersTotal(); bool haveBuy=false; bool haveSell=false; for(int i=0; i<total; i++) { if(OrderSelect(i, SELECT_BY_POS) && (OrderMagicNumber()==Index)) { int type=OrderType(); if(type==OP_BUY) haveBuy=true; if(type==OP_SELL) haveSell=true; } } if(!haveBuy) { double price=SymbolInfoDouble(symbol,SYMBOL_ASK); int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); double tp=NormalizeDouble(price*(1.0+TPdist/100.0), digits); double sl=NormalizeDouble(price*(1.0-SLdist/100.0), digits); OrderSend( symbol, OP_BUY, LotSize, price, 0, sl, tp, NULL, Index); } if(!haveSell) { double price=SymbolInfoDouble(symbol,SYMBOL_BID); int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); double tp=NormalizeDouble(price*(1.0-TPdist/100.0), digits); double sl=NormalizeDouble(price*(1.0+SLdist/100.0), digits); OrderSend( symbol, OP_SELL, LotSize, price, 0, sl, tp, NULL, Index); } }
Конфигурация | Результат |
---|---|
Without Virtual.mqh. | shortest pass 0:00:13.184, longest pass 0:00:15.031, average pass 0:00:13.633 |
Выше выделил в коде простой способ ускорения мультивалютного советника без каких-либо Virtual-библиотек.
Конфигурация | Результат |
---|---|
Without Virtual.mqh + MagicNumberOrderSymbol | shortest pass 0:00:08.608, longest pass 0:00:10.236, average pass 0:00:08.942 |
Бесплатное ускорение в 1.5 раза!
Проверил замедление Тестера при переходе от моносимвольного режима в мультисимвольный. Делал это не совсем идеально - советник пустышка.
Моносимвольный советник.
#property tester_no_cache input group "Benchmark: https://www.mql5.com/ru/forum/282062/page49#comment_50801337" input int inRange = 0; const ulong StartTime = GetMicrosecondCount(); int AmountTicks = 0; double OnTester() { return((double)(GetMicrosecondCount() - StartTime)); // return(AmountTicks); // return((double)AmountTicks / (GetMicrosecondCount() - StartTime)); } void OnTick() { AmountTicks++; }
Configuration (OnTick) | TimeLength (mcs) | AmountTicks | Performance (ticks/mcs) |
---|---|---|---|
EURUSD | 1079331 | 9927153 | 9.19 |
GBPUSD | 1229032 | 11309740 | 9.20 |
USDJPY | 1307322 | 11986756 | 9.16 |
USDCHF | 1121541 | 10359511 | 9.23 |
AUDUSD | 1175578 | 10758136 | 9.15 |
Хорошо видно, что производительность Тестера в виде количества тиков в единицу времени не зависит от символа (режим по пипсам).
Мультисимвольный советник.
#property tester_no_cache input group "Benchmark: https://www.mql5.com/ru/forum/282062/page49#comment_50801337" input int inRange = 0; #include <fxsaber\OnTickMulti\OnTickMulti.mqh> // https://www.mql5.com/ru/code/47647 const ulong StartTime = GetMicrosecondCount(); int AmountTicks = 0; double OnTester() { return((double)(GetMicrosecondCount() - StartTime)); // return(AmountTicks); // return((double)AmountTicks / (GetMicrosecondCount() - StartTime)); } // Мультисимвольный OnTick. void OnTickMulti( const string &Symb, const int &Index ) { AmountTicks++; }
Configuration (OnTickMulti) | TimeLength (OnTickMulti) | TimeLength (OnTick) | AmountTicks | Performance (OnTickMulti) | Performance (OnTick) |
---|---|---|---|---|---|
EURUSD | 3455901 | 1079331 | 9927153 | 2.87 | 9.19 |
EURUSD, GBPUSD | 6617085 | 2308363 | 21236893 | 3.20 | 9.19 |
EURUSD, GBPUSD, USDJPY | 9188781 | 3615685 | 33223649 | 3.61 | 9.18 |
EURUSD, GBPUSD, USDJPY, USDCHF | 11517804 | 4737226 | 43583160 | 3.78 | 9.20 |
EURUSD, GBPUSD, USDJPY, USDCHF, AUDUSD | 16058223 | 5912804 | 54341296 | 3.38 | 9.19 |
Производительность слабо зависит от количества символов, но при этом ниже в три раза.
Вывод.
Если ваш мультивалютный советник представляет из себя солянку из независимых моновалютных подТС, то будет (как минимум) в три раза быстрее оптимизировать каждую из подТС (и потом объединить через Validate в один проход) отдельно, чем оптимизировать всем скопом в одном мультивалютном советнике.
- www.mql5.com
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
OnTickMulti:
Мультисимвольный OnTick.
Автор: fxsaber