Что с массивами в MQL4?

 

Столкнулся с такой вот проблемой, может кто поможет?

Дилинговый центр: Fibo.

Суть проблемы: Объявляем массив например TBuffer[] типа Double. Пишем: TBuffer[i]=Bid; i++; Вроде все просто, да вот только не очень. Появляются в массиве значения, которых нет в графике, либо если этот массив начать выводить на экран, то значения будут меняться возможно вообще хаотично. Т.е. только что было допустим 1.3276, а стало 1.3268 и т.д. (пример организации тикового графика).

Вторая не совсем понятка: Если мы начинаем сдвигать массив for (int i:=TBufferCount;i>=0;i--);TBuffer[i+1]=TBuffer[i];TBuffer[0]=Bid;TBufferCount++; В данной ситуации появляются значения EMPTY_VALUE при банальном переносе. Пробовал присваивать значения переменной: TVarible=TBuffer[i]; TBuffer[i+1]=TVarible; все одно и то же. Выводишь Printом вроде есть нормальное значение, проверяешь на EMPTY_VALUE уже есть. Такая же история и у моего друга, который пишет абсолютно другую программулину. Проблемы с массивами возникают на разных компьютерах с разными операционками.

Помогите, уже голову сломал!

 

А какого размера был объявлен массив?

 
KffAlex >>:

Столкнулся с такой вот проблемой, может кто поможет?

Дилинговый центр: Fibo.

Суть проблемы: 

Помогите, уже голову сломал!

Элементарно: суть проблемы - выход за границы массива. И Вам еще везет - у МКЛ свой менеджер памяти  ;)....

Успехов.

ЗЫ  Собственно, ответ на Ваш вопрос такой : С массивами в МКЛ все в порядке - присутствуют.

 

Я пробовал объявлять статический массив, а, не динамический - история таже. Самое интересное, что данные могут теряться как в начале, так и в середине. Но за советы СПАСИБО!!!

 
KffAlex >>:

Я пробовал объявлять статический массив, а, не динамический - история таже. Самое интересное, что данные могут теряться как в начале, так и в середине. Но за советы СПАСИБО!!!

Массивы в советнике чаще всего зло. Если Вам надо по ходу собирать данные, да еще и двигать -- индикаторы -- то что надо. Ничего архисложного там нет и массивы динамические.

 
KffAlex >>:

Я пробовал объявлять статический массив, а, не динамический - история таже. Самое интересное, что данные могут теряться как в начале, так и в середине. Но за советы СПАСИБО!!!

Если хотите помощи не в общем, а конкретно - приведите код, а так  - это гадание на кофейной гуще.... Если у всех работает - значит что-то Вы неверно делаете.

Успехов.

 

Вот собственно код, возможны вариации: например убрать переменные, или сделать массив динамическим:


#property indicator_separate_window

#property indicator_color1 Red

double Ticks[1000];
double Price, PriceD;
int handle,count;

int init()
{
SetIndexStyle(0,DRAW_SECTION,EMPTY,1); SetIndexBuffer(0,Ticks);
Price=Bid;
count=-1;
return;
}

int deinit()
{
string FileName="История "+Symbol()+" Tick-"+count+"t "+TimeToStr(TimeCurrent(),TIME_DATE)+" .csv";
int handle=FileOpen(FileName, FILE_CSV|FILE_WRITE);
if (handle>0)
{
Print ("Файл ",FileName, " создан. Начинаю запись...");
FileWrite(handle,"#",Symbol());
for (int i=0;i<count;i++)
{ if (Ticks[i]==EMPTY_VALUE) Print ("Пустое значение в массиве в позиции ",i);
else FileWrite(handle,Ticks[i]);
}
Print ("Запись окончена.");
FileClose(handle);
Print ("Файл закрыт.");
}

return;
}

int start()
{

Price=Bid;
for (int i=count;i>=0;i--)
{
PriceD=Ticks[i];
Ticks[i+1]=PriceD;
if (Ticks[i+1]==EMPTY_VALUE) Print (i+1, " Пустое значение в приемнике");
if (Ticks[i]==EMPTY_VALUE) Print (i, " Пустое значение в источнике");
}
Ticks[0]=Price;
if (Ticks[0]==EMPTY_VALUE) Print ("Источник 0 ошибочен!!!");
count++;
Print (count," Bid=",Price," [1]=",Ticks[1]," [2]=",Ticks[2]," [3]=",Ticks[3]);

return;
}
 
