//+------------------------------------------------------------------+ //| RAVI FX Fisher.mq4 | //| Copyright © 2005, Luis Guilherme Damiani | //| http://www.damianifx.com.br | //+------------------------------------------------------------------+ //------------------------------------------------------------------ #property copyright "www.forex-station.com" #property link "www.forex-station.com" //------------------------------------------------------------------ #property indicator_separate_window #property indicator_buffers 6 #property indicator_label1 "Ravi Fisher up" #property indicator_type1 DRAW_HISTOGRAM #property indicator_color1 clrLimeGreen #property indicator_width1 3 #property indicator_label2 "Ravi fisher down" #property indicator_type2 DRAW_HISTOGRAM #property indicator_color2 clrRed #property indicator_width2 3 #property indicator_label3 "Ravi fisher neutral" #property indicator_type3 DRAW_HISTOGRAM #property indicator_color3 clrGoldenrod #property indicator_width3 3 #property indicator_label4 "Ravi fisher" #property indicator_type4 DRAW_LINE #property indicator_color4 clrDarkGray #property indicator_width4 3 #property indicator_label5 "Ravi fisher lower trigger" #property indicator_type5 DRAW_LINE #property indicator_color5 clrMediumVioletRed #property indicator_width5 1 #property indicator_label6 "Ravi fisher upper trigger" #property indicator_type6 DRAW_LINE #property indicator_color6 clrMediumVioletRed #property indicator_width6 1 #property strict // // // input double inpFastPeriod = 4.0; // Ravi fast period input double inpSlowPeriod = 49.0; // Ravi slow period enum enMaTypes { ma_sma, // Simple moving average ma_ema, // Exponential moving average ma_smma, // Smoothed MA ma_lwma, // Linear weighted MA }; input enMaTypes maType = ma_ema; // Ma type 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 maPrice = pr_close; // Ma price input double TriggerUp = 0.07; // Upper trigger level input double TriggerDn = -0.07; // Lower trigger level input int VolPeriod = 15; // Volatility period input int VolSmooth = 10; // Volatility smoothing input bool alertsOn = true; // Alerts? input bool alertsOnCurrent = false; // Alerts open bar? input bool alertsMessage = true; // Alerts message? input bool alertsSound = false; // Alerts sound? input bool alertsNotify = false; // Alerts notification? input bool alertsEmail = false; // Alerts email? input string soundFile = "alert2.wav";// Alerts sound file double huu[],hdd[],hnn[],val[],dnVal[],upVal[],valc[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { IndicatorBuffers(7); SetIndexBuffer(0,huu, INDICATOR_DATA); SetIndexBuffer(1,hdd, INDICATOR_DATA); SetIndexBuffer(2,hnn, INDICATOR_DATA); SetIndexBuffer(3,val, INDICATOR_DATA); SetIndexBuffer(4,dnVal,INDICATOR_DATA); SetIndexBuffer(5,upVal,INDICATOR_DATA); SetIndexBuffer(6,valc); IndicatorSetString(INDICATOR_SHORTNAME,"VA Ravi Fisher of "+getAvgName(maType)+" ("+DoubleToStr(inpFastPeriod,2)+","+DoubleToStr(inpSlowPeriod)+")"); return(INIT_SUCCEEDED); } void OnDeinit(const int reason){ } //+------------------------------------------------------------------+ //| 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[]) { int limit = fmin(rates_total-prev_calculated+1,rates_total-1); // // // struct sWork { double sum; double prc; }; static sWork wrk[]; static int wrkSize=-1; if (wrkSize=0;i--,r++) { wrk[r].prc = getPrice(maPrice,open,close,high,low,i,rates_total); wrk[r].sum = 0; for (int k=0; k=0; k++) wrk[r].sum += fabs(wrk[r-k].prc-wrk[r-k-1].prc); double avg = wrk[r].sum; for (int k=1; k=0; k++) avg += wrk[r-k].sum; avg /= VolSmooth; // // // double fastPer = inpFastPeriod; double slowPer = inpSlowPeriod; if (avg!=0 && wrk[r].sum!=0) { fastPer = fmax(inpFastPeriod/(wrk[r].sum/avg),inpFastPeriod/2.0); slowPer = fmax(inpSlowPeriod/(wrk[r].sum/avg),inpSlowPeriod/2.0); } double maf = iCustomMa(maType,wrk[r].prc,fastPer,i,rates_total,0); double mas = iCustomMa(maType,wrk[r].prc,slowPer,i,rates_total,1); double atf = iATR(NULL,0,(int)fastPer,i); double ats = iATR(NULL,0,(int)slowPer,i); double ma = (mas!=0 && ats!=0) ? 100 * ((maf-mas)*atf)/mas/ats : 0; double fish = (exp(2*ma)-1)/(exp(2*ma)+1); val[i] = fish; upVal[i] = TriggerUp; dnVal[i] = TriggerDn; valc[i] = (iupVal[i]) ? 1 : (val[i]dnVal[i]) ? 0 : valc[i+1] : 0; huu[i] = (valc[i] == 1) ? val[i] : EMPTY_VALUE; hdd[i] = (valc[i] ==-1) ? val[i] : EMPTY_VALUE; hnn[i] = (valc[i] == 0) ? val[i] : EMPTY_VALUE; } if (alertsOn) { int whichBar = 1; if (alertsOnCurrent) whichBar = 0; if (valc[whichBar] != valc[whichBar+1]) { if (valc[whichBar] == 1) doAlert(whichBar,"up"); if (valc[whichBar] ==-1) doAlert(whichBar,"down"); if (valc[whichBar] == 0 && valc[whichBar+1]== 1) doAlert(whichBar,"back from up now neutral"); if (valc[whichBar] ==-0 && valc[whichBar+1]==-1) doAlert(whichBar,"back from down now neutral"); } } return(rates_total); } //------------------------------------------------------------------ // //------------------------------------------------------------------ string getAvgName(int method) { switch(method) { case ma_ema: return("EMA"); case ma_lwma: return("LWMA"); case ma_sma: return("SMA"); case ma_smma: return("SMMA"); } return(""); } //------------------------------------------------------------------ // //------------------------------------------------------------------ #define _maInstances 2 #define _maWorkBufferx1 1*_maInstances #define _maWorkBufferx2 2*_maInstances #define _maWorkBufferx3 3*_maInstances double iCustomMa(int mode, double price, double length, int r, int bars, int instanceNo=0) { r = bars-r-1; switch (mode) { case ma_sma : return(iSma(price,(int)ceil(length),r,bars,instanceNo)); case ma_ema : return(iEma(price,length,r,bars,instanceNo)); case ma_smma : return(iSmma(price,(int)ceil(length),r,bars,instanceNo)); case ma_lwma : return(iLwma(price,(int)ceil(length),r,bars,instanceNo)); default : return(price); } } // // // // // double workSma[][_maWorkBufferx1]; double iSma(double price, int period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workSma,0)!= _bars) ArrayResize(workSma,_bars); workSma[r][instanceNo+0] = price; double avg = price; int k=1; for(; k=0; k++) avg += workSma[r-k][instanceNo+0]; return(avg/(double)k); } // // // // // double workEma[][_maWorkBufferx1]; double iEma(double price, double period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workEma,0)!= _bars) ArrayResize(workEma,_bars); workEma[r][instanceNo] = price; if (r>0 && period>1) workEma[r][instanceNo] = workEma[r-1][instanceNo]+(2.0/(1.0+period))*(price-workEma[r-1][instanceNo]); return(workEma[r][instanceNo]); } // // // // // double workSmma[][_maWorkBufferx1]; double iSmma(double price, double period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workSmma,0)!= _bars) ArrayResize(workSmma,_bars); workSmma[r][instanceNo] = price; if (r>1 && period>1) workSmma[r][instanceNo] = workSmma[r-1][instanceNo]+(price-workSmma[r-1][instanceNo])/period; return(workSmma[r][instanceNo]); } // // // // // double workLwma[][_maWorkBufferx1]; double iLwma(double price, double period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workLwma,0)!= _bars) ArrayResize(workLwma,_bars); workLwma[r][instanceNo] = price; if (period<=1) return(price); double sumw = period; double sum = period*price; for(int k=1; k=0; k++) { double weight = period-k; sumw += weight; sum += weight*workLwma[r-k][instanceNo]; } return(sum/sumw); } //------------------------------------------------------------------ // //------------------------------------------------------------------ #define _prHABF(_prtype) (_prtype>=pr_habclose && _prtype<=pr_habtbiased2) #define _priceInstances 1 #define _priceInstancesSize 4 double workHa[][_priceInstances*_priceInstancesSize]; double getPrice(int tprice, const double& open[], const double& close[], const double& high[], const double& low[], int i, int bars, int instanceNo=0) { if (tprice>=pr_haclose) { if (ArrayRange(workHa,0)!= bars) ArrayResize(workHa,bars); instanceNo*=_priceInstancesSize; int r = bars-i-1; // // // // // double haOpen = (r>0) ? (workHa[r-1][instanceNo+2] + workHa[r-1][instanceNo+3])/2.0 : (open[i]+close[i])/2;; double haClose = (open[i]+high[i]+low[i]+close[i]) / 4.0; if (_prHABF(tprice)) if (high[i]!=low[i]) haClose = (open[i]+close[i])/2.0+(((close[i]-open[i])/(high[i]-low[i]))*fabs((close[i]-open[i])/2.0)); else haClose = (open[i]+close[i])/2.0; 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]=0; i--) if (tf==iTfTable[i]) return(sTfTable[i]); return(""); }