how to code a ea with ma on stochastic indicator - page 2

 
Ivan Titov #:

Just get the indicator value using ChartIndicatorGet() and CopyBuffer() and then compare it with your level in the EA.

Until you put it in the oscillator window as above.

now you have me interested, I'll look at it


this what I made last night..something edgy with possible room for improvement. It's an MA that uses dynamic levels


//+------------------------------------------------------------------+
//|                                          SexualMovingAverage.mq5 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright phade 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots 3

#property indicator_label1  "MA Line"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrSilver
#property indicator_width1  2

#property indicator_label2  "Buy Level"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrNONE
#property indicator_style2  STYLE_DOT
#property indicator_width2  1

#property indicator_label3  "Sell Level"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrNONE
#property indicator_style3  STYLE_DOT
#property indicator_width3  1


double ma[];
double level_data_a[];
double level_data_b[];


input int MA_Period = 40; // Period
input int lev_1 = 200;  // Tweek Level 1 (buy)
input int lev_2 = 200;  // Tweek Level 2 (sell)
input int bars = 1000; // Bars used


double min_ma = DBL_MAX;
double max_ma = DBL_MIN;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{  
    SetIndexBuffer(0, ma, INDICATOR_DATA);  
    SetIndexBuffer(1, level_data_a, INDICATOR_DATA);
    SetIndexBuffer(2, level_data_b, INDICATOR_DATA);  
    
    ChartRedraw(0);  

    IndicatorSetInteger(INDICATOR_LEVELS, 2); 
    
    IndicatorSetString(INDICATOR_SHORTNAME,"MA and Levels (Period " + IntegerToString(MA_Period) + ")");
    return INIT_SUCCEEDED;
}

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[])
{

   int i,start;
   
   int per = MA_Period;
   
  // CopySeries(Symbol(), Period(), rates_total-bars, rates_total, COPY_RATES_CLOSE, ma);   
     
   //--- first calculation or number of bars was changed
   if(prev_calculated==0){
   
      start = per;

      for(i=0; i<start-1; i++)
         ma[i]=0.0;
         
      //--- calculate first visible value
      double first_value=0;
           
      for(i=0; i<start; i++)
         first_value+=close[i];
               
      first_value /= per;
      ma[start-1]=first_value;
  }
  else
      start=rates_total-bars;

   SimpleMA(ma, start, rates_total, per, close);
    

   // Find the minimum and maximum values of the MA buffer with the number of bars used
   for(int i = rates_total-1; i>=rates_total-bars; i--){

      min_ma = MathMin(ma[i], min_ma);
      max_ma = MathMax(ma[i], max_ma);
   }
   
   for(int i = rates_total-1; i>=rates_total-bars; i--){
   
      level_data_a[i] = min_ma + lev_1;  // buy level   
      level_data_b[i] = max_ma - lev_2;  // sell level           
   }
   
   IndicatorSetDouble(INDICATOR_MAXIMUM, max_ma + lev_2);
   IndicatorSetDouble(INDICATOR_MINIMUM, min_ma - lev_1);
   IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, (min_ma + lev_1));
   IndicatorSetDouble(INDICATOR_LEVELVALUE, 1, (max_ma - lev_2)); 
    
   return rates_total;
}

  
double SimpleMA(double &ma_buf[], int start, int end, int period, const double &price[]){
   
   for(int i=start; i<end && !IsStopped(); i++){
   
      ma_buf[i]=ma_buf[i-1]+(price[i]-price[i-period])/period;
   }   
   
   return ma_buf[end-1];
}

 

To prove your point, yes it can work with a bit of hacking.


We can use the crosshair tool to find out what value the MA consistently is when it reaches the 80 level and the 20 level (but the caveat is that those values might not be consistent):


I made an indicator and attached it. I'm not sure about accuracy, and not sure why it works when loading the indicator on a chart, but will not show the added MA in the strategy tester


might be a good idea to alter the code to use greater than or equal to:

if(NormalizeDouble(ma[j-1], 4) >= LEVEL_80 && NormalizeDouble(ma[j], 4) < LEVEL_80){
      
    Print("SIGNAL: MA CROSSED THE 80 LEVEL DOWN FROM TOP");
}
   
else if(NormalizeDouble(ma[j-1], 4) <= LEVEL_20 && NormalizeDouble(ma[j], 4) > LEVEL_20){
      
    Print("SIGNAL: MA CROSSED THE 20 LEVEL UP FROM BOTTOM"); 
}
 
Ivan Titov #:

Just get the indicator value using ChartIndicatorGet() and CopyBuffer() and then compare it with your level in the EA.

Until you put it in the oscillator window as above.

Thank you for your suggestion Ivan Titov like you said I think the ideal way would be to use that as an indicator to give signal to EA
 
Conor Mcnamara #:

To prove your point, yes it can work with a bit of hacking.


We can use the crosshair tool to find out what value the MA consistently is when it reaches the 80 level and the 20 level (but the caveat is that those values might not be consistent):


I made an indicator and attached it. I'm not sure about accuracy, and not sure why it works when loading the indicator on a chart, but will not show the added MA in the strategy tester


might be a good idea to alter the code to use greater than or equal to:

Thank you for the indicator Conor Mcnamara
Reason: