Доброго времени суток!
Что то я был уверен что плотно изучил структуры на пути к оптимизации кода и его уменьшении, пока не столкнулся с массивами.
Для примера приведу код.
Получаю ошибку "array out of range" в выделенной красным строке.
Чего не так? Делаю ведь ресайз массива, а не могу задать значение ни одному из индексов массива.
Если Вы массив устанавливаете как индикаторный буфер, то Resize ему уже не нужно делать - это берёт на себя подсистема терминала.
Опять-таки не понятно, это MQL5 или 4 ?
В первую очередь нужно сделать структуру с единственным буфером и добиться его правильного назначения как индикаторного буфера и обращения к нему. В OnCalculate() (Вы почему-то в скрипте пытаетесь сделать индикаторные буферы) после назначения массива буфером, проверьте его размер. Он должен быть rates_total
Если Вы массив устанавливаете как индикаторный буфер, то Resize ему уже не нужно делать - это берёт на себя подсистема терминала.
Опять-таки не понятно, это MQL5 или 4 ?
В первую очередь нужно сделать структуру с единственным буфером и добиться его правильного назначения как индикаторного буфера и обращения к нему. В OnCalculate() (Вы почему-то в скрипте пытаетесь сделать индикаторные буферы) после назначения массива буфером, проверьте его размер. Он должен быть rates_total
Это MQL5.
Изначально код в индикаторе. Но для моделирования ситуации и вопроса на форуме я сделал аналог в виде скрипта. Ошибка такая же.
Я хочу чтобы массив был строгого размера. И индикатор должен рисовать стрелки на последних образно 2000 барах.
Поэтому я задал размер массива в 2000. Перевел его в таймсерию. И привязал к буферу чтобы видеть его на графике.
Тогда возьму часть кода из моего индикатора для разбора.
//+------------------------------------------------------------------+ //| ProjectName | //| Copyright 2020, CompanyName | //| http://www.companyname.net | //+------------------------------------------------------------------+ #property version "1.00" #property indicator_separate_window #property indicator_buffers 32 int bars = 2200; int totalSymbols = 8; struct PANEL { double bufferBlock[]; void initial(int poz) { SetIndexBuffer(poz,bufferBlock,INDICATOR_DATA); ArrayResize(bufferBlock,2200,0); ArraySetAsSeries(bufferBlock,true); Print("poz "+(string)poz+" имеет размер "+(string)ArraySize(bufferBlock)); bufferBlock[0]=5; } }; PANEL _panel[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- return value of prev_calculated for next call ArrayResize(_panel,totalSymbols,0); for(int i=0; i<totalSymbols; i++) { _panel[i].symbol = SymbolName(i,true); _panel[i].initial(i); } return(rates_total); } //+------------------------------------------------------------------+
Код выше выдает:
poz 0 имеет размер 101204 poz 1 имеет размер 101204 array out of range in 'test.mq5' (22,19)
То есть я обозначаю как буфер. Потом меняю размер на нужный, и все равно размер массива игнорирует мой ресайз. И при попытке изменить значение получаю ошибку.
При этом в коде ниже я закомментировал строку с присвоением буфера.
//| ProjectName | //| Copyright 2020, CompanyName | //| http://www.companyname.net | //+------------------------------------------------------------------+ #property version "1.00" #property indicator_separate_window #property indicator_buffers 32 int bars = 2200; int totalSymbols = 2; struct PANEL { double bufferBlock[]; void initial(int poz) { //SetIndexBuffer(poz,bufferBlock,INDICATOR_DATA); ArrayResize(bufferBlock,2200,0); ArraySetAsSeries(bufferBlock,true); Print("poz "+(string)poz+" имеет размер "+(string)ArraySize(bufferBlock)); bufferBlock[0]=5; } }; PANEL _panel[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- return value of prev_calculated for next call ArrayResize(_panel,totalSymbols,0); for(int i=0; i<totalSymbols; i++) { _panel[i].initial(i); } return(rates_total); } //+------------------------------------------------------------------+
Результат:
poz 0 имеет размер 2000 poz 1 имеет размер 2000
И ошибки присвоения значения не получаю.
То есть вроде это и решает проблему. Но цель не достигнута. Я не увижу на графике визуальное отображение из за того что массиву не присвоен буфер.
Видимо нашел решение. Но осталось обдумать как это сунуть в мой код.
//+------------------------------------------------------------------+ //| ProjectName | //| Copyright 2020, CompanyName | //| http://www.companyname.net | //+------------------------------------------------------------------+ #property version "1.00" #property indicator_separate_window #property indicator_buffers 8 int bars = 2200; int totalSymbols = 2; struct PANEL { double bufferBlock[]; void initial(int poz) { ArrayResize(bufferBlock,bars,0); ArraySetAsSeries(bufferBlock,true); Print("poz "+(string)poz+" имеет размер "+(string)ArraySize(bufferBlock)); bufferBlock[1]=5; Print(bufferBlock[1]); } }; PANEL _panel[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping ArrayResize(_panel,totalSymbols,0); for(int i=0;i<totalSymbols;i++) { SetIndexBuffer(i,_panel[i].bufferBlock,INDICATOR_DATA); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- return value of prev_calculated for next call for(int i=0; i<totalSymbols; i++) { _panel[i].initial(i); } return(rates_total); } //+------------------------------------------------------------------+
Ошибок не выдает.
Это MQL5.
Изначально код в индикаторе. Но для моделирования ситуации и вопроса на форуме я сделал аналог в виде скрипта. Ошибка такая же.
Я хочу чтобы массив был строгого размера. И индикатор должен рисовать стрелки на последних образно 2000 барах.
Поэтому я задал размер массива в 2000. Перевел его в таймсерию. И привязал к буферу чтобы видеть его на графике.
Тогда возьму часть кода из моего индикатора для разбора.
Код выше выдает:
То есть я обозначаю как буфер. Потом меняю размер на нужный, и все равно размер массива игнорирует мой ресайз. И при попытке изменить значение получаю ошибку.
При этом в коде ниже я закомментировал строку с присвоением буфера.
Результат:
И ошибки присвоения значения не получаю.
То есть вроде это и решает проблему. Но цель не достигнута. Я не увижу на графике визуальное отображение из за того что массиву не присвоен буфер.
#property indicator_buffers 32
Это общее количество буферов.
А где рисуемые? Их тоже нужно указывать
Видимо нашел решение. Но осталось обдумать как это сунуть в мой код.
Ошибок не выдает.
Для начала возможно стОит "обдумать" после прочтения справки, документации и запросы в гугл по сайту, типа этого
Имхенько
- www.mql5.com
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Доброго времени суток!
Что то я был уверен что плотно изучил структуры на пути к оптимизации кода и его уменьшении, пока не столкнулся с массивами.
Для примера приведу код.
Получаю ошибку "array out of range" в выделенной красным строке.
Чего не так? Делаю ведь ресайз массива, а не могу задать значение ни одному из индексов массива.