//+------------------------------------------------------------------+ //| TmaTrue.mq4 | //+------------------------------------------------------------------+ #property copyright "Copyright © 2010, zznbrm" //---- indicator settings #property indicator_chart_window #property indicator_buffers 3 #property indicator_color1 CLR_NONE #property indicator_color2 Maroon #property indicator_color3 Maroon #property indicator_width1 1 #property indicator_width2 1 #property indicator_width3 1 #property indicator_style1 STYLE_SOLID #property indicator_style2 STYLE_SOLID #property indicator_style3 STYLE_SOLID //---- input parameters extern int eintTimeframe = 0; extern int eintHalfLength = 56; extern double edblAtrMultiplier = 3.0; extern int eintAtrPeriod = 100; extern int eintBarsToProcess = 0; extern bool eblnAlerts = false; extern color gc_Mid = CLR_NONE; extern color gc_Upper = DarkGreen; extern color gc_Lower = Gold; //---- indicator buffers double gadblMid[]; double gadblUpper[]; double gadblLower[]; int gintTF = 0; datetime gdtLastAlert = 0; int gi_PipsDecimal; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { if ( eintTimeframe == 0 ) gintTF = Period(); else gintTF = eintTimeframe; gdtLastAlert = 0; IndicatorBuffers( 3 ); IndicatorDigits( 5 ); SetIndexBuffer( 0, gadblMid ); SetIndexLabel( 0, "TMA Mid" ); SetIndexBuffer( 1, gadblUpper ); SetIndexLabel( 1, "TMA Upper" ); SetIndexBuffer( 2, gadblLower ); SetIndexLabel( 2, "TMA Lower" ); //---- name for DataWindow and indicator subwindow label IndicatorShortName( "TmaTrue(" + eintHalfLength + ",M" + gintTF + ")" ); gi_PipsDecimal = Get_Pips_Decimal(); return( 0 ); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { ObjectDelete("!Mid"); ObjectDelete("!Upp"); ObjectDelete("!Low"); ObjectDelete("!Range"); return( 0 ); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { int counted_bars = IndicatorCounted(); if (counted_bars < 0) return (-1); if (counted_bars > 0) counted_bars--; int intLimit = Bars - counted_bars; double dblTma, dblRange; int intBarShift; if ( eintBarsToProcess > 0 && intLimit > eintBarsToProcess ) intLimit = eintBarsToProcess; for( int inx = intLimit; inx >= 0; inx-- ) { if ( gintTF == Period() ) { dblRange = iATR( Symbol(), gintTF, eintAtrPeriod, inx+10 ); dblTma = calcTma( eintHalfLength, inx ); } else { intBarShift = iBarShift( Symbol(), gintTF, Time[inx] ); dblRange = iATR( Symbol(), gintTF, eintAtrPeriod, intBarShift+10 ); dblTma = calcTmaMtf( gintTF, eintHalfLength, intBarShift, Close[inx] ); } gadblMid[inx] = dblTma; gadblUpper[inx] = dblTma + ( edblAtrMultiplier * dblRange ); gadblLower[inx] = dblTma - ( edblAtrMultiplier * dblRange ); } if ( eblnAlerts && gdtLastAlert < Time[1] ) { if ( ( Close[1] > gadblUpper[1] ) && ( Close[2] < gadblUpper[2] ) ) { Alert( Symbol(), " - M", Period(), " - ", TimeToStr( Time[1], TIME_DATE|TIME_MINUTES ), " closed above upper TMA." ); gdtLastAlert = Time[1]; } if ( ( Close[1] < gadblLower[1] ) && ( Close[2] > gadblLower[2] ) ) { Alert( Symbol(), " - M", Period(), " - ", TimeToStr( Time[1], TIME_DATE|TIME_MINUTES ), " closed below lower TMA." ); gdtLastAlert = Time[1]; } } // Calculate the distances between bid & bands double ld_Dist_Pts, ld_Dist_Pips; // Distance to mid ld_Dist_Pts = MathAbs(Bid - gadblMid[0]); ld_Dist_Pips = Convert_2_Pips(ld_Dist_Pts); ObjectCreate("!Mid",OBJ_TEXT,0,0,0); ObjectSet("!Mid",OBJPROP_TIME1,Time[0]+(3*Period()*60)); ObjectSet("!Mid",OBJPROP_PRICE1,gadblMid[0]); ObjectSetText("!Mid",DoubleToStr(ld_Dist_Pips,gi_PipsDecimal),8,"Arial",gc_Mid); // Distance to upper ld_Dist_Pts = MathAbs(Bid - gadblUpper[0]); ld_Dist_Pips = Convert_2_Pips(ld_Dist_Pts); ObjectCreate("!Upp",OBJ_TEXT,0,0,0); ObjectSet("!Upp",OBJPROP_TIME1,Time[0]+(3*Period()*60)); ObjectSet("!Upp",OBJPROP_PRICE1,gadblUpper[0]); ObjectSetText("!Upp",DoubleToStr(ld_Dist_Pips,gi_PipsDecimal),8,"Arial",gc_Upper); // Distance to lower ld_Dist_Pts = MathAbs(Bid - gadblLower[0]); ld_Dist_Pips = Convert_2_Pips(ld_Dist_Pts); ObjectCreate("!Low",OBJ_TEXT,0,0,0); ObjectSet("!Low",OBJPROP_TIME1,Time[0]+(3*Period()*60)); ObjectSet("!Low",OBJPROP_PRICE1,gadblLower[0]); ObjectSetText("!Low",DoubleToStr(ld_Dist_Pips,gi_PipsDecimal),8,"Arial",gc_Lower); // Display the total range of the bands ld_Dist_Pts = MathAbs(gadblUpper[0] - gadblLower[0]); ld_Dist_Pips = Convert_2_Pips(ld_Dist_Pts); Object_Create("!Range",5,5,"TMA Range: "+DoubleToStr(ld_Dist_Pips,gi_PipsDecimal),10,"Arial",gc_Lower); return( 0 ); } //+------------------------------------------------------------------+ //| calcTma() | //+------------------------------------------------------------------+ double calcTma( int intHalfLength, int intShift ) { double dblResult, dblSum, dblSumW; int inx, jnx; dblSumW = intHalfLength + 1; dblSum = dblSumW * Close[intShift]; jnx = intHalfLength; for ( inx = 1, jnx = intHalfLength; inx <= intHalfLength; inx++, jnx-- ) { dblSumW += jnx; dblSum += ( jnx * Close[intShift+inx] ); } dblResult = dblSum / dblSumW; return( dblResult ); } //+------------------------------------------------------------------+ //| calcTmaMtf() | //+------------------------------------------------------------------+ double calcTmaMtf( int intTF, int intHalfLength, int intUpperTfShift, double dblClose ) { double dblResult, dblSum, dblSumW; int inx, jnx; // This is the current bar dblSumW = intHalfLength + 1; dblSum = dblSumW * dblClose; jnx = intHalfLength; for ( inx = 1, jnx = intHalfLength; inx <= intHalfLength; inx++, jnx-- ) { dblSumW += jnx; dblSum += ( jnx * iClose( Symbol(), intTF, intUpperTfShift+inx ) ); } dblResult = dblSum / dblSumW; return( dblResult ); } //+------------------------------------------------------------------+ //| create screen objects | //+------------------------------------------------------------------+ void Object_Create(string ps_name,int pi_x,int pi_y,string ps_text=" ",int pi_size=12, string ps_font="Arial",color pc_colour=CLR_NONE) { //---- // if (colour==CLR_NONE) colour=xcBackground; ObjectCreate(ps_name,OBJ_LABEL,0,0,0,0,0); ObjectSet(ps_name,OBJPROP_CORNER,3); ObjectSet(ps_name,OBJPROP_COLOR,pc_colour); ObjectSet(ps_name,OBJPROP_XDISTANCE,pi_x); ObjectSet(ps_name,OBJPROP_YDISTANCE,pi_y); ObjectSetText(ps_name,ps_text,pi_size,ps_font,pc_colour); //---- } //+------------------------------------------------------------------+ //| convert to points | //+------------------------------------------------------------------+ double Convert_2_Pts(double pd_Pips) { //---- int pd_Points=pd_Pips; // Default - no conversion if (Digits == 5 || (Digits == 3 && StringFind(Symbol(), "JPY") != -1)) pd_Points=pd_Pips*10; if (Digits == 6 || (Digits == 4 && StringFind(Symbol(), "JPY") != -1)) pd_Points=pd_Pips*100; //---- return(pd_Points); } //+------------------------------------------------------------------+ //| convert to pips | //+------------------------------------------------------------------+ double Convert_2_Pips(double pd_Points) { //---- double pd_Pips=pd_Points/Point; // Default - no conversion if (Digits == 5 || (Digits == 3 && StringFind(Symbol(), "JPY") != -1)) { pd_Pips=pd_Points/Point/10; } if (Digits == 6 || (Digits == 4 && StringFind(Symbol(), "JPY") != -1)) { pd_Pips=pd_Points/Point/100; } //---- return(pd_Pips); } //+------------------------------------------------------------------+ //| get the pips decimal places | //+------------------------------------------------------------------+ int Get_Pips_Decimal() { //---- int pi_PipsDecimal = 0; // Default - no decimals if (Digits == 5 || (Digits == 3 && StringFind(Symbol(), "JPY") != -1)) { pi_PipsDecimal = 1; } if (Digits == 6 || (Digits == 4 && StringFind(Symbol(), "JPY") != -1)) { pi_PipsDecimal = 2; } //---- return(pi_PipsDecimal); }