Вопросы к MQ: О функции Highest() и пользовательских индикаторах

 
Вопросы к MQ: О функции Highest() и пользовательских индикаторах
Добрый день.

1) Ниже приведен пример индикатора. Суть его в компрессии минуток в 4-х часовки. Я хотел использовать для этого функцию Highest().
Но оказалось, что она неверно работает. Как видно из примера, я заменил её на цикл. Из отладочной печати видно, что цикл и функция возвращают разные значения. Почему ?. Это баг, или я неверно понимаю смысл Вашей функции Highest().

2) Как упоминал Steel_Rat в вопросе "Ошибки в custom indicator (+) MT3.12 build 2917 - ", не всегда работает кнопка "Обновить индикатор". Я с этим также столкнулся. Прошу проверить.

3) Поясните, пожалуйста, подробнее смысл функции SetLoopCount() при исполльзовании её в коде индикатора.
Я задаю вопрос, т.к. столкнулся со следующим.
Если я вызваю SetLoopCount(0) в индикаторе при расчёте исторических баров, то код индикатора вызывается только при смене бара, если не вызываю, то код индикатора вызывается для каждого тика.
Как это связано с смыслом самой функции SetLoopCount() ?
Есть ли разница от использования функции SetLoopCount() при вызове кода индикатора для исторического бара и для текущего ?

4) Не воспринимайте этот вопрос как упрёк, а отнеситесь к нему с помиманием и конструктивно.
Хочу выразить своё недоумение по поводу Вашего подхода к расчётам значений индикаторов, а для исторических данных особенно.
Вы говорите, что значения индикаторов раcчитываются до запуска эксперта. Возникает вопрос, почему при этом код индикатора должен отслеживать сам все исторические бары.
Логичнее было бы интерпретатору кода вызвать в цикле код индикатора для каждого исторического бара, как для текущего, тем более, что эксперт в это время ещё не запущен, и можно не устанавливать лимит времени на выполнение цикла. При этом код индикатора был бы идентичен для любого бара.
Насколько я знаю, такой подход используется в ОМЕГЕ и Метастоке.
Это очень удобно, экономично и позволяет организовать рекурсию.
Почему Вы избрали другой подход, и возможно ли его изменить в сторону предлагаемого мною ?

У уважением, NIL.
 
Привожу код индикатора к вопросу
/*[[
Name := NILiH4MA
Author := Copyright © 2002, Company
Link := http://www.company.com/
Separate Window := No
First Color := Blue
First Draw Type := Line
First Symbol := 217
Use Second Data := Yes
Second Color := Red
Second Draw Type := Line
Second Symbol := 218
Notes := From M1 Build H4 and MA from H4
]]*/
Inputs: frame(21), AppPrice(PRICE_HIGH);
Vars: Per(240);
Vars : prevBars(0), Enter(0), CurBar(0),
minBar(0), maxBar(0), step(300);
Vars: ii(0), hh(0), hha(0);

//SetLoopCount(0);
if Period != 1 then exit;
Comment("Bars=", Bars);
//If prevBars = Bars Then Exit;
//prevBars = Bars;

// First Time
if enter >= 0 then
Begin
Comment("Wait...");
//print("Enter");
maxBar = Bars - 1 - Step*enter;
enter = enter + 1;
minBar = Bars - 1 - Step*enter;
if minBar < 0 then Begin minBar = 0; enter = -1; SetLoopCount(0); End;
/*
For CurBar = maxBar downto minBar
Begin
SetIndexValue(CurBar, 0);
SetIndexValue2(CurBar, 0);
End;
*/

For CurBar = maxBar downto minBar
Begin
if CurBar > Bars-1-Per then
Begin
SetIndexValue(CurBar, 0);
SetIndexValue2(CurBar, 0);
Continue;
End;
if AppPrice = PRICE_CLOSE then
Begin
SetIndexValue( CurBar, Close[CurBar] );
SetIndexValue2(CurBar, 0);
End
else
if AppPrice = PRICE_HIGH then
Begin
hha = 0;
for ii = CurBar to CurBar-1+Per
Begin
if hha < High[ii] then
Begin
hha = High[ii];
hh = ii;
End;
End;
//hh = Highest(PRICE_HIGH, CurBar, Per);
SetIndexValue( CurBar, High[hh] );
SetIndexValue2(CurBar, 0);
//SetArrow(Time[hh], High[hh], 218, Blue);
print("Bars=", Bars, " TimeHH=", TimeToStr(Time[hh]), " Time=", TimeToStr(Time[CurBar]), " CurBar=", CurBar, " hh=", hh, " Highest=", Highest(MODE_HIGH, CurBar, Per));
End
else
if AppPrice = PRICE_LOW then
Begin
hha = 99999;
for ii = CurBar to CurBar-1+Per
Begin
if hha > Low[ii] then
Begin
hha = Low[ii];
hh = ii;
End;
End;
//hh = Lowest(PRICE_LOW, CurBar, Per);
SetIndexValue( CurBar, Low[hh]);
SetIndexValue2(CurBar, 0);
End
else
if AppPrice = PRICE_OPEN then
Begin
SetIndexValue( CurBar, Open[CurBar-1-Per] );
SetIndexValue2(CurBar, 0);
End;
End;

End
else
Begin
Comment("Ok!", "\n", "Bars=", Bars, "\n", "PRICE_HIGH = ",
PRICE_HIGH, "\n", "PRICE_LOW = ", PRICE_LOW);
if Volume = 1 then
Begin
if Bars < Per then
Begin
SetIndexValue(0, 0);
SetIndexValue2(0, 0);
End;
if AppPrice = PRICE_CLOSE then
Begin
SetIndexValue( 0, Close );
SetIndexValue2(0, 0);
End
else
if AppPrice = PRICE_HIGH then
Begin
hha = 0;
for ii = 0 to Per-1
Begin
if hha < High[ii] then
Begin
hha = High[ii];
hh = ii;
End;
End;

//hh = Highest(PRICE_HIGH, 0, Per);
SetIndexValue( 0, High[hh] );
SetIndexValue2(0, 0);
End
else
if AppPrice = PRICE_LOW then
Begin
hha = 99999;
for ii = 0 to Per-1
Begin
if hha > Low[ii] then
Begin
hha = Low[ii];
hh = ii;
End;
End;
//print("Bars=", Bars, " TimeHH=", TimeToStr(Time[hh]), " Time=", TimeToStr(Time[0]), " hh=", hh, " Lowest=", Lowest(MODE_LOW, 0, Per));
//hh = Lowest(PRICE_LOW, 0, Per);
SetIndexValue( 0, Low[hh] );
SetIndexValue2(0, 0);
End
else
if AppPrice = PRICE_OPEN then
Begin
SetIndexValue( 0, Open[Per-1] );
SetIndexValue2(0, 0);
End;
End;

End;
 
Пооддерживаю и подтверждаю аргументы NIL касательно п.4
 
RE: Поддерживаю и подтверждаю аргументы NIL касательно п.4
Благодарю за поддержку.
Надеюсь, что и многие другие пользователи MQII согласны с этим.
Хочется, чтобы MQII стал поистине могучим средством.

С уважением, NIL.
 
Хотите ли вы чтобы могучее средство тормозило при реальной торговле?
Не думаете ли вы что чем больше возможностей будет в MT, тем больше будет всяких задержек в работе терминала. Как по-вашему это отразится при реальной торговле? Если вы хотите крутую программу тех-анализа это одно. А если вы хотите терминал, который будет обеспечивать вам быструю связь с брокером и оперативное получение котировок - это другое. Определитесь!
 
функция Highest возвращает смещение наибольшего значения, а не значение
2. действие кнопки Refresh проверим
3. SetLoopCount устанавливает предельное количество выполняемых инструкций за один запуск эксперта. это - защита от бесконечного цикла.
4. во-первых, наш подход гораздо менее затратен по ресурсам. во-вторых, попробуйте в той же омеге организовать смещение рассчитанных значений скользящего среднего (экспоненциального или сглаженного) вперёд на несколько баров (как в аллигаторе). поверьте, первая версия custom indicator была именно так организована, как в омеге, и эксперт вызывался на каждом баре. была даже введена переменная CurrentBar. нам не понравились возникшие в связи с этим ограничения.
 
позволю себе процитировать описание функции Highest
Highest
- возвращает смещение относительно текущего бара наибольшего значения Open, Low, High, Close или Volume (в зависимости от параметра type) за определённое число периодов.
Синтаксис: Highest( type, beginbar, periods )
Параметры:
type - возвращаемая переменная, может принимать одно из значений: MODE_OPEN, MODE_LOW, MODE_HIGH, MODE_CLOSE, MODE_VOLUME
beginbar - смещение, показывающее, начиная с какого бара от текущего надо брать данные.
periods - число периодов, на которых производится расчёт.
===
на форуме неоднократно обсуждалась эта функция
вместо hh = Highest(PRICE_HIGH, CurBar, Per);
надо писать hh = Highest(PRICE_HIGH, Per, Per);
а если мы учитываем текущий бар, то
hh = Highest(PRICE_HIGH, Per-1, Per);
 
повторю аргументацию по п.4
во-первых, наш подход гораздо менее затратен по ресурсам. во-вторых, попробуйте в той же омеге организовать смещение рассчитанных значений скользящего среднего (экспоненциального или сглаженного) вперёд на несколько баров (как в аллигаторе). поверьте, первая версия custom indicator была именно так организована, как в омеге, и эксперт вызывался на каждом баре. была даже введена переменная CurrentBar. нам не понравились возникшие в связи с этим ограничения.
 
Протестировал - логично, Вы правы.
 
stringo, Благодарю за разъяснения.
 
RE:Хотите ли вы чтобы могучее средство тормозило при реальной торговле
Одно от другого неотделимо, поэтому надо искать компромис.
А что касается скорости работы кода индикатора, то это в большей степени задача интерпретатора языка при всех остальных равных условиях.
Вы не сможете убедить меня в том, что лучше написать 100 строк кода на MQLII вместо 4-х на Омеге. Эффективность работы кода зависит во многом от того, насколько эффектино язык решает задачу данной предметной облати. Язык MQII, как и EL, это, в первую очередь, язык удобной и эффективной обработки таймсерий, и это он должен делать и описывать компактно и лучше всего остального на свете. А касаемо скрорости - это задача компилятора. А плохой програмер плохо и медленно напишет и на С++.
Хочу ещё раз напомнить, что речь идёт об эффективном синтаксисе языка , а не о скорости его интерпретеции.
И потом, я что-то не заметил, чтобы Омега медленно считала. Индикатор, который я приводил в качесте примера молотит в Омеге удовлетворительна на выборке в 12000 точек (пару секунд) без всяких сообщений о превышении лимита времени даже при отладочной печати, чего, не могу, к сожалению, сказать об MQLII (приходится ждать большое количество тиков).

Я благодарен Вам за отзывчивость, за участие в дискуссии, а то скучновато было.
Прошу не разжигать страсти и относиться к этому философски, я уважаю Ваше мнение, и конечно всё ещё много раз взвешу и проверю. Я верю в будущую могучую версию нашего MQL III, которую нам обещают разработчики, и тогда мы покажем Омеге, что мы тоже кое-что умеем.

С уважением, NIL.
Причина обращения: