Создание верхней и нижней полосы одного стандартного отклонения
Я пытаюсь создать верхнюю и нижнюю полосу с одним стандартным отклонением в массиве с именем 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--;
}
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
может потребоваться некоторое количественное моделирование для достижения наилучшего баланса точности / computing_expenses, настоятельно рекомендуется не копировать WHOLE_ARRAY
, если только какая-либо действительно (математически поддерживаемая) свертка с обратной глубиной полной глубины (где любое изменение в [0] происходит из-за обратного распространения в вычислительном отношении, способом домино, глубже обратно в историю aTimeDOMAIN - что по очевидным причинам является совершенно противоположное поведение, прямо противоположное потребностям, с которыми технически подготовленный количественно технический анализ будет рад работать.). Так что скорее копируйте, поскольку Альберт ЭЙНШТЕЙН так мило придумал современную физику - " КОПИРУЙТЕ МНОГО БАРСОВ НАЗАД, КАК НУЖНО, НО НЕ БОЛЬШЕ " - тогда вы получите лучшую производительность.
В то время как повторное использование iMAOnArray()
а также iStdDevOnArray()
, он не так численно и вычислительно эффективен, как при использовании вычислений со скользящим окном, который никогда не пересчитывает какое-либо значение, но повышает скорость за счет повторного использования всех уже однажды вычисленных значений - iMAOnArray( ATTREx, WHOLE_ARRAY, 3, 0, MODE_SMA, j);
являясь одним из примеров, как повторяется в [j]
от while(){...}
,