//------------------------------------------------------------------ #property copyright "© mladen, 2020" #property link "mladenfx@gmail.com" #property version "1.00" //------------------------------------------------------------------ #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 2 #property indicator_label1 "Fast TrendFlex" #property indicator_type1 DRAW_LINE #property indicator_color1 clrDeepSkyBlue #property indicator_width1 2 #property indicator_label2 "Slow TrendFlex" #property indicator_type2 DRAW_LINE #property indicator_color2 clrCoral #property indicator_style2 STYLE_DOT // //--- // enum enTimeFrames { tf_cu = PERIOD_CURRENT, // Current time frame tf_m1 = PERIOD_M1, // 1 minute tf_m2 = PERIOD_M2, // 2 minutes tf_m3 = PERIOD_M3, // 3 minutes tf_m4 = PERIOD_M4, // 4 minutes tf_m5 = PERIOD_M5, // 5 minutes tf_m6 = PERIOD_M6, // 6 minutes tf_m10 = PERIOD_M10, // 10 minutes tf_m12 = PERIOD_M12, // 12 minutes tf_m15 = PERIOD_M15, // 15 minutes tf_m20 = PERIOD_M20, // 20 minutes tf_m30 = PERIOD_M30, // 30 minutes tf_h1 = PERIOD_H1, // 1 hour tf_h2 = PERIOD_H2, // 2 hours tf_h3 = PERIOD_H3, // 3 hours tf_h4 = PERIOD_H4, // 4 hours tf_h6 = PERIOD_H6, // 6 hours tf_h8 = PERIOD_H8, // 8 hours tf_h12 = PERIOD_H12, // 12 hours tf_d1 = PERIOD_D1, // daily tf_w1 = PERIOD_W1, // weekly tf_mn = PERIOD_MN1, // monthly tf_cp1 = -1, // Next higher time frame tf_cp2 = -2, // Second higher time frame tf_cp3 = -3 // Third higher time frame }; enum enPrices { pr_close, // Close pr_open, // Open pr_high, // High pr_low, // Low pr_median, // Median pr_typical, // Typical pr_weighted, // Weighted pr_average, // Average (high+low+open+close)/4 pr_medianb, // Average median body (open+close)/2 pr_tbiased, // Trend biased price pr_tbiased2, // Trend biased (extreme) price pr_haclose, // Heiken ashi close pr_haopen , // Heiken ashi open pr_hahigh, // Heiken ashi high pr_halow, // Heiken ashi low pr_hamedian, // Heiken ashi median pr_hatypical, // Heiken ashi typical pr_haweighted, // Heiken ashi weighted pr_haaverage, // Heiken ashi average pr_hamedianb, // Heiken ashi median body pr_hatbiased, // Heiken ashi trend biased price pr_hatbiased2 // Heiken ashi trend biased (extreme) price }; input enTimeFrames inpTimeFrame = tf_cu; // Time frame input int inpFastPeriod = 20; // Fast trend-flex period input int inpSlowPeriod = 50; // Slow trend-flex period input enPrices Price = pr_close; // Price input int _bar = 4000; enum enIterpolate { interolate_yes=(int)true, // Interpolate data when in multi time frame interolate_no =(int)false // Do not interpolate data when in multi time frame }; input enIterpolate inpInterpolate = interolate_no; // Interpolation double valf[],vals[]; ENUM_TIMEFRAMES _indicatorTimeFrame; string _indicatorName; int _indicatorMtfHandle; #define _mtfCall iCustom(_Symbol,_indicatorTimeFrame,_indicatorName,0,inpFastPeriod,inpSlowPeriod,Price,_bar ) //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // int OnInit() { SetIndexBuffer(0,valf ,INDICATOR_DATA); SetIndexBuffer(1,vals ,INDICATOR_DATA); PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,_bar); PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,_bar);//c iTfFast.OnInit(inpFastPeriod); iTfSlow.OnInit(inpSlowPeriod); // // // IndicatorSetString(INDICATOR_SHORTNAME,"TrendFlex x 2 ("+(string)inpFastPeriod+","+(string)inpSlowPeriod+")"); _indicatorTimeFrame = MathMax(_Period,timeFrameGet(inpTimeFrame)); if (_indicatorTimeFrame != _Period) { _indicatorName = getIndicatorName(); _indicatorMtfHandle = _mtfCall; if (!_checkHandle(_indicatorMtfHandle,"Target time frame instance")) return(INIT_FAILED); } return(INIT_SUCCEEDED); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // double work[][1]; #define _pr 0 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[]) { if(rates_total<10) return(0); if(_indicatorTimeFrame!=_Period) { double result[1]; if (CopyBuffer(_indicatorMtfHandle,2,0,1,result)<0) result[0] = rates_total; // //--- // #define _mtfRatio (double)PeriodSeconds((ENUM_TIMEFRAMES)_indicatorTimeFrame)/PeriodSeconds(_Period) int n,k,i=MathMin(MathMax(prev_calculated-1,0),MathMax(rates_total-int(result[0]*_mtfRatio)-1,0)),_prevMark=-99; datetime _prevTime; for(; i 0 && time[i-n] >= _prevTime; n++) continue; for (k=1; (i-k)>=0 && k0 ? (work[i][_pr]+work[i-1][_pr])/2 : work[i][_pr]); valf[i] = iTfFast.OnCalculate(_price,i,rates_total); vals[i] = iTfSlow.OnCalculate(_price,i,rates_total); } return(rates_total); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // class CTrendFlex { private : double m_c1; double m_c2; double m_c3; struct sWorkStruct { double value; double ssm; double sum; double ms; }; sWorkStruct m_array[]; int m_arraySize; int m_period; public : CTrendFlex() : m_c1(1), m_c2(1), m_c3(1), m_arraySize(-1) { } ~CTrendFlex() { } // //--- // void OnInit(int period) { m_period = (period>1) ? period : 1; double a1 = MathExp(-1.414*M_PI/m_period); double b1 = 2.0*a1*MathCos(1.414*M_PI/m_period); m_c2 = b1; m_c3 = -a1*a1; m_c1 = 1.0 - m_c2 - m_c3; } double OnCalculate(double value, int i, int bars) { if (m_arraySize1) m_array[i].ssm = m_c1*(m_array[i].value+m_array[i-1].value)/2.0 + m_c2*m_array[i-1].ssm + m_c3*m_array[i-2].ssm; else m_array[i].ssm = value; if (i>m_period) m_array[i].sum = m_array[i-1].sum + m_array[i].ssm - m_array[i-m_period].ssm; else { m_array[i].sum = m_array[i].ssm; for (int k=1; k=0; k++) m_array[i].sum += m_array[i-k].ssm; } // // // double sum = m_period*m_array[i].ssm-m_array[i].sum; sum /= m_period; m_array[i].ms = (i>0) ? 0.04 * sum*sum+0.96*m_array[i-1].ms : 0; return (m_array[i].ms!=0 ? sum/MathSqrt(m_array[i].ms) : 0); } }; CTrendFlex iTfSlow,iTfFast; double getPricec(int price,int pos) { MqlRates rates[]; int result = CopyRates(_Symbol,_Period,pos,1,rates); if (result!=1) return(0); switch (price) { case PRICE_CLOSE : return(rates[0].close); case PRICE_OPEN : return(rates[0].open); case PRICE_HIGH : return(rates[0].high); case PRICE_LOW : return(rates[0].low); case PRICE_MEDIAN : return((rates[0].high+rates[0].low)/2.0); case PRICE_TYPICAL : return((rates[0].high+rates[0].low+rates[0].close)/3.0); case PRICE_WEIGHTED : return((rates[0].high+rates[0].low+rates[0].close+rates[0].close)/4.0); } return(0); } double workHa[][4]; double getPrice(int tprice, const double& open[], const double& close[], const double& high[], const double& low[], int i, int _tbars, int instanceNo=0) { if (tprice>=pr_haclose) { if (ArrayRange(workHa,0)!= _tbars) ArrayResize(workHa,_tbars); instanceNo*=4; // // // // // double haOpen; if (i>0) haOpen = (workHa[i-1][instanceNo+2] + workHa[i-1][instanceNo+3])/2.0; else haOpen = (open[i]+close[i])/2; double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0; double haHigh = MathMax(high[i], MathMax(haOpen,haClose)); double haLow = MathMin(low[i] , MathMin(haOpen,haClose)); if(haOpen haOpen) return((haHigh+haClose)/2.0); else return((haLow+haClose)/2.0); case pr_hatbiased2: if (haClose>haOpen) return(haHigh); if (haCloseopen[i]) return((high[i]+close[i])/2.0); else return((low[i]+close[i])/2.0); case pr_tbiased2: if (close[i]>open[i]) return(high[i]); if (close[i]=0 && _partsA[n]!="indicators"; n--) name=_partsA[n]+"\\"+name; return(name); } // //--- // bool _checkHandle(int _handle, string _description) { static int _chandles[]; int _size = ArraySize(_chandles); bool _answer = (_handle!=INVALID_HANDLE); if (_answer) { ArrayResize(_chandles,_size+1); _chandles[_size]=_handle; } else { for (int i=_size-1; i>=0; i--) IndicatorRelease(_chandles[i]); ArrayResize(_chandles,0); Alert(_description+" initialization failed"); } return(_answer); }