DPO_modified

Author: Copyright 2000-2024, MetaQuotes Ltd.
0 Views
0 Downloads
0 Favorites
DPO_modified
//+------------------------------------------------------------------+
//|                                                 DPO_modified.mq5 |
//|                             Copyright 2000-2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright     "Copyright 2000-2024, MetaQuotes Ltd."
#property link          "https://www.mql5.com"
#property version       "1.10"
#property description   "Detrended Price Oscillator - modified"
#include <MovingAverages.mqh>
//--- indicator settings
#property indicator_separate_window
#property indicator_buffers      3
#property indicator_plots        1
#property indicator_type1        DRAW_LINE
#property indicator_color1       DodgerBlue
#property indicator_levelstyle   STYLE_DOT
#property indicator_levelcolor   DarkGray
#property indicator_level1       0

//--- input parameters
input int                  InpDetrendPeriod  = 61;                // DPO Period
input ENUM_MA_METHOD       MAmethod          = MODE_SMA;          // MA Method 
input ENUM_APPLIED_PRICE   appliedprice      = PRICE_CLOSE;       // MA Applied price

//--- indicator buffers
double    ExtDPOBuffer[];
double    ExtMABuffer[];
double    Extprice[];
int       helpMABuffer;

int       ExtMAPeriod;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- get length of cycle for smoothing
   //ExtMAPeriod = InpDetrendPeriod / 2 + 1;
   ExtMAPeriod = InpDetrendPeriod;                 // change input period to equal MA period
//--- indicator buffers mapping
   SetIndexBuffer(0, ExtDPOBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, ExtMABuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(2, Extprice, INDICATOR_CALCULATIONS);
//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS, _Digits + 1);
//--- set first bar from what index will be drawn
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtMAPeriod - 1);
//--- name for DataWindow and indicator subwindow label
   string short_name = StringFormat("modified DPO(%d)", InpDetrendPeriod);

//--- set short name according to MA mode
   switch(MAmethod)
     {
      case MODE_EMA :
         short_name = short_name + " (EMA)";
         break;
      case MODE_LWMA :
         short_name = short_name + " (LWMA)";
         break;
      case MODE_SMA :
         short_name = short_name + " (SMA)";
         break;
      case MODE_SMMA :
         short_name = short_name + " (SMMA)";
         break;
      default :
         short_name = short_name;
     }

   IndicatorSetString(INDICATOR_SHORTNAME, short_name);
  }
//+------------------------------------------------------------------+
//| Detrended Price Oscillator                                       |
//+------------------------------------------------------------------+
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 start;
   
   int begin = 0;
   int first_index = begin + ExtMAPeriod - 1;
//--- preliminary filling
   if(prev_calculated < first_index)
     {
      ArrayInitialize(ExtDPOBuffer, 0.0);
      start = first_index;
      if(begin > 0)
         PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, first_index);
     }
   else
      start = prev_calculated - 1;
      
//---get price array if chosen MA applied price is PRICE_MEDIAN, PRICE_TYPICAL, or PRICE_WEIGHTED
   if(appliedprice >= 4)getLprice(rates_total, prev_calculated, begin, open, high, low, close, Extprice, appliedprice);      


//--- get MA buffer based on MA applied price and MA mode
   switch(appliedprice)
     {
      case PRICE_CLOSE :
         AverageOnArray(MAmethod, rates_total, prev_calculated, begin, ExtMAPeriod, close, ExtMABuffer);
         break;
      case PRICE_OPEN :
         AverageOnArray(MAmethod, rates_total, prev_calculated, begin, ExtMAPeriod, open, ExtMABuffer);
         break;
      case PRICE_HIGH :
         AverageOnArray(MAmethod, rates_total, prev_calculated, begin, ExtMAPeriod, high, ExtMABuffer);
         break;
      case PRICE_LOW :
         AverageOnArray(MAmethod, rates_total, prev_calculated, begin, ExtMAPeriod, low, ExtMABuffer);
         break;
      case PRICE_MEDIAN :
         AverageOnArray(MAmethod, rates_total, prev_calculated, begin, ExtMAPeriod, Extprice, ExtMABuffer);
         break;
      case PRICE_TYPICAL :
         AverageOnArray(MAmethod, rates_total, prev_calculated, begin, ExtMAPeriod, Extprice, ExtMABuffer);
         break;
      case PRICE_WEIGHTED :
         AverageOnArray(MAmethod, rates_total, prev_calculated, begin, ExtMAPeriod, Extprice, ExtMABuffer);
         break;
      default :
         AverageOnArray(MAmethod, rates_total, prev_calculated, begin, ExtMAPeriod, close, ExtMABuffer);
     }
      
//--- the main loop of calculations
   for(int i = start; i < rates_total && !IsStopped(); i++)
      ExtDPOBuffer[i] = close[i] - ExtMABuffer[i];
//--- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| calculate average on array                                       |
//+------------------------------------------------------------------+
void AverageOnArray(const int mode, 
                     const int rates_total, 
                     const int prev_calculated, 
                     const int begin,
                     const int period, 
                     const double& source[], 
                     double& destination[])
  {
   switch(mode)
     {
      case MODE_EMA:
         ExponentialMAOnBuffer(rates_total, prev_calculated, begin, period, source, destination);
         break;
      case MODE_SMMA:
         SmoothedMAOnBuffer(rates_total, prev_calculated, begin, period, source, destination);
         break;
      case MODE_LWMA:
         LinearWeightedMAOnBuffer(rates_total, prev_calculated, begin, period, source, destination);
         break;
      default:
         SimpleMAOnBuffer(rates_total, prev_calculated, begin, period, source, destination);
     }
  }
//+------------------------------------------------------------------+
//| get median , typical, & weighted prices (when requested)         |
//+------------------------------------------------------------------+
int getLprice(const  int      rates_total,
               const int      prev_calculated, 
               const int      begin, 
               const double   &op[], 
               const double   &hi[], 
               const double   &lo[], 
               const double   &cl[], 
               double         &destination[],
               ENUM_APPLIED_PRICE Lprice)
  {
   
   bool as_series_destination=ArrayGetAsSeries(destination);
   ArraySetAsSeries(destination,false);
   
   int start_position = prev_calculated-1;
  
   if(start_position < 0){start_position = 0;}

//--- main loop
   for(int i = start_position; i < rates_total; i++)
     {
      if(Lprice == PRICE_WEIGHTED)destination[i] = (hi[i] + lo[i] + cl[i] * 2) / 4;
      if(Lprice == PRICE_TYPICAL)destination[i] = (hi[i] + lo[i] + cl[i]) / 3;
      if(Lprice == PRICE_MEDIAN)destination[i] = (hi[i] + lo[i]) / 2;
     }
   ArraySetAsSeries(destination,as_series_destination);
   return rates_total;
  }
//+------------------------------------------------------------------+





Comments