Помогите оптимизировать индикатор

 

Помогите, пожалуйста, оптимизировать индикатор.

Очень "тяжелый", использует внешний кастомный индюк, рисует графические объекты, работает сразу с 10ю парами и 7ю таймфреймами.

Но очень нужно чтобы работал.

Платформа начинает виснуть примерно через сутки работы.

#property indicator_chart_window

// EMP band period
extern int bandPeriod = 20;

// price levels for color definition
extern double scaleLowNeutral = 5,
              scaleLowNeutralPlus = 10,
              scaleLowStrongMinus = 20,
              scaleLowStrongPlus = 30,
              scaleHighNeutral = 20,
              scaleHighNeutralPlus = 30,
              scaleHighStrongMinus = 50,
              scaleHighStrongPlus = 100;

// colors of the heat map
extern color signalBuyVeryStrong = SeaGreen,
             signalBuyStrongPlus = LimeGreen,
             signalBuyStrongMinus = DarkSeaGreen,
             signalBuyNeutralPlus = Yellow, 
             neutralColor = Yellow,
             signalSellNeutralPlus = Yellow,
             signalSellStrongMinus = LightPink,
             signalSellStrongPlus = FireBrick,
             signalSellVeryStrong = Red,             
             textColor = White;            

// pairs 
extern string pair1 = "USDJPY",
              pair2 = "USDCAD",
              pair3 = "USDCHF",
              pair4 = "EURCHF",
              pair5 = "EURUSD",
              pair6 = "GBPUSD",
              pair7 = "EURGBP",
              pair8 = "EURJPY", 
              pair9 = "AUDUSD", 
              pair10 = "NZDUSD";

// table struсture parameters
extern int fontSize = 15;
/*extern*/ int scaleX = 20,
           scaleY = 20,
           offsetX = 45,
           offsetY = 20,
           corner = 0, // correct parameters from 0 to 3
           symbolCode = 110; 

// calling arrays                         
int period[] = {1,5,15,30,60,240,1440,10080,43200}; // timeframes array for heat map 
string periodString[] = {"M1","M5","M15","M30","H1","H4","D1"}, // timeframes array for header
       signalNameString[] = {"1","2","3","4","","","","","",""}; // pairs array 


//////////////////////////////////////////////////////////////////////
//
// init()          
//
//////////////////////////////////////////////////////////////////////
int init()
{
 // pairs array filling
 signalNameString[0] = pair1;
 signalNameString[1] = pair2;
 signalNameString[2] = pair3;
 signalNameString[3] = pair4;
 signalNameString[4] = pair5;
 signalNameString[5] = pair6;
 signalNameString[6] = pair7;
 signalNameString[7] = pair8;
 signalNameString[8] = pair9;
 signalNameString[9] = pair10;

 // scales normilizing
 scaleLowNeutral = scaleLowNeutral*0.0001;
 scaleLowNeutralPlus = scaleLowNeutralPlus*0.0001;
 scaleLowStrongMinus = scaleLowStrongMinus*0.0001;
 scaleLowStrongPlus = scaleLowStrongPlus*0.0001;
 scaleHighNeutral = scaleHighNeutral*0.0001;
 scaleHighNeutralPlus = scaleHighNeutralPlus*0.0001;
 scaleHighStrongMinus = scaleHighStrongMinus*0.0001;
 scaleHighStrongPlus = scaleHighStrongPlus*0.0001;    
 
   // the heat map
   for(int x=0;x<7;x++)
      for(int y=0;y<10;y++)
      {
         ObjectCreate("signal"+x+y,OBJ_LABEL,0,0,0,0,0);
         ObjectSet("signal"+x+y,OBJPROP_CORNER,corner);
         ObjectSet("signal"+x+y,OBJPROP_XDISTANCE,x*scaleX+offsetX);
         ObjectSet("signal"+x+y,OBJPROP_YDISTANCE,y*scaleY+20);
         ObjectSetText("signal"+x+y,CharToStr(symbolCode),fontSize,"Wingdings",textColor);
      }
  // timeframes names  
  for(x=0;x<7;x++)
  {
      ObjectCreate("textPeriod"+x,OBJ_LABEL,0,0,0,0,0);   
      ObjectSet("textPeriod"+x,OBJPROP_CORNER,corner); 
      ObjectSet("textPeriod"+x,OBJPROP_XDISTANCE,x*scaleX+offsetX);
      ObjectSet("textPeriod"+x,OBJPROP_YDISTANCE,offsetY-10);
      ObjectSetText("textPeriod"+x,periodString[x],8,"Tahoma",textColor);
  }
  // pairs names
  for(y=0;y<10;y++)
  {
      ObjectCreate("textSignal"+y,OBJ_LABEL,0,0,0,0,0);   
      ObjectSet("textSignal"+y,OBJPROP_CORNER,corner);
      ObjectSet("textSignal"+y,OBJPROP_XDISTANCE,offsetX-40);
      ObjectSet("textSignal"+y,OBJPROP_YDISTANCE,y*(scaleY)+offsetY+8);
      ObjectSetText("textSignal"+y,signalNameString[y],8,"Tahoma",textColor);      
  }
  
  return(0);
}
  
int start()
{
   for(int x=0;x<7;x++)
      for(int y=0;y<10;y++)
      {
         color clr = White;
         double emp = iCustom(signalNameString[y],period[x],"Gomez EMP",bandPeriod,0,0);
         // color defenition
         if (x <= 3) 
           {
            if (emp >= scaleLowNeutral*(-1) && emp <= scaleLowNeutral) clr = neutralColor;
            
            if (emp > scaleLowNeutral && emp <= scaleLowNeutralPlus) clr = signalBuyNeutralPlus;
            if (emp > scaleLowNeutralPlus && emp <= scaleLowStrongMinus) clr = signalBuyStrongMinus;
            if (emp > scaleLowStrongMinus && emp <= scaleLowStrongPlus) clr = signalBuyStrongPlus;
            if (emp > scaleLowStrongPlus) clr = signalBuyVeryStrong;
           
            if (emp < scaleLowNeutral*(-1) && emp >= scaleLowNeutralPlus*(-1)) clr = signalSellNeutralPlus;
            if (emp < scaleLowNeutralPlus*(-1) && emp >= scaleLowStrongMinus*(-1)) clr = signalSellStrongMinus;
            if (emp < scaleLowStrongMinus*(-1) && emp >= scaleLowStrongPlus*(-1)) clr = signalSellStrongPlus;
            if (emp < scaleLowStrongPlus*(-1)) clr = signalSellVeryStrong;          
           } 
         else 
           {
            if (emp >= scaleHighNeutral*(-1) && emp <= scaleHighNeutral) clr = neutralColor;
            
            if (emp > scaleHighNeutral && emp <= scaleHighNeutralPlus) clr = signalBuyNeutralPlus;
            if (emp > scaleHighNeutralPlus && emp <= scaleHighStrongMinus) clr = signalBuyStrongMinus;
            if (emp > scaleHighStrongMinus && emp <= scaleHighStrongPlus) clr = signalBuyStrongPlus;
            if (emp > scaleHighStrongPlus) clr = signalBuyVeryStrong;
           
            if (emp < scaleHighNeutral*(-1) && emp >= scaleHighNeutralPlus*(-1)) clr = signalSellNeutralPlus;
            if (emp < scaleHighNeutralPlus*(-1) && emp >= scaleHighStrongMinus*(-1)) clr = signalSellStrongMinus;
            if (emp < scaleHighStrongMinus*(-1) && emp >= scaleHighStrongPlus*(-1)) clr = signalSellStrongPlus;
            if (emp < scaleHighStrongPlus*(-1)) clr = signalSellVeryStrong;             
           }
            // object setting
            ObjectSetText("signal"+x+y,CharToStr(symbolCode),fontSize,"Wingdings",clr);
      }

   return(0);
}

//////////////////////////////////////////////////////////////////////
//
//  deinit()                       
//
//////////////////////////////////////////////////////////////////////
int deinit()
{
   // deleting all objects 
   ObjectsDeleteAll();
   return(0);
}
Файлы:
 

Кастомный индикатор

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 DarkOrange
//---- input parameters
extern int BandPeriod = 20;
//---- buffers
double BandBuffer[];
double UpSwingBuffer[];
double LowSwingBuffer[];
double DevBuffer[];
double LnBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string short_name;
//---- 4 additional buffers are used for counting.
   IndicatorBuffers(5);
   
   SetIndexBuffer(1, UpSwingBuffer);
   SetIndexBuffer(2, DevBuffer);
   SetIndexBuffer(3, LnBuffer);
   SetIndexBuffer(4, LowSwingBuffer);

   
//---- indicator lines
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(0, BandBuffer);

//----
   if(BandPeriod <= 0)
       BandPeriod = 20;
//----
   SetIndexDrawBegin(0, BandPeriod);
  
//---- name for DataWindow and indicator subwindow label
   short_name="Gomez Band(" + BandPeriod + ")";
   IndicatorShortName(short_name);
   SetIndexLabel(0, short_name);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Commodity Channel Index                                          |
//+------------------------------------------------------------------+
int start()
  {
   int i, k, counted_bars = IndicatorCounted();
   double sum = 0;
   double av_sum = 0; 
   
   if(BandPeriod <= 1)
       return(0);
   if(Bars <= BandPeriod) 
       return(0);
//---- initial zero
   if(counted_bars < 1)
     {
       for(i = 1; i <= BandPeriod; i++) 
           BandBuffer[Bars-i] = 0.0;
       for(i = 1; i <= BandPeriod; i++) 
           DevBuffer[Bars-i] = 0.0;
       for(i = 1; i <= BandPeriod; i++) 
           LnBuffer[Bars-i] = 0.0;
       for(i = 1; i <= BandPeriod; i++) 
           LowSwingBuffer[Bars-i] = 0.0;     
       for(i = 1; i <= BandPeriod; i++) 
           UpSwingBuffer[Bars-i] = 0.0;     
     }
//---- last counted bar will be recounted
   int limit = Bars - counted_bars;
   if(counted_bars > 0) 
       limit++;
//---- natural log
   i = Bars - BandPeriod + 1;
   if(counted_bars > BandPeriod - 1) 
       i = Bars - counted_bars - 1;
   while(i >= 0)
     {
       LnBuffer[i] = (Close[i]/Close[i+1]);
       i--;
     }
//---- standard deviation
   i = Bars - BandPeriod + 1;
   if(counted_bars > BandPeriod - 1) 
       i = Bars - counted_bars - 1;
   while(i >= 0)
     {
      av_sum = 0;
      sum = 0;      
      for (k = i; k < i + BandPeriod; k++)
        av_sum = av_sum + LnBuffer[k]/BandPeriod; 
      for (k = i; k < i + BandPeriod; k++)
        sum = sum + (LnBuffer[k] - av_sum)*(LnBuffer[k] - av_sum);
      DevBuffer[i] = MathSqrt(sum/(BandPeriod-1))*MathSqrt(2*BandPeriod);
       i--;
     }
//---- up swing  counting
   i = Bars - BandPeriod + 1;
   if(counted_bars > BandPeriod - 1) 
       i = Bars - counted_bars - 1;
   while(i >= 0)
     {
      sum = 0;
      for (k = i; k < i + BandPeriod; k++)
         sum = sum + Close[k]/BandPeriod;     
      UpSwingBuffer[i] = (1-DevBuffer[i])*Close[i]/sum;
       i--;
     }
//---- low swing  counting
   i = Bars - BandPeriod + 1;
   if(counted_bars > BandPeriod - 1) 
       i = Bars - counted_bars - 1;
   while(i >= 0)
     {
      sum = 0;
      for (k = i; k < i + BandPeriod; k++)
         sum = sum + Close[k]/BandPeriod;     
      LowSwingBuffer[i] = (1-DevBuffer[i])*sum/Close[i];
       i--;
     }
//---- swing distance counting
   i = Bars - BandPeriod + 1;
   if(counted_bars > BandPeriod - 1) 
       i = Bars - counted_bars - 1;
   while(i >= 0) {
       BandBuffer[i] = UpSwingBuffer[i] - LowSwingBuffer[i];
       i--;
   }
//----
   return(0);
  }
Файлы:
gomeztemp.mq4  5 kb
 
fxprogrammer:

Помогите, пожалуйста, оптимизировать индикатор.

Очень "тяжелый", использует внешний кастомный индюк, рисует графические объекты, работает сразу с 10ю парами и 7ю таймфреймами.

Но очень нужно чтобы работал.

Платформа начинает виснуть примерно через сутки работы.


Оптимизировать индикатор можно, и нужно. Иначе его лучше выкинуть в "топку"
 

Выглядит все примерно вот так:

Буду благодарен любой конструктивной помощи!

 
Есть у кого-нибудь дельные мысли?
 
fxprogrammer:
Есть у кого-нибудь дельные мысли?

Для начала будет достаточно отказаться от полного перерасчета индикатора на каждом тике
 

Перерасчет на барах не вариант совсем. А можно ли в индикаторе сделать задержку на несколько секунд, например, чтобы пересчитывался каждые 10 секунд? Sleep() ведь в индикаторах не работает.

думаю, что как-то так должно выглядеть:

extern int delay = 10;

 ......................

 if (TimeCurrent() > last_time + delay)

   ........ проводим расчеты ..........

 last_time = TimeCurrent();

Не будет ли это забивать тред индикатора еще сильнее?

 
fxprogrammer:

Перерасчет на барах не вариант совсем. А можно ли в индикаторе сделать задержку на несколько секунд, например, чтобы пересчитывался каждые 10 секунд? Sleep() ведь в индикаторах не работает.

думаю, что как-то так должно выглядеть:

Не будет ли это забивать тред индикатора еще сильнее?



Ответь для начала :

- зачем в индикаторе есть переменная limit?

- почему она не используется?

 

действительно, незачем

видимо, что-то хотел добавить и не стал.

взгляд уже замыленный, поэтому и не замечаю :)

 

тормозит индикатор не второй, а первый.

Тот, который квадратики рисует.

Понятно, что они связаны, но ко второму претензий не было пока.

 
fxprogrammer:

тормозит индикатор не второй, а первый.

Тот, который квадратики рисует.

Понятно, что они связаны, но ко второму претензий не было пока.


Попробуй с этим вариантом. Но надо бы еще сделать ограничение по количеству обрабатываемых баров
Файлы:
Причина обращения: