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

 

Возможно ли сделать в индикаторе скрытие всех полос уровней разворота, не тестированных и остальных а оставить только тестированные а то есть скрытие extern bool zone_show_weak  = true; и ниже в коде if (zone_strength[i] == ZONE_WEAK && zone_show_weak == false) а другие скрыть не получается попробовал поставить им всем черный цвет, но тогда если их и нет, то они мешают видеть цену на графике в вертикальном масштабе. Может кто разбирается и подправит код или удалит те уровни, что описывал выше. Код индикатора:

#property copyright "Copyright © 2017 Andrew Sumner"

#property link      ""

#property indicator_chart_window

#property indicator_buffers 4

#property indicator_color1 Red

#property indicator_color2 Red

#property indicator_color3 DodgerBlue

#property indicator_color4 DodgerBlue


extern int BackLimit   = 300;  //Back - назад

extern int TimeFrame   = 0;

extern string TimeString  = "0=Current, 60=H1, 240=H4, 1440=Day, 10080=Week, 43200=Month";


extern color color_support_weak     = MediumAquamarine;  //support - поддержка  weak-слабый  DarkSlateGray

extern color color_support_untested = SeaGreen;      //  непроверенный

extern color color_support_verified = Green;

extern color color_support_proven   = LimeGreen;

extern color color_support_turncoat = OliveDrab;

extern color color_resist_weak      = Sienna;

extern color color_resist_untested  = Orchid;

extern color color_resist_verified  = Crimson;

extern color color_resist_proven    = Red;

extern color color_resist_turncoat  = DarkOrange;


extern bool zone_show_weak  = true;

extern double zone_fuzzfactor = 0.2;

extern bool zone_solid = false; //true  при false будет не полные зоны полос а обрамленные прямоугольником с толщиной width

extern int zone_linewidth = 2;

extern int zone_style = 0;

extern bool zone_show_info    = true;

extern int zone_label_shift  = 22;  //смещение по горизонтали надписей, но только после удаления индикатора

extern bool zone_show_alerts  = false;

extern bool zone_alert_popups = true;

extern bool zone_alert_sounds = true;

extern bool send_email        = false;

extern int zone_alert_waitseconds = 300; 

extern bool zone_merge = true;

extern bool zone_extend = true;


extern bool fractals_show = false;

extern double fractal_fast_factor = 3.0;

extern double fractal_slow_factor = 6.0;

extern bool SetGlobals = true;


double FastDnPts[], FastUpPts[];

double SlowDnPts[], SlowUpPts[];


double zone_hi[1000], zone_lo[1000];

int    zone_start[1000], zone_hits[1000], zone_type[1000], zone_strength[1000], zone_count = 0;

bool   zone_turn[1000];


#define ZONE_SUPPORT 1

#define ZONE_RESIST  2


#define ZONE_WEAK      0

#define ZONE_TURNCOAT  1

#define ZONE_UNTESTED  2

#define ZONE_VERIFIED  3

#define ZONE_PROVEN    4


#define UP_POINT 1

#define DN_POINT -1


int time_offset = 0;


int init()

{

   IndicatorBuffers(4);


   SetIndexBuffer(0, SlowDnPts);

   SetIndexBuffer(1, SlowUpPts);

   SetIndexBuffer(2, FastDnPts);

   SetIndexBuffer(3, FastUpPts);


   if (fractals_show == true)

   {

      SetIndexStyle(0, DRAW_ARROW, 0, 3);

      SetIndexStyle(1, DRAW_ARROW, 0, 3);

      SetIndexStyle(2, DRAW_ARROW, 0, 1);

      SetIndexStyle(3, DRAW_ARROW, 0, 1);

      SetIndexArrow(0, 218);

      SetIndexArrow(1, 217);

      SetIndexArrow(2, 218);

      SetIndexArrow(3, 217);

   }

   else

   {

      SetIndexStyle(0, DRAW_NONE);

      SetIndexStyle(1, DRAW_NONE);

      SetIndexStyle(2, DRAW_NONE);

      SetIndexStyle(3, DRAW_NONE);

   }


   if (TimeFrame != 1 && TimeFrame != 5 && TimeFrame != 15 &&

       TimeFrame != 60 && TimeFrame != 240 && TimeFrame != 1440 &&

       TimeFrame != 10080 && TimeFrame != 43200)

      TimeFrame = 0;


   if (TimeFrame < Period())

      TimeFrame = Period();


   return(0);

}


int deinit()

{

   DeleteZones();

   DeleteGlobalVars();

   return(0);

}


int start()

{

   if (NewBar() == true)

   {

      int old_zone_count = zone_count;


      FastFractals();

      SlowFractals();

      DeleteZones();

      FindZones();

      DrawZones();

      if (zone_count < old_zone_count)

         DeleteOldGlobalVars(old_zone_count);

   }


   if (zone_show_info == true)

   {

      for (int i=0; i<zone_count; i++)

      {

         string lbl;

         if (zone_strength[i] == ZONE_PROVEN)

            lbl = ""; //   Доказан

         else if (zone_strength[i] == ZONE_VERIFIED)

            lbl = "";  //   Проверен

         else if (zone_strength[i] == ZONE_UNTESTED)

            lbl = "";   //      НЕ тест

         else if (zone_strength[i] == ZONE_TURNCOAT)

            lbl = "";  //        Разворот

         else

            lbl = "";       //Слабое


         if (zone_type[i] == ZONE_SUPPORT)

            lbl = lbl + "под";  //Support

         else

            lbl = lbl + "соп";  //Resistance


         if (zone_hits[i] > 0 && zone_strength[i] > ZONE_UNTESTED)

         {

            if (zone_hits[i] == 1)

               lbl = lbl + ",Т=" + zone_hits[i]; //Test Count

            else

               lbl = lbl + ",Т=" + zone_hits[i];  //Test Count

         }


         int adjust_hpos;

         int wbpc = WindowBarsPerChart();

         int k;

         

         k = Period() * 60 + (20 + StringLen(lbl));

         

         if (wbpc < 80)  

            adjust_hpos = Time[0] + k * 4;

         else if (wbpc < 125)  

            adjust_hpos = Time[0] + k * 8;

         else if (wbpc < 250)

            adjust_hpos = Time[0] + k * 15;

         else if (wbpc < 480)

            adjust_hpos = Time[0] + k * 29;

         else if (wbpc < 950)

            adjust_hpos = Time[0] + k * 58;

         else

            adjust_hpos = Time[0] + k * 115;

         

        


         int shift = k * zone_label_shift;

         double vpos = zone_hi[i] - (zone_hi[i] - zone_lo[i]) / 2;


         

         

          //Текст описаний уровней

         string s = "SSSR#"+i+"LBL";

         ObjectCreate(s, OBJ_TEXT, 0, 0, 0);

         ObjectSet(s, OBJPROP_TIME1, adjust_hpos + shift);

         ObjectSet(s, OBJPROP_PRICE1, vpos);

         ObjectSetText(s, StringRightPad(lbl, 36, "  "), 11, "Courier New",clrWhite);  //Black

      }

   }


   CheckAlerts();


   return(0);

}


void CheckAlerts()

{

   static int lastalert = 0;


   if (zone_show_alerts == false)

      return;


   if (Time[0] - lastalert > zone_alert_waitseconds)

      if (CheckEntryAlerts() == true)

         lastalert = Time[0];

}


bool CheckEntryAlerts()

{

   // проверить записи

   for (int i=0; i<zone_count; i++)

   {

      if (Close[0] >= zone_lo[i] && Close[0] < zone_hi[i])

      {

         if (zone_show_alerts == true)

         {

            if (zone_alert_popups == true)

            {

               if (zone_type[i] == ZONE_SUPPORT)

               Alert(Symbol() + TimeFrameToString(TimeFrame) + ": Support Zone Entered"); //Введена зона поддержки

               else

               Alert(Symbol() + TimeFrameToString(TimeFrame) + ": Resistance Zone Entered"); //Введена зона сопротивления

            }


            if (zone_alert_sounds == true)

               PlaySound("alert.wav");

         }

         

         if (send_email == true)

         {

            string dir = "";

            string msg = StringConcatenate(Symbol(), "-", TimeFrameToString(TimeFrame), " at ", TimeToStr(Time[0], TIME_DATE|TIME_SECONDS),

                                           " ", dir, " Zone Entered");

            if (zone_type[i] == ZONE_SUPPORT)

            {

               dir = "Support";

               SendMail("SS_SupRes_v04c alert", msg);

            }

            else

            {

               dir = "Resistance";

               SendMail("SS_SupRes_v04c alert", msg);

            }

         }

         return(true);

      }

   }


   return(false);

}


void DeleteGlobalVars()

{

   if (SetGlobals == false)

      return;


   GlobalVariableDel("SSSR_Count_"+Symbol()+TimeFrame);

   GlobalVariableDel("SSSR_Updated_"+Symbol()+TimeFrame);


   int old_count = zone_count;

   zone_count = 0;

   DeleteOldGlobalVars(old_count);

}


void DeleteOldGlobalVars(int old_count)

{

   if (SetGlobals == false)

      return;


   for (int i=zone_count; i<old_count; i++)

   {

      GlobalVariableDel("SSSR_HI_"+Symbol()+TimeFrame+i);

      GlobalVariableDel("SSSR_LO_"+Symbol()+TimeFrame+i);

      GlobalVariableDel("SSSR_HITS_"+Symbol()+TimeFrame+i);

      GlobalVariableDel("SSSR_STRENGTH_"+Symbol()+TimeFrame+i);

      GlobalVariableDel("SSSR_AGE_"+Symbol()+TimeFrame+i);

   }

}


void FindZones()

{

   int i, j, shift, bustcount=0, testcount = 0;

   double hival, loval;

   bool turned = false, hasturned = false;


   double temp_hi[1000], temp_lo[1000];

   int    temp_start[1000], temp_hits[1000], temp_strength[1000], temp_count = 0;

   bool   temp_turn[1000], temp_merge[1000];

   int merge1[1000], merge2[1000], merge_count = 0;


   // перебирать зоны от самых старых до самых маленьких (игнорировать последние 5 баров),

   // нахождение тех, кто выжил до настоящего...

   for (shift=MathMin(iBars(NULL, TimeFrame)-1, BackLimit); shift>5; shift--)

   {

      double atr = iATR(NULL, TimeFrame, 7, shift);

      double fu = atr/2 * zone_fuzzfactor;

      bool isWeak;

      bool touchOk = false;

      bool isBust = false;

      double close = iClose(NULL, TimeFrame, shift);

      double high  = iHigh(NULL, TimeFrame, shift);

      double low   = iLow(NULL, TimeFrame, shift);

      double hi_i;

      double lo_i;


      if (FastUpPts[shift] > 0.001)

      {

         // зигзаг высокой точки

         isWeak = true;

         if (SlowUpPts[shift] > 0.001)

            isWeak = false;


         hival = high;

         if (zone_extend == true)

            hival += fu;


         loval = MathMax(MathMin(close, high-fu), high-fu*2);

         turned = false;

         hasturned = false;

         isBust = false;


         bustcount = 0;

         testcount = 0;


         for (i=shift-1; i>=0; i--)

         {

            hi_i = iHigh(NULL, TimeFrame, i);

            lo_i = iLow(NULL, TimeFrame, i);


            if ((turned == false && FastUpPts[i] >= loval && FastUpPts[i] <= hival) ||

                (turned == true && FastDnPts[i] <= hival && FastDnPts[i] >= loval))

            {

               // Потенциальное касание, просто убедитесь, что оно было 10 + свечей с момента предыдущего

               touchOk = true;

               for (j=i+1; j<i+11; j++)

               {

                  if ((turned == false && FastUpPts[j] >= loval && FastUpPts[j] <= hival) ||

                      (turned == true && FastDnPts[j] <= hival && FastDnPts[j] >= loval))

                  {

                     touchOk = false;

                     break;

                  }

               }


               if (touchOk == true)

               {

                  // у нас есть прикосновение.  Если он был разорен один раз, удалите bustcount

                  // поскольку мы знаем, что этот уровень по-прежнему действителен и только что сменил стороны

                  bustcount = 0;

                  testcount++;

               }

            }


            if ((turned == false && hi_i > hival) ||

                (turned == true && lo_i < loval))

            {

               // этот уровень был разорен по крайней мере один раз

               bustcount++;


               if (bustcount > 1 || isWeak == true)

               {

                  // два или более

                  isBust = true;

                  break;

               }


               if (turned == true)

                  turned = false;

               else if (turned == false)

                  turned = true;


               hasturned = true;


               // забыть предыдущие hits

               testcount = 0;

            }

         }


         if (isBust == false)

         {

            // уровень по-прежнему действителен, добавьте в наш список

            temp_hi[temp_count] = hival;

            temp_lo[temp_count] = loval;

            temp_turn[temp_count] = hasturned;

            temp_hits[temp_count] = testcount;

            temp_start[temp_count] = shift;

            temp_merge[temp_count] = false;

            

            if (testcount > 3)

               temp_strength[temp_count] = ZONE_PROVEN;

            else if (testcount > 0)

               temp_strength[temp_count] = ZONE_VERIFIED;

            else if (hasturned == true)

               temp_strength[temp_count] = ZONE_TURNCOAT;

            else if (isWeak == false)

               temp_strength[temp_count] = ZONE_UNTESTED;

            else

               temp_strength[temp_count] = ZONE_WEAK;


            temp_count++;

         }

      }

      else if (FastDnPts[shift] > 0.001)

      {

         // низкая зигзагообразная точка

         isWeak = true;

         if (SlowDnPts[shift] > 0.001)

            isWeak = false;


         loval = low;

         if (zone_extend == true)

            loval -= fu;


         hival = MathMin(MathMax(close, low+fu), low+fu*2);

         turned = false;

         hasturned = false;


         bustcount = 0;

         testcount = 0;

         isBust = false;


         for (i=shift-1; i>=0; i--)

         {

            hi_i = iHigh(NULL, TimeFrame, i);

            lo_i = iLow(NULL, TimeFrame, i);


            if ((turned == true && FastUpPts[i] >= loval && FastUpPts[i] <= hival) ||

                (turned == false && FastDnPts[i] <= hival && FastDnPts[i] >= loval))

            {

               // Потенциальное касание, просто убедитесь, что оно было 10 + свечей с момента предыдущего

               touchOk = true;

               for (j=i+1; j<i+11; j++)

               {

                  if ((turned == true && FastUpPts[j] >= loval && FastUpPts[j] <= hival) ||

                      (turned == false && FastDnPts[j] <= hival && FastDnPts[j] >= loval))

                  {

                     touchOk = false;

                     break;

                  }

               }


               if (touchOk == true)

               {

                  // у нас есть прикосновение.  Если он был разорен один раз, удалите bustcount

                  // поскольку мы знаем, что этот уровень по-прежнему действителен и только что сменил стороны

                  bustcount = 0;

                  testcount++;

               }

            }


            if ((turned == true && hi_i > hival) ||

                (turned == false && lo_i < loval))

            {

               // этот уровень был разорен по крайней мере один раз

               bustcount++;


               if (bustcount > 1 || isWeak == true)

               {

                  // два или более

                  isBust = true;

                  break;

               }


               if (turned == true)

                  turned = false;

               else if (turned == false)

                  turned = true;


               hasturned = true;


               // забыть предыдущие hits

               testcount = 0;

            }

         }


         if (isBust == false)

         {

            // уровень по-прежнему действителен, добавьте в наш список

            temp_hi[temp_count] = hival;

            temp_lo[temp_count] = loval;

            temp_turn[temp_count] = hasturned;

            temp_hits[temp_count] = testcount;

            temp_start[temp_count] = shift;

            temp_merge[temp_count] = false;


            if (testcount > 3)

               temp_strength[temp_count] = ZONE_PROVEN;

            else if (testcount > 0)

               temp_strength[temp_count] = ZONE_VERIFIED;

            else if (hasturned == true)

               temp_strength[temp_count] = ZONE_TURNCOAT;

            else if (isWeak == false)

               temp_strength[temp_count] = ZONE_UNTESTED;

            else

               temp_strength[temp_count] = ZONE_WEAK;


            temp_count++;

         }

      }

   }


   // искать перекрывающиеся зоны...

   if (zone_merge == true)

   {

      merge_count = 1;

      int iterations = 0;

      while (merge_count > 0 && iterations < 3)

      {

         merge_count = 0;

         iterations++;


         for (i = 0; i < temp_count; i++)

            temp_merge[i] = false;


         for (i = 0; i < temp_count-1; i++)

         {

            if (temp_hits[i] == -1 || temp_merge[j] == true)

               continue;


            for (j = i+1; j < temp_count; j++)

            {

               if (temp_hits[j] == -1 || temp_merge[j] == true)

                  continue;


               if ((temp_hi[i] >= temp_lo[j] && temp_hi[i] <= temp_hi[j]) ||

                   (temp_lo[i] <= temp_hi[j] && temp_lo[i] >= temp_lo[j]) ||

                   (temp_hi[j] >= temp_lo[i] && temp_hi[j] <= temp_hi[i]) ||

                   (temp_lo[j] <= temp_hi[i] && temp_lo[j] >= temp_lo[i]))

               {

                  merge1[merge_count] = i;

                  merge2[merge_count] = j;

                  temp_merge[i] = true;

                  temp_merge[j] = true;

                  merge_count++;

               }

            }

         }


         // ... и объединить их ...

         for (i=0; i<merge_count; i++)

         {

            int target = merge1[i];

            int source = merge2[i];


            temp_hi[target] = MathMax(temp_hi[target], temp_hi[source]);

            temp_lo[target] = MathMin(temp_lo[target], temp_lo[source]);

            temp_hits[target] += temp_hits[source];

            temp_start[target] = MathMax(temp_start[target], temp_start[source]);

            temp_strength[target] = MathMax(temp_strength[target], temp_strength[source]);

            if (temp_hits[target] > 3)

               temp_strength[target] = ZONE_PROVEN;


            if (temp_hits[target] == 0 && temp_turn[target] == false)

            {

               temp_hits[target] = 1;

               if (temp_strength[target] < ZONE_VERIFIED)

                  temp_strength[target] = ZONE_VERIFIED;

            }


            if (temp_turn[target] == false || temp_turn[source] == false)

               temp_turn[target] = false;

            if (temp_turn[target] == true)

               temp_hits[target] = 0;


            temp_hits[source] = -1;

         }

      }

   }


   // скопируйте оставшийся список в наши официальные зоны

   zone_count = 0;

   for (i=0; i<temp_count; i++)

   {

      if (temp_hits[i] >= 0 && zone_count < 1000)

      {

         zone_hi[zone_count]       = temp_hi[i];

         zone_lo[zone_count]       = temp_lo[i];

         zone_hits[zone_count]     = temp_hits[i];

         zone_turn[zone_count]     = temp_turn[i];

         zone_start[zone_count]    = temp_start[i];

         zone_strength[zone_count] = temp_strength[i];

         

         if (zone_hi[zone_count] < Close[4])

            zone_type[zone_count] = ZONE_SUPPORT;

         else if (zone_lo[zone_count] > Close[4])

            zone_type[zone_count] = ZONE_RESIST;

         else

         {

            for (j=5; j<1000; j++)

            {

               if (iClose(NULL, TimeFrame, j) < zone_lo[zone_count])

               {

                  zone_type[zone_count] = ZONE_RESIST;

                  break;

               }

               else if (iClose(NULL, TimeFrame, j) > zone_hi[zone_count])

               {

                  zone_type[zone_count] = ZONE_SUPPORT;

                  break;

               }

            }


            if (j == 1000)

               zone_type[zone_count] = ZONE_SUPPORT;

         }


         zone_count++;

      }

   }

}


