Вопрос по MT Language!!! - страница 3

 
во втором случае условие не даст выполнить тело цикла, так как i небудет равно 0 что означает выход из цикла.
правельно:
  for(int i=Bars; i>=0; i--)
    {
     high=High[i]; low=Low[i];
     UpBuffer[i]=high;
     DnBuffer[i]=low;
     MdBuffer[i]=(high+low)/2;
    }
 
Кроме того, в обоих фрагментах, по-моему, должно быть i=Bars-1, так как отсчет баров начинается с нулевого, то первый же цикл приведет к считыванию данных из несуществующего бара.
 
Подскажите пожалуйста почему значение DnBuffer в нижеприведенном коде, на первых от начала Range-1
интервалах равно 0.

//+------------------------------------------------------------------+
//| PChannel_m.mq4 |
//+------------------------------------------------------------------+

#property indicator_chart_window //Назначаем окно для вывода графика (там, где бары)
#property indicator_buffers 3 //Выделяем для индикатора три буфера
#property indicator_color1 DodgerBlue //Назначаем цвет для отображения данных 1 буфера
#property indicator_color2 DodgerBlue //Назначаем цвет для отображения данных 2 буфера
#property indicator_color3 DodgerBlue //Назначаем цвет для отображения данных 3 буфера
//---- input parameters //объявление вводимых внешних параметров
extern int Range=14; //по умолчанию вводимое значение равно 14
//---- buffers
double UpBuffer[]; //обявление массива UpBuffer типа "число с плавающей точкой"
double DnBuffer[]; //обявление массива DnBuffer типа "число с плавающей точкой"
double MdBuffer[]; //обявление массива MdBuffer типа "число с плавающей точкой"
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init() //инициализация переменных
{
string short_name; //обявление переменной short_name типа "строковый"
//---- indicator line
SetIndexStyle(0,DRAW_LINE,1,2); //установка стиля для первого значения индикатора
SetIndexStyle(1,DRAW_LINE,1,2); //установка стиля для второго значения индикатора
SetIndexStyle(2,DRAW_LINE,2); //установка стиля для третьего значения индикатора
SetIndexBuffer(0,UpBuffer); //значение записываемое в 0 буфер равно переменной UpBuffer
SetIndexBuffer(1,DnBuffer); //значение записываемое в 1 буфер равно переменной DnBuffer
SetIndexBuffer(2,MdBuffer); //значение записываемое в 2 буфер равно переменной MdBuffer
//---- name for DataWindow and indicator subwindow label
short_name="PriceChannel("+Range+")"; //переменной short_name присваиваем строковое
//значение равное выражению
IndicatorShortName(short_name); //для отображения на графике присвоим индикатору краткое
//наименование
SetIndexLabel(0,"Up Channel"); //для отображения на графике присвоим метке отображающей
//значения 0 буфера имя Up Channel
SetIndexLabel(1,"Down Channel"); //для отображения на графике присвоим метке отображающей
//значения 1 буфера имя Down Channel
SetIndexLabel(2,"Middle Channel"); //для отображения на графике присвоим метке отображающей
//значения 2 буфера имя Middle Channel
//----
SetIndexDrawBegin(0,0); //установка начальной точки прорисовки для 0 буфера
SetIndexDrawBegin(1,0); //установка начальной точки прорисовки для 1 буфера
SetIndexDrawBegin(2,0); //установка начальной точки прорисовки для 2 буфера
//----
return(0); //возврат из секции инициализации
}
//+------------------------------------------------------------------+
//| PriceChannel |
//+------------------------------------------------------------------+
int start() //начало программы (расчета)
{
int i,k; //объявление целочисленной переменной i,k
double high,low,price; //объявление переменных high,low,price типа число с плавающей точкой
//----

high=High[Bars-1]; //присваиваем начальные значения переменной
low=Low[Bars-1]; //присваиваем начальные значения переменной
for(i=Bars-1;i>=0;i--)
{
if(Bars<Range)
{
k=i;
while(k>=0)
{
if(High[k]>high) high=High[k];
if(Low[k]<low) low=Low[k];
k--;
}
}
else
{
k=i+Range-1;
while(k>=i)
{
if(High[k]>high) high=High[k];
if(Low[k]<low) low=Low[k];
k--;
}
}
UpBuffer[i]=high;
DnBuffer[i]=low;
MdBuffer[i]=(high+low)/2;
high=High[i];
low=Low[i];
}
return(0);
}
//+------------------------------------------------------------------+
 
To Profi_R

Первая ошибка в том, что Вы пишите не советник, а индикатор, поэтому Bars всегда равно количеству баров на данный момент, а не на том баре, на котором рисуется индикатор. Следовательно, условие if(Bars<Range)
никогда не выполняется, у Вас наверняка истории больше 14 баров. Значит выполняется вторая часть условия (после else), в которой тоже допущена ошибка. Строка k=i+Range-1. i-1 - это уже вся история, Вы еще прибавляете Range. Естественно, все High и Low за пределами истории равны 0. Когда данные начинают браться из существующей истории, то High сразу принимает нормальное значение, так как выполняется условие High>0, а вот Low меньше 0 быть не может и поэтому low обнуляется до тех пор, пока данные берутся из несуществующей истории, т.е. величина Range.

P.S. По-моему, с Вами спорили нужен отладчик или нет, еще раз убеждаюсь, что нужен. Не очень-то удобно через принт ошибки ловить.
 
Мысль понял. Спасибо. А необходимость отладчика на оспаривал, сам ратую за него , т.к. пишешь код, получаешь результат не соответствующий рассчитанному (или вообще зависание как программы так и системы) и не знаешь на каком этапе в какой переменной какое значение, тем более что осваиваешь MQL4 методом научного тыка. :)
 
To Profi_R

А зачем Вы так дико мучаетесь в поисках максимумов и минимумов? Есть же стандартные функции. Попробуйте заменить тело своего индикатора (int start) на это:

int start() //начало программы (расчета)
{
int i;
for(i=Bars-1;i>=0;i--)
{
UpBuffer[i]=High[Highest(NULL,0,MODE_HIGH,Range,i)];
DnBuffer[i]=Low[Lowest(NULL,0,MODE_LOW,Range,i)];
MdBuffer[i]=(UpBuffer[i]+DnBuffer[i])/2;
}
}

Гораздо компактнее, а результат тот же и ошибиться негде. Если Вы, конечно, не собираетесь использовать Ваши промежуточные расчеты. С уважением.
 
Пардон, return(0) забыл, все никак привыкнуть не могу
 
а можно описательные синонимы ошибок добавить в stdlib.mqh?
добавив "#define ERR_NOT_ENOUGH_MONEY 134"

ведь гораздо приятнее использовать конструкции типа "case ERR_NOT_ENOUGH_MONEY:"
чем "case 134:"

к тому же в первых (ещё летних) версиях программ встречались какие-то константы ошибок с описательными названиями.

или просто пока руки не дошли до этого? тогда примите этот пост как ненавязчивое напоминание :)
 
Если у меня MQL-программа будет зависеть от 10-ти файлов, то будет в MetaEditor встроена какая-нибудь возможность отслеживать зависимости между файлами и автоматической перекомпиляции модулей зависимых от изменённого?
Имхо, какая-нибудь лёгенькая встроенная функциональность утилиты make не помешала бы.
 
прошу прощения, немного коряво вопрос зада, но я думаю смысл его ясен.
Причина обращения: