Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 1036

 
Vladimir Karputov:

Тут: 

Спасибо. У компа буду, может гляну.
 
Artyom Trishkin:
Спасибо. У компа буду, может гляну.

там в совсем-совсем старом формате индикатор под MQL4 написан, давно не трогал таких, не уверен, что помню как их писали

@zig2003 как вариант, попробуйте убрать из start()   IndicatorBuffers(6);

а вверху исправьте #property indicator_buffers 6

 
Igor Makanu, а после того, как исправлю индюк, мне в советнике что с чем нужно будет сравнить, чтобы запрограммировать разворот?
Igor Makanu
Igor Makanu
  • www.mql5.com
Стал часто замечать у некоторых пользователей приаттаченные графики баланса из тестера стратегий. Я многое не понимаю, но видимо в этом есть смысл? Это религия? Или все таки работает примета деньги к деньгам... Появился интерес к изучению возможностей Python 3.7.2 Давно не занимался парсингом сайтов, ибо утомительное и неэффективное занятие...
 
zig2003:
Igor Makanu, а после того, как исправлю индюк, мне в советнике что с чем нужно будет сравнить, чтобы запрограммировать разворот?

каждый индикатор состоит из нескольких индикаторных буферов

при вызове индикатора из советника через iCustom() Вы получаете значение одного буфера на конкретном баре, эти значение Вы можете посмотреть в окне данных Ctrl+D

что и с чем сравнивать зависит от Вашей ТС, или значения буферов индикатора или буфер и цену - вариантов много

Вы бы для начала сделали бы советник по МАшке, а потом когда разберетесь вместо МА будете свой индикатор вызывать

в общем не так все просто - написал пару команд и готов советник


ЗЫ: разворот индикатора это сравнение нескольких значений индикаторных буферов, судя по Вашему скрину на баре №2 должны быть значения  рядом с ценой буфера №1 и у остальных буферов будут EMPTY_VALUE значения, а на баре №1 наоборот у буфера №1 значение EMPTY_VALUE , а у какого то из 2 или 3 буфера будет значение отличное от EMPTY_VALUE - это все в окне обзор данных нужно смотреть (перемещаете стрелку мыши на барах и видите значения буферов)

 

Igor, спасибо, поправил индюк, но значение из буфера так и не появилось. Машки давно пройденный этап, там все просто, там две линии - два буфера. А тут одна линия и, похоже, один буфер.  Обычно для подобных индикаторов, состоящих из одной линии, но с разными буферами для цвета, я пишу код так:

//Функция для определения входа и выхода по AMA 
 int Enter()
  {
   double AMAbuy_1  =iCustom(NULL,_Period, "AMA", Range, FastMA,SlowMA,filter,normalizeDigits, 0,1);             //Подключаем AMA для первого бара (buy)
   double AMAsell_1 =iCustom(NULL,_Period, "AMA", Range, FastMA,SlowMA,filter,normalizeDigits, 1,1);             //                                (sell)
   double AMAbuy_2  =iCustom(NULL,_Period, "AMA", Range, FastMA,SlowMA,filter,normalizeDigits, 0,2);             //Подключаем AMA для второго бара (buy)       
   double AMAsell_2 =iCustom(NULL,_Period, "AMA", Range, FastMA,SlowMA,filter,normalizeDigits, 1,2);             //                                (sell)                    
                         
   if(AMAbuy_1>0 && AMAsell_2>0)                                                                                 //Вход в бай
      return(1);                                                                                           
   if(AMAsell_1>0 && AMAbuy_2>0)                                                                                 //Вход в селл
      return(-1);                                                                                          
        
   return(0);
  } 

Но это только если каждому цвету назначен реальный буфер. При смене цвета на первом закрытом баре значение буфера становится больше нуля, а на предыдущем баре оно было либо равно нулю, либо буфер другого цвета был больше нуля. А из этого индюка никак не могу получить значение для второго, селловского цвета и непонятно что с чем сравнить, чтобы поймать разворот. Перепробовал все номера буферов. И это печалька, ибо этот Младеновский индюк, хоть и старенький, но весьма прилично трендит в ручных стратежках....Может кто-то догадается, как вытащить значение из второго буфера и записать формулу разворота? 

 
zig2003:

Igor, спасибо, поправил индюк, но значение из буфера так и не появилось. Машки давно пройденный этап, там все просто, там две линии - два буфера. А тут одна линия и, похоже, один буфер.  Обычно для подобных индикаторов, состоящих из одной линии, но с разными буферами для цвета, я пишу код так:

Но это только если каждому цвету назначен реальный буфер. При смене цвета на первом закрытом баре значение буфера становится больше нуля, а на предыдущем баре оно было либо равно нулю, либо буфер другого цвета был больше нуля. А из этого индюка никак не могу получить значение для второго цвета и непонятно что с чем сравнить, чтобы поймать разворот. И это печалька, ибо этот Младеновский индюк, хоть и старенький, но весьма прилично трендит в ручных стратежках....Может кто-то догадается, как записать формулу разворота?

Без всяких правок индикатора.

Что означают данные в двух буферах - в 0 и 1:

  • Если есть значение в буфере 0 и нет значения в буфере 1, то это направление в лонг (синий цвет линии индикатора (если по умолчанию))
  • Если есть значение в буфере 0 и есть значение в буфере 1, то это направление в шорт (красный цвет линии индикатора (если по умолчанию))

Смена направления (цвета) линии:

  • В буфере 0 значение есть всегда и, кстати, по нему тоже можно определять (сравнивать значения на трёх барах: 2<=1 && 1>0 --> вниз, 2>=1 && 1<0 --> вверх)
    ...
    Но можно использовать и только буфер 1:
  • Если в буфере 1 на баре 0 нет значения, а на баре 1 есть значение, то это смена направления линии в лонг;
  • Если в буфере 1 на баре 0 есть значение, а на баре 1 нет значения, то это смена направления линии в шорт;

"Нет значения" здесь это EMPTY_VALUE. Ну или DBL_MAX - не важно, это одно и то же. Т.е., не ноль, а именно EMPTY_VALUE.

 
zig2003:

Может кто-то догадается, как вытащить значение из второго буфера и записать формулу разворота? 

не нужно догадываться, нужно сначала переписать индикатор в нормальный вид соответствующий текущему состоянию языка MQL4

вот немного привел код в порядок, но не уверен, что не будет ошибок, не нравится мне исходник, но увы, что есть с тем и работал

#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 clrDodgerBlue
#property indicator_color2 clrTomato
#property indicator_color3 clrTomato
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 2
//----
input int    Range           = 9;
input int    FastMA          = 3;
input int    SlowMA          = 30;
input int    filter          = 25;
input int    normalizeDigits = 4;

input bool   alertsOn        = false;
input bool   alertsOnCurrent = false;
input bool   alertsMessage   = true;
input bool   alertsSound     = true;
input bool   alertsEmail     = false;
input string soundfile       = "alert2.wav";


double Downa[];
double Downb[];
double trend[];
double fAMA[];
double mAMA[];
double AMA[];
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0, fAMA);
   SetIndexLabel(0, "fAMA");
   SetIndexBuffer(1, Downa);
   SetIndexLabel(1, "Downa");
   SetIndexBuffer(2, Downb);
   SetIndexLabel(2, "Downb");
   SetIndexBuffer(3, trend);
   SetIndexLabel(3, "trend");
   SetIndexBuffer(4, mAMA);
   SetIndexLabel(4, "mAMA");
   SetIndexBuffer(5, AMA);
   SetIndexLabel(5, "AMA");
   for (int i=0; i<indicator_buffers; i++) {
      SetIndexStyle(i, DRAW_LINE);
   }
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,      // размер входных таймсерий
                 const int prev_calculated,  // обработано баров на предыдущем вызове
                 const datetime &time[],     // Time
                 const double &open[],       // Open
                 const double &high[],       // High
                 const double &low[],        // Low
                 const double &close[],      // Close
                 const long &tick_volume[],  // Tick Volume
                 const long &volume[],       // Real Volume
                 const int &spread[]         // Spread
                )
{
   int limit;
   if(prev_calculated==0) limit=rates_total-1;
   else limit=rates_total-prev_calculated+1;
   if (trend[limit] == -1) ClearPoint(limit, Downa, Downb);
   double k1 = 2.0 / (SlowMA + 1);
   double k2 = 2.0 / (FastMA + 1) - k1;
   for(int i = limit; i>= 0; i--) {
      double sdAMA = 0;
      double Noise = 0;
      for(int k=0; k<Range; k++) Noise += MathAbs(Close[i+k] - Close[i+k+1]);
      double ER    = 0;
      if(Noise != 0) ER = MathAbs(Close[i] - Close[i+Range]) / Noise;
      double SSC   = (ER*k2+k1);



      AMA[i]  = AMA[i+1] + NormalizeDouble(SSC*SSC*(Close[i] - AMA[i+1]), normalizeDigits);
      mAMA[i] = AMA[i];

      if(filter < 1) fAMA[i] = mAMA[i];
      else {
         for(k = i; k <= i + SlowMA - 1; k++)  sdAMA = sdAMA + MathAbs(mAMA[k] - mAMA[k+1]);
         double dAMA  = mAMA[i] - mAMA[i+1];
         if(dAMA >= 0)
            if(dAMA < NormalizeDouble(filter*sdAMA/(100*SlowMA), 4) &&  High[i] <= High[Highest(NULL, 0, MODE_HIGH, 4, i)]+10*Point)
               fAMA[i] = fAMA[i+1];
            else   fAMA[i] = mAMA[i];
         else if(MathAbs(dAMA) < NormalizeDouble(filter*sdAMA/(100*SlowMA), 4) && Low[i] > Low[Lowest(NULL, 0, MODE_LOW, 4, i)]-10*Point)
            fAMA[i] = fAMA[i+1];
         else  fAMA[i] = mAMA[i];
      }

      Downa[i] = EMPTY_VALUE;
      Downb[i] = EMPTY_VALUE;
      trend[i] = trend[i+1];
      if (fAMA[i]> fAMA[i+1]) trend[i] =1;
      if (fAMA[i]< fAMA[i+1]) trend[i] =-1;
      if (trend[i]==-1) PlotPoint(i, Downa, Downb, fAMA);
   }

//


   if (alertsOn) {
      if (alertsOnCurrent)
         int whichBar = 0;
      else     whichBar = 1;
      if (trend[whichBar] != trend[whichBar+1])
         if (trend[whichBar] == 1)
            doAlert("buy");
         else  doAlert("sell");
   }
   return(rates_total);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void doAlert(string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;

   if (previousAlert != doWhat || previousTime != Time[0]) {
      previousAlert  = doWhat;
      previousTime   = Time[0];

      //
      //


      message =  StringConcatenate(Symbol(), " at ", TimeToStr(TimeLocal(), TIME_SECONDS), " AMA STL_Color ", doWhat);
      if (alertsMessage) Alert(message);
      if (alertsEmail)   SendMail(StringConcatenate(Symbol(), " AMA STL_Color "), message);
      if (alertsSound)   PlaySound(soundfile);
   }
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ClearPoint(int i, double& first[], double& second[])
{
   if ((second[i]  != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE))
      second[i+1] = EMPTY_VALUE;
   else if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE))
      first[i+1] = EMPTY_VALUE;
}
void PlotPoint(int i, double& first[], double& second[], double& from[])
{
   if (first[i+1] == EMPTY_VALUE)
      if (first[i+2] == EMPTY_VALUE) {
         first[i]  = from[i];
         first[i+1]  = from[i+1];
         second[i] = EMPTY_VALUE;
      }
      else  {
         second[i] = from[i];
         second[i+1] = from[i+1];
         first[i]  = EMPTY_VALUE;
      }
   else     {
      first[i]  = from[i];
      second[i]   = EMPTY_VALUE;
   }
}
//+------------------------------------------------------------------+

вот вижу значения индикаторных буферов этого индикатора:


 
Парни, спасибо вам за подсказки. Особенно Igor Makanu. Да, действительно, сделал 6 буферов вместо трех по умолчанию и появились значения 1 и -1 в одном из буферов, но совсем не в тех, что были изначально. Потому и не мог вытащить значения. А сам не догадался бы никогда. Теперь все стало на свои места. Все работает. Игорь, спасибо также за перегонку индюка в новый формат.  Еще раз низкий поклон за ваши знания!!! 
Igor Makanu
Igor Makanu
  • www.mql5.com
Стал часто замечать у некоторых пользователей приаттаченные графики баланса из тестера стратегий. Я многое не понимаю, но видимо в этом есть смысл? Это религия? Или все таки работает примета деньги к деньгам... Появился интерес к изучению возможностей Python 3.7.2 Давно не занимался парсингом сайтов, ибо утомительное и неэффективное занятие...
 
Igor Makanu:

не нужно догадываться, нужно сначала переписать индикатор в нормальный вид соответствующий текущему состоянию языка MQL4

вот немного привел код в порядок, но не уверен, что не будет ошибок, не нравится мне исходник, но увы, что есть с тем и работал

вот вижу значения индикаторных буферов этого индикатора:

Он без переписывания работает, и очень просто позволяет получать свои данные. Я выше всё описал - стоило только глянуть на показания его буферов в окне данных (Ctrl+D)

 
Artyom Trishkin:

Он без переписывания работает, и очень просто позволяет получать свои данные. Я выше всё описал - стоило только глянуть на показания его буферов в окне данных (Ctrl+D)

я выше писал, что не помню как работают функции IndicatorCounted()  в старых индикаторах, новая форма индикаторов с OnCalculate() как то более понятная

ну вопрос вроде решен, ну и ладненько ;)

Причина обращения: