//+------------------------------------------------------------------+ //| AdpvCyberCycle.mq4 | //| Copyright 2014, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2014, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" #property strict #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 2 //--- plot AdpvCycle #property indicator_label1 "AdpvCycle" #property indicator_type1 DRAW_LINE #property indicator_color1 clrLime #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot AdpvTrigger #property indicator_label2 "AdpvTrigger" #property indicator_type2 DRAW_LINE #property indicator_color2 clrRed #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- indicator buffers #define Price(s) ((High[s]+Low[s])/2.0) //Close Location Value #define CLV(s) ((Close[s]-Low[s])-(High[s]-Close[s])) input double InpAlpha = 0.07; input bool UseCLV = true; double AdpCycle[]; double AdpTrigger[]; double Smooth[], Cycle[], Q1[], I1[], DeltaPhase[], InstPeriod[], cPeriod[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping IndicatorDigits(8); ArraySetAsSeries(cPeriod,true); ArraySetAsSeries(Smooth,true); ArraySetAsSeries(Cycle,true); SetIndexBuffer(0,AdpCycle); SetIndexBuffer(1,AdpTrigger); PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { //--- long tickCnt[1]; int s; int ticks=CopyTickVolume(Symbol(), 0, 0, 1, tickCnt); if(ticks!=1) return(rates_total); double DC, MedianDelta; Comment(tickCnt[0]); if(prev_calculated==0 || tickCnt[0]==1) { //--- last counted bar will be recounted int nLimit=rates_total-prev_calculated-1; // start index for calculations ArrayResize(cPeriod,Bars(_Symbol,_Period)); ArrayResize(Smooth,Bars(_Symbol,_Period)); ArrayResize(Cycle,Bars(_Symbol,_Period)); ArrayResize(DeltaPhase,Bars(_Symbol,_Period)); ArrayResize(InstPeriod,Bars(_Symbol,_Period)); ArrayResize(Q1,Bars(_Symbol,_Period)); ArrayResize(I1,Bars(_Symbol,_Period)); //if (nLimit>rates_total-7) nLimit=rates_total-7; for(s=nLimit-7; s>=0 && !IsStopped(); s--) { Smooth[s] = (Price(s)+2*Price(s+1)+2*Price(s+2)+Price(s+3))/6.0; if(UseCLV) { Cycle[s] = ((1.0-0.5*InpAlpha) * (1.0-0.5*InpAlpha) * (Smooth[s]-2.0*Smooth[s+1]+Smooth[s+2]) +2.0*(1.0-InpAlpha)*Cycle[s+1]-(1.0-InpAlpha)*(1.0-InpAlpha)*Cycle[s+2]) + CLV(s);// } else { Cycle[s] = ((1.0-0.5*InpAlpha) * (1.0-0.5*InpAlpha) * (Smooth[s]-2.0*Smooth[s+1]+Smooth[s+2]) +2.0*(1.0-InpAlpha)*Cycle[s+1]-(1.0-InpAlpha)*(1.0-InpAlpha)*Cycle[s+2]);// } if (s > rates_total - 7) { Cycle[s]=(Price(s)-2.0*Price(s+1)+Price(s+2))/4.0; } /* */ Q1[s] = (0.0962*Cycle[s]+0.5769*Cycle[s+2]-0.5769*Cycle[s+4]-0.0962*Cycle[s+6])*(0.5+0.08*InstPeriod[s+1]); I1[s] = Cycle[s+3]; if (Q1[s]!=0.0 && Q1[s+1]!=0.0) DeltaPhase[s] = (I1[s]/Q1[s]-I1[s+1]/Q1[s+1])/(1.0+I1[s]*I1[s+1]/(Q1[s]*Q1[s+1])); if (DeltaPhase[s] < 0.1) DeltaPhase[s] = 0.1; if (DeltaPhase[s] > 0.9) DeltaPhase[s] = 0.9; MedianDelta = Median(DeltaPhase, 5);//, s if (MedianDelta == 0.0) DC = 15.0; else DC = (6.28318/MedianDelta) + 0.5; InstPeriod[s] = 0.33 * DC + 0.67 * InstPeriod[s+1]; cPeriod[s] = 0.15 * InstPeriod[s] + 0.85 * cPeriod[s+1]; //+------------------------------------------------------------------+ double Alpha = cPeriod[s]; Alpha=2.0/(Alpha+1); if(UseCLV) { AdpCycle[s]=((1.0 - 0.5 * Alpha) * (1.0 - 0.5 * Alpha) * (Smooth[s] - 2.0 * Smooth[s+1] + Smooth[s+2]) + 2.0 * (1.0 - Alpha) * AdpCycle[s+1] - (1.0 - Alpha) * (1.0 - Alpha) * AdpCycle[s+2]) + CLV(s);// } else { AdpCycle[s]=((1.0 - 0.5 * Alpha) * (1.0 - 0.5 * Alpha) * (Smooth[s] - 2.0 * Smooth[s+1] + Smooth[s+2]) + 2.0 * (1.0 - Alpha) * AdpCycle[s+1] - (1.0 - Alpha) * (1.0 - Alpha) * AdpCycle[s+2]);// } AdpTrigger[s]=AdpCycle[s+1]; } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ double Median(double& arr[], int m_len) {//, int idx double MedianArr[]; int copied; double result = 0.0; ArraySetAsSeries(MedianArr, true); ArrayResize(MedianArr, m_len); copied = ArrayCopy(MedianArr, arr, 0, 0, m_len);//, idx if (copied == m_len) { ArraySort(MedianArr); if (m_len %2 == 0) result = (MedianArr[m_len/2] + MedianArr[(m_len/2)+1])/2.0; else result = MedianArr[m_len / 2]; } else Print(__FILE__+__FUNCTION__+"median error - wrong number of elements copied."); return result; } //+------------------------------------------------------------------+