Создание верхней и нижней полосы одного стандартного отклонения

Я пытаюсь создать верхнюю и нижнюю полосу одного стандартного отклонения в массиве с именем ATREx. Первый цикл while ниже создает массив ATREx. Я считаю, что этот раздел правильно закодирован.

Однако второй цикл while, который используется для создания верхней и нижней полосы в массиве ATREx, похоже, не дает правильного результата.

Есть идеи, что мне не хватает?

Counted_bars=IndicatorCounted();
i=Bars-Counted_bars-1;
while(i>0)
{
    Moving_Average_Close=iMA(NULL,0,40,0,MODE_EMA,PRICE_CLOSE,i);
    Moving_Average_Low=iMA(NULL,0,40,0,MODE_EMA,PRICE_LOW,i);
    Moving_Average_High=iMA(NULL,0,40,0,MODE_EMA,PRICE_HIGH,i);
    ATR=iATR(NULL,0,14,i);

    if(close[i]<Moving_Average_Close)
    {
        ATREx[i]=(((low[i]-Moving_Average_Low)/close[i])*100)*((ATR/close[i])*100);
        //ATREx_200[i]=(((low[i]-Moving_Average_Low_200)/close[i])*100)*((ATR/close[i])*100);
    }
    else
        ATREx[i]=(((high[i]-Moving_Average_High)/close[i])*100)*((ATR/close[i])*100);

        i--;
}

j=Bars-Counted_bars-1;

while (j>0)
{
    ATREx_Upper[j]=iMAOnArray(ATREx,0,40,0,MODE_EMA,j)+iStdDevOnArray(ATREx,0,200,0,MODE_EMA,j);
    ATREx_Lower[j]=iMAOnArray(ATREx,0,40,0,MODE_EMA,j)-iStdDevOnArray(ATREx,0,200,0,MODE_EMA,j);
    j--;
}

person chweet    schedule 27.06.2017    source источник


Ответы (1)


Соблюдайте призывные подписи:

Индикатор { iMAOnArray | iStdDevOnArray() | ... } рассчитывается слева направо. Для доступа к элементам массива как к массиву серий (т.е. справа налево) необходимо использовать функцию ArraySetAsSeries().

double  iMAOnArray(     double array[],   // array with data <--------------
                        int    total,     // number of elements <-----------
                        int    ma_period, // MA averaging period
                        int    ma_shift,  // MA shift
                        int    ma_method, // MA averaging method
                        int    shift      // shift
                        )

double  iStdDevOnArray( double array[],   // array with data <--------------
                        int    total,     // number of elements <-----------
                        int    ma_period, // MA averaging period
                        int    ma_shift,  // MA shift
                        int    ma_method, // MA averaging method
                        int    shift      // shift
                        )

Второй раздел был крайне неэффективным:

Терминал MT4 известен тем, что имеет одно центральное узкое место. Общий одиночный поток всех графов для каждого экземпляра CustomIndicator. Так что будьте в разы внимательнее внутри кода CustomIndicator:

Counted_bars = IndicatorCounted();
       i     = Bars -   Counted_bars - 1;
while( i >  0 )
{      Moving_Average_Close = iMA(  _Symbol, PERIOD_CURRENT, 40, 0, MODE_EMA, PRICE_CLOSE, i );
       Moving_Average_Low   = iMA(  _Symbol, PERIOD_CURRENT, 40, 0, MODE_EMA, PRICE_LOW,   i );
       Moving_Average_High  = iMA(  _Symbol, PERIOD_CURRENT, 40, 0, MODE_EMA, PRICE_HIGH,  i );
       ATR                  = iATR( _Symbol, PERIOD_CURRENT, 14, i );

       if (  close[i] < Moving_Average_Close )
       {     ATREx[i] = ( ( (  low[i] - Moving_Average_Low     ) / close[i] ) * 100 ) * ( ( ATR / close[i] ) * 100 );
      // ATREx_200[i] = ( ( (  low[i] - Moving_Average_Low_200 ) / close[i] ) * 100 ) * ( ( ATR / close[i] ) * 100 );
       }
       else  ATREx[i] = ( ( ( high[i] - Moving_Average_High    ) / close[i] ) * 100 ) * ( ( ATR / close[i] ) * 100 );
       i--;
       }

       int    nBARs   = 40;  //              //?40  vvv                     // NEVER LEAVE ANY FULL-DEPTH PROCESSING aFeasibleDEPTH WILL SUITE ENOUGH
       double aCPY[];                        // ||
       ArraySetAsSeries();                   // ||
                                             // ||
       j  = Bars - Counted_bars - 1;         // ||
