Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 1036

 
Vladimir Karputov:

There:

Thanks. I'll be at the computer, maybe I'll have a look.
 
Artyom Trishkin:
Thank you. I'll be at the computer, maybe I'll have a look.

the indicator is written in a very-very old format in MQL4, I haven't touched it for a long time, I'm not sure I remember how it was written

@zig2003 as an option, try to remove IndicatorBuffers(6) from start()

and at the top fix #property indicator_buffers 6

 
Igor Makanu, and after I fix the indicator, what will I need to compare with what in the EA to program a reversal?
Igor Makanu
Igor Makanu
  • www.mql5.com
Стал часто замечать у некоторых пользователей приаттаченные графики баланса из тестера стратегий. Я многое не понимаю, но видимо в этом есть смысл? Это религия? Или все таки работает примета деньги к деньгам... Появился интерес к изучению возможностей Python 3.7.2 Давно не занимался парсингом сайтов, ибо утомительное и неэффективное занятие...
 
zig2003:
Igor Makanu, and after I correct the indicator what should I compare to in my Expert Advisor to programme the pivot?

each indicator consists of several indicator buffers

when you call the indicator from the Expert Advisor through iCustom(), you get the value of one buffer on a certain bar, and you can view this value in the data window Ctrl+D

what to compare depends on your TS, either the values of indicator buffers or buffer and price - there are many variants

You should first create an MA indicator, and then, when you understand it, you will call your own indicator instead of the MA

It's not that easy - just write a couple of commands and your Expert Advisor will be ready


ZS: an indicator pivot is a comparison of several values of indicator buffers, judging by your screenshot on the bar number 2 must be set near the price of buffer number 1 and the rest of the buffers will haveEMPTY_VALUE values, and on the bar №1, on the contrary, buffer №1 has the value EMPTY_VALUE , and one of 2 or 3 buffers will have the value different from EMPTY_VALUE - you should look it all in the window of data overview (move the mouse arrow on the bars and you see the buffers values)

 

Igor, thank you, I corrected the indicator, but the value from the buffer still did not appear. I have long ago passed that stage, everything is simple there, there are two lines - two buffers. Usually for similar indicators, which consist of one line, but with different buffers for colour, I write the code so:

//Функция для определения входа и выхода по 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);
  } 

But this is only if a real buffer is assigned to each colour. When you change colour on the first closed bar, the buffer value becomes greater than zero, while on the previous bar it was either equal to zero or the buffer of another colour was greater than zero. I can't get the value for the second Sell colour from this indicator and I don't know what to compare it with to catch the reversal. I've tried every buffer number. This is unfortunate, because this Mladenov's turntable, although old, but very decent trending in manual strategics.... Can someone guess how to pull the value from the second buffer and write the formula for the reversal?

 
zig2003:

Igor, thank you, I corrected the indicator, but the value from the buffer still did not appear. I have long ago passed that stage, everything is simple there, there are two lines - two buffers. Usually for similar indicators, which consist of one line but with different buffers for colour, I write the code in this way:

But this is only if a real buffer is assigned to each colour. When you change colour on the first closed bar, the buffer value becomes greater than zero, while on the previous bar it was either equal to zero or the buffer of another colour was greater than zero. I cannot get the value for the second colour from this indicator and I cannot understand what to compare it with to catch the reversal. And this is unfortunate, because this Mladenov's indicator, though old, but very well trending in manual strategics.... Can someone figure out how to write the reversal formula?

Without any indicator edits.

What does the data in the two buffers mean - in 0 and 1:

  • If there is a value in buffer 0 and no value in buffer 1, this is the direction to go long (blue indicator line (if default))
  • If there is a value in buffer 0 and there is a value in buffer 1, then this is a short direction (red colour of indicator line (if default))

Change of direction (colour) of the line:

  • There is always a value in the buffer 0 and, by the way, one can always define it (compare values on three bars: 2<=1 && 1>0 --> down, 2>=1 && 1<0 --> up)
    ...
    But you can also use only buffer 1:
  • If there is no value in buffer 1 on bar 0 and there is a value on bar 1, this is a change of line direction to long;
  • If there is a value on bar 0 in buffer 1 and no value on bar 1, this is a change of line direction to short;

"No value" here is EMPTY_VALUE. Or DBL_MAX - doesn't matter, it's the same thing. I.e. it's not zero, but EMPTY_VALUE.

 
zig2003:

Can anyone guess how to pull the value from the second buffer and write the pivot formula?

You don't have to guess, you should first rewrite the indicator in a normal form corresponding to the current state of MQL4

I have put the code in order a bit, but I'm not sure that there won't be errors. I don't like the source code, but I've worked with what I've got.

#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;
   }
}
//+------------------------------------------------------------------+

Here I see the values of indicator buffers of this indicator:


 
Guys, thank you for the tips. EspeciallyIgor Makanu. Yes, indeed, I made 6 buffers instead of the default three and the values 1 and -1 appeared in one of the buffers, but not at all in the original ones. That's why I couldn't get the values out. And I never would have guessed it myself. Everything is back to normal now. Everything is working. Igor, thank you also for the distillation of the indicator into the new format. Thanks again for your knowledge!!!
Igor Makanu
Igor Makanu
  • www.mql5.com
Стал часто замечать у некоторых пользователей приаттаченные графики баланса из тестера стратегий. Я многое не понимаю, но видимо в этом есть смысл? Это религия? Или все таки работает примета деньги к деньгам... Появился интерес к изучению возможностей Python 3.7.2 Давно не занимался парсингом сайтов, ибо утомительное и неэффективное занятие...
 
Igor Makanu:

You don't have to guess, first you need to rewrite the indicator in a normal form corresponding to the current state of the MQL4 language

I have put the code in order a bit, but I'm not sure that there will be no errors, I don't like the source code, but I've worked with what I've got

Here I see the values of indicator buffers of this indicator:

It works without overwriting, and makes it very easy to get your data. I described it above - you just need to look at its buffer readings in the data window (Ctrl+D)

 
Artyom Trishkin:

It works without rewriting and allows to receive its data very simply. I described it above - you just need to look at its buffer readings in the data window (Ctrl+D)

I wrote above that I don't remember how the IndicatorCounted() function works in old indicators, the new form of indicators with OnCalculate() is more understandable

Well, the issue seems to be solved, all right ;)