Как нарисовать разницу между двумя скользящими средними в виде гистограммы на таймфрейме H1 в MQL4?

Это моя попытка нарисовать разницу между двумя скользящими средними в виде гистограммы на таймфрейме H1. Проблема в том, что он не меняется, когда я меняю временные рамки, особенно на более низкие. Я новичок в MQL4, не имеющий опыта или опыта программирования, поэтому, пожалуйста, объясните мне ошибку.

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1  Gray
#property indicator_width1  2

extern int maperiod1 = 25;
extern int maperiod2 = 55;
extern int timefr    = 60;

double mainbuffer[];

int init(){
    SetIndexBuffer( 0, mainbuffer );
    SetIndexStyle(  0, DRAW_HISTOGRAM );
    return(0);
}

int start(){
    int  counted_bars = IndicatorCounted();

    if ( counted_bars < 0) return(-1);
    if ( counted_bars > 0) return( 0);

    int  limit        = ( Bars - counted_bars );

    for ( int    i     = limit; i >= 0; i-- ){
          int    shift = iBarShift( NULL, timefr, Time[i] );
          double maB   = iMA(       NULL, timefr, maperiod1, 0, MODE_EMA, 0, shift );
          double maR   = iMA(       NULL, timefr, maperiod2, 0, MODE_EMA, 0, shift );
          mainbuffer[shift]= ( maB - maR );
    }
    return(0);
}

2 ответа

В вашем коде вы вычисляете MA таймфрейма H1, поэтому нет разницы, что происходит на меньших таймфреймах - он проверяет только H1.

if (counted_bars>0) return(0); - насколько я помню, если количество подсчитанных баров положительное, нужно уменьшить его на единицу, чтобы пересчитать ранее известный бар: if (counted_bars>0) counted_bars--;

Помимо "иммунитета" к любому выбору таймфрейма,
код не предоставляет средства для обновления в синхронизации с Time[] должным образом

Как Даниил уже отметил выше, "жесткое", жестко закодированное отношение к extern предварительно выбранный период времени (который технически должен быть разработан как enum:

enum ENUM_GUI_SELECT_TFRAME {
                              M1 = PERIOD_M1,
                              M5 = PERIOD_M5,
                              ...
                              ..
                              .
                              H1 = PERIOD_H1,
                              H4 = PERIOD_H4,
                              ...
                              ..
                              .
                              MN = PERIOD_MN
     };
  //   ++++------------------------------------------ MAKES SURE,
  //   ||||                                           ALWAYS ONLY
  //   ||||                                           PROPER VALUES GET
  //   vvvv                                           EVER SELECTED
extern ENUM_GUI_SELECT_TFRAME timefr = PERIOD_H1;

) Есть еще несколько моментов, которые нужно решить с помощью барьеров активации кода / выполнения.

Что мешает коду от правильных обновлений?

Это тандем условий:

if ( counted_bars < 0) return(-1);
if ( counted_bars > 0) return( 0);

выполняется, если и только если IndicatorCounted() == 0 никогда больше.

IndicatorCounted() ~ Функция возвращает количество баров, не измененных после последнего запуска индикатора.

Таким образом, пользовательский индикатор работает как дьявол во время первого вызова, когда все столбцы "изменились" с момента (не существующего) предыдущего вызова. После этого, до вновь созданного бара, индикатор вызывается с выполнением условия, потому что IndicatorCounted() == 0, но никаких новых баров еще не появилось, что IndicatorCounted() == 1 и остальная часть кода пользовательского индикатора не будет выполнена - что кажется скорее очень зеркальной логикой, которой были оснащены пользовательские индикаторы, чтобы избежать непроизводительных циклов в случае, если не были созданы новые бары, но чтобы получить немедленное обновление в случае, если новый бар начался.

Другими словами, даже в случае IndicatorCounted() == 0 последнее (горячее) значение [0] может еще и действительно измениться, так что если и только если значение пользовательского индикатора каким-то образом зависит от этого фактического (все еще изменяющегося) реального значения Close[0], имеет смысл обновить [0] клетка mainbuffer[],

Если это не зависит от Close[0] нет смысла запускать код, так как он ничего не обновит.

Другие вопросы по тегам