void DrawZones()

{

   if (SetGlobals == true)

   {

      GlobalVariableSet("SSSR_Count_"+Symbol()+TimeFrame, zone_count);

      GlobalVariableSet("SSSR_Updated_"+Symbol()+TimeFrame, TimeCurrent());

   }


   for (int i=0; i<zone_count; i++)

   {

      if (zone_strength[i] == ZONE_WEAK && zone_show_weak == false)

         continue;


      string s = "SSSR#"+i+" Strength=";

      if (zone_strength[i] == ZONE_PROVEN)

         s = s + "Proven, Test Count=" + zone_hits[i];

      else if (zone_strength[i] == ZONE_VERIFIED)

         s = s + "Verified, Test Count=" + zone_hits[i];

      else if (zone_strength[i] == ZONE_UNTESTED)

         s = s + "Untested";

      else if (zone_strength[i] == ZONE_TURNCOAT)

         s = s + "Turncoat";

      else

         s = s + "Weak";


      ObjectCreate(s, OBJ_RECTANGLE, 0, 0, 0, 0, 0);

      ObjectSet(s, OBJPROP_TIME1, iTime(NULL, TimeFrame, zone_start[i]));

      ObjectSet(s, OBJPROP_TIME2, TimeCurrent());

      ObjectSet(s, OBJPROP_PRICE1, zone_hi[i]);

      ObjectSet(s, OBJPROP_PRICE2, zone_lo[i]);

      ObjectSet(s, OBJPROP_BACK, zone_solid);

      ObjectSet(s, OBJPROP_WIDTH, zone_linewidth);

      ObjectSet(s, OBJPROP_STYLE, zone_style);


      if (zone_type[i] == ZONE_SUPPORT)

      {

         // зона поддержки

         if (zone_strength[i] == ZONE_TURNCOAT)

            ObjectSet(s, OBJPROP_COLOR, color_support_turncoat);

         else if (zone_strength[i] == ZONE_PROVEN)

            ObjectSet(s, OBJPROP_COLOR, color_support_proven);

         else if (zone_strength[i] == ZONE_VERIFIED)

            ObjectSet(s, OBJPROP_COLOR, color_support_verified);

         else if (zone_strength[i] == ZONE_UNTESTED)

            ObjectSet(s, OBJPROP_COLOR, color_support_untested);

         else

            ObjectSet(s, OBJPROP_COLOR, color_support_weak);

      }

      else

      {

         // зона сопротивления

         if (zone_strength[i] == ZONE_TURNCOAT)

            ObjectSet(s, OBJPROP_COLOR, color_resist_turncoat);

         else if (zone_strength[i] == ZONE_PROVEN)

            ObjectSet(s, OBJPROP_COLOR, color_resist_proven);

         else if (zone_strength[i] == ZONE_VERIFIED)

            ObjectSet(s, OBJPROP_COLOR, color_resist_verified);

         else if (zone_strength[i] == ZONE_UNTESTED)

            ObjectSet(s, OBJPROP_COLOR, color_resist_untested);

         else

            ObjectSet(s, OBJPROP_COLOR, color_resist_weak);

      }




      if (SetGlobals == true)

      {

         GlobalVariableSet("SSSR_HI_"+Symbol()+TimeFrame+i, zone_hi[i]);

         GlobalVariableSet("SSSR_LO_"+Symbol()+TimeFrame+i, zone_lo[i]);

         GlobalVariableSet("SSSR_HITS_"+Symbol()+TimeFrame+i, zone_hits[i]);

         GlobalVariableSet("SSSR_STRENGTH_"+Symbol()+TimeFrame+i, zone_strength[i]);

         GlobalVariableSet("SSSR_AGE_"+Symbol()+TimeFrame+i, zone_start[i]);

      }

   }

}


