fxsaber #: Обратной связи нет, не всегда есть понимание, что залито в КБ криво. Обновил.
Спасибо.
По округлению комиссий на каждую сделку. У вас сделано без округления this.Commission = this.Lots * (ORDER_COMMISSION);, но как видно из распечаток - в тестере MQ округление идет вверх. Тестер MQ. Лот=1
N
Ticket
OpenTime
Type
Lots
Symbol
OpenPrice
StopLoss
TakeProfit
CloseTime
ClosePrice
Commission
Swap
Profit
Comment
Pips
Slippage
MagicNumber
LengthTime
Balance
1
1
2022.05.23 00:00:00.000
balance
+1000000.00
1000000.00
2
2
2022.05.23 00:15:00.518
buy
1.00 (211 265.00)
EURUSD
1.05654
1.05606
2022.05.23 00:15:07.480
1.05611
-3.41 (-3.41)
-43.00 (-49.00)
-43 (-49)
+1, +5
1
00:00:06.962
999953.59
Тестер MQ. Лот=0,01
N
Ticket
OpenTime
Type
Lots
Symbol
OpenPrice
StopLoss
TakeProfit
CloseTime
ClosePrice
Commission
Swap
Profit
Comment
Pips
Slippage
MagicNumber
LengthTime
Balance
1
1
2022.05.23 00:00:00.000
balance
+1000000.00
1000000.00
2
2(1)/5
2022.05.23 00:15:00.518
buy
0.01 (2 112.65)
EURUSD
1.05654
1.05606
2022.05.23 00:15:07.480
1.05611
-0.04 (-4.00)
-0.43 (-0.49)
tp 1.05606
-43 (-49)
+1, +5
1
00:00:06.962
999999.53
Если бы округляло правильно, то было бы -0,03, значит округляют вверх чем то вроде
где Points=1.0 / pow(10.0, DigitsCurrency); лучше 1 раз посчитать, чтобы потом не возводить степени тысячи раз. Или из таблички брать 0.1, 0,01 ....
*****************************
Еще посмотрел cвопы: при лоте=1
76490
152960(1)/152986
2022.05.23 23:54:43.620
buy
1.00 (213 789.00)
EURUSD
1.06907
1.06878
2022.05.24 00:15:49.581
1.06882
-3.42 (-3.42)
-7.71 (-7.71)
-25.00 (-30.00)
tp 1.06878
-25 (-30)
+1, +4
10
00:21:05.961
500316.23
76491
152983(1)/152990
2022.05.23 23:54:51.632
sell
1.00 (213 852.00)
EURUSD
1.06914
1.06938
2022.05.24 00:15:49.701
1.06938
-3.42 (-3.42)
3.09 (3.09)
-24.00
tp 1.06938
-24
1
00:20:58.069
500291.90
Свопы при лоте=0,01
76490
152960(1)/152986
2022.05.23 23:54:43.620
buy
0.01 (2 137.89)
EURUSD
1.06907
1.06878
2022.05.24 00:15:49.581
1.06882
-0.04 (-4.00)
-0.08 (-8.00)
-0.25 (-0.30)
tp 1.06878
-25 (-30)
+1, +4
10
00:21:05.961
994548.98
76491
152983(1)/152990
2022.05.23 23:54:51.632
sell
0.01 (2 138.52)
EURUSD
1.06914
1.06938
2022.05.24 00:15:49.701
1.06938
-0.04 (-4.00)
0.03 (3.00)
-0.24
tp 1.06938
-24
1
00:20:58.069
994548.73
Матматически правильно и оба в пользу ДЦ. В вашем тестере так же - через NormalizeDouble . Еще 2 символа проверил - у обоих математически правильно (например для NZDUSD -0,0148 округляет к -0,01, т.е. в убыток ДЦ, а -0,0175 к -0,02), т.е. свопам в тестере MQ применено NormalizeDouble (). Но это тестер, а как в реальности на реальном счете - надо кому-то проверить. Возможно тут недоработка тестера, если ДЦ все-таки всегда в прибыль себе округляют.
По округлению комиссий на каждую сделку. У вас сделано через NormalizeDouble(d, dig), судя по справке он округлит математически, но как видно из распечаток округление идет вверх.
Еще 2 символа проверил - у обоих математически правильно (например для NZDUSD -0,0148 округляет к -0,01, т.е. в убыток ДЦ, а -0,0175 к -0,02), т.е. свопам нужно NormalizeDouble (). Но это тестер, а как в реальности на реальном счете - надо кому-то проверить. Возможно тут недоработка тестера, если ДЦ все-таки всегда в прибыль себе округляют.
Сам тестирую в режиме по пипсам. Там свопов нет. И быстрее пашет.
В этом режиме еще и без комиссии. Тестер округляет и прибыль. Не округляются цены. Например, POSITION_PRICE_OPEN может быть ненормализованным числом при открытии позиции несколькими сделками.
В реальности комиссия может округляться в обе стороны. Был случай, когда на крипте торговля минимальным лотом вызывала нулевую комиссию. Некоторые из-за этого открывали массированно кучу позиций по мин. лоту.
Virtual совсем ничего не округляет, и так правильно. Report, конечно, показывать всю длину double не может, поэтому комиссию 0.1234 покажет, как 0.123, а не 0.12.
Попробуйте выставить одним OrderSend BuyLimit = Ask, TP = Bid. И увидите различия с тестером. Не эталон он, к сожалению.
Никто на этом форуме не в состоянии это дописать до рабочего состояния.
имел в виду сложность в подсчете комиссии для каждой закрытой позиции так, чтобы ее сумма совпала с реальностью суммой. Для этого нормализовывать ни в коем случае нельзя.
Да - ваш OnTester был вызван. Буду разбираться, почему в моем советнике он не вызывается.
Разобрался с OnTester() . 1) В вашем последнем примере используется #define VIRTUAL_TESTER в нем мой OnTester() не вызывается, а только ваш. Нашел почему: в конце вашего OnTester() надо вставить OldOnTester2();
#ifndef BESTINTERVAL_ONTESTER
doubleOnTester()
{Print ("OnTester virtual");
VIRTUAL::SelectByHandle(VirtualHandle);
#ifdef VIRTUAL_CLOSEALL_BYEND
VIRTUAL::Stop();
#endif // VIRTUAL_CLOSEALL_BYEND
OldOnTester2(); // <<<<<<<<<<------------------------- надо вставить OldOnTester2();
/* делать это в основном OnTester()
#ifdef VIRTUAL_ONTESTER_FORMULA
return(VIRTUAL_ONTESTER_FORMULA);
#else // VIRTUAL_ONTESTER_FORMULA
return(::AccountEquity());
#endif // VIRTUAL_ONTESTER_FORMULA
*/
}
#define OnTester OldOnTester2
#endif // BESTINTERVAL_ONTESTER
2) Я в своем коде подключаю виртуальный тестер, как в примере из КБ т.е. без #define VIRTUAL_TESTER и библиотечный OnTester() не запускается и не завершает открытые сделки в конце теста по VIRTUAL_CLOSEALL_BYEND. Видимо надо вызывать оба OnTester() независимо от VIRTUAL_TESTER
Перенес наверх от #ifdef VIRTUAL_TESTER в таком виде:
#ifndef BESTINTERVAL_ONTESTER
doubleOnTester(){
Print ("OnTester virtual");
for (int v = 0 ; v <= VIRTUAL::Total(); v++){
#ifdef VIRTUAL_CLOSEALL_BYEND
if (VIRTUAL::SelectByIndex(v)){
VIRTUAL::NewTick(); VIRTUAL::Stop(); //последний тик для стопов // закрыть незавершенные сделки
}
#endif // VIRTUAL_CLOSEALL_BYEND
OldOnTester2();
/* делать это в основном OnTester()
#ifdef VIRTUAL_ONTESTER_FORMULA
return(VIRTUAL_ONTESTER_FORMULA);
#else // VIRTUAL_ONTESTER_FORMULA
return(::AccountEquity());
#endif // VIRTUAL_ONTESTER_FORMULA
*/
}
return0.0;//заглушка, все нужное вернется из OldOnTester2()из цикла
}
#endif // BESTINTERVAL_ONTESTER#define OnTester OldOnTester2
но не компилируется, т.к. не видит OldOnTester. Я с переименованием функций не знаком, тут наверное у вас лучше получится решить эту задачу.
1) В вашем последнем примере используется #define VIRTUAL_TESTER в нем мой OnTester() не вызывается, а только ваш. Нашел почему: в конце вашего OnTester() надо вставить OldOnTester2();
Этот макрос нужен, чтобы сходу добавить в советник возможность тестирования в виртуалке. Поэтому только свой OnTester без запуска чужого (который может быть и не задан даже).
2) Я в своем коде подключаю виртуальный тестер, как в примере из КБ т.е. без #define VIRTUAL_TESTER и библиотечный OnTester() не запускается и не завершает открытые сделки в конце теста по VIRTUAL_CLOSEALL_BYEND. Видимо надо вызывать оба OnTester() независимо от VIRTUAL_TESTER
Если не используете этот макрос, то вариант с макросом для CloseAll теряет смысл.
В Вашем случае целесообразно
В OnTick в начале прописать VIRTUAL::NewTick(); - делаете, похоже.
В OnDeinit в начале прописать VIRTUAL::Stop();
Использовал в этом коде макросы, потому что девственный MQL4-style. Вставил макросы, чтобы сразу запахало без рутины прописывания пунктов выше.
Лучше рутина, чем когда своя функция вообще не вызывается. Я бы в основной OnTester() вставлял бы вызов виртуального типа VIRTUAL::OnTester (). В общем как с VIRTUAL::NewTick();
Есть предложение по ускорению. Orders.mqh IsChange() строка 80. Если у вас например 90 ордеров, и закрылся один из них, например 5-й, то потом код все ордера выше сместит их копированием 6->5, 7->6 ... 90->89. Работает, но долго. Можно просто переместить последний на место удаленного 90->5. Вместо 85 копирований, всего 1 (может и несколько, если они все на 1 тике закрылись). Вот так
Итоговый результат совпадает Есть смена порядка сделок в истории, для сделок закрывшихся на одном тике Старая версия
41583
41598
2022.05.30 23:50:09.897
sell
1.00 (215 604.00)
EURUSD
1.07797
1.07807
2022.05.30 23:50:12.538
1.07807
-10.00 (-14.00)
-10 (-14)
+4, 0
1
00:00:02.641
871985.00
41584
41595
2022.05.30 23:50:07.877
sell
1.00 (215 598.00)
EURUSD
1.07794
1.07805
2022.05.30 23:50:35.750
1.07804
-10.00 (-11.00)
-10 (-11)
0, +1
2
00:00:27.873
871975.00
41585
41596
2022.05.30 23:50:09.897
sell
1.00 (215 601.00)
EURUSD
1.07797
1.07804
2022.05.30 23:50:35.750
1.07804
-7.00 (-9.00)
-7 (-9)
+2, 0
3
00:00:25.853
871968.00
41586
41600
2022.05.30 23:50:12.538
buy
1.00 (215 597.00)
EURUSD
1.07807
1.07790
2022.05.30 23:51:07.013
1.07790
-17.00
-17
1
00:00:54.475
871951.00
Новая версия
41583
41598
2022.05.30 23:50:09.897
sell
1.00 (215 604.00)
EURUSD
1.07797
1.07807
2022.05.30 23:50:12.538
1.07807
-10.00 (-14.00)
-10 (-14)
+4, 0
1
00:00:02.641
871985.00
41584
41596
2022.05.30 23:50:09.897
sell
1.00 (215 601.00)
EURUSD
1.07797
1.07804
2022.05.30 23:50:35.750
1.07804
-7.00 (-9.00)
-7 (-9)
+2, 0
3
00:00:25.853
871978.00
41585
41595
2022.05.30 23:50:07.877
sell
1.00 (215 598.00)
EURUSD
1.07794
1.07805
2022.05.30 23:50:35.750
1.07804
-10.00 (-11.00)
-10 (-11)
0, +1
2
00:00:27.873
871968.00
41586
41600
2022.05.30 23:50:12.538
buy
1.00 (215 597.00)
EURUSD
1.07807
1.07790
2022.05.30 23:51:07.013
1.07790
-17.00
-17
1
00:00:54.475
871951.00
Для оценки ускорения сделал расчет за неделю: old Clear Pass time: 8.456 s. Report Generation time: 12.100 s. 2023.11.26 17:54:09.333 EURUSD,M5: 537636 ticks, 1725 bars generated. Environment synchronized in 0:00:00.049. Test passed in 0:00:21.745 (including ticks preprocessing 0:00:00.063).
new Clear Pass time: 7.978 s. Report Generation time: 12.068 s. 2023.11.26 17:50:08.349 EURUSD,M5: 537636 ticks, 1725 bars generated. Environment synchronized in 0:00:00.046. Test passed in 0:00:21.316 (including ticks preprocessing 0:00:00.078).
Пол секунды разница, ускорение около 6%.
П.С. Хотя возможно не стоит это применять. Любители сравнивать распечатки (вроде меня) тестера MQ и виртуального будут озадачены не полным совпадением.
в тестере не получается получить эти финальные сделки.
Запустите этот советник на интервале в один день (много сделок), включив в исходник Report.
Запустите этот советник на интервале в один день (много сделок), включив в исходник Report.
Скопировал отсюда https://www.mql5.com/ru/code/viewcode/18801/288604/report.mq5
При компиляции ошибка:
'DiapasonToString' - undeclared identifier Report.mqh 3440 76
А там
Если убрать комментарий
#ifdef __MQL5__
то компилируется.
Да - ваш OnTester был вызван. Буду разбираться, почему в моем советнике он не вызывается.
Скопировал отсюда https://www.mql5.com/ru/code/viewcode/18801/288604/report.mq5
При компиляции ошибка:
'DiapasonToString' - undeclared identifier Report.mqh 3440 76
Обратной связи нет, не всегда есть понимание, что залито в КБ криво. Обновил.
Спасибо.
По округлению комиссий на каждую сделку. У вас сделано без округления this.Commission = this.Lots * (ORDER_COMMISSION);, но как видно из распечаток - в тестере MQ округление идет вверх.
Тестер MQ. Лот=1
1.05606
Тестер MQ. Лот=0,01
1.05606
Если бы округляло правильно, то было бы -0,03, значит округляют вверх чем то вроде
где Points=1.0 / pow(10.0, DigitsCurrency); лучше 1 раз посчитать, чтобы потом не возводить степени тысячи раз. Или из таблички брать 0.1, 0,01 ....
*****************************
Еще посмотрел cвопы:
при лоте=1
1.06878
1.06938
Свопы при лоте=0,01
1.06878
1.06938
Матматически правильно и оба в пользу ДЦ. В вашем тестере так же - через NormalizeDouble .
Еще 2 символа проверил - у обоих математически правильно (например для NZDUSD -0,0148 округляет к -0,01, т.е. в убыток ДЦ, а -0,0175 к -0,02), т.е. свопам в тестере MQ применено NormalizeDouble (). Но это тестер, а как в реальности на реальном счете - надо кому-то проверить. Возможно тут недоработка тестера, если ДЦ все-таки всегда в прибыль себе округляют.
0.64680
0.64603
По округлению комиссий на каждую сделку. У вас сделано через NormalizeDouble(d, dig), судя по справке он округлит математически, но как видно из распечаток округление идет вверх.
Еще 2 символа проверил - у обоих математически правильно (например для NZDUSD -0,0148 округляет к -0,01, т.е. в убыток ДЦ, а -0,0175 к -0,02), т.е. свопам нужно NormalizeDouble (). Но это тестер, а как в реальности на реальном счете - надо кому-то проверить. Возможно тут недоработка тестера, если ДЦ все-таки всегда в прибыль себе округляют.
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Библиотеки: Virtual
fxsaber, 2023.11.23 19:39
Сам тестирую в режиме по пипсам. Там свопов нет. И быстрее пашет.
В этом режиме еще и без комиссии. Тестер округляет и прибыль. Не округляются цены. Например, POSITION_PRICE_OPEN может быть ненормализованным числом при открытии позиции несколькими сделками.
В реальности комиссия может округляться в обе стороны. Был случай, когда на крипте торговля минимальным лотом вызывала нулевую комиссию. Некоторые из-за этого открывали массированно кучу позиций по мин. лоту.
Virtual совсем ничего не округляет, и так правильно. Report, конечно, показывать всю длину double не может, поэтому комиссию 0.1234 покажет, как 0.123, а не 0.12.
Попробуйте выставить одним OrderSend BuyLimit = Ask, TP = Bid. И увидите различия с тестером. Не эталон он, к сожалению.
ЗЫ Когда говорил такое,
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
MQL5 Ордера истории
fxsaber, 2023.11.21 13:41
Никто на этом форуме не в состоянии это дописать до рабочего состояния.имел в виду сложность в подсчете комиссии для каждой закрытой позиции так, чтобы ее сумма совпала с реальностью суммой. Для этого нормализовывать ни в коем случае нельзя.
Да - ваш OnTester был вызван. Буду разбираться, почему в моем советнике он не вызывается.
Разобрался с OnTester() .
1) В вашем последнем примере используется #define VIRTUAL_TESTER в нем мой OnTester() не вызывается, а только ваш. Нашел почему: в конце вашего OnTester() надо вставить OldOnTester2();
Результат
2023.11.26 13:34:03.334 2022.05.30 23:59:30 OnTester virtual
2023.11.26 13:34:03.334 2022.05.30 23:59:30 OnTester main
2) Я в своем коде подключаю виртуальный тестер, как в примере из КБ т.е. без #define VIRTUAL_TESTER и библиотечный OnTester() не запускается и не завершает открытые сделки в конце теста по VIRTUAL_CLOSEALL_BYEND. Видимо надо вызывать оба OnTester() независимо от VIRTUAL_TESTER
Перенес наверх от #ifdef VIRTUAL_TESTER в таком виде:
но не компилируется, т.к. не видит OldOnTester. Я с переименованием функций не знаком, тут наверное у вас лучше получится решить эту задачу.
1) В вашем последнем примере используется #define VIRTUAL_TESTER в нем мой OnTester() не вызывается, а только ваш. Нашел почему: в конце вашего OnTester() надо вставить OldOnTester2();
Этот макрос нужен, чтобы сходу добавить в советник возможность тестирования в виртуалке. Поэтому только свой OnTester без запуска чужого (который может быть и не задан даже).
2) Я в своем коде подключаю виртуальный тестер, как в примере из КБ т.е. без #define VIRTUAL_TESTER и библиотечный OnTester() не запускается и не завершает открытые сделки в конце теста по VIRTUAL_CLOSEALL_BYEND. Видимо надо вызывать оба OnTester() независимо от VIRTUAL_TESTER
Если не используете этот макрос, то вариант с макросом для CloseAll теряет смысл.
В Вашем случае целесообразно
Использовал в этом коде макросы, потому что девственный MQL4-style. Вставил макросы, чтобы сразу запахало без рутины прописывания пунктов выше.
без рутины прописывания пунктов выше.
Лучше рутина, чем когда своя функция вообще не вызывается. Я бы в основной OnTester() вставлял бы вызов виртуального типа VIRTUAL::OnTester (). В общем как с VIRTUAL::NewTick();
Есть предложение по ускорению. Orders.mqh IsChange() строка 80. Если у вас например 90 ордеров, и закрылся один из них, например 5-й, то потом код все ордера выше сместит их копированием 6->5, 7->6 ... 90->89. Работает, но долго.
Можно просто переместить последний на место удаленного 90->5. Вместо 85 копирований, всего 1 (может и несколько, если они все на 1 тике закрылись).
Вот так
Итоговый результат совпадает
Есть смена порядка сделок в истории, для сделок закрывшихся на одном тике
Старая версия
1.07807
1.07805
1.07804
1.07790
Новая версия
1.07807
1.07804
1.07805
1.07790
Для оценки ускорения сделал расчет за неделю:
old
Clear Pass time: 8.456 s.
Report Generation time: 12.100 s.
2023.11.26 17:54:09.333 EURUSD,M5: 537636 ticks, 1725 bars generated. Environment synchronized in 0:00:00.049. Test passed in 0:00:21.745 (including ticks preprocessing 0:00:00.063).
new
Clear Pass time: 7.978 s.
Report Generation time: 12.068 s.
2023.11.26 17:50:08.349 EURUSD,M5: 537636 ticks, 1725 bars generated. Environment synchronized in 0:00:00.046. Test passed in 0:00:21.316 (including ticks preprocessing 0:00:00.078).
Пол секунды разница, ускорение около 6%.
П.С.
Хотя возможно не стоит это применять. Любители сравнивать распечатки (вроде меня) тестера MQ и виртуального будут озадачены не полным совпадением.
Пол секунды разница, ускорение около 6%
Спасибо, проверю предложение.
Я бы в основной OnTester() вставлял бы вызов виртуального типа VIRTUAL::OnTester ().
Нет такой функции. Более того, непонятно, зачем она может быть нужна.
Тестирование в виртуалке - это просто один из бонусов концепции виртуалки. Сценариев использования гораздо больше.