Фича в эмуляции развития бара при тестировании эксперта.

 
Фича в эмуляции развития бара при тестировании эксперта.
Здравствуйте, уважаемые разработчики!

Хочу обратить Ваше внимание на один момент, который принято сейчас называть "фичей". Фича заключается в некорректном моделировании баров во время тестирования экспертов. Приведу код простейшего эксперта:

/*[[
Name := First High Low Expert
Author := Copyright © 2002, Company
Link := http://www.company.com/
Lots := 1.00
Stop Loss := 0
Take Profit := 0
Trailing Stop := 0
]]*/

Vars: stepIndx(0),numBars(0);

if stepIndx = 0 then Begin
stepIndx = 1;
Print("Дата Время High Low");
end;

if Bars <> numBars then Begin
numBars=Bars;
SetArrow(Time[0],High[0],4,Yellow);
SetArrow(Time[0],Low[0],4,Red);
Print(TimeToStr(Time[0]), " ", NumberToStr(High[0], 2), " ", NumberToStr(Low[0], 2));
end;

Тестировал на USDJPY (2 знака после запятой в NumberToStr) 1 мин. (здесь нередки бары с объемами = 1, т.е. High-Low=5). Далее данные из лог-файла загрузил в Excel и обнаружил, что на некоторых барах High-Low всего 4 пункта!
Кроме того, еще SetArrow на некоторых барах (кажется именно на тех, на которых как раз High-Low всего 4 пункта) рисует желтую черточку поверх красной, хотя в логах High и Low на этих барах различаются. У меня версия MetaTrader 3.14 build 3126, на 3.20 не проверял.

Далее попробовал написать индикатор в точности повторяющий график, нарисованный данным экспертом. Вот что получилось:

/*[[
Name := First High Low Indicator
Author := Copyright © 2002, Company
Link := http://www.company.com/
Separate Window := No
First Color := Cyan
First Draw Type := Line
First Symbol := 217
Use Second Data := Yes
Second Color := Magenta
Second Draw Type := Line
Second Symbol := 218
]]*/
Variable: FloatDigits(0), PointPrice(0), HalfSpredPrice(0), SpredPrice(0), Shift(0), CurHigh(0), CurLow(0);

If PointPrice = 0 Then Begin
PointPrice = Point;
While PointPrice < 1 Begin
FloatDigits = FloatDigits + 1;
PointPrice = PointPrice * 10;
End;
SpredPrice = Ask - Bid;
HalfSpredPrice = Normalize(SpredPrice / 2, FloatDigits + 1);
Print("Дата Время High Low");
For Shift = Bars - 1 DownTo 0 Begin
CurLow = Normalize(Open[Shift] - HalfSpredPrice, FloatDigits);
CurHigh = CurLow + SpredPrice; // Правильнее это поместить за следующим If
// А так - это воспроизведение MT ошибки: после этого на некоторых барах выползает спред в 4 пункта!
If CurLow < Low[Shift] Then
CurLow = Low[Shift];

//CurHigh = CurLow + SpredPrice; // Сюда было бы правильнее это поместить
If CurHigh > High[Shift] Then //Begin // надо бы здесь вместе с CurHigh и CurLow подкорректировать
CurHigh = High[Shift];
// CurLow = CurHigh - SpredPrice;
//End;

SetIndexValue(Shift, CurHigh);
SetIndexValue2(Shift, CurLow);

Print(TimeToStr(Time[Shift]), " ", NumberToStr(CurHigh, FloatDigits), " ", NumberToStr(CurLow, FloatDigits));
End;
End;

Сравнил данные из лог-файла в Excel, получилось один в один. Комментарии вставлены по месту, вроде добавить особо больше нечего, если только пожелание. Я думаю, не помешала бы встроенная функция типа моей переменной FloatDigits, для использования с текущим инструментом в функции Normalize.

Кроме того, у меня давно возник по этому поводу вопрос с mtapi.dll. После всех этих экспериментов в MT я вернулся к тому месту кода, который пишу с использованием mtapi.dll, где у меня вычисляются по пришедщим Bid/Ask уровни OHLC. До этого я приводил эти данные к 8-байтовому числу с плавающей запятой (в Delphi тип Double) через свою Normalize, где Result := Round(Price * Multiply) / Multiply; (для USDJPY Multiply=100). Таким образом, Open и Close вычислялись как Normalize((Bid+Ask)/2,Multiply). High и Low точно соответствовали историческим данным, скачанным потом с сервера MT, а вот Open и Close на многих барах отличались на 1 пункт. Ясно, что все дело в неидентичном округлении. Проанализировав данные и поэкспериментировав в Excel, я пришел к выводу, что все же Open и Close надо считать как Int(Price * Multiply) / Multiply; (Int - целая часть от числа), чтобы данные получались идентичными с MT. Тогда для спреда, равного пяти, Open от первого Bid будет отстоять всегда на 2 пункта. Но что-то мне это утверждение не очень нравится, т.к. в MT текущая цена Close отстоит от Bid то на 2 пункта, а то на 3. Разъясните, пожалуйста, правильно ли я считаю?

Итак подъитожу свои замечания/предложения/вопросы:
1. Собственно фича.
2. Неверная работа SetArrow
3. функция типа FloatDigits
4. Вычисление Open и Close при использовании mtapi.dll

Спасибо за внимание. Вячеслав.
 
будем проверять в понедельник
Причина обращения: