Особенности языка mql4, тонкости и приёмы работы - страница 6

 
fxsaber:
В отличие от MQL5, в MQL4 статические массивы могут менять размер.
Не всегда

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

Новая версия платформы MetaTrader 5 build 1595: доступ к ценовой истории

fxsaber, 2017.05.01 16:36

#property strict

template <typename T>
struct ARRAY
{
  T Simple[100];
};

void OnStart()
{
  int ArraySimple[100];
  ARRAY<int> Array;

  Print(ArrayResize(Array.Simple, 10)); // MQL4: -1
  Print(ArrayResize(ArraySimple, 10));  // MQL4: 10
  
  Print(ArraySize(ArraySimple));        // MQL4: 10
  Print(ArraySize(Array.Simple));       // MQL4: 100
}
 

Всегда в MT4 был баг в Трейлинг Стоп. Если понаблюдать во время сильного вверх-вниз движения цены,
то можно заметить движение SL вверх-вниз. Вот поймал малое движение, бывает во много раз больше
2017.05.22 10:53:38.563    '9898616': trailing stop #1465775202 -> 1.29765
2017.05.22 10:53:38.483    '9898616': trailing stop #1465775202 -> 1.29764
2017.05.22 10:53:33.236    '9898616': trailing stop #1465775202 -> 1.29763
2017.05.22 10:53:33.130    '9898616': trailing stop #1465775202 -> 1.29764
2017.05.22 10:53:32.813    '9898616': trailing stop #1465775202 -> 1.29762
Получилось когда SL = 2 (для простоты последняя цифра), на очередном тике цена поднялась и терминал выдал приказ поднять SL до 4.
На следующем тике цена опустилась, а SL пока стоит на 2. Термина выдал приказ ПОДНЯТЬ SL до 3.
Сервер, как жираф с длинной шеей, обработав первый приказ, поднял SL до 4. Обработав второй приказ, ОПУСТИЛ SL до 3.
Получается, что терминал выдает лишние бессмысленные приказы, что увеличивает нагрузку на сервер.
Кроме того, имеется риск лишней потери для трейдера из-за обратного движения SL.
Это касается и программного трейлинга советником или скриптом. Частично исправляем движением SL шагом в 3..5 пунктов.

Что делать. Запоминать величину SL, выданную в последнем приказе OrderModify.
И расчет следующего приказа производить от этой величины.
Было бы так: на два приказа серверу меньше, движение SL только вперед, уменьшение загрузки процессора компьютера
2017.05.22 10:53:38.563    '9898616': trailing stop #1465775202 -> 1.29765
2017.05.22 10:53:33.130    '9898616': trailing stop #1465775202 -> 1.29764
2017.05.22 10:53:32.813    '9898616': trailing stop #1465775202 -> 1.29762

 

При модификациях ордеров часто приходится сравнивать предыдущий TP/SL с новым изменяемым значением. Т.к. если будет попытка модификации старым значением, получим ошибку №1.

Возьмем для примера, что нужно сравнивать старый SL (100.03) и новый SL(100.02) для USDJPY (Digits = 2). В справке написано:

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

Т.е. сравнить нужно таким образом:

if(NormalizeDouble(100.03 - 100.02, Digits) != 0) // можно модифицировать

Но иногда брокер может давать ненормализованные цены. И к примеру, мы получили цену не 100.02, а 100.025. Сравнив по вышеуказанной схеме получим разность 0.01, т.е. можно модифицировать. Но передав для модификации нормализованную до Digits 100.025, мы фактически передадим 100.03 и соответственно получим ошибку №1.

В общем, опытным путем пока пришел к тому, что при одинаковом Digits для модификаций лучше сравнивать разность нормализованных чисел с нулём (что справка не рекомендует делать).

Скрипт для проверки:

void OnStart()
{
  double a = 0.02;
  double b = 0.015;
  
  Print(" norm1 dif=", ND(a - b));            // результат = 0.01
  Print(" norm2 dif=", ND(a) - ND(b));        // результат = 0.0
}

double ND(double d) {return NormalizeDouble(d, 2);}
Вещественные типы (double, float) - Типы данных - Основы языка - Справочник MQL4
Вещественные типы (double, float) - Типы данных - Основы языка - Справочник MQL4
  • docs.mql4.com
Вещественные типы (double, float) - Типы данных - Основы языка - Справочник MQL4
 
if(MathAbs(a-b)>=Point)
 
Yurij Kozhevnikov:
Да, можно и так. Это первый способ сравнения, приведенный в справке. Я просто указал на ловушку с нормализацией вещественных чисел, в которую попадал сам, используя второй способ, рекомендуемый документацией.
 
Комментарии, не относящиеся к этой теме, были перенесены в "Организация цикла перебора ордеров".
 

В отличие от OrderProfit() в MT4 OrderCommission() хранит данные не округленные до центов.


ЗЫ В OrderPrint() комиссия округлена (как в GUI).

 
fxsaber:

В отличие от OrderProfit() в MT4 OrderCommission() хранит данные не округленные до центов.


ЗЫ В OrderPrint() комиссия округлена (как в GUI).

Соответственно, чтобы получить верное значение OrderProfit()+OrderComission()+OrderSwap(), что нужно сделать?

 
Artyom Trishkin:

Соответственно, чтобы получить верное значение OrderProfit()+OrderComission()+OrderSwap(), что нужно сделать?

Ничего! Это и есть наиболее верное значение. Благодаря такой комиссии можно наблюдать в GUI, что суммарная комиссия отличается на цент от суммы тех чисел, что показывает GUI.

 
fxsaber:

Ничего! Это и есть наиболее верное значение. Благодаря такой комиссии можно наблюдать в GUI, что суммарная комиссия отличается на цент от суммы тех чисел, что показывает GUI.

Тогда совсем не понял. Что вы имеете в виду под "OrderCommission() хранит данные не округленные до центов" ? А где они округлённые? И как они округлены?