while( j >  0 )                              // ||   ?40                    // OUGHT BE 40?
{      ArrayCopy( aCPY, ATREx, 0, j, nBARs );// vv   vvv
       double aStDev  = iStdDevOnArray( aCPY, nBARs, 200, 0, MODE_EMA, 0 ), // NEVER LEAVE ANY  EXTENSIVE PROCESSING PIECE OF CODE IN INDICATOR (a blocking solo-thread for *ALL* MT4.Graphs !!! )
              aMeanL  = iMAOnArray(     aCPY, nBARs,  40, 0, MODE_EMA, 0 ); // NEVER LEAVE ANY  EXTENSIVE PROCESSING PIECE OF CODE IN INDICATOR ( a blocking solo-thread for *ALL* MT4.Graphs !!! )

       ATREx_Upper[j] = aMean + aStDev;                                     // REUSE VALUEs      NEVER RE-PROCESS THE SAME THING, THAT HAS ALREADY BEEN COMPUTED
       ATREx_Lower[j] = aMean - aStDev;                                     // REUSE VALUEs      NEVER RE-PROCESS THE SAME THING, THAT HAS ALREADY BEEN COMPUTED
    // *******************************************************************************************************************
    //                                                               WAS 4x MORE EXPENSIVE:
    // *******************************************************************************************************************
    // ATREx_Upper[j] = iMAOnArray(     ATREx, 0,  40, 0, MODE_EMA, j ) + iStdDevOnArray( ATREx, 0, 200, 0, MODE_EMA, j );
    // ATREx_Lower[j] = iMAOnArray(     ATREx, 0,  40, 0, MODE_EMA, j ) - iStdDevOnArray( ATREx, 0, 200, 0, MODE_EMA, j ); 
    // *******************************************************************************************************************
       j--;
}

Эпилог и исправления:

double            aCPY[];       // best put MEM .ALLOC in file-scope declarations
ArraySetAsSeries( aCPY, True ); // lock a TimeSeries ordering right there

Хотя nBARs может потребоваться некоторое количественное моделирование для достижения наилучшего баланса между точностью и вычислительными_затратами, настоятельно рекомендуется не копировать WHOLE_ARRAY, за исключением случаев, когда действительно (математически подтверждено) полное обратное преобразование -ступенчатая свертка (где любое изменение в [0] должно получить вычислительное обратное распространение по принципу домино, более глубокое назад в историю aTimeDOMAIN - что по очевидным причинам является совершенно противоположным типом поведения, прямо противоположным потребности, с которыми технический анализ, основанный на количественных показателях, счастлив работать). Так что скорее копируйте, как Альберт ЭЙНШТЕЙН так прекрасно придумал для современной физики: «КОПИРУЙТЕ СКОЛЬКО ПОЛОС НАЗАД, СКОЛЬКО НЕОБХОДИМО, НО НЕ НИ ОДНИМ БОЛЬШЕ» — тогда вы получите наилучшие результаты.

Хотя повторное использование iMAOnArray() и iStdDevOnArray() не так эффективно в числовом и вычислительном отношении, как при использовании вычислений со скользящим окном, при котором никогда не выполняется повторный расчет какого-либо значения, но повышается скорость за счет повторного использования всех уже однажды вычисленных значений — iMAOnArray( ATTREx, WHOLE_ARRAY, 3, 0, MODE_SMA, j); один из примеров, повторно зацикленный в [j] автором while(){...}.

person user3666197    schedule 27.06.2017
comment
Спасибо! У меня есть несколько дополнительных вопросов, но я не могу разместить их все в этом разделе комментариев. Я указал выше как ответ. Надеюсь, вы поможете взглянуть. Еще раз спасибо заранее! - person chweet; 27.06.2017