//+------------------------------------------------------------------+ //| mama - smoothed | //+------------------------------------------------------------------+ #property copyright "mladen" #property link "www.forex-whereever.com" #property indicator_chart_window #property indicator_buffers 6 #property strict // // // enum enTimeFrames { tf_cu = 0, // Current time frame tf_m1 = PERIOD_M1, // 1 minute tf_m5 = PERIOD_M5, // 5 minutes tf_m15 = PERIOD_M15, // 15 minutes tf_m30 = PERIOD_M30, // 30 minutes tf_h1 = PERIOD_H1, // 1 hour tf_h4 = PERIOD_H4, // 4 hours tf_d1 = PERIOD_D1, // Daily tf_w1 = PERIOD_W1, // Weekly tf_mn1 = PERIOD_MN1, // Monthly tf_n1 = -1, // First higher time frame tf_n2 = -2, // Second higher time frame tf_n3 = -3, // Third higher time frame tf_cus = 12345678 // Custom time frame }; input enTimeFrames inpTimeFrame = tf_cu; // Time frame to use input int inpTimeFrameCustom = 0; // Custom timeframe 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 pr_habclose, // Heiken ashi (better formula) close pr_habopen , // Heiken ashi (better formula) open pr_habhigh, // Heiken ashi (better formula) high pr_hablow, // Heiken ashi (better formula) low pr_habmedian, // Heiken ashi (better formula) median pr_habtypical, // Heiken ashi (better formula) typical pr_habweighted, // Heiken ashi (better formula) weighted pr_habaverage, // Heiken ashi (better formula) average pr_habmedianb, // Heiken ashi (better formula) median body pr_habtbiased, // Heiken ashi (better formula) trend biased price pr_habtbiased2 // Heiken ashi (better formula) trend biased (extreme) price }; input enPrices inpPrice = pr_median; // Mama Price input double inpSlowLimit = 0.05; // Mama slow limit input double inpFastLimit = 0.5; // Mama fast limit input double inpSmthAlpha = 10; // Mama + Fama smoothing period input string __ma1__00 = ""; //. Mama settings input int inpMa1LineWidth = 2; // Line width input color inpMa1ColorUp = clrSpringGreen; // Bullish color input color inpMa1ColorDn = clrCrimson; // Bearish color input string __ma2__00 = ""; //. Fama settings input int inpMa2LineWidth = 2; // Line width input color inpMa2ColorUp = clrSpringGreen; // Bullish color input color inpMa2ColorDn = clrCrimson; // Bearish color input bool Interpolate = true; // Interpolate when in multi time frame mode? double ma1[],ma1Da[],ma1Db[],ma2[],ma2Da[],ma2Db[],cMa1[],cMa2[],cnt[]; struct sGloStruct { double alp,alpSmth,dphase,_max,_min; int indiTimeFrame,lim,tfcustom; string indiFileName; datetime btime; }; sGloStruct glo; #define _mtfCall(_buff,_y) iCustom(_Symbol,glo.indiTimeFrame,glo.indiFileName,tf_cu,0,inpPrice,inpSlowLimit,inpFastLimit,inpSmthAlpha,"",inpMa1LineWidth,inpMa1ColorUp,inpMa1ColorDn,"",inpMa2LineWidth,inpMa2ColorUp,inpMa2ColorDn,_buff,_y) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { IndicatorBuffers(9); SetIndexBuffer(0,ma1 ,INDICATOR_DATA); SetIndexStyle(0,DRAW_LINE,EMPTY,inpMa1LineWidth,inpMa1ColorUp); SetIndexBuffer(1,ma1Da,INDICATOR_DATA); SetIndexStyle(1,DRAW_LINE,EMPTY,inpMa1LineWidth,inpMa1ColorDn); SetIndexBuffer(2,ma1Db,INDICATOR_DATA); SetIndexStyle(2,DRAW_LINE,EMPTY,inpMa1LineWidth,inpMa1ColorDn); SetIndexBuffer(3,ma2 ,INDICATOR_DATA); SetIndexStyle(3,DRAW_LINE,EMPTY,inpMa2LineWidth,inpMa2ColorUp); SetIndexBuffer(4,ma2Da,INDICATOR_DATA); SetIndexStyle(4,DRAW_LINE,EMPTY,inpMa2LineWidth,inpMa2ColorDn); SetIndexBuffer(5,ma2Db,INDICATOR_DATA); SetIndexStyle(5,DRAW_LINE,EMPTY,inpMa2LineWidth,inpMa2ColorDn); SetIndexBuffer(6,cMa1 ,INDICATOR_CALCULATIONS); SetIndexBuffer(7,cMa2 ,INDICATOR_CALCULATIONS); SetIndexBuffer(8,cnt ,INDICATOR_CALCULATIONS); glo.alpSmth = (2.0/(1.0+fmax(inpSmthAlpha,1.0))); glo.indiFileName = WindowExpertName(); if (inpTimeFrameCustom==0) glo.tfcustom =(enTimeFrames)timeFrameValue(inpTimeFrameCustom); glo.indiTimeFrame = (inpTimeFrame!=tf_cus) ? (enTimeFrames)timeFrameValue(inpTimeFrame) : (enTimeFrames)inpTimeFrameCustom; IndicatorSetString(INDICATOR_SHORTNAME,timeFrameToString(glo.indiTimeFrame)+" Mama Fama"); 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[]) { glo.lim = fmin(rates_total-prev_calculated+1,rates_total-1); cnt[0] = glo.lim; if (glo.indiTimeFrame!=_Period) { glo.lim = (int)fmax(glo.lim,fmin(rates_total-1,_mtfCall(8,0)*glo.indiTimeFrame/_Period)); if (cMa1[glo.lim]==-1) iCleanPoint(glo.lim,rates_total,ma1Da,ma1Db); if (cMa1[glo.lim]==-1) iCleanPoint(glo.lim,rates_total,ma2Da,ma2Db); for(int i=glo.lim; i>=0 && !_StopFlag; i--) { int y = iBarShift(_Symbol,glo.indiTimeFrame,time[i]); ma1[i] = _mtfCall(0,y); ma2[i] = _mtfCall(3,y); cMa1[i] = _mtfCall(6,y); cMa2[i] = _mtfCall(7,y); // // // if (!Interpolate || (i>0 && y==iBarShift(_Symbol,glo.indiTimeFrame,time[i-1]))) continue; #define _interpolate(buff) buff[i+k] = buff[i]+(buff[i+n]-buff[i])*k/n int n,k; glo.btime = iTime(_Symbol,glo.indiTimeFrame,y); for(n = 1; (i+n)= glo.btime; n++) continue; for(k = 1; k=0 && !_StopFlag; i--) { if (cMa1[i]==-1) iPlotPoint(i,rates_total,ma1Da,ma1Db,ma1); else ma1Da[i] = ma1Db[i] = EMPTY_VALUE; if (cMa2[i]==-1) iPlotPoint(i,rates_total,ma2Da,ma2Db,ma2); else ma2Da[i] = ma2Db[i] = EMPTY_VALUE; } return(rates_total); } // // // struct sWrkStruct { double _prc,_smth,_detr,_per,_pha,_Q1,_I1,_JI,_JQ,_Q2,_I2,_Re,_Im,_sa; }; static sWrkStruct wrk[]; static int wrkSize = -1; if (wrkSize<=rates_total) wrkSize = ArrayResize(wrk,rates_total+500,2000); // // // if (cMa1[glo.lim]==-1) iCleanPoint(glo.lim,rates_total,ma1Da,ma1Db); if (cMa1[glo.lim]==-1) iCleanPoint(glo.lim,rates_total,ma2Da,ma2Db); for (int i=glo.lim, r=rates_total-i-1; i>=0 && !_StopFlag; i--, r++) { #define rad2degree (180.0/M_PI) #define calcComp(_ind) (r>6 ?(0.0962*wrk[r]._ind+0.5769*wrk[r-2]._ind-0.5769*wrk[r-4]._ind-0.0962*wrk[r-6]._ind) *(0.075*wrk[r-1]._per+0.54) : wrk[r]._ind) wrk[r]._prc = iGetPrice(inpPrice,open,high,low,close,i,rates_total); wrk[r]._smth = (r>3) ? (4.0*wrk[r]._prc+3.0*wrk[r-1]._prc+2.0*wrk[r-2]._prc+wrk[r-3]._prc)/10.0 : wrk[r]._prc; wrk[r]._detr = calcComp(_smth); wrk[r]._Q1 = calcComp(_detr); wrk[r]._I1 = (r>2) ? wrk[r-3]._detr : wrk[r]._detr; wrk[r]._JI = calcComp(_I1); wrk[r]._JQ = calcComp(_Q1); // // // wrk[r]._I2 = (r==0) ? wrk[r]._I1 : 0.2*(wrk[r]._I1-wrk[r]._JQ) + 0.8*wrk[r-1]._I2; wrk[r]._Q2 = (r==0) ? wrk[r]._Q1 : 0.2*(wrk[r]._Q1+wrk[r]._JI) + 0.8*wrk[r-1]._Q2; wrk[r]._Re = (r==0) ? wrk[r]._I2 : 0.2*(wrk[r]._I2*wrk[r-1]._I2 + wrk[r]._Q2*wrk[r-1]._Q2) + 0.8*wrk[r-1]._Re; wrk[r]._Im = (r==0) ? wrk[r]._I2 : 0.2*(wrk[r]._I2*wrk[r-1]._Q2 - wrk[r]._Q2*wrk[r-1]._I2) + 0.8*wrk[r-1]._Im; if(wrk[r]._Re!=0 && wrk[r]._Im!=0) wrk[r]._per = 360.0/(MathArctan(wrk[r]._Im/wrk[r]._Re)*rad2degree); wrk[r]._per = (r==0) ? wrk[r]._per : fmin(wrk[r]._per,1.50*wrk[r-1]._per); wrk[r]._per = (r==0) ? wrk[r]._per : fmax(wrk[r]._per,0.67*wrk[r-1]._per); wrk[r]._per = fmin(fmax(wrk[r]._per,6),50); wrk[r]._per = (r==0) ? wrk[r]._per : 0.2*wrk[r]._per+0.8*wrk[r-1]._per; if(wrk[r]._I1!=0) wrk[r]._pha = MathArctan(wrk[r]._Q1/wrk[r]._I1)*rad2degree; glo.dphase = (r==0) ? 0 : fmax(wrk[r-1]._pha-wrk[r]._pha,1); glo.alp = (glo.dphase!=0) ? fmax(fmin(inpFastLimit/glo.dphase,inpFastLimit),inpSlowLimit) : 1; wrk[r]._sa = (r>0) ? wrk[r-1]._sa+glo.alpSmth*(glo.alp-wrk[r-1]._sa) : 0; ma1[i] = (r==0) ? wrk[r]._prc : wrk[r]._sa*wrk[r]._prc + (1.0- wrk[r]._sa)*ma1[i+1]; //MAMA ma2[i] = (r==0) ? wrk[r]._prc : 0.5*wrk[r]._sa*ma1[i] + (1.0-0.5*wrk[r]._sa)*ma2[i+1]; //FAMA cMa1[i] = (r>0) ? (ma1[i]>ma2[i]) ? 1 : (ma1[i] double iGetPrice(int tprice, T& open[], T& high[], T& low[], T& close[], int i, int bars) { if (tprice>=pr_haclose) { struct sHaStruct { double open; double high; double low; double close; }; static sHaStruct m_array[]; static int m_arraySize = -1; if (m_arraySize0) ? (m_array[r-1].open + m_array[r-1].close)/2.0 : (open[i]+close[i])/2;; double haClose = (open[i]+high[i]+low[i]+close[i]) / 4.0; #define _prHABF(_prtype) (_prtype>=pr_habclose && _prtype<=pr_habtbiased2) if (_prHABF(tprice)) if (high[i]!=low[i]) haClose = (open[i]+close[i])/2.0+(((close[i]-open[i])/(high[i]-low[i]))*MathAbs((close[i]-open[i])/2.0)); else haClose = (open[i]+close[i])/2.0; #undef _prHABF double haHigh = fmax(high[i], fmax(haOpen,haClose)); double haLow = fmin(low[i] , fmin(haOpen,haClose)); // // // if(haOpenhaOpen) return((haHigh+haClose)/2.0); else return((haLow+haClose)/2.0); case pr_hatbiased2: case pr_habtbiased2: 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]=bars-3) return; if ((second[i] != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE)) second[i+1] = EMPTY_VALUE; else if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE)) first[i+1] = EMPTY_VALUE; } void iPlotPoint(int i, int bars,double& first[],double& second[],double& from[]) { if (i>=bars-2) return; if (first[i+1] == EMPTY_VALUE) if (first[i+2] == EMPTY_VALUE) { first[i] = from[i]; first[i+1] = from[i+1]; second[i] = EMPTY_VALUE; } else { second[i] = from[i]; second[i+1] = from[i+1]; first[i] = EMPTY_VALUE; } else { first[i] = from[i]; second[i] = EMPTY_VALUE; } } //------------------------------------------------------------------- // //------------------------------------------------------------------- string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"}; int iTfTable[] = {1,5,15,30,60,240,1440,10080,43200}; string timeFrameToString(int tf) { for (int i=ArraySize(iTfTable)-1; i>=0; i--) if (tf==iTfTable[i]) return(sTfTable[i]); return(""); } int timeFrameValue(int _tf) { int add = (_tf>=0) ? 0 : fabs(_tf); if (add != 0) _tf = _Period; int size = ArraySize(iTfTable); int i =0; for (;i