Та самая 4806 ошибка - страница 3

 
Petr Zharuk #:

Я вложил ниже инпуты для понимания.

Обратите внимание на кол-во циклов for. 

Проходится по периоду АДХ с 5 до 15

Внутри него цикл

Который так же перебирается с 5 до 15

Внутри которого еще цикл

Который перебирается с 0 до 5

А так далее в глубину.

Логика в том, что каждое значение счетчика for это период или параметр расчета.
И все комбинации параметров индикаторов должны перебраться между собой для того чтобы выдать нужные мне результаты.

Почему вы их складываете? 12 вариантов АДХ должны перебраться с 12 вариантами АТР = 144. Это только АДХ и АТР. А если вы глянете на то какие в циклах for параметры, которые только приумножают количество итераций, то доходит до 2-5 миллионов.

needCalcBars. Для примера мне надо 30 дней. На ТФ М1 это ~43000 баров. На М5 это ~8600. И так далее. Мой код считает сколько надо баров перебрать на выбранном ТФ исходя из дней истории.
В окне настроек терминала у меня 100 000 баров стоит. Доступны 100 000.
Да и код есть который выдает мне доступное кол-во баров. BARS он же iBars(), просто в препроцессорах сделал себе BARS.

Остальные значения из вложенных for тоже используются в коде, но я его не отображал. В этом нет смысла. Ошибка на уровне CopyBuffer.



Возможно конечно вы предлагаете создавать хендл не внутри всех циклов, а внутри его конректного цикла.
Например хендл АДХ создавать сразу после его for. 
Но я не уверен что это решит проблему CopyBuffer. 
И все еще вижу необходимость объявлять хендлы внутри циклов, а не в OnInit()

Всё это абсолютно неубедительно. Вот все места где используется adx

Попробуйте найти такое обращение к adx где-то в другом цикле который повлиял-бы на хендл индикатора adx

А так, получается, что каждый цикл с новым значением адх повторяется те самые 2 миллиона раз абсолютно даром. 

 
Alexey Viktorov #:

Всё это абсолютно неубедительно. Вот все места где используется adx

Попробуйте найти такое обращение к adx где-то в другом цикле который повлиял-бы на хендл индикатора adx

А так, получается, что каждый цикл с новым значением адх повторяется те самые 2 миллиона раз абсолютно даром. 

В каком другом цикле? Я делаю перебор всех возможных комбинаций ADX, ATR,DOGON,EXP,SHIFT,LEVEL. Все эти параметры в диапазоне своих заданных значений должны перебраться между собой.

Почему даром? Имеет ли то, о чем вы говорите отношение к ошибке 4806? 

ERR_INDICATOR_DATA_NOT_FOUND

4806

Запрошенные данные не найдены


Я пытаюсь понять, что не так, с тем, что я внутри цикла объявляю хэндл ADX с периодом из счетчика for adx. 
Почему CopyBuffer мне возвращает 4806 если баров хватает с запасом в несколько раз.

Вот я себе в журнал внутри цикла логирую.

Первая строка показывает выбранные в цикле ТФ, сколько баров надо для расчетов, и сколько доступно.

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

Третья строка мне выкидывает ошибку 4806. То есть по второй строке видим, что все идет гладко аж до 2512 цикла итерации.
То есть ошибка появляется как только меняется ATR после 2 на 3. При этом ошибки хэндла нет. А вот новое значение ATR в CopyBuffer уже не лезет. 

 
Petr Zharuk #:

В каком другом цикле? Я делаю перебор всех возможных комбинаций ADX, ATR,DOGON,EXP,SHIFT,LEVEL. Все эти параметры в диапазоне своих заданных значений должны перебраться между собой.

Почему даром? Имеет ли то, о чем вы говорите отношение к ошибке 4806? 

ERR_INDICATOR_DATA_NOT_FOUND

4806

Запрошенные данные не найдены


Я пытаюсь понять, что не так, с тем, что я внутри цикла объявляю хэндл ADX с периодом из счетчика for adx. 
Почему CopyBuffer мне возвращает 4806 если баров хватает с запасом в несколько раз.

Вот я себе в журнал внутри цикла логирую.

Первая строка показывает выбранные в цикле ТФ, сколько баров надо для расчетов, и сколько доступно.

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

Третья строка мне выкидывает ошибку 4806. То есть по второй строке видим, что все идет гладко аж до 2512 цикла итерации.
То есть ошибка появляется как только меняется ATR после 2 на 3. При этом ошибки хэндла нет. А вот новое значение ATR в CopyBuffer уже не лезет. 

В чём будет отличие такого кода

  int handleADX[10];
    for(int adx = 5; adx < 15 && !IsStopped(); adx++) 
     {
      //Далее согласно перебору параметров создаю хендлы с этими параметрами. Ошибок создания хэндла нет, проверял.
      handleADX[i] = iADX(_Symbol, TFs[tf], adx);
     }

от вашего… Я взял константные значения просто чтобы не заморачиваться с инпут переменными. Я надеюсь вы понимаете это…

Вам уже устали объяснять, что хендлы надо получать в OnInit()

Все следующие вложенные циклы никакие параметры не вносят в параметры iADX и следовательно абсолютно бесполезны.

Вот потому я и прошу показать какое значение из полученных во внутренних циклах влияет на iADX 

 
Petr Zharuk #:

Мне к сожалению не очевидно то, что вы предложили. 
Что сделать?

Остальные индикаторы по аналогии, тогда хендлы не нужны.

Проверки не делал, это уже на вашей стороне

//+------------------------------------------------------------------+
//|                                                  Custom_iADX.mq5 |
//+------------------------------------------------------------------+
#property version   "1.00"

input int InpPeriodADX   = 14; // Period ADX
input ENUM_TIMEFRAMES TF = PERIOD_CURRENT;

double    ExtADXBuffer[200];
double    ExtPDIBuffer[200];
double    ExtNDIBuffer[200];
double    ExtPDBuffer[200];
double    ExtNDBuffer[200];
double    ExtTmpBuffer[200];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{

  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  Comment("");
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
  ADX(_Symbol, TF, InpPeriodADX, 1); // значение бара №1
  Comment(DoubleToString(ExtADXBuffer[0],2),
          "\n",DoubleToString(ExtPDIBuffer[0],2),
          "\n",DoubleToString(ExtNDIBuffer[0],2));
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool ADX(string symb, ENUM_TIMEFRAMES tf, int per, int cnt)
{
  for(int i=per*6; i>=0 && !IsStopped(); i--) {
    double high_price=iHigh(symb,tf,cnt+i);
    double prev_high =iHigh(symb,tf,cnt+i+1);
    double low_price =iLow(symb,tf,cnt+i);
    double prev_low  =iLow(symb,tf,cnt+i+1);
    double prev_close=iClose(symb,tf,cnt+i+1);
    //--- fill main positive and main negative buffers
    double tmp_pos=high_price-prev_high;
    double tmp_neg=prev_low-low_price;
    if(tmp_pos<0.0) tmp_pos=0.0;
    if(tmp_neg<0.0) tmp_neg=0.0;
    if(tmp_pos>tmp_neg) tmp_neg=0.0;
    else {
      if(tmp_pos<tmp_neg)
        tmp_pos=0.0;
      else {
        tmp_pos=0.0;
        tmp_neg=0.0;
      }
    }
    //--- define TR
    double tr=MathMax(MathMax(MathAbs(high_price-low_price),MathAbs(high_price-prev_close)),MathAbs(low_price-prev_close));
    if(tr!=0.0) {
      ExtPDBuffer[i]=100.0*tmp_pos/tr;
      ExtNDBuffer[i]=100.0*tmp_neg/tr;
    } else {
      ExtPDBuffer[i]=0.0;
      ExtNDBuffer[i]=0.0;
    }
    //--- fill smoothed positive and negative buffers
    ExtPDIBuffer[i]=ExponentialMA(i,per,ExtPDIBuffer[i+1],ExtPDBuffer);
    ExtNDIBuffer[i]=ExponentialMA(i,per,ExtNDIBuffer[i+1],ExtNDBuffer);
    //--- fill ADXTmp buffer
    double tmp=ExtPDIBuffer[i]+ExtNDIBuffer[i];
    if(tmp!=0.0)
      tmp=100.0*MathAbs((ExtPDIBuffer[i]-ExtNDIBuffer[i])/tmp);
    else
      tmp=0.0;
    ExtTmpBuffer[i]=tmp;
    //--- fill smoothed ADX buffer
    ExtADXBuffer[i]=ExponentialMA(i,per,ExtADXBuffer[i+1],ExtTmpBuffer);
  }
  return(false); // здесь вернуть результат успеха / неуспеха 
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double ExponentialMA(const int position,const int period,const double prev_value,const double &price[])
{
  double result=0.0;
  if(period>0) {
    double pr=2.0/(period+1.0);
    result=price[position]*pr+prev_value*(1-pr);
  }
  return(result);
}
//+------------------------------------------------------------------+
 

Всем спасибо. Решил проблему создав структуры хендлов и объявив их в OnInit заранее.

struct HANDLE {
    int handle;
};

struct TF {
    ENUM_TIMEFRAMES tf;
    HANDLE          handles[];
};

TF tfADX[];
TF tfATR[];
TF tfRSI[];

int OnInit() {
ArrayResize(tfADX, ArraySize(TFs));
    ArrayResize(tfATR, ArraySize(TFs));
    ArrayResize(tfRSI, ArraySize(TFs));

    for(int i = 0; i < ArraySize(TFs); i++) {
        ArrayResize(tfADX[i].handles, MathAbs(i_ADX_period_end - i_ADX_period_start)+1);
        ArrayResize(tfATR[i].handles, MathAbs(i_atr_period_end - i_atr_period_start)+1);
        ArrayResize(tfRSI[i].handles, 1);
        tfADX[i].tf = TFs[i];
        tfATR[i].tf = TFs[i];
        tfRSI[i].tf = TFs[i];
        for(int adx = 0; adx < ArraySize(tfADX[i].handles); adx++) {
            tfADX[i].handles[adx].handle = iADX(_Symbol, TFs[i], i_ADX_period_start + adx);
        }
        for(int atr = 0; atr < ArraySize(tfATR[i].handles); atr++) {
            tfATR[i].handles[atr].handle = iATR(_Symbol, TFs[i], i_atr_period_start + atr);
        }
        tfRSI[i].handles[0].handle=iRSI(_Symbol,TFs[i],i_rsi_period,PRICE_CLOSE);
    }
}

А в цикле уже обращаюсь к этим хендлам на основе счетчиков циклов.