Demande d'aide pour créer un indicateur avec signaux

par stephaneM » 05 déc. 2021 04:33

Bonjour à tous,
j'aimerais savoir si vous pourriez m'aider pour la programmation d'un indicateur qui me permettrait de m'envoyer à moi-même des signaux de trading.

J'ai essayé de modifier un indicateur déjà existant provenant de MQL5 (pour Metatrader 4).

J'aimerais si possible ajouter les bandes de bollinger à mon indicateur.
Le souci c'est que j'ai essayé plusieurs fois d'ajouter les bouts de codes des bandes de bollinger dans mon code mais j'ai des erreurs lors de la compilation.

Je vous poste donc mon code actuel :

Code : #

//+--------------------------------------------------------------------+
//|                                             RSI stop & reverse.mq4 |
//+--------------------------------------------------------------------+
#property copyright "Copyright © 2021, Max Michael"
#property indicator_chart_window


#property indicator_buffers 10
#property indicator_color1 Chocolate
#property indicator_color2 Orange
#property indicator_color3 Chocolate
#property indicator_color4 Orange
#property indicator_color5 Snow
#property indicator_color6 Blue
#property indicator_color7 Red
#property indicator_color8 Blue
#property indicator_color9 Red
#property indicator_color10 Purple
#property strict

// inputs 1
extern int           Length4 = 4;
extern int         Level_Up = 70;    
extern int         Level_Dn = 30;
extern bool    ShowRSIbands = true;
extern int          MaxBars = 1000;

// inputs 2
extern int           Length8 = 8;
//extern int         Level_Up = 70;    
//extern int         Level_Dn = 30;
//extern bool    ShowRSIbands = true;
//extern int          MaxBars = 1000;

// globals
double LevUp4, LevDn4, LevUp8, LevDn8;
string UT;

// buffers
double emaUp4[];
double emaDn4[];
double Eup4[];
double Edn4[];
double Stop4[];
double emaUp8[];
double emaDn8[];
double Eup8[];
double Edn8[];
double Stop8[];


//TheTime = Period();
//if (TheTime==1)       UT ='M1';
//if (TheTime==5)       UT ='M5';
//if (TheTime==15)      UT ='M15';
//if (TheTime==30)      UT ='M30';
//if (TheTime==60)      UT ='H1';
//if (TheTime==240)     UT ='H4';
//if (TheTime==1440)    UT ='Daily';
//if (TheTime==10080)   UT ='Weekly';
//if (TheTime==43200)   UT ='Monthly';


int init()
{
   IndicatorShortName("RSI("+IntegerToString(Length4) +","+IntegerToString(Length8)+") ");
   SetIndexBuffer(0,emaUp4); SetIndexStyle(0,DRAW_NONE);
   SetIndexBuffer(1,emaDn4); SetIndexStyle(1,DRAW_NONE);
   SetIndexBuffer(5,emaUp8); SetIndexStyle(5,DRAW_NONE);
   SetIndexBuffer(6,emaDn8); SetIndexStyle(6,DRAW_NONE);
   if(ShowRSIbands)
   {
     SetIndexBuffer(2,Eup4); SetIndexStyle(2,DRAW_LINE); 
     SetIndexBuffer(3,Edn4); SetIndexStyle(3,DRAW_LINE);
     SetIndexBuffer(7,Eup8); SetIndexStyle(7,DRAW_LINE); 
     SetIndexBuffer(8,Edn8); SetIndexStyle(8,DRAW_LINE); 
   }
   else
   {
     SetIndexBuffer(2,Eup4); SetIndexStyle(2,DRAW_NONE); 
     SetIndexBuffer(3,Edn4); SetIndexStyle(3,DRAW_NONE); 
     SetIndexBuffer(7,Eup8); SetIndexStyle(7,DRAW_NONE); 
     SetIndexBuffer(8,Edn8); SetIndexStyle(8,DRAW_NONE);
   }
   SetIndexBuffer(4,Stop4); SetIndexStyle(4,DRAW_LINE);
   SetIndexBuffer(9,Stop8); SetIndexStyle(9,DRAW_LINE);
   SetIndexLabel(4,"RSI stop level length 4");
   SetIndexLabel(9,"RSI stop level length 8");
   MaxBars=MathMin(Bars,MaxBars);
   Length4 = (Length4<2) ? 2 : Length4;
   Length8 = (Length8<2) ? 2 : Length8;
   Level_Up= (Level_Up<51) ? 51 : Level_Up; Level_Up= (Level_Up>100) ? 100 : Level_Up;   
   Level_Dn= (Level_Dn>49) ? 49 : Level_Dn; Level_Dn= (Level_Dn<0) ? 0 : Level_Dn;
   // Convert level values to percent
   LevUp4=(Level_Up-50)/20.0;
   LevDn4=(50-Level_Dn)/20.0;
   LevUp8=(Level_Up-50)/20.0;
   LevDn8=(50-Level_Dn)/20.0;
   return(0);
}

int deinit() { return(0); }

int start()
{
   int CountedBars=IndicatorCounted();
   if (CountedBars<0) return(-1);
   int limit = Bars-CountedBars-1;
   if (limit > MaxBars) limit=MaxBars;
   double wilders4 = Length4*2-1;
   double   alpha4 = 2.0/(1+wilders4);
   double wilders8 = Length8*2-1;
   double   alpha8 = 2.0/(1+wilders8);
   // Differential equation of length, level, delta.
   double delta_up4 = (wilders4/((1+1/wilders4)*5))*LevUp4;
   double delta_dn4 = (wilders4/((1+1/wilders4)*5))*LevDn4;
   double delta_up8 = (wilders8/((1+1/wilders8)*5))*LevUp8;
   double delta_dn8 = (wilders8/((1+1/wilders8)*5))*LevDn8;
   
   for (int i=limit; i>=0; i--)
   {
      if (i==MaxBars) { emaUp4[i]=0.0001; emaUp8[i]=0.0001; emaDn4[i]=0.0001; emaDn8[i]=0.0001; } //initialize emas
      else 
      {
         double Su=(Close[i]-Close[i+1]>0) ? Close[i]-Close[i+1] : 0;
         double Sd=(Close[i]-Close[i+1]<0) ? Close[i+1]-Close[i] : 0;
         emaUp4[i]= (Su - emaUp4[i+1]) * alpha4 + emaUp4[i+1];
         emaDn4[i]= (Sd - emaDn4[i+1]) * alpha4 + emaDn4[i+1];
         double ccrange4 = emaUp4[i]+emaDn4[i];
         Eup4[i]  = ccrange4 *delta_up4 + iMA(NULL,0,wilders4,0,MODE_EMA,PRICE_CLOSE,i);
         Edn4[i]  =-ccrange4 *delta_dn4 + iMA(NULL,0,wilders4,0,MODE_EMA,PRICE_CLOSE,i);
         
         double prev4 = Stop4[i+1];
         if ( Close[i] > prev4 && Close[i+1] > prev4) { Stop4[i] = MathMax(prev4, Edn4[i]); } //uptrend
         else if ( Close[i] < prev4 && Close[i+1] < prev4) { Stop4[i] = MathMin(prev4, Eup4[i]); } //dntrend
         else if ( Close[i] > prev4) { Stop4[i] = Edn4[i]; } //change of trend up else down
         else { Stop4[i] = Eup4[i]; }      
         
         //double Su=(Close[i]-Close[i+1]>0) ? Close[i]-Close[i+1] : 0;
         //double Sd=(Close[i]-Close[i+1]<0) ? Close[i+1]-Close[i] : 0;
         emaUp8[i]= (Su - emaUp8[i+1]) * alpha8 + emaUp8[i+1];
         emaDn8[i]= (Sd - emaDn8[i+1]) * alpha8 + emaDn8[i+1];
         double ccrange8 = emaUp8[i]+emaDn8[i];
         Eup8[i]  = ccrange8 *delta_up8 + iMA(NULL,0,wilders8,0,MODE_EMA,PRICE_CLOSE,i);
         Edn8[i]  =-ccrange8 *delta_dn8 + iMA(NULL,0,wilders8,0,MODE_EMA,PRICE_CLOSE,i);
         
         double prev8 = Stop8[i+1];
         if ( Close[i] > prev8 && Close[i+1] > prev8) { Stop8[i] = MathMax(prev8, Edn8[i]); } //uptrend
         else if ( Close[i] < prev8 && Close[i+1] < prev8) { Stop8[i] = MathMin(prev8, Eup8[i]); } //dntrend
         else if ( Close[i] > prev8) { Stop8[i] = Edn8[i]; } //change of trend up else down
         else { Stop8[i] = Eup8[i]; }  
      }
   }
   return(0);
}
Et le code des bandes de bollinger :

Code : #

//+------------------------------------------------------------------+
//|                                                        Bands.mq4 |
//|                   Copyright 2005-2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "2005-2015, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property description "Bollinger Bands"
#property strict

#include <MovingAverages.mqh>

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 LightSeaGreen
#property indicator_color2 LightSeaGreen
#property indicator_color3 LightSeaGreen
//--- indicator parameters
input int    InpBandsPeriod=20;      // Bands Period
input int    InpBandsShift=0;        // Bands Shift
input double InpBandsDeviations=2.0; // Bands Deviations
//--- buffers
double ExtMovingBuffer[];
double ExtUpperBuffer[];
double ExtLowerBuffer[];
double ExtStdDevBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- 1 additional buffer used for counting.
   IndicatorBuffers(4);
   IndicatorDigits(Digits);
//--- middle line
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtMovingBuffer);
   SetIndexShift(0,InpBandsShift);
   SetIndexLabel(0,"Bands SMA");
//--- upper band
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,ExtUpperBuffer);
   SetIndexShift(1,InpBandsShift);
   SetIndexLabel(1,"Bands Upper");
//--- lower band
   SetIndexStyle(2,DRAW_LINE);
   SetIndexBuffer(2,ExtLowerBuffer);
   SetIndexShift(2,InpBandsShift);
   SetIndexLabel(2,"Bands Lower");
//--- work buffer
   SetIndexBuffer(3,ExtStdDevBuffer);
//--- check for input parameter
   if(InpBandsPeriod<=0)
     {
      Print("Wrong input parameter Bands Period=",InpBandsPeriod);
      return(INIT_FAILED);
     }
//---
   SetIndexDrawBegin(0,InpBandsPeriod+InpBandsShift);
   SetIndexDrawBegin(1,InpBandsPeriod+InpBandsShift);
   SetIndexDrawBegin(2,InpBandsPeriod+InpBandsShift);
//--- initialization done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Bollinger Bands                                                  |
//+------------------------------------------------------------------+
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,pos;
//---
   if(rates_total<=InpBandsPeriod || InpBandsPeriod<=0)
      return(0);
//--- counting from 0 to rates_total
   ArraySetAsSeries(ExtMovingBuffer,false);
   ArraySetAsSeries(ExtUpperBuffer,false);
   ArraySetAsSeries(ExtLowerBuffer,false);
   ArraySetAsSeries(ExtStdDevBuffer,false);
   ArraySetAsSeries(close,false);
//--- initial zero
   if(prev_calculated<1)
     {
      for(i=0; i<InpBandsPeriod; i++)
        {
         ExtMovingBuffer[i]=EMPTY_VALUE;
         ExtUpperBuffer[i]=EMPTY_VALUE;
         ExtLowerBuffer[i]=EMPTY_VALUE;
        }
     }
//--- starting calculation
   if(prev_calculated>1)
      pos=prev_calculated-1;
   else
      pos=0;
//--- main cycle
   for(i=pos; i<rates_total && !IsStopped(); i++)
     {
      //--- middle line
      ExtMovingBuffer[i]=SimpleMA(i,InpBandsPeriod,close);
      //--- calculate and write down StdDev
      ExtStdDevBuffer[i]=StdDev_Func(i,close,ExtMovingBuffer,InpBandsPeriod);
      //--- upper line
      ExtUpperBuffer[i]=ExtMovingBuffer[i]+InpBandsDeviations*ExtStdDevBuffer[i];
      //--- lower line
      ExtLowerBuffer[i]=ExtMovingBuffer[i]-InpBandsDeviations*ExtStdDevBuffer[i];
      //---
     }
//---- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Calculate Standard Deviation                                     |
//+------------------------------------------------------------------+
double StdDev_Func(int position,const double &price[],const double &MAprice[],int period)
  {
//--- variables
   double StdDev_dTmp=0.0;
//--- check for position
   if(position>=period)
     {
      //--- calcualte StdDev
      for(int i=0; i<period; i++)
         StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],2);
      StdDev_dTmp=MathSqrt(StdDev_dTmp/period);
     }
//--- return calculated value
   return(StdDev_dTmp);
  }
//+------------------------------------------------------------------+

J'aimerais donc savoir s'il était possible d'ajouter les bandes de bollinger à mon indicateur.
Et aussi est-il possible de rendre l'indicateur automatique (pas forcément faire un robot automatique) en faisant qu'il visionnerait les graphiques de plusieurs paires en même temps dans plusieurs unités de temps en même temps (par exemple en H1, H2 si possible, H4, Daily et Weekly) pour pouvoir me fournir des signaux qui dépendraient de la position de la ligne "stop" des deux "rsi en bandes" et que l'indicateur me donnerait des signaux d'achat lorsque la ligne "stop" irait vers la ligne orange en H1 et en même temps que je serais entre la bande inférieure de bollinger et la bande centrale de bollinger en H4.
La même logique pour les signaux de vente.