Здравствуйте Господа!
У меня следующий вопрос.
Эксперт получает сигнал short / long от всем известного индикатора ASCtrend. При тестировании, просмотрев график, замечаю, что не на всех образовавшихся точках, эксперт выполняят операции. Думал что проблемма в длинном коде индикатора, вставлял в эксперта задержку Sleep, но безрезультатно. Подскажите пожалуйста кто знает, в чём проблема.
Будь ласка, продемонстрируй код.
#property indicator_chart_window #property indicator_buffers 3 #property indicator_color1 Aqua #property indicator_color2 Magenta extern int RISK=4; extern int AllBars=250; int up=0,dn=0; double val1buffer[]; double val2buffer[]; double doc[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- indicators SetIndexStyle(0,DRAW_ARROW,EMPTY); SetIndexArrow(0,108); SetIndexBuffer(0, val1buffer); SetIndexStyle(1,DRAW_ARROW,EMPTY); SetIndexArrow(1,108); SetIndexBuffer(1, val2buffer); SetIndexBuffer(2,doc); return(0); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ // int counted_bars=IndicatorCounted(); int start() { double value2; double value3; double value10=10; double value11; double x1=70; double x2=30; int TrueCount; int counter; int MRO1; int MRO2; int i1; double Range; double AvgRange; double val1; double val2; double Table_value2[500][2]; int counted_bars=IndicatorCounted(); value10=3+RISK*2; x1=67+RISK; x2=33-RISK; value11=value10; //---------------------------- if(counted_bars<0) return (-1); if(counted_bars>0) counted_bars--; //last bar recounted int i; int shift = Bars-counted_bars-1; if (shift > AllBars) shift = AllBars; for(i=shift; i>0; i--) { counter=i; Range=0; AvgRange=0; for (counter=i ;counter<=i+9;counter++) { AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]); } Range=AvgRange/10; counter=i; TrueCount=0; while (counter<i+9 && TrueCount<1) { if (MathAbs(Open[counter]-Close[counter+1])>=Range*2.0 ) TrueCount++; counter++; } if (TrueCount>=1) MRO1=counter ; else MRO1=-1; counter=i; TrueCount=0; while (counter<i+6 && TrueCount<1) { if(MathAbs(Close[counter+3]-Close[counter])>=Range*4.6) {TrueCount++;} counter++; } if(TrueCount>=1) MRO2=counter; else MRO2=-1; if (MRO1>-1) value11=3; else value11=value10; if (MRO2>-1) value11=4; else value11=value10; value2=100-MathAbs(iWPR(NULL,0,value11,i)); Table_value2[i][0]=i; Table_value2[i][1]=value2; val1=0; val2=0; value3=0; //------------------- val1 if (value2<x2 ) // x2 = 30 { i1=1; while (Table_value2[i+i1][1]>=x2 && Table_value2[i+i1][1]<=x1) {i1++;} if (Table_value2[i+i1][1]>x1) { value3=High[i]+Range*0.5; val1=value3; } } //------------------- val2 if ( value2>x1) // x1 = 70 { i1=1; while (Table_value2[i+i1][1]>=x2 && Table_value2[i+i1][1]<=x1) {i1++;} if (Table_value2[i+i1][1]< x2) { value3=Low[i]-Range*0.5; val2=value3; } } if (val2!=0 && up==0 ) { val1buffer[i]= val2-1*Point; up=1; dn=0; if(shift<=2) { doc[0]=1; } } if (val1 !=0 && dn==0) { val2buffer[i]= val1+1*Point; dn=1; up=0; if(shift<=2) { doc[0]=2; } } } return(0); }Это индикатор. Обращение из эксперта обычное через iCustom. Если возвращает 1 - buy, а если 2 - sell.
Да нет. У меня там предусмотрено, если открыт в другую стороно, сначало закрываем, а потом открываем новый. Да и ведь через несколько точек срабатывает. Похоже что в момент, когда индикатор показывает цыфру, эксперт уже проскакивает нужный код, или ещё не доходит. А может и тестр забавляется.
Наверное, нужно ещё раз пересмотреть код индикатора.
Без комментариев сразу не понять, но по-моему в этой строке
for(i=shift; i>0; i--)
следует использовать >= , чтобы считался и нулевой бар.
Лучше принять как шаблон для построения индикаторов следующий
код:
//-------------------------------------------------------------------- int start() // Специальная функция start() { int i, // Индекс бара Counted_bars; // Количество просчитанных баров //-------------------------------------------------------------------- Counted_bars=IndicatorCounted(); // Количество просчитанных баров i=Bars-Counted_bars-1; // Индекс первого непосчитанного while(i>=0) // Цикл по непосчитанным барам { // === сюда вставить расчёт === i--; // Расчёт индекса следующего бара } //-------------------------------------------------------------------- return; // Выход из спец. ф-ии start() } //--------------------------------------------------------------------
Наверное, нужно ещё раз пересмотреть код индикатора.
Без комментариев сразу не понять, но по-моему в этой строке
for(i=shift; i>0; i--)
следует использовать >= , чтобы считался и нулевой бар.
Лучше принять как шаблон для построения индикаторов следующий
код:
//-------------------------------------------------------------------- int start() // Специальная функция start() { int i, // Индекс бара Counted_bars; // Количество просчитанных баров //-------------------------------------------------------------------- Counted_bars=IndicatorCounted(); // Количество просчитанных баров i=Bars-Counted_bars-1; // Индекс первого непосчитанного while(i>=0) // Цикл по непосчитанным барам { // === сюда вставить расчёт === i--; // Расчёт индекса следующего бара } //-------------------------------------------------------------------- return; // Выход из спец. ф-ии start() } //--------------------------------------------------------------------
Чем лучше?
Может, ничем особо и не лучше. Несколько привычней свиду, немного компактней. С точки зрения работоспособности можно использовать любой способ. Я имел ввиду, что если использовать один и тот же шаблон, то любые отклонения от шаблона бросаются в глаза, легко ориентироваться.
Например, в рассматриваемом коде мне представляется инородной
строка:
if(counted_bars>0) counted_bars--; //last bar recountedЯ думаю, что неправильно каждый новый индикатор строить как-то оригинально, всякий раз изобретая велосипед.
Если б я что нибудь понимал в программировании, проявил бы к этому моменту принципиальный интерес. А пока, скрывая свою необразованность, ссылаю всё на несовершенство MQ4. Да простят меня авторы.
//+------------------------------------------------------------------+ //| ASC_Trend_1sig.mq4 | //| thanks to komposter |C0Rpus - big thanks CHANGE2002, STEPAN and SERSH //| komposterius[@]mail[.]ru | //+------------------------------------------------------------------+ #property copyright "thanks to komposter" #property link "komposterius[@]mail[.]ru" #property indicator_chart_window #property indicator_buffers 2 #property indicator_color1 Lime #property indicator_color2 Red extern double RISK = 3; /*extern*/ double K = 0.5; double buf0[]; //ASC_Trend_Up double buf1[]; //ASC_Trend_Down int init() { IndicatorShortName( "ASC_Trend" ); IndicatorDigits ( MarketInfo( Symbol(), MODE_DIGITS ) ); SetIndexBuffer( 0 , buf0 ); SetIndexStyle ( 0 , DRAW_ARROW , EMPTY , 1 ); SetIndexArrow( 0 , 217); SetIndexDrawBegin( 0 , 12 ); SetIndexLabel( 0 , "ASC_Trend_Up"); SetIndexBuffer( 1 , buf1 ); SetIndexStyle ( 1 , DRAW_ARROW , EMPTY , 1 ); SetIndexArrow( 1 , 218); SetIndexDrawBegin( 1 , 12 ); SetIndexLabel( 1 , "ASC_Trend_Down"); return(0); } int ASC_Trend_Prev = 1; int start() { int counted_bars=IndicatorCounted(); if ( counted_bars < 0 ) { Print( "counted_bars < 0 !" ); return(-1); } if ( Bars < 100 ) { Print( "Bars < 100 !" ); return(-1); } if ( counted_bars > 0 ) { counted_bars -- ; } int limit = Bars - 12; if ( counted_bars > 0 ) { limit = Bars - counted_bars - 12; } double x1 = 67 + RISK, x2 = 33 - RISK; for ( int i = limit; i >= 0; i -- ) { double ASC_Trend_Up = 0, ASC_Trend_Down = 0, SummRange = 0, AvgRange = 0; for ( int u = i + 9; u >= i; u -- ) { SummRange += High[u] - Low[u]; } AvgRange = SummRange / 10; int WprPeriod = 3 + RISK * 2; for ( u = i + 9; u >= i; u -- ) { if ( MathAbs( Open[u] - Close[u+1] ) >= AvgRange * 2 ) { WprPeriod = 3; break; } } for ( u = i + 6; u >= i; u -- ) { if ( MathAbs( Close[u+3] - Close[u] ) >= AvgRange * 4.6 ) { WprPeriod = 4; break; } } double WprAbs = 100 + iWPR( Symbol(), 0, WprPeriod, i ); if ( WprAbs > x1 && ASC_Trend_Prev == -1 ) { ASC_Trend_Up = Low[i] - AvgRange * K; ASC_Trend_Prev = 1; } if ( WprAbs < x2 && ASC_Trend_Prev == 1 ) { ASC_Trend_Down = High[i] + AvgRange * K; ASC_Trend_Prev = -1; } buf0[i] = ASC_Trend_Up; buf1[i] = ASC_Trend_Down; } return(0); }
А во-вторых, берите его значения не с 0-го, а с 1-го бара.
Удачи!
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
У меня следующий вопрос.
Эксперт получает сигнал short / long от всем известного индикатора ASCtrend. При тестировании, просмотрев график, замечаю, что не на всех образовавшихся точках, эксперт выполняят операции. Думал что проблемма в длинном коде индикатора, вставлял в эксперта задержку Sleep, но безрезультатно. Подскажите пожалуйста кто знает, в чём проблема.