Вопрос в тему....Существут ли другие способы хранения данных кроме массива.....Если мне действительно по ходу работы индикатора нужно собирать данные для того что бы по ним потом работать??????
 

В start i == -1, поэтому массив возвращает пустое значение, как ошибку обращения к несуществующему эл-ту. Оно и присваивается первому эл-ту массива. Нужно использовать Bars, iBars()...

 
KffAlex >>:

Вот собственно код, возможны вариации: например убрать переменные, или сделать массив динамическим:


Странно, я наверное что-то не так делаю ? У меня вроде все работает. 

#property indicator_separate_window
#property indicator_color1 Red

double Ticks[];
double Price=0.0, PriceD=0.0;
int handle=-1,count=-1;

int init()
{
    SetIndexStyle(0,DRAW_SECTION,EMPTY,1); 
    SetIndexBuffer(0,Ticks);
    return;
}

 int deinit()
 {
 string FileName="История "+Symbol()+" Tick-"+count+"t "+TimeToStr(TimeCurrent(),TIME_DATE)+" .csv";
 int handle=FileOpen(FileName, FILE_CSV|FILE_WRITE);
 if (handle>0)
 {
 Print ("Файл ",FileName, " создан. Начинаю запись...");
 FileWrite(handle,"#",Symbol());
 for (int i=0;i<count;i++)
 { if (Ticks[i]==EMPTY_VALUE) Print ("Пустое значение в массиве в позиции ",i);
 else FileWrite(handle,Ticks[i]);
 }
 Print ("Запись окончена.");
 FileClose(handle);
 Print ("Файл закрыт.");
 }

 return;
 }

 int start()
 {

 Price=Bid;
 for (int i=count;i>=0;i--)
 {
 PriceD=Ticks[i];
 Ticks[i+1]=PriceD;
 if (Ticks[i+1]==EMPTY_VALUE) Print (i+1, " Пустое значение в приемнике");
 if (Ticks[i]==EMPTY_VALUE) Print (i, " Пустое значение в источнике");
 }
 Ticks[0]=Price;
 if (Ticks[0]==EMPTY_VALUE) Print ("Источник 0 ошибочен!!!");
 count++;
 Print (count," Bid=",Price," [1]=",Ticks[1]," [2]=",Ticks[2]," [3]=",Ticks[3]);

 return;
 }
Есть несколько моментов, на которые нужно обратить внимание:
1.  в инит еще не известна цена бид - ее там не нужно получать.
2. в 
SetIndexBuffer(0,Ticks);
нужен адрес массива - статически выделять память для  массива не нужно - то есть правильно описать так: double Ticks[], правда, если Вам нужно использовать массив не в индикаторе, а в эксперте или скрипте, то СетБуфер вне индикаторов не работает и там память отводится функцией АррейРесайз или память нужно выделять статически.

Вроде все.

Успехов.

ЗЫ увеличение счетчика лучше делать так : if(count<(Bars-1)) count++; иначе возможен выход за границы массива.

 
KffAlex >>:

Вот собственно код, возможны вариации: например убрать переменные, или сделать массив динамическим:


Понаблюдал за работой. Я понял в чем проблема - смотрите: поскольку Вы используете индикаторные буферы для записи тиков, то при появлении нового бара в буфер добавляется новый элемент с индексом ноль ( Тикс[0]) его значение ЄмтпиВалуе, все остальное сдвигается на один бар - это делается автоматически и от трейдера скрыто - для индикатора удобно. Ваш же эксперт продолжает сдвигать тики, как будто все в порядке и получаются пропуски, заполненные этими самыми ЄмптиВалуе... Надо рихтовать логику - например при смене бара не переносить тики, а просто дописывать нулевой элемент или отказаться от буферных массивов, объявить рабочий массив статически и работать с ним.

Может еще чего придумаете.


Успехов.