//+------------------------------------------------------------------+ //| Uni Cross Histo.mq4 | //| Copyright 2015, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //| disclaimer : centered triangular moving average | //| recalculates last half cycle bars, and thus those | //| bars are subject of changing | //| | //+------------------------------------------------------------------+ #property copyright "www.forex-tsd.com" #property link "www.forex-tsd.com" #property indicator_separate_window #property indicator_buffers 2 #property indicator_color1 Blue #property indicator_color2 Red #property indicator_width1 4 #property indicator_width2 4 #property indicator_minimum 0 #property indicator_maximum 1 // // // // // extern string TimeFrame = "Current time frame"; extern int T3Period = 14; extern int T3Price = PRICE_CLOSE; extern double T3Hot = 0.618; extern bool T3Original = true; extern int TMAHalfCycle = 5; extern int TMAPrice = PRICE_CLOSE; extern bool alertsOn = false; extern bool alertsOnCurrent = true; extern bool alertsMessage = true; extern bool alertsSound = false; extern bool alertsEmail = false; extern string soundfile = "alert2.wav"; // // // // // double UpH[]; double DnH[]; double trend[]; // // // // // string indicatorFileName; bool returnBars; bool calculateValue; int timeFrame; //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // int init() { IndicatorBuffers(3); SetIndexBuffer(0,UpH); SetIndexStyle(0,DRAW_HISTOGRAM); SetIndexBuffer(1,DnH); SetIndexStyle(1,DRAW_HISTOGRAM); SetIndexBuffer(2,trend); // // // // // indicatorFileName = WindowExpertName(); calculateValue = TimeFrame=="calculateValue"; if (calculateValue) { return(0); } returnBars = TimeFrame=="returnBars"; if (returnBars) { return(0); } timeFrame = stringToTimeFrame(TimeFrame); // // // // // IndicatorShortName(timeFrameToString(timeFrame)+" Uni Cross ("+T3Period+","+TMAHalfCycle+")"); return(0); } int deinit() { return(0); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // int start() { int i,j,k,counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; int limit=MathMax(MathMin(Bars-counted_bars,Bars-1),2*TMAHalfCycle); if (returnBars) { UpH[0] = MathMin(limit+1,Bars-1); return(0); } // // // // // if (calculateValue || timeFrame == Period()) { for (i=limit; i>=0; i--) { double sum = (TMAHalfCycle+1)*iMA(NULL,0,1,0,MODE_SMA,TMAPrice,i); double sumw = (TMAHalfCycle+1); for (j=1, k=TMAHalfCycle; j<=TMAHalfCycle; j++, k--) { sum += k*iMA(NULL,0,1,0,MODE_SMA,TMAPrice,i+j); sumw += k; if (j<=i) { sum += k*iMA(NULL,0,1,0,MODE_SMA,TMAPrice,i-j); sumw += k; } } double tma = sum/sumw; double t3 = iT3(iMA(NULL,0,1,0,MODE_SMA,T3Price,i),T3Period,T3Hot,T3Original,i); // // // // // UpH[i] = EMPTY_VALUE; DnH[i] = EMPTY_VALUE; trend[i] = trend[i+1]; if (t3tma) trend[i] = -1; if (trend[i] == 1) UpH[i] = 1; if (trend[i] ==-1) DnH[i] = 1; } manageAlerts(); return(0); } // // // // // limit = MathMax(limit,MathMin(Bars-1,iCustom(NULL,timeFrame,indicatorFileName,"returnBars",0,0)*timeFrame/Period())); for (i=limit; i>=0; i--) { int y = iBarShift(NULL,timeFrame,Time[i]); trend[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",T3Period,T3Price,T3Hot,T3Original,TMAHalfCycle,TMAPrice,2,y); UpH[i] = EMPTY_VALUE; DnH[i] = EMPTY_VALUE; if (trend[i] == 1) UpH[i] = 1; if (trend[i] ==-1) DnH[i] = 1; } manageAlerts(); return(0); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // double workT3[][6]; double workT3Coeffs[][6]; #define _period 0 #define _c1 1 #define _c2 2 #define _c3 3 #define _c4 4 #define _alpha 5 // // // // // double iT3(double price, double period, double hot, bool original, int i, int instanceNo=0) { if (ArrayRange(workT3,0) != Bars) ArrayResize(workT3,Bars); if (ArrayRange(workT3Coeffs,0) < (instanceNo+1)) ArrayResize(workT3Coeffs,instanceNo+1); if (workT3Coeffs[instanceNo][_period] != period) { workT3Coeffs[instanceNo][_period] = period; double a = hot; workT3Coeffs[instanceNo][_c1] = -a*a*a; workT3Coeffs[instanceNo][_c2] = 3*a*a+3*a*a*a; workT3Coeffs[instanceNo][_c3] = -6*a*a-3*a-3*a*a*a; workT3Coeffs[instanceNo][_c4] = 1+3*a+a*a*a+3*a*a; if (original) workT3Coeffs[instanceNo][_alpha] = 2.0/(1.0 + period); else workT3Coeffs[instanceNo][_alpha] = 2.0/(2.0 + (period-1.0)/2.0); } // // // // // int buffer = instanceNo*6; int r = Bars-i-1; if (r == 0) { workT3[r][0+buffer] = price; workT3[r][1+buffer] = price; workT3[r][2+buffer] = price; workT3[r][3+buffer] = price; workT3[r][4+buffer] = price; workT3[r][5+buffer] = price; } else { workT3[r][0+buffer] = workT3[r-1][0+buffer]+workT3Coeffs[instanceNo][_alpha]*(price -workT3[r-1][0+buffer]); workT3[r][1+buffer] = workT3[r-1][1+buffer]+workT3Coeffs[instanceNo][_alpha]*(workT3[r][0+buffer]-workT3[r-1][1+buffer]); workT3[r][2+buffer] = workT3[r-1][2+buffer]+workT3Coeffs[instanceNo][_alpha]*(workT3[r][1+buffer]-workT3[r-1][2+buffer]); workT3[r][3+buffer] = workT3[r-1][3+buffer]+workT3Coeffs[instanceNo][_alpha]*(workT3[r][2+buffer]-workT3[r-1][3+buffer]); workT3[r][4+buffer] = workT3[r-1][4+buffer]+workT3Coeffs[instanceNo][_alpha]*(workT3[r][3+buffer]-workT3[r-1][4+buffer]); workT3[r][5+buffer] = workT3[r-1][5+buffer]+workT3Coeffs[instanceNo][_alpha]*(workT3[r][4+buffer]-workT3[r-1][5+buffer]); } // // // // // return(workT3Coeffs[instanceNo][_c1]*workT3[r][5+buffer] + workT3Coeffs[instanceNo][_c2]*workT3[r][4+buffer] + workT3Coeffs[instanceNo][_c3]*workT3[r][3+buffer] + workT3Coeffs[instanceNo][_c4]*workT3[r][2+buffer]); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // void manageAlerts() { if (!calculateValue && alertsOn) { if (alertsOnCurrent) int whichBar = 0; else whichBar = 1; whichBar = iBarShift(NULL,0,iTime(NULL,timeFrame,whichBar)); if (trend[whichBar] != trend[whichBar+1]) { if (trend[whichBar] == 1) doAlert(whichBar,"up"); if (trend[whichBar] == -1) doAlert(whichBar,"down"); } } } // // // // // void doAlert(int forBar, string doWhat) { static string previousAlert="nothing"; static datetime previousTime; string message; if (previousAlert != doWhat || previousTime != Time[forBar]) { previousAlert = doWhat; previousTime = Time[forBar]; // // // // // message = StringConcatenate(Symbol()," ",timeFrameToString(timeFrame)," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," Uni cross changed to ",doWhat); if (alertsMessage) Alert(message); if (alertsEmail) SendMail(StringConcatenate(Symbol()," ",timeFrameToString(timeFrame)," Uni cross "),message); if (alertsSound) PlaySound("alert2.wav"); } } //+------------------------------------------------------------------- //| //+------------------------------------------------------------------- // // // // // string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"}; int iTfTable[] = {1,5,15,30,60,240,1440,10080,43200}; // // // // // int stringToTimeFrame(string tfs) { tfs = stringUpperCase(tfs); for (int i=ArraySize(iTfTable)-1; i>=0; i--) if (tfs==sTfTable[i] || tfs==""+iTfTable[i]) return(MathMax(iTfTable[i],Period())); return(Period()); } // // // // // string timeFrameToString(int tf) { for (int i=ArraySize(iTfTable)-1; i>=0; i--) if (tf==iTfTable[i]) return(sTfTable[i]); return(""); } // // // // // string stringUpperCase(string str) { string s = str; for (int length=StringLen(str)-1; length>=0; length--) { int cha = StringGetChar(s, length); if((cha > 96 && cha < 123) || (cha > 223 && cha < 256)) s = StringSetChar(s, length, cha - 32); else if(cha > -33 && cha < 0) s = StringSetChar(s, length, cha + 224); } return(s); }