Very slow calculation time for LWMA, I need help optimising MA on Array - page 3

 
Dominik Christian Egert #:
I suppose you need to do some more research...

Handle creation goes into OnInit()

The last handle of your iMA-chain is the one you use in OnTick with CopyBuffer..

Beyond that, it's easier for me to post code as I have offered yesterday.


If you have any time to post it, that would help me a lot understanding how to manage this difficulty, thanks :) 

In the meantime I will start to dig into the forum about the OnCalculate function ;)

 
winGou- #:

If you have any time to post it, that would help me a lot understanding how to manage this difficulty, thanks :) 

In the meantime I will start to dig into the forum about the OnCalculate function ;)

Honestly, Ive just typed this and I cannot say if it is bugfree, or even compiles, but it should give you an outline of how to cascade the calculations in your EA.

Please try to figure this out on your own, if possible.


{
    // Local init
    const int       lwma_periods    = 25;
    const int       cascade_cnt     = 6;
    double          tmp_array[]
    double          result[];

    // Static init
    static double   lwma_stage_values[];

    // Operation mode
    const bool      update          = ArraySize(lwma_stage_values) == NULL;


    // Initial calcualtions run
    if(!update)
    {
        // Get required data
        ResetLastError();
        const int datasets_count = CopyClose(Symbol(), _Period, TimeCurrent() - (TimeCurrent() % PeriodSeconds()), lwma_periods * cascade_cnt, tmp_array);
        if(datasets_count != lwma_periods * cascade_cnt)
        { 
            printf("Error receiving data. ErrNo: %i", _LastError);
            return;
        }

        // Init staging values array
        if(ArrayResize(lwma_stage_values, cascade_cnt) != cascade_cnt)
        { 
            printf("Error resizing array. ErrNo: %i", _LastError);
            return;
        }
        
        // Initial calculations run
        int data_ptr = NULL;
        for(int loop1 = 1; (loop1 < cascade_cnt) && !_StopFlag; loop1++)
        {
            // Calculate uneven cascade
            data_ptr = lwma_periods * loop1;
            if(calc_lwma(data_ptr - lwma_periods, datasets_count, tmp_array, result) < 1)
            { 
                printf("Error calculating lwma. ErrNo: %i", _LastError);
                return;
            }

            // Intermediate loop control        
            loop1++;
    
            // Calculate even cascade
            data_ptr = lwma_periods * loop1;
            if(calc_lwma(data_ptr - lwma_periods, datasets_count, result, tmp_array) < 1)
            { 
                printf("Error calculating lwma. ErrNo: %i", _LastError);
                return;
            }
    
            // Early break, result copy
            if( (loop1 >= cascade_cnt) 
             && (ArrayCopy(result, tmp_array) != ArraySize(tmp_array)) )
            { 
                printf("Error copying array. ErrNo: %i", _LastError);
                return;
            }
        }
    }
    
    // Update calculations
    else
    {
        ResetLastError();
        const int datasets_count = CopyClose(Symbol(), _Period, TimeCurrent() - (TimeCurrent() % PeriodSeconds()), lwma_periods, tmp_array);
        if(datasets_count != lwma_periods)
        { 
            printf("Error receiving data. ErrNo: %i", _LastError);
            return;
        }

        const int idx = lwma_periods - 1;
        for(int loop1 = NULL; (loop1 < lwma_cascade) && !_StopFlag; loop1++)
        {
            lwma_stage_values[loop1] = lwma(tmp_array, idx, lwma_periods, lwma_stage_values[loop1]);
            tmp_array[idx] = lwma_stage_values[loop1];
        }
    }

    // Get final result
    const double cascaded_lwma_value = (update) ? lwma_stage_values[ArraySize(lwma_stage_values) - 1] : result[ArraySize(result) - 1];    


}


const int calc_lwma(const int prev_calculated, const int rates_total, const double& source[], double& result[])
{
    if(ArrayResize(result, ArraySize(source)) < 1)
    { return(-1); }

    for(int idx = prev_calculated; (idx < rates_total) && !_StopFlag; idx++)
    { result[idx] = lwma(source, idx, lwma_periods, (idx > NULL) ? result[idx - 1] : NULL); }

    return(ArraySize(result));
}

 
Dominik Christian Egert #:

Honestly, Ive just typed this and I cannot say if it is bugfree, or even compiles, but it should give you an outline of how to cascade the calculations in your EA.

Please try to figure this out on your own, if possible.

Many thanks Dominik, I will look this after lunch. 

I'm pretty sure I will encounter a problem with the last part, as "prev_calculated" doesn't exist in my EA, but I will look more in depth at this time !

 
winGou- #:

Many thanks Dominik, I will look this after lunch. 

I'm pretty sure I will encounter a problem with the last part, as "prev_calculated" doesn't exist in my EA, but I will look more in depth at this time !

Dont worry about prev_calculated,as I have filled that gap....
 
Dominik Christian Egert #:
Dont worry about prev_calculated,as I have filled that gap....

Hello Dominik, In the meantime I tried to write and Indicator that seems to be working.

I would like to try to call it from the EA, but i was wondering, how do you select the price used ? I defined TYPICAL in the properties, but as it's not an input, how do I change it via the iCustom ?

EDIT : 2nd question : as I have never used any buffer, when callling with iCustom, how do you define the index you are looking for ? ==> FORGET about this one, there is a shift parameters ;)

#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_plots   1
#property indicator_applied_price PRICE_TYPICAL
#include <Indicators\MovingAverages.mqh>
//--- plot MaxilimW
#property indicator_label1  "MaxilimW"
#property indicator_type1   DRAW_COLOR_LINE
#property indicator_color1  clrLime,clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      shortM;
input int      longM;
//--- indicator buffers
double         MaxilimWBuffer[];
double         M1[];
double         M2[];
double         M3[];
double         M4[];
double         M5[];
double         M6[];
double         buffer_color[];
double         colors_options[]= {clrLime,clrRed};

int            mix0;       // --> 3
int            mix1;       // --> 5
int            mix2;       // --> 8
int            mix3;       // --> 13
int            mix4;       // --> 21
int            mix5;       // --> 34

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MaxilimWBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,buffer_color,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2,M1,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,M2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,M3,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,M4,INDICATOR_CALCULATIONS);
   SetIndexBuffer(6,M5,INDICATOR_CALCULATIONS);
   SetIndexBuffer(7,M6,INDICATOR_CALCULATIONS);

   mix0 = shortM;         // --> 3
   mix1 = longM;          // --> 5
   mix2 = shortM + longM; // --> 8
   mix3 = mix2 + longM;   // --> 13
   mix4 = mix3 + mix2;    // --> 21
   mix5 = mix4 + mix3;    // --> 34