bool Fractal(int M, int P, int shift)

{

   if (TimeFrame > P)

      P = TimeFrame;

   

   P = P / TimeFrame*2 + MathCeil(P / TimeFrame / 2);

   

   if (shift < P)

      return(false);


   if (shift > iBars(Symbol(), TimeFrame)-P)

      return(false); 

   

   for (int i=1; i<=P; i++)

   {

      if (M == UP_POINT)

      {

         if (iHigh(NULL, TimeFrame, shift+i) > iHigh(NULL, TimeFrame, shift))

            return(false);

         if (iHigh(NULL, TimeFrame, shift-i) >= iHigh(NULL, TimeFrame, shift))

            return(false);     

      }

      if (M == DN_POINT)

      {

         if (iLow(NULL, TimeFrame, shift+i) < iLow(NULL, TimeFrame, shift))

            return(false);

         if (iLow(NULL, TimeFrame, shift-i) <= iLow(NULL, TimeFrame, shift))

            return(false);

      }        

   }

   return(true);   

}  


void FastFractals()

{

   int shift;

   int limit = MathMin(Bars-1, BackLimit);

   int P = TimeFrame * fractal_fast_factor;


   FastUpPts[0] = 0.0; FastUpPts[1] = 0.0;

   FastDnPts[0] = 0.0; FastDnPts[1] = 0.0;


   for (shift=limit; shift>1; shift--)

   {

      if (Fractal(UP_POINT, P, shift) == true)

         FastUpPts[shift] = iHigh(NULL, TimeFrame, shift);

      else

         FastUpPts[shift] = 0.0;


      if (Fractal(DN_POINT, P, shift) == true)

         FastDnPts[shift] = iLow(NULL, TimeFrame, shift);

      else

         FastDnPts[shift] = 0.0;

   }

}


void SlowFractals()

{

   int shift;

   int limit = MathMin(iBars(Symbol(), TimeFrame) - 1, BackLimit);

   int P = TimeFrame * fractal_slow_factor;


   SlowUpPts[0] = 0.0; SlowUpPts[1] = 0.0;

   SlowDnPts[0] = 0.0; SlowDnPts[1] = 0.0;


   for (shift=limit; shift>1; shift--)

   {

      if (Fractal(UP_POINT, P, shift) == true)

         SlowUpPts[shift] = iHigh(NULL, TimeFrame, shift);

      else

         SlowUpPts[shift] = 0.0;


      if (Fractal(DN_POINT, P, shift) == true)

         SlowDnPts[shift] = iLow(NULL, TimeFrame, shift);

      else

         SlowDnPts[shift] = 0.0;

   }

}


bool NewBar()

{

   static datetime LastTime = 0;

   if (iTime(NULL, TimeFrame, 0) != LastTime)

   {

      LastTime = iTime(NULL, TimeFrame, 0)+time_offset;

      return (true);

   }

   else

      return (false);

}


void DeleteZones()

{

   int len = 5;

   int i;


   while (i < ObjectsTotal())

   {

      string objName = ObjectName(i);

      if (StringSubstr(objName, 0, len) != "SSSR#")

      {

         i++;

         continue;

      }

      ObjectDelete(objName);

   }

}


string TimeFrameToString(int tf) // код от TRO

{

   string tfs;


   switch(tf)

   {

      case PERIOD_M1:

         tfs = "M1"  ;

         break;

      case PERIOD_M5:

         tfs = "M5"  ;

         break;

      case PERIOD_M15:

         tfs = "M15" ;

         break;

      case PERIOD_M30:

         tfs = "M30" ;

         break;

      case PERIOD_H1:

         tfs = "H1"  ;

         break;

      case PERIOD_H4:

         tfs = "H4"  ;

         break;

      case PERIOD_D1:

         tfs = "D1"  ;

         break;

      case PERIOD_W1:

         tfs = "W1"  ;

         break;

      case PERIOD_MN1:

         tfs = "MN";

   }


   return(tfs);

}


string StringRepeat(string str, int n = 1)

{

  string outstr = "";

  for(int i = 0; i < n; i++) outstr = outstr + str;

  return(outstr);

}


string StringRightPad(string str, int n=1, string str2=" ")

{

  return(str + StringRepeat(str2,n-StringLen(str)));


 

Перехожу на МТ5. Помогите словом. Как в МТ5 пишется в коде, что не так?

//+------------------------------------------------------------------+
//|                                                          123.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
//+----------------------------------------------+
//|  Параметры отрисовки индикатора 1            |
//+----------------------------------------------+
#property indicator_type1   DRAW_ARROW
#property indicator_color1  Blue
#property indicator_style1  STYLE_DASHDOTDOT
#property indicator_width1  0
#property indicator_label1  "Label 1"
//----
input int MAPeriod=13;
//---=
int handle_ma;
double ExtLineBuffer[];
double BufferPrice[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,BufferPrice,INDICATOR_CALCULATIONS);
//---- символы для индикатора
   PlotIndexSetInteger(0,PLOT_ARROW,108);
//---- создание метки для отображения в DataWindow
   PlotIndexSetString(0,PLOT_LABEL,"PROBA");
//----
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
   IndicatorSetString(INDICATOR_SHORTNAME," 123");
//---- массива будет производиться как в таймсериях
   ArraySetAsSeries(ExtLineBuffer,true);
   ArraySetAsSeries(BufferPrice,true);
//--- create MA's handles
   ResetLastError();
      handle_ma=iMA(NULL,Period(),MAPeriod,0,MODE_SMA,PRICE_CLOSE); 
   if(handle_ma==INVALID_HANDLE)
     {
      Print("The iMA (1) object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 | 
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
 {
 Comment("");
 }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
//--- Проверка количества доступных баров
   if(rates_total<4) return 0;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-1;
   ArrayInitialize(ExtLineBuffer,EMPTY_VALUE);
   ArrayInitialize(BufferPrice,0);
     }
//--- Подготовка данных
   int count=(limit>1 ? rates_total : 2),copied=0;
   copied=CopyBuffer(handle_ma,0,0,count,BufferPrice);
   if(copied!=count) return 0;
//----   
 for(int i=limit; i>0 && !IsStopped(); i--)
   {
//----------------------------------------- ОСНОВНОЙ МОДУЛЬ КОТОРЫЙ НЕ РАБОТАЕТ ----------------------------
 if(PERIOD_H1==Period())
  {
//--- High signal
 if(BufferPrice[i]>open[i] && BufferPrice[i]<close[i])   
   ExtLineBuffer[i]=high[i];
//--- Low signal
 if(BufferPrice[i]<open[i] && BufferPrice[i]>close[i])
   ExtLineBuffer[i]=low[i];
  } /*
  else
  {
  ExtLineBuffer[i]=0.0;
  ExtLineBuffer[i]=0.0;
  } */
  }    
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

ВОПРОС: Почему в буфер падает всякий мусор? 

Пока нахожусь на этапе конструктора Lego, т.е. копирую модуль и опытным путем вьезжаю в особенности МТ%. Документация само собой.

 
kopeyka2:

Перехожу на МТ5. Помогите словом. Как в МТ5 пишется в коде, что не так?

ВОПРОС: Почему в буфер падает всякий мусор? 

в мт5 таймсерии идут наоборот
если нужно также как в мт4, то есть ArraySetAsSeries

 
kopeyka2:

Перехожу на МТ5. Помогите словом. Как в МТ5 пишется в коде, что не так?

ВОПРОС: Почему в буфер падает всякий мусор? 

Пока нахожусь на этапе конструктора Lego, т.е. копирую модуль и опытным путем вьезжаю в особенности МТ%. Документация само собой.

//+------------------------------------------------------------------+
//|                                                          123.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
//+----------------------------------------------+
//|  Параметры отрисовки индикатора 1            |
//+----------------------------------------------+
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrBlue
#property indicator_width1  1
#property indicator_label1  "Label 1"
//----
input int MAPeriod=13;
//---=
int handle_ma;
double ExtLineBuffer[];
double BufferPrice[];
//---
int    period;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   period=(MAPeriod<1 ? 1 : MAPeriod);
//---
   SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferPrice,INDICATOR_CALCULATIONS);
//---- символы для индикатора
   PlotIndexSetInteger(0,PLOT_ARROW,108);
//---- создание метки для отображения в DataWindow
   PlotIndexSetString(0,PLOT_LABEL,"PROBA");
//----
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
   IndicatorSetString(INDICATOR_SHORTNAME," 123");
//---- массива будет производиться как в таймсериях
   ArraySetAsSeries(ExtLineBuffer,true);
   ArraySetAsSeries(BufferPrice,true);
//--- create MA's handles
   ResetLastError();
   handle_ma=iMA(NULL,PERIOD_CURRENT,period,0,MODE_SMA,PRICE_CLOSE);
   if(handle_ma==INVALID_HANDLE)
     {
      Print("The iMA (",(string)period,") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 | 
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//--- 
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true); 
//--- Проверка количества доступных баров
   if(rates_total<4) return 0;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-1;
      ArrayInitialize(ExtLineBuffer,EMPTY_VALUE);
      ArrayInitialize(BufferPrice,0);
     }
//--- Подготовка данных
   int count=(limit>1 ? rates_total : 2),copied=0;
   copied=CopyBuffer(handle_ma,0,0,count,BufferPrice);
   if(copied!=count) return 0;
//----   
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      //----------------------------------------- ОСНОВНОЙ МОДУЛЬ КОТОРЫЙ НЕ РАБОТАЕТ ----------------------------
      if(Period()==PERIOD_H1)
        {
         //--- High signal
         if(BufferPrice[i]>open[i] && BufferPrice[i]<close[i])
            ExtLineBuffer[i]=high[i];
         //--- Low signal
         if(BufferPrice[i]<open[i] && BufferPrice[i]>close[i])
            ExtLineBuffer[i]=low[i];
        }
/*
  else
  {
  ExtLineBuffer[i]=0.0;
  ExtLineBuffer[i]=0.0;
  } */
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Artyom Trishkin:

Спасибо за ответ.

Проверил в МТ5... Незадача какая то... Точки раскидало по графику непонятно как, гдето глубоко в истории.. Не понятно что и почему  МТ5 не нравится? Задача простая!!!

ТАК В МТ4

ТАК ВЫГЛЯДИТ В МТ4


А ТАК В МТ5. Конечно в один буфер. Но проблема в том, что точки индикатор ловит, но не те и не там...(((


Еще раз подскажите пожста. Что я не так в коде указал МТ5????

Кое что в МТ5 понял. А буферы ... загадка

 
kopeyka2:

Спасибо за ответ.

Проверил в МТ5... Незадача какая то... Точки раскидало по графику непонятно как, гдето глубоко в истории.. Не понятно что и почему  МТ5 не нравится? Задача простая!!!

ТАК В МТ4


А ТАК В МТ5. Конечно в один буфер. Но проблема в том, что точки индикатор ловит, но не те и не там...(((


Еще раз подскажите пожста. Что я не так в коде указал МТ5????

Кое что в МТ5 понял. А буферы ... загадка

Никакой загадки. Нумерация отличается от mql4 и не обнуляются индикаторные буферы автоматически. Для очистки от "мусора" программист сам должен позаботиться о чистоте индексов если в них не должно быть значений.

 
Alexey Viktorov:

Никакой загадки. Нумерация отличается от mql4 и не обнуляются индикаторные буферы автоматически. Для очистки от "мусора" программист сам должен позаботиться о чистоте индексов если в них не должно быть значений.Вопрос 

Вопрос о том, ПОЧЕМУ метки (точки) ставятся куда попало? Я же в коде определил алгоритм!!!! Условие МА в теле свечи. Разве этого мал?

 
kopeyka2:

Вопрос о том, ПОЧЕМУ метки (точки) ставятся куда попало? Я же в коде определил алгоритм!!!! Условие МА в теле свечи. Разве этого мал?

Вот смотри

kopeyka2:
Перехожу на МТ5. Помогите словом.


Артём дал полный код вместо помощи словом. К этому у каждого свой подход. Я стараюсь не давать готовый код, но всё-же иногда не получается.

kopeyka2:

Спасибо за ответ.

Проверил в МТ5... Незадача какая то...


Но графики для сравнения совершенно разного времени. Как можно судить о правильности или неправильности отображения точек???

Отсюда помощь словом.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

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

Alexey Viktorov, 2019.01.21 11:04

Никакой загадки. Нумерация отличается от mql4 и не обнуляются индикаторные буферы автоматически. Для очистки от "мусора" программист сам должен позаботиться о чистоте индексов если в них не должно быть значений.

Ещё помощь словом: В МТ5 сделали неадекватную последовательность выполнения OnInit и OnDeinit отсюда тоже могут быть проблемы. Но это в каких-то особых случаях, а перерасчёт индикатора ВСЕГДА должен быть последовательным. При условии, что prev_calculated == 0 пересчёт по всем барам и на каждой итерации цикла, если значения в буфере быть не должно, то заполнять этот индекс массива значением EMPTY_VALUE или 0 в зависимости от установки PLOT_EMPTY_VALUE
 
Alexey Viktorov:

Вот смотри

Артём дал полный код вместо помощи словом. К этому у каждого свой подход. Я стараюсь не давать готовый код, но всё-же иногда не получается.

Но графики для сравнения совершенно разного времени. Как можно судить о правильности или неправильности отображения точек???

Отсюда помощь словом.

Ещё помощь словом: В МТ5 сделали неадекватную последовательность выполнения OnInit и OnDeinit отсюда тоже могут быть проблемы. Но это в каких-то особых случаях, а перерасчёт индикатора ВСЕГДА должен быть последовательным. При условии, что prev_calculated == 0 пересчёт по всем барам и на каждой итерации цикла, если значения в буфере быть не должно, то заполнять этот индекс массива значением EMPTY_VALUE или 0 в зависимости от установки PLOT_EMPTY_VALUE

Аллилуйя!!!!!  Изменил open[i] и close[i] на iOpen(NULL,PERIOD_H1,i)



 
kopeyka2:

Аллилуйя!!!!!  Изменил open[i] и close[i] на iOpen(NULL,PERIOD_H1,i)



А в чём разница? Если индикатор на Н1, то только в скорости доступа - у вас медленнее. Вы в моём примере наверное пропустили что нужно задать массивам open и close серийную индексацию. Я ж цветом выделял то, что у вас не было. У вас цикл от начала данных к концу - от limit до 0, а индексацию массивов вы не делали - вот и рисовалось задом-наперёд.