Как нарисовать разницу между двумя скользящими средними в виде гистограммы на таймфрейме 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]
нет смысла запускать код, так как он ничего не обновит.