//---

   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Lime);   //Zeroth index -> Blue
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,Red);    //First index  -> Orange

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,     // size of the price[] array;
                const int prev_calculated,// number of available bars;
                // at the previous call;
                const int begin,// from what index of the
                // price[] array true data start;
                const double &price[]) // array, at which the indicator will be calculated;
  {
//---

//--- if the size of price[] is too small
   if(rates_total < mix0+mix1+mix2+mix3+mix4+mix5)
      return(0); // do not calculate or draw anything
//--- if it's the first call
   if(prev_calculated == 0)
     {
      //--- set zero values for zero indexes
      M1[0]=0.0;
      M2[0]=0.0;
      M1[0]=0.0;
      M2[0]=0.0;
      M1[0]=0.0;
      M2[0]=0.0;
      MaxilimWBuffer[0]=0.0;
     }


//int LinearWeightedMAOnBuffer(const int rates_total,const int prev_calculated,const int begin,const int period,const double& price[],double& buffer[])

//--- calculate the first moving average on price
   LinearWeightedMAOnBuffer(rates_total,prev_calculated,
                            0,                        // index, starting from which data for MA are available
                            mix0,                     // period of the LWMA
                            price,                    // buffer to calculate average from
                            M1);                      // into this buffer locate value of the average

//--- calculate the 2nd moving average on price
   LinearWeightedMAOnBuffer(rates_total,prev_calculated,
                            mix0,                     // index, starting from which data for MA are available
                            mix1,                     // period of the LWMA
                            M1,                       // buffer to calculate average from
                            M2);                      // into this buffer locate value of the average

//--- calculate the 3rd moving average on price
   LinearWeightedMAOnBuffer(rates_total,prev_calculated,
                            mix0+mix1,                // index, starting from which data for MA are available
                            mix2,                     // period of the LWMA
                            M2,                       // buffer to calculate average from
                            M3);                      // into this buffer locate value of the average

//--- calculate the 4th moving average on price
   LinearWeightedMAOnBuffer(rates_total,prev_calculated,
                            mix0+mix1+mix2,           // index, starting from which data for MA are available
                            mix3,                     // period of the LWMA
                            M3,                       // buffer to calculate average from
                            M4);                      // into this buffer locate value of the average

//--- calculate the 5th moving average on price
   LinearWeightedMAOnBuffer(rates_total,prev_calculated,
                            mix0+mix1+mix2+mix3,      // index, starting from which data for MA are available
                            mix4,                     // period of the LWMA
                            M4,                       // buffer to calculate average from
                            M5);                      // into this buffer locate value of the average

//--- calculate the 6th moving average on price
   LinearWeightedMAOnBuffer(rates_total,prev_calculated,
                            mix0+mix1+mix2+mix3+mix4, // index, starting from which data for MA are available
                            mix5,                     // period of the LWMA
                            M5,                       // buffer to calculate average from
                            M6);                      // into this buffer locate value of the average

//--- now calculate values of the indicator
   int start;
   if(prev_calculated <= mix0+mix1+mix2+mix3+mix4+mix5)
      start=mix0+mix1+mix2+mix3+mix4+mix5;            // start filling out 
   else
      start=prev_calculated-1;                          // set start equal to the last index in the arrays
   for(int i=start; i<rates_total; i++)
     {
      MaxilimWBuffer[i]=M6[i];
      buffer_color[i] = M6[i] > M6[i-1] ? 0 : 1;
     }


//--- return value of prev_calculated for next call
   return(rates_total);
  }
 
winGou- #:

Hello Dominik, In the meantime I tried to write and Indicator that seems to be working.

I would like to try to call it from the EA, but i was wondering, how do you select the price used ? I defined TYPICAL in the properties, but as it's not an input, how do I change it via the iCustom ?

EDIT : 2nd question : as I have never used any buffer, when callling with iCustom, how do you define the index you are looking for ? ==> FORGET about this one, there is a shift parameters ;)

Answer to question 1: make it an input.

Answer to question 2: No, that's not what shift is for. Use the buffer index in CopyBuffer()

Edit: CopyBuffer gives you the possibility to choose the range of data you want to copy, as a hint, use time and count, it's most easy approach.
 
Dominik Christian Egert #:
Answer to question 1: make it an input.

Answer to question 2: No, that's not what shift is for. Use the buffer index in CopyBuffer()


I see how to put it as input, but how to apply it in the price[] array from OnCalculate ? 

I'm sorry I have so much questions :/

 
winGou- #:

I see how to put it as input, but how to apply it in the price[] array from OnCalculate ? 

I'm sorry I have so much questions :/

Sorry, I was wrong...

You are using price array.

"When you call a custom indicator from mql5-program, the Applied_Price parameter or a handle of another indicator should be passed last, after all input variables of the custom indicator."



 
Dominik Christian Egert #:
Sorry, I was wrong...

You are using price array.

"When you call a custom indicator from mql5-program, the Applied_Price parameter or a handle of another indicator should be passed last, after all input variables of the custom indicator."



Oh perfect, thank you very much ! 

I will start with this, as I understand every step of the code, but I will probably switch to the materials you provided in the near future, as soon as I understand every part of it. 

Many many thanks for your time and your help Dominik !

EDIT : let's hope that this could improve my EA results, if it does I owe you one ;) 
 
winGou- #:

Oh perfect, thank you very much ! 

I will start with this, as I understand every step of the code, but I will probably switch to the materials you provided in the near future, as soon as I understand every part of it. 

Many many thanks for your time and your help Dominik !

EDIT : let's hope that this could improve my EA results, if it does I owe you one ;) 
Fine, report back and tell how it went...
Reason: