Библиотеки: Virtual - страница 8

 

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

В этот раз я сделал простой и быстрый расчет для инструментов по типу EURUSD, AUDUSD ... при валюте депозита USD  и для всей крипты, там все к USDT.  Т.е. если валюта котировки == валюте счета, то расчет будет верным.

#define COMMISSION_TO_PRICE 2 // умножить полученную комиссию на цену, например для EURUSD *=1.12345; 1 - комиссия берется только при входе, 2 - комиссия берется 2 раза и при входе и при выходе

Комиссия просто умножается на OpenPrice или ClosePrice. Для инструментов по типу USDJPY или если валюта депозита не USD(T), опцию можно отключать, т.к. она не будет точной (как и ваш текущий вариант).

#ifdef ORDER_COMMISSION
 this.Commission = this.Lots * (ORDER_COMMISSION);
 #ifdef COMMISSION_TO_PRICE
   this.Commission *= this.OpenPrice + (COMMISSION_TO_PRICE==2 ? this.ClosePrice : 0.0);
 #endif // COMMISSION_TO_PRICE
#endif// ORDER_COMMISSION

Вот что получилось на EURUSD:

ДЦ:
Virtual c * на цену
Virtual без * на цену

 

Как видите с добавленной опцией комиссия отличается всего на 18 центов для 140 сделок. А без нее на 42 доллара. Можно конечно подобрать в вашем варианте средний множитель не 4, а 4.305 например (средняя комиссия за тест), но это надо будет делать вручную каждому инструменту и перекомпилировать.

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


Файлы:
Order.mqh  36 kb
 
Forester #:

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

Много времени надо было, чтобы въехать во все нюансы и оценить слабые/сильные стороны. Не сдюжил.

В этот раз я сделал простой и быстрый расчет для инструментов по типу EURUSD, AUDUSD ... при валюте депозита USD  и для всей крипты, там все к USDT.  Т.е. если валюта котировки == валюте счета, то расчет будет верным.

На самом деле эта формула работает всегда.

Commission = 0.002%; // per side.

OrderCommission = (OrderOpenPrice + OrderClosePrice) * Commission * OrderLots * TickValue / TickSize;

Можно конечно подобрать в вашем варианте средний множитель не 4, а 4.305 например (средняя комиссия за тест), но это надо будет делать вручную каждому инструменту и перекомпилировать.

Другой вариант.

input double inCommission = 0;
// .....
#define ORDER_COMMISSION inCommission // Задание комиссии (OrderCommission() = OrderLots() * (ORDER_COMMISSION)), включая динамический вариант.

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

Полностью согласен, что правка полезная и должна быть внесена. Надо проверить для частичного закрытия (OrderClose не на весь лот) и CloseBy. Для проверки достаточно написать скрипт, где на одном и том же тике открываются две разнонаправленные позиции и делается сразу частичное и CloseBy-закрытие. Сам пока не готов этим заниматься. Если от Вас будет такой скрипт с корректным результатом, внесу Ваши правки быстрее.

 
fxsaber #:

На самом деле эта формула работает всегда.

Вам это проще, вы постоянно в теме. А я урывками занимаюсь. Вот первый раз с июля снова решил потестировать что-то...

Насчет
OrderClosePrice
- есть наверное ДЦ, которые комиссию только при открытии берут - для них лучше не учитывать. Для пипсовки разница будет небольшая, а для больших целей уже заметна.
 
fxsaber #:
Полностью согласен, что правка полезная и должна быть внесена. Надо проверить для частичного закрытия (OrderClose не на весь лот) и CloseBy. Для проверки достаточно написать скрипт, где на одном и том же тике открываются две разнонаправленные позиции и делается сразу частичное и CloseBy-закрытие. Сам пока не готов этим заниматься. Если от Вас будет такой скрипт с корректным результатом, внесу Ваши правки быстрее.
То что там закоментировано я тестировал и я оставил это рабочей версией. Но сейчас уже всё забылось. CloseBy - не пользуюсь, идеи попроще обычно. Тоже нет времени на это. Пока есть энтузиазм - займусь стратегией.
 

Virtual добавляет комиссию несработавшим лимиткам:


Видимо надо делать проверку на тип
 
Forester #:

Virtual добавляет комиссию несработавшим лимиткам:

Видимо надо делать проверку на тип
#define ORDER_COMMISSION -5 // Задание комиссии (OrderCommission() = OrderLots() * (ORDER_COMMISSION)), включая динамический вариант.
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577

void OnStart()
{
  if (VIRTUAL::SelectByHandle(VIRTUAL::Create()))
  {
    VIRTUAL::NewTick();
    
    OrderDelete(OrderSend(_Symbol, OP_BUYLIMIT, 1, 0.01, 0, 0, 0));
    
    Print(VIRTUAL::ToString(1));
  }
}


Результат.

#2 2025.11.25 19:23:11.105 buy limit 1.00 EURGBP.pro 0.01000 0.00000 0.00000 2025.11.25 19:23:11.105 0.87715 0.00 0.00 0.00 0 - 00:00:00


Работает правильно. Видимо, эти правки требуют доп. проверки.

 
fxsaber #:

Работает правильно. Видимо, эти правки требуют доп. проверки.

Вы правы.

В ToClose() добавил расчет комиссий вне if (this.IsPosition()){

Исправил, файл приложил

Файлы:
Order.mqh  37 kb
 

Считываю из Virtual на каждом тике эквити и баланс и создаю график. До сегодняшнего дня не было заметно, но сегодня поставили огромные свопы -66.

График стал таким



А должен быть, как запись из МТ5

Итоговый профит как видно, отличается на несколько центов из за ошибок округления комиссий (применил реальные, а не в пунктах) и свопов (так и не понял как в МТ округляют - не через round()).

Сумма свопов сегодня для этого расчета -5208.97. Как раз размер скачка на графике. Думаю, что свопы не добавляются к эквити и балансу по ходу расчета, а применяются только в конце, потому и выглядит так.

Я вызываю VIRTUAL::CalcSwaps(..) в OnTester() Как то можно при виртуальной торговле это сделать? На каждом тике слишком накладно будет. Наверное надо в начале каждого дня. Может это уже запрограммировано и надо каким то дефайном включить? Помню, что в своей версии я делал свопы на каждый день, т.к. у вас как то по другому. Если вы не сделали за прошедшее время это, то могу скинуть тот свой код для примера.

 
Aleksei Kuznetsov #:

Может это уже запрограммировано и надо каким то дефайном включить? Помню, что в своей версии я делал свопы на каждый день, т.к. у вас как то по другому. Если вы не сделали за прошедшее время это, то могу скинуть тот свой код для примера.

Не делал. Но для решения задачи построения Balance/Equity-Curve делал бы один раз CalcSwaps в OnTester и после этого соответствующую однопроходную корректировку Balance[]/Equity[]. Это супер-дешево и точно.

Вся канитель со свопами в MT5 видится ущербной, т.к. истории свопов нет. И на большой истории результаты жутко кривые при учете свопов. Может так случиться, что на выходных оптимизировали, а потом лучшие проходы из opt-файлов показывают совсем иные значения, если будут делаться на буднях.

Все же MT5-тестер не эталон.