Auto Fibo Retracement Indicator

Auto Fibo Retracement

This MetaTrader 4 indicator automatically draws a Fibonacci retracement on your chart given a set of parameters. The indicator can also be set to highlight the retraced and un-retraced area on the chart.

Download

Product Description

The Auto Fibo Retracement indicator draws a Fibonacci retracement and optionally, the retraced and/or unretraced zone automatically on your chart. The retracement and un/retraced zones can update automatically during a live candle (default setting) or they can wait for the candle close. The retracement and corresponding zones will update automatically when you switch time frames and even symbols.

The default parameters work great, but are limited to the visible bars on the chart (which may be too many or too little). Make sure to experiment with your own parameters. In a nutshell, the calculation parameters can be tweaked to give you a retracement for any area on the chart. You could even isolate the current bar if you wanted to (maybe handy for a scalper)!

Why stop at one? You can add more instances with different parameter sets for multiple retracements.

 

PARAMETERS AND USAGE

  • FiboColor [DEFAULT: Yellow] the color of the Fibonacci retracement chart object. For information on valid values, please refer to the mql4 documentation on color type and web colors.
  • FiboWidth [DEFAULT: 1]  – the width of the retracement lines. Valid values are 1 to 5 (integer).
  • FiboStyle [DEFAULT: 0 (STYLE_SOLID)] – the style of the retracement lines. Valid values are 0 to 4 (integer) and the numbers correspond to line styles as follows:
    0 STYLE_SOLID The pen is solid
    1 STYLE_DASH The pen is dashed
    2 STYLE_DOT The pen is dotted
    3 STYLE_DASHDOT The pen has alternating dashes and dots
    4 STYLE_DASHDOTDOT The pen has alternating dashes and double dots
  • FiboLevels [DEFAULT: “0.0, 0.236, 0.382, 0.50, 0.618, 0.786, 1.0″] – the retracement levels to be calculated in the chart object. This parameter must be entered as a string with the retracement levels in decimal form and separated by commas. Levels greater than 1.0 (or 100%) are OK. However, negative retracement levels won’t work on live fibo retracements because a breach of this level will trigger the object to be redrawn.
  • LookbackBars [DEFAULT: 0] – sets the number of bars to be used in the calculation of the retracement levels. If the parameter is left at 0, the indicator will use the visible bars in the calculation (in a sense, this parameter is disregarded if set to 0). This parameter is affected significantly by BarShift (see next parameter). Valid values are 0 and positive integers.
  • BarShift [DEFAULT: 0] – sets the bar shift to start the calculation. The first bar on the chart is 0. So for example, if BarShift is set to 2, the fibo calculation starts 2 bars back. If this is set to 0, the fibo will update during the live candle (unless WaitForCloseToUpdate is set to true, in which case, BarShift should really be set to 1 or higher).
    An example including LookbackBars is if LookbackBars is set to 100 and BarShift is set to 5. The indicator will begin looking for high/low values 5 bars back (BarShift) and continue looking for another 100 bars (LookbackBars). In other words, the bars in calculation are 5 to 105 (remember that most recent bars have a lower number starting from the current bar which has an index of 0) . Finally, the high, low, and trend of bar 5 to 105 are used to calculate and draw the Fibonacci retracement. It’s also worth noting that if BarShift is set to 0, the number of visible bars on the chart will replace it.
    Valid values are 0 and positive integers.
  • WaitForCloseToUpdate [DEFAULT: false] – this parameter is only used if BarShift is set to 0 and tells the indicator whether to update the retracement and corresponding retraced/unretraced zones during a live candle or wait for the candle to close. Valid values are true/false.
  • ShowRetracedZone [DEFAULT: true] – this parameter tells the indicator whether or not to draw a rectangle in the retracement zone. This zone is drawn from 0.0 to the furthest retraced price. Valid values are true/false.
  • RetracedZoneColor [DEFAULT: Green] – the color of the retracement zone rectangle (if shown). For information on valid values, please refer to the mql4 documentation on color type and web colors.
  • ShowUnretracedZone [DEFAULT: true] – this parameter tells the indicator whether or not to draw a rectangle in the unretraced zone. This zone is drawn from  the furthest retraced price (edge of retracement zone) to 1.0 (100%). Valid values are true/false.
  • UnretracedZoneColor [DEFAULT: Red] – the color of the unretraced zone rectangle (if shown). For information on valid values, please refer to the mql4 documentation on color type and web colors.
  • SpanMode [DEFAULT: 0] – this parameter is only used if one of the above two Show*Zone parameters is set to true. It tells the indicator how to draw the zone rectangle(s) in terms of width. Valid values are 0 to 2 (integer) and correspond to the span as follows:0 – Spans only the zone where the retracement occurred
    1 – Spans the zone (encompasses 0) plus expands up to the shift bar (as defined by BarShift)
    2 – Spans from the shift bar (as defined by BarShift) to the end of the retracement
  • FiboObjPrefix [DEFAULT: “AutoFibo_”] – the prefix for all chart object name created by the indicator. Most people don’t need to change this. This can be used by other indicators, expert advisors, or scripts to find objects created by this indicator. Please note that each indicator instance will derive another prefix from this by appending an id for that instance (e.g. AutoFibo_872874_0).

Feel free to tweak the above parameters as you see fit. However, the indicator should work fine with the default settings and can be simply added to charts after installation. It is perfectly OK to edit the inputs after applying the indicator to a chart from right click->Indicators List (or CTRL + I).

If you are isolating a single bar or two for retracement, the zone rectangle(s) may not draw properly.

When using the default parameter for LookbackBars, the retracement will update (on next tick) if you zoom in/out because it is based on the visible bars on the chart (this number changes on zoom). If this parameter is changed from 0, then the bars in the calculation will be fixed and zoom in/out will not affect the retracement.

You can also automatically generate more than one retracement by adding more instances of the indicator to the chart. Please note that this only makes sense if each instance has different parameters. Otherwise, there will be redundant chart objects using up resources with no additional utility.

Each instance tracks its own objects and only those objects will be removed when it is removed from a chart.

AutoFiboRetracementIndicator.mq4 (Currently Viewing)
//+------------------------------------------------------------------+
//|                                  AutoFiboRetracementIndicator.mq4|                       
//|                                                       Paul Nordin|
//|                                    http://www.tradertools-fx.com |
//+------------------------------------------------------------------+
#property copyright "© 2010, 2014 TradertoolsFX"
#property link      "http://www.tradertools-fx.com"
/*
Copyright (c) 2010, 2014 TradertoolsFX

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

 1. The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.
    
 2. The end-user documentation included with any redistribution, if any, must include the following acknowledgment: 
      "This product includes software and/or derivative works developed by TradertoolsFX (http://www.tradertools-fx.com)"
    The above acknowledgment must reside in the same place and form as other third-party acknowledgments. 
    Alternatively, this acknowledgment may appear in the software itself, in the same form and location as other such third-party acknowledgments.
    
 3. If the source code of the Software is modified, and if this source code is made available to the public or the end-user, then the following terms apply:
      A. The modifications by any author not listed in the copyright above must be sufficiently noted. If the source contains a change log, the modifications should
         be appended to that section in this form:
            v, Date, Revisions by 
               
         If no change log is present, then please comment as you make modifications. For example, if you add a function, you should add something like this:
          * newFunc() 
          * Added by  
          *...
          *
          int newFunc() {...}
               
      B. The new author is permitted, but NOT OBLIGATED, to amend the above copyright as follows:
            Copyright (c) ,  TradertoolsFX, ,  
             For example, if the existing copyright is Copyright (c) 2014 TradertoolsFX, your name is John Doe, and the year is 2014; 
             the copyright may be changed to:
               Copyright (c) 2014, 2016 TradertoolsFX, John Doe

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

If you have any questions about this license, please contact us at http://www.tradertools-fx.com/support/
*/

/*=====Change Log=====
*
* v2.9, March 17, 2014 (NOTE: Still using build 509)
*   -REMOVED Comment
*   -ADDED Parameter group explanations to user inputs
*   -ADDED Option to change how fib is drawn. This was previously based on the visible bars. Now you can specify a lookback and shift parameter. If the lookback is a non-zero positive number, 
*          fibo is drawn based on this number of bars to lookback and shift. This also opens up the option to draw multiple retracements.
*   -ADDED Support for drawing multiple retracements on the same chart
*   -ADDED SpanMode parameter that allows the user to choose how the unretraced zone box is displayed (cover only the zone, zone to shift bar, or the whole fibo area)
*   -ADDED WaitForCloseToUpdate parameter that gives option to only update retracement and unretraced zone on candle close (only applie to live fibos with BarShift >= 1)
*   -ADDED Option to show retraced zone in addition to unretraced zone
*   -CHANGED Retracement levels can now be customized by user per input FiboLevels which takes a comma delimited string. This also removes the limit of only using 0-100% retracement (e.g. 123.6% can be used now)
*            No error checking on this parameter (e.g. valid number) for now. This is the responsibility of user.
*   -Code cleanup/refactoring
*   -Improved code documentation  
*/

#property description "This program comes with ABSOLUTELY NO WARRANTY.\r\nThis is free software, and you are welcome to redistribute it under certain conditions.\r\nFull details of the license can be found in the source file(s) or at http://www.tradertools-fx.com/modified-mit-license"
#property indicator_chart_window

#define MODE_SPAN_ZONE         0
#define MODE_SPAN_ZONETOSHIFT  1
#define MODE_SPAN_ALL          2

//User Parameters
extern string  FiboStyleParamExp = "===Enter parameters for fibonacci below===";
extern color   FiboColor = Yellow;
extern int     FiboWidth = 1;
extern int     FiboStyle = 0;
extern string  FiboLevels = "0.0, 0.236, 0.382, 0.50, 0.618, 0.786, 1.0";//enter as decimal
extern string  FiboCalcParamExp = "===Enter parameters for fibonacci calculation below===";
extern int     LookbackBars = 0;//if 0, uses visible bars
extern int     BarShift = 0;
extern bool    WaitForCloseToUpdate = false;//if true, the retracement and unretraced zone won't update until candle close. Additionally, this only applies to live fibos with BarShift=0 (if > 0, fibo always has to wait for new bar to redraw ...)
extern string  ZoneParamExp = "===Enter retraced/unretraced zone options below===";
extern bool    ShowRetracedZone = true;
extern color   RetracedZoneColor = Green;
extern bool    ShowUnretracedZone = true;
extern color   UnretracedZoneColor = Red;
extern int     SpanMode = 0;//0 spans the actual zone where the retracement occur/1 spans the zone and up to the shift bar/2 spans from the shift bar to the start of the fibo
extern string  OtherParamExp = "===Other parameters===";
extern string  FiboObjPrefix = "AutoFibo_";
//

int objCnt = 0;
double fiboLevel[10];
int nFiboLevels = 0;
double fp1, fp2;

int init() {
   FiboObjPrefix = StringConcatenate( FiboObjPrefix, TimeLocal(), "_" );//give this instance of the indicator a unique id for its chart objects so it doesn't interfere with other instances' objects  
   nFiboLevels = explodeToDouble( ",", FiboLevels, fiboLevel );   
   fibo();
   return(0);
}

int deinit() {
   deleteObjects( FiboObjPrefix, objCnt ); 
   return(0);
}

int start() {
   if ( WaitForCloseToUpdate || BarShift > 0 ) {
      if ( !isNewBar() ) return(0);
   }
   
   fibo();
   
   return(0);
}

/**
* fibo()
* Function to calculate parameters and pass them to drawing functions
*/
void fibo() {
   int shift = BarShift;
   int bar;
   if ( LookbackBars <= 0 ) {
      bar = WindowFirstVisibleBar();
   } else {
      bar = LookbackBars + shift;
   }
     
   int idLow  = iLowest( NULL, 0, MODE_LOW, bar - 1, shift );
   int idHigh = iHighest( NULL, 0, MODE_HIGH, bar - 1, shift );
   
   bool   isDownTrend = (idHigh > idLow);
   double retracementExtent;

   
   datetime tHigh = Time[idHigh];
   datetime tLow = Time[idLow];
   double pHigh = High[idHigh];
   double pLow = Low[idLow];
   
   int iMaxRetraced;
   double pZone1, pZone2, pZone1U, pZone2U;
   bool isLive = (shift <= 1);//retracement only treated as live if shift is 0-1
   if ( isDownTrend ) {
      drawFibo( tHigh, tLow, pHigh, pLow, isLive );
      iMaxRetraced = iHighest( NULL, 0, MODE_HIGH, idLow - 1, shift );
      pZone1 = pLow;
      pZone2 = High[iMaxRetraced];
      pZone1U = pZone2;
      pZone2U = pHigh;
   } else {
      drawFibo( tLow, tHigh, pLow, pHigh, isLive );
      iMaxRetraced = iLowest( NULL, 0, MODE_LOW, idHigh - 1, shift );
      pZone1 = pHigh;
      pZone2 = Low[iMaxRetraced];
      pZone1U = pZone2;
      pZone2U = pLow;
   }
   
   datetime tZone1, tZone2;
   switch ( SpanMode ) {
      case MODE_SPAN_ZONE:   
         if ( isDownTrend ) tZone1 = tLow;
         else tZone1 = tHigh;
         tZone2 = Time[iMaxRetraced];
         break;
      case MODE_SPAN_ZONETOSHIFT:
         if ( isDownTrend ) tZone1 = tLow;
         else tZone1 = tHigh;
         tZone2 = Time[shift];
         break;
      case MODE_SPAN_ALL:
        if ( isDownTrend ) tZone1 = tHigh;
        else tZone1 = tLow;
        tZone2 = Time[shift];
        break;
      default:
        pmErrMsg( "SpanMode", "valid inputs are 0, 1, or 2" );
        break;
   }

   if ( ShowRetracedZone ) drawRetracementZone( tZone1, tZone2, pZone1, pZone2, RetracedZoneColor, isLive );
   if ( ShowUnretracedZone ) drawRetracementZone( tZone1, tZone2, pZone1U, pZone2U, UnretracedZoneColor, isLive );
}

/**
* drawFibo()
* Draws a fibo retracement on the chart given two time and two price parameters
* Returns true on success/false on failure
* 
* Function is dependent on user input variables FiboWidth, FiboStyle, FiboColor, FiboObjPrefix
* Function is also dependent on global vars objCnt, nFiboLevels, fiboLevel[], fp1, fp2
*/
bool drawFibo( datetime t1, datetime t2, double p1, double p2, bool isLive=true ) {
   static int id = -1;
   string objName; 
   bool res, isUpdate; 
   
   if ( id == -1 ) {//create fibo
      isUpdate = false;
      id = objCnt;
      objName = StringConcatenate( FiboObjPrefix, id );
      res = ObjectCreate( objName, OBJ_FIBO, 0, t1, p1, t2, p2 );
   } else {//update fibo    
      if ( isLive ) {
        /* TODO: this causes problem updating on zoom in/out. For the time being, prefer to make unnecessary calls to ObjectMove
         bool isChanged = false;
         if ( fp1 > fp2 ) {//down
            isChanged = (p2 < fp2);//only redraw if breaks 0.000 level, but not 1.000
         } else {//up
            isChanged = (p2 > fp2);//only redraw if breaks 0.000 level, but not 1.000
         } */

         //if ( isChanged ) {
            isUpdate = true;
            objName = StringConcatenate( FiboObjPrefix, id );
            res = ObjectMove( objName, 0, t1, p1 );
            if ( res ) res = ObjectMove( objName, 1, t2, p2 ); 
         /*} else {
            res = false;
         }*/    
      } else {
         res = false;
      }
   }    
   
   if ( res ) {    
      fp1 = p1;
      fp2 = p2;
      if ( !isUpdate ) {
         //set fibo styles
         ObjectSet( objName, OBJPROP_LEVELWIDTH, FiboWidth );
         ObjectSet( objName, OBJPROP_LEVELSTYLE, FiboStyle );
         ObjectSet( objName, OBJPROP_COLOR, FiboColor );
         //ObjectSet( objName, OBJPROP_RAY, setRay );
      
         ObjectSet( objName, OBJPROP_FIBOLEVELS, nFiboLevels );
         for ( int i = 0; i < nFiboLevels; i++ ) {
            ObjectSet( objName, OBJPROP_FIRSTLEVEL + i, fiboLevel[i] );
            ObjectSetFiboDescription( objName, i, StringConcatenate( DoubleToStr( fiboLevel[i], 3 ), " - %$" ) );
         }

         objCnt++;
      }
   } 
   
   return(res);
}

/**
* drawRetracementZone()
* Draws rectangular object on chart given two time parameters and two price parameters
* Returns true on success/false on failure
*
* Function is dependent on user input variables Un/retracedZoneColor, FiboObjPrefix, ShowRetracementZone
* Function also uses global var objCnt
*/
bool drawRetracementZone( datetime t1, datetime t2, double p1, double p2, color clr, bool isLive=true ) {  
   string objName;
   bool res = false;
   
   if ( objCnt <= 2 ) {
     objName = StringConcatenate( FiboObjPrefix, objCnt );
     res = ObjectCreate( objName, OBJ_RECTANGLE, 0, t1, p1, t2, p2 );
     if ( res ) {
        ObjectSet( objName, OBJPROP_COLOR, clr );
        objCnt++;
     }
   } else {
     if ( isLive ) {
        //TODO: check if changed before ObjectMove
        int i;
        if ( clr == RetracedZoneColor ) i = 1;
        else i = 2;
   
        objName = StringConcatenate( FiboObjPrefix, i );
        res = ObjectMove( objName, 0, t1, p1 );
        if ( res ) res = ObjectMove( objName, 1, t2, p2 );
     } 
   }   
   
   return(res);
}

/**
* deleteObjects()
* Deletes all objects on chart containing the given prefix objPrefix or all objects if objPrefix ""
* The prefix must be at the beginning of the object name (position 0) in order for the object to be deleted
* The optional objCount parameter takes an integer that is used to break the for loop is the delete count reaches objCount (if objCount > 0, otherwise, the parameter is disregarded)
* Returns the number of objects deleted
*/
int deleteObjects( string objPrefix="", int objCount=0 ) {  
   if ( objPrefix == "" ) {//delete all
      return( ObjectsDeleteAll() );//nothing left to do ...
   }
   
   int cnt = 0;
   int nObj = ObjectsTotal();
   bool limitCnt = (objCount > 0);
   string objName;
   
   for ( int i = 0; i < nObj; i++ ) {
      objName = ObjectName(i);
      if ( StringFind( objName, objPrefix ) < 0 ) continue;//skip deleting this object because objPrefix is not present OR is not a prefix (not at position 0)
      
      if ( ObjectDelete(objName) ) {
         cnt++;//increment cnt only if ObjectDelete successful  
         if ( limitCnt ) {
            if ( cnt >= objCount ) break;
         }
         i--;//index shift
         nObj--;
      }
   }
   
   return(cnt);
}

/**
* explodeToDouble()
* Splits string str up by delimiter, converts tokens into doubles, and inserts tokens into array of doubles outArr
* Returns the number of tokens inserted into the array
*/
int explodeToDouble( string delimiter, string str, double& outArr[] ) {
   int szArr = ArraySize(outArr);
   int delLen = StringLen(delimiter);
   int delPos=0, lastPos=0, i=0;
   
   while ( delPos >= 0 ) {
      if ( szArr <= i ) {//Resize array if necessary
         szArr *= 2;
         ArrayResize( outArr, szArr );
      }
   
      delPos = StringFind( str, delimiter, lastPos );
      outArr[i] = StrToDouble( trim( StringSubstr( str, lastPos, delPos ) ) );
      lastPos = delPos + delLen;
      i++;
   }
   
   return(i);
}

/**
* trim()
* Trims both right and left (cuts line feed characters, spaces, and tabs)
* Returns the trimmed string of string str
*/
string trim( string str ) {
   str = StringTrimLeft(str);
   str = StringTrimRight(str);
   
   return(str);
}

/**
* isNewBar()
* Detects new bar
* Returns true on new bar
*/
bool isNewBar() {
   static datetime open = 0;
   if ( open != Time[0] ) {
      open = Time[0];
      return(true);
   }
   return(false);
}

void pmErrMsg( string paramName, string additionalInfo="" ) {
   MessageBox(  StringConcatenate( "You have enter an invalid parameter for ", paramName, " - ", additionalInfo ) );
}