Самый прикол в том, что стиль DRAW_ZIGZAG я по отрывкам собрал :) Надеюсь, он не изменится уже.
а смены цвета смог добиться?
Такой цели не было. Да и невозможно это через DRAW_ZIGZAG. В этом стиле важно только чередование буферов, при этом взаимное расположение четного/нечетного буфера для цвета не имеет значения, имеет значение только абсолютные значения буферов безотносительно порядка их объявления в индикаторе.
не мог долго найти ошибки (довольно редко уже просчитанный бар пересчитывался, хотя по коду вроде везде старался не допустить этого), закрыл дыру грубо, полезли другие бяки, вылазивают совершенно бессистемно, то ни с того, ни с сего индюк вообще перерисуется на протяжении всей истории неверным образом, другой вариант запечатлил
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 DeepSkyBlue
#property indicator_color2 DeepSkyBlue
#property indicator_color3 DeepSkyBlue
#property indicator_color4 DeepSkyBlue
//---- buffers
double Upz[];
double Dnz[];
double Uph[];
double Dnh[];
//----
int lb,sp,leb; //,fp
double aH,aL;
bool fH,fL,lH,lL;
bool draw_up,draw_dn;
//----
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_ZIGZAG,STYLE_SOLID);
SetIndexStyle(1,DRAW_ZIGZAG,STYLE_SOLID);
SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_SOLID);
SetIndexStyle(3,DRAW_HISTOGRAM,STYLE_SOLID);
SetIndexBuffer(0,Upz);
SetIndexBuffer(1,Dnz);
SetIndexBuffer(2,Uph);
SetIndexBuffer(3,Dnh);
SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);
SetIndexEmptyValue(2,0.0);
SetIndexEmptyValue(3,0.0);
//----
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
//----
int cb,ai,i,limit,index;
double a;
//----
if( counted_bars>=0 )
{
index=Bars-1;
if( counted_bars!=0 )
{
if( index-counted_bars-1<=0 )
{
limit=0;
}
else
{
limit=index-counted_bars;
}
}
else
{
limit=index-1;
aH=High[index];
aL=Low[index];
}
}
else
{
Alert("Сбой расчета индикатора rvmGSv_mt");
}
//----
for( cb=limit; cb>=0; cb-- )
{
//******************************************************************
ai=index-cb;
//если новый бар
if( lb!=ai )
{
lb=ai;
//если предыдущий бар не внутренний
if( High[cb+1]>aH || Low[cb+1]<aL )
{
aH=High[cb+1];
aL=Low[cb+1];
}
//обнуляем
fH=0;
fL=0;
lH=0;
lL=0;
}
//******************************************************************
//если текущий бар внутренний
if( High[cb]<=aH && Low[cb]>=aL )
{
continue;
}
//******************************************************************
Extr_seq(cb,counted_bars);
//если индикатор уже рисуется
if( sp!=0 )
{
//отработка на первое появление экстримума на баре
if( leb!=ai )
{
leb=ai;
if( draw_up!=0 )
{
//если сначала максимум
if( fH!=0 )
{
Upz[index-sp]=0;
sp=ai;
Upz[index-sp]=High[cb];
}
else //иначе сначала максимум (сначала минимум)
{
//fp=sp;
sp=ai;
Dnz[index-sp]=Low[cb];
draw_up=0;
draw_dn=1;
}
}
else
{
if( draw_dn!=0 )
{
//если сначала максимум
if( fH!=0 )
{
//fp=sp;
sp=ai;
Upz[cb]=High[cb];
draw_up=1;
draw_dn=0;
}
else //иначе если сначала максимум (сначала минимум)
{
Dnz[index-sp]=0;
sp=ai;
Dnz[cb]=Low[cb];
}
}
}
}
//если текущий бар внешний
if( High[cb]>aH && Low[cb]<aL )
{
//и первым и последним являются один и тот же экстримум
if( fH==lH || fL==lL )
{
Uph[cb]=High[cb];
Dnh[cb]=Low[cb];
//если первым появился максимум
if( fH!=0 )
{
Upz[cb]=High[cb];
Dnz[cb]=High[cb];
draw_up=1;
draw_dn=0;
}
else //иначе если первым появился максимум (первым появился минимум)
{
Upz[cb]=Low[cb];
Dnz[cb]=Low[cb];
draw_up=0;
draw_dn=1;
}
}
else
{
//если уже нарисовали гистограмму стираем
Uph[cb]=0;
Dnh[cb]=0;
//если сначала максимум
if( fH!=0 )
{
Upz[cb]=High[cb];
Dnz[cb]=Low[cb];
draw_up=0;
draw_dn=1;
}
else
{
Upz[cb]=High[cb];
Dnz[cb]=Low[cb];
draw_up=1;
draw_dn=0;
}
}
}
else //иначе если текущий бар внешний
{
//если первый максимум
if( fH!=0 )
{
Upz[cb]=High[cb];
}
else //иначе если первый максимум (первый минимум)
{
Dnz[cb]=Low[cb];
}
}
}
else //иначе если индикатор уже рисуется (он еше не рисуется)
{
//если сначала максимум
if( fH!=0 )
{
sp=ai;
Upz[cb]=High[cb];
Dnz[index]=Low[index];
draw_up=1;
//если к тому же текущая свеча внешняя
if( lL!=0 )
{
Dnz[cb]=Low[cb];
draw_up=0;
draw_dn=1;
}
}
else //иначе сначала максимум (сначала минимум)
{
sp=ai;
Upz[index]=High[index];
Dnz[index-sp]=Low[cb];
draw_dn=1;
//если к тому же текущая свеча внешняя
if( lH!=0 )
{
Upz[cb]=High[cb];
draw_up=1;
draw_dn=0;
}
}
}
//******************************************************************
}
//----
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Функция определяет последовательность появления экстремумов |
//+------------------------------------------------------------------+
void Extr_seq(int curb, int count_b)
{
//----
//******************************************************************
//если просчитывается реал-тайм
if( count_b>0 && curb==0 )
{
//определяем очередность появления экстримумов
//если еще не было экстримума (т.е. первый экстримум)
if( fH!=1 && fL!=1 )
{
if( High[curb]>aH )
{
fH=1;
lH=1;
}
else
{
if( Low[curb]<aL )
{
fL=1;
lL=1;
}
}
}
else
{
if( Close[curb]==High[curb] && High[curb]>aH )
{
lH=1;
lL=0;
}
else
{
if( Close[curb]==Low[curb] && Low[curb]<aL )
{
lL=1;
lH=0;
}
}
}
}
else //иначе если просчитывается реал-тайм (история)
{
if( Upz[curb]<1*Point && Dnz[curb]<1*Point )
{
if( curb<3 ) Alert(curb);
//определяем очередность появления экстримумов
//если открытие было уже экстримумом
if( Open[curb]>aH || Low[curb]>=aL )
{
fH=1;
if( Low[curb]<aL )
{
lL=1;
}
}
else
{
if( Open[curb]<aL || High[curb]<=aH )
{
fL=1;
if( High[curb]>aH )
{
lH=1;
}
}
else
{
if( MathAbs(Close[curb]-aH)>MathAbs(Close[curb]-aL) )
{
fH=1;
if( Low[curb]<aL )
{
lL=1;
}
}
else
{
if( MathAbs(Close[curb]-High[curb])>MathAbs(Close[curb]-Low[curb]) )
{
if( Open[curb]>Close[curb] )
{
fH=1;
if( Low[curb]<aL )
{
lL=1;
}
}
else
{
fL=1;
if( High[curb]>aH )
{
lH=1;
}
}
}
else
{
fL=1;
if( High[curb]>aH )
{
lH=1;
}
}
}
}
}
}
}
//******************************************************************
//----
return(0);
}
//+------------------------------------------------------------------+
стиль отрисовки линии такой же как и драв лайн, драв гисторграмм, или драв арров, драв секшн. На предыдущей страничке ссылка (автор: Rosh) на страничку где упомянается о драв зигзаге
Еще вопрос.
Взял последний ваш индикатор и и уcтановил не один, а разные цвета для каждого double, но он показывает только один цвет. А зачем остальные?
так построен MQL4 что для отрисовки стилей гистограмм и зигзаг нужно использовать два буфера, для каждого из которых прописывается два цвета, хотя отрисовываться будет одна линия.
индикатор который я пытаюсь закодировать представляет из себя линию, которую не возможно построить только одним из представленых в языке стилей, раньше я использовал три драв лайн и один драв гистограмм (итого пять основных буферов), теперь заменил три драв лайна на один драв зигзаг (итого четыре основных буфера)
а смены цвета смог добиться?
а смены цвета смог добиться?
Такой цели не было. Да и невозможно это через DRAW_ZIGZAG. В этом стиле важно только чередование буферов, при этом взаимное расположение четного/нечетного буфера для цвета не имеет значения, имеет значение только абсолютные значения буферов безотносительно порядка их объявления в индикаторе.
#property indicator_chart_window #property indicator_buffers 4 #property indicator_color1 DeepSkyBlue #property indicator_color2 DeepSkyBlue #property indicator_color3 DeepSkyBlue #property indicator_color4 DeepSkyBlue //---- buffers double Upz[]; double Dnz[]; double Uph[]; double Dnh[]; //---- int lb,sp,leb; //,fp double aH,aL; bool fH,fL,lH,lL; bool draw_up,draw_dn; //---- //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- indicators SetIndexStyle(0,DRAW_ZIGZAG,STYLE_SOLID); SetIndexStyle(1,DRAW_ZIGZAG,STYLE_SOLID); SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_SOLID); SetIndexStyle(3,DRAW_HISTOGRAM,STYLE_SOLID); SetIndexBuffer(0,Upz); SetIndexBuffer(1,Dnz); SetIndexBuffer(2,Uph); SetIndexBuffer(3,Dnh); SetIndexEmptyValue(0,0.0); SetIndexEmptyValue(1,0.0); SetIndexEmptyValue(2,0.0); SetIndexEmptyValue(3,0.0); //---- return(0); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { int counted_bars=IndicatorCounted(); //---- int cb,ai,i,limit,index; double a; //---- if( counted_bars>=0 ) { index=Bars-1; if( counted_bars!=0 ) { if( index-counted_bars-1<=0 ) { limit=0; } else { limit=index-counted_bars; } } else { limit=index-1; aH=High[index]; aL=Low[index]; } } else { Alert("Сбой расчета индикатора rvmGSv_mt"); } //---- for( cb=limit; cb>=0; cb-- ) { //****************************************************************** ai=index-cb; //если новый бар if( lb!=ai ) { lb=ai; //если предыдущий бар не внутренний if( High[cb+1]>aH || Low[cb+1]<aL ) { aH=High[cb+1]; aL=Low[cb+1]; } //обнуляем fH=0; fL=0; lH=0; lL=0; } //****************************************************************** //если текущий бар внутренний if( High[cb]<=aH && Low[cb]>=aL ) { continue; } //****************************************************************** Extr_seq(cb,counted_bars); //если индикатор уже рисуется if( sp!=0 ) { //отработка на первое появление экстримума на баре if( leb!=ai ) { leb=ai; if( draw_up!=0 ) { //если сначала максимум if( fH!=0 ) { Upz[index-sp]=0; sp=ai; Upz[index-sp]=High[cb]; } else //иначе сначала максимум (сначала минимум) { //fp=sp; sp=ai; Dnz[index-sp]=Low[cb]; draw_up=0; draw_dn=1; } } else { if( draw_dn!=0 ) { //если сначала максимум if( fH!=0 ) { //fp=sp; sp=ai; Upz[cb]=High[cb]; draw_up=1; draw_dn=0; } else //иначе если сначала максимум (сначала минимум) { Dnz[index-sp]=0; sp=ai; Dnz[cb]=Low[cb]; } } } } //если текущий бар внешний if( High[cb]>aH && Low[cb]<aL ) { //и первым и последним являются один и тот же экстримум if( fH==lH || fL==lL ) { Uph[cb]=High[cb]; Dnh[cb]=Low[cb]; //если первым появился максимум if( fH!=0 ) { Upz[cb]=High[cb]; Dnz[cb]=High[cb]; draw_up=1; draw_dn=0; } else //иначе если первым появился максимум (первым появился минимум) { Upz[cb]=Low[cb]; Dnz[cb]=Low[cb]; draw_up=0; draw_dn=1; } } else { //если уже нарисовали гистограмму стираем Uph[cb]=0; Dnh[cb]=0; //если сначала максимум if( fH!=0 ) { Upz[cb]=High[cb]; Dnz[cb]=Low[cb]; draw_up=0; draw_dn=1; } else { Upz[cb]=High[cb]; Dnz[cb]=Low[cb]; draw_up=1; draw_dn=0; } } } else //иначе если текущий бар внешний { //если первый максимум if( fH!=0 ) { Upz[cb]=High[cb]; } else //иначе если первый максимум (первый минимум) { Dnz[cb]=Low[cb]; } } } else //иначе если индикатор уже рисуется (он еше не рисуется) { //если сначала максимум if( fH!=0 ) { sp=ai; Upz[cb]=High[cb]; Dnz[index]=Low[index]; draw_up=1; //если к тому же текущая свеча внешняя if( lL!=0 ) { Dnz[cb]=Low[cb]; draw_up=0; draw_dn=1; } } else //иначе сначала максимум (сначала минимум) { sp=ai; Upz[index]=High[index]; Dnz[index-sp]=Low[cb]; draw_dn=1; //если к тому же текущая свеча внешняя if( lH!=0 ) { Upz[cb]=High[cb]; draw_up=1; draw_dn=0; } } } //****************************************************************** } //---- return(0); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Custor indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Функция определяет последовательность появления экстремумов | //+------------------------------------------------------------------+ void Extr_seq(int curb, int count_b) { //---- //****************************************************************** //если просчитывается реал-тайм if( count_b>0 && curb==0 ) { //определяем очередность появления экстримумов //если еще не было экстримума (т.е. первый экстримум) if( fH!=1 && fL!=1 ) { if( High[curb]>aH ) { fH=1; lH=1; } else { if( Low[curb]<aL ) { fL=1; lL=1; } } } else { if( Close[curb]==High[curb] && High[curb]>aH ) { lH=1; lL=0; } else { if( Close[curb]==Low[curb] && Low[curb]<aL ) { lL=1; lH=0; } } } } else //иначе если просчитывается реал-тайм (история) { if( Upz[curb]<1*Point && Dnz[curb]<1*Point ) { if( curb<3 ) Alert(curb); //определяем очередность появления экстримумов //если открытие было уже экстримумом if( Open[curb]>aH || Low[curb]>=aL ) { fH=1; if( Low[curb]<aL ) { lL=1; } } else { if( Open[curb]<aL || High[curb]<=aH ) { fL=1; if( High[curb]>aH ) { lH=1; } } else { if( MathAbs(Close[curb]-aH)>MathAbs(Close[curb]-aL) ) { fH=1; if( Low[curb]<aL ) { lL=1; } } else { if( MathAbs(Close[curb]-High[curb])>MathAbs(Close[curb]-Low[curb]) ) { if( Open[curb]>Close[curb] ) { fH=1; if( Low[curb]<aL ) { lL=1; } } else { fL=1; if( High[curb]>aH ) { lH=1; } } } else { fL=1; if( High[curb]>aH ) { lH=1; } } } } } } } //****************************************************************** //---- return(0); } //+------------------------------------------------------------------+Взял последний ваш индикатор и и уcтановил не один, а разные цвета для каждого double, но он показывает только один цвет. А зачем остальные?
индикатор который я пытаюсь закодировать представляет из себя линию, которую не возможно построить только одним из представленых в языке стилей, раньше я использовал три драв лайн и один драв гистограмм (итого пять основных буферов), теперь заменил три драв лайна на один драв зигзаг (итого четыре основных буфера)