Download MetaTrader 5
To add comments, please log in or register
Are you a good trader? Become a signals provider and make even more money!
enjoysmath
64
enjoysmath 2015.07.13 20:42 
//+------------------------------------------------------------------+
//|                                                        MySMI.mq4 |
//|                                                  Daniel Donnelly |
//|                                             enjoysmath@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Daniel Donnelly"
#property link      "enjoysmath@gmail.com"
#property version   "1.00"
#property strict

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 White
#property indicator_color2 Red
#property indicator_level1 0

// Input parameters
input int PeriodQ = 2;
input int PeriodR= 8;
input int PeriodS = 5;
input int PeriodSlow = 5;
input float PeriodFactor = 1.0f;
input string            TextFont="Arial";         // Text Font
input int               TextFontSize=10;          // Text Font size
input color             TextColor=clrRed;         // Text Color
input double            TextAngle=90.0;           // Text slope angle in degrees
input ENUM_ANCHOR_POINT TextAnchor=ANCHOR_BOTTOM; // Text anchor type
input bool              TextBack=false;           // Text background object
input bool              TextSelection=false;      // Text highlight to move
input bool              TextHidden=true;          // Text hidden in the object list
input long              TextZOrder=0;             // Text priority for mouse click

const int _PeriodQ       = (int)MathFloor(PeriodQ * PeriodFactor);
const int _PeriodR      = (int)MathFloor(PeriodR* PeriodFactor);
const int _PeriodS       = (int)MathFloor(PeriodS * PeriodFactor);
const int _PeriodSlow    = (int)MathFloor(PeriodSlow * PeriodFactor);

const string shortName = "MySMI";

// Buffers 
double   smi[], 
         slow_smi[], 
         sm[], 
         ma_sm[], 
         ma2_sm[], 
         ma_hq[], 
         ma2_hq[], 
         hq[];


// Custom indicator initialization function    
int OnInit() {
   // Indicator buffers mapping
   IndicatorBuffers(8);
   
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(0, smi);
   SetIndexLabel(0, shortName);
   
   SetIndexStyle(1, DRAW_LINE);
   SetIndexBuffer(1, slow_smi);
   SetIndexLabel(1, "Slowed "+shortName);
   
   SetIndexBuffer(2, sm);
   SetIndexBuffer(3, ma_sm);
   SetIndexBuffer(4, ma2_sm);
   SetIndexBuffer(5, ma_hq);
   SetIndexBuffer(6, ma2_hq);
   SetIndexBuffer(7, hq);
   
   IndicatorShortName(shortName + "(" + IntegerToString(_PeriodQ) + "," +
                                       + IntegerToString(PeriodR) + "," + 
                                       + IntegerToString(_PeriodS) + "," + 
                                       + IntegerToString(_PeriodSlow) + ")" );
   
   return(INIT_SUCCEEDED);
}


// 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 = prev_calculated - 1;
   double maxH, minL;
   int i;
   
      //--- create the texts
   i = limit;
   if(!TextCreate(   0, "TextHigh_"+(string)i, 0, time[i], high[i], DoubleToString(high[i],5), 
                     TextFont, TextFontSize, TextColor, TextAngle, TextAnchor, TextBack, TextSelection, TextHidden, TextZOrder))
   {
      Print("Error creating text.");
   }

   
   // limit = N = rates_total <=> infinite lookback
   for (i = limit; i >= 0; i--)  {
      maxH = high[iHighest(NULL, 0, MODE_HIGH, _PeriodQ, i)];  // maxH[i] = max{h[i], h[i+1], h[i+2], ..., h[i + QPeriod - 1]}
      minL = low[iLowest(NULL, 0, MODE_LOW, _PeriodQ, i)];     // minL[i] = min{l[i], l[i+1], ..., l[i + QPeriod - 1]}
      hq[i] = maxH - minL;                                     // hq[i] = maxH[i] - minL[i]
      sm[i] = close[i] - (maxH + minL)/2;                      // sm[i] = c[i] - avg{maxH[i], minL[i]}
   }
   
   for (i = limit-PeriodR; i >= 0; i--) {
      ma_sm[i] = iMAOnArray(sm, 0, PeriodR, 0, MODE_EMA, i);
      ma_hq[i] = iMAOnArray(hq, 0, PeriodR, 0, MODE_EMA, i);
   }
   
   for (i = limit-PeriodR-_PeriodS; i >= 0; i--) {
      ma2_sm[i] = iMAOnArray(ma_sm, 0, _PeriodS, 0, MODE_EMA, i);
      ma2_hq[i] = iMAOnArray(ma_hq, 0, _PeriodS, 0, MODE_EMA, i);
   }
   
   for (i = limit-PeriodR-_PeriodS-_PeriodSlow; i>=0; i--) {
      smi[i] = 100 * ma2_sm[i] /(0.5 * ma2_hq[i]);
   }
   
   for (i = limit-PeriodR-_PeriodS; i >=0; i--) {
      slow_smi[i] = iMAOnArray(smi, 0, _PeriodSlow, 0, MODE_EMA, i);
   }
   
   // Return value of prev_calculated for next call
   return(rates_total);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////// TEXT LIBRARY /////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////

//+------------------------------------------------------------------+
//| Creating Text object                                             |
//+------------------------------------------------------------------+
bool TextCreate(const long              chart_ID=0,               // chart's ID
                const string            name="Text",              // object name
                const int               sub_window=0,             // subwindow index
                datetime                time=0,                   // anchor point time
                double                  price=0,                  // anchor point price
                const string            text="Text",              // the text itself
                const string            font="Arial",             // font
                const int               font_size=10,             // font size
                const color             clr=clrRed,               // color
                const double            angle=0.0,                // text slope
                const ENUM_ANCHOR_POINT anchor=ANCHOR_LEFT_UPPER, // anchor type
                const bool              back=false,               // in the background
                const bool              selection=false,          // highlight to move
                const bool              hidden=true,              // hidden in the object list
                const long              z_order=0)                // priority for mouse click
  {
//--- set anchor point coordinates if they are not set
   ChangeTextEmptyPoint(time,price);
//--- reset the error value
   ResetLastError();
//--- create Text object
   if(!ObjectCreate(chart_ID,name,OBJ_TEXT,sub_window,time,price))
     {
      Print(__FUNCTION__,
            ": failed to create \"Text\" object! Error code = ",GetLastError());
      return(false);
     }
//--- set the text
   ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
//--- set text font
   ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
//--- set font size
   ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
//--- set the slope angle of the text
   ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle);
//--- set anchor type
   ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- set color
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- display in the foreground (false) or background (true)
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the object by mouse
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Move the anchor point                                            |
//+------------------------------------------------------------------+
bool TextMove(const long   chart_ID=0,  // chart's ID
              const string name="Text", // object name
              datetime     time=0,      // anchor point time coordinate
              double       price=0)     // anchor point price coordinate
  {
//--- if point position is not set, move it to the current bar having Bid price
   if(!time)
      time=TimeCurrent();
   if(!price)
      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
   ResetLastError();
//--- move the anchor point
   if(!ObjectMove(chart_ID,name,0,time,price))
     {
      Print(__FUNCTION__,
            ": failed to move the anchor point! Error code = ",GetLastError());
      return(false);
     }
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Change the object text                                           |
//+------------------------------------------------------------------+
bool TextChange(const long   chart_ID=0,  // chart's ID
                const string name="Text", // object name
                const string text="Text") // text
  {
//--- reset the error value
   ResetLastError();
//--- change object text
   if(!ObjectSetString(chart_ID,name,OBJPROP_TEXT,text))
     {
      Print(__FUNCTION__,
            ": failed to change the text! Error code = ",GetLastError());
      return(false);
     }
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Delete Text object                                               |
//+------------------------------------------------------------------+
bool TextDelete(const long   chart_ID=0,  // chart's ID
                const string name="Text") // object name
  {
//--- reset the error value
   ResetLastError();
//--- delete the object
   if(!ObjectDelete(chart_ID,name))
     {
      Print(__FUNCTION__,
            ": failed to delete \"Text\" object! Error code = ",GetLastError());
      return(false);
     }
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Check anchor point values and set default values                 |
//| for empty ones                                                   |
//+------------------------------------------------------------------+
void ChangeTextEmptyPoint(datetime &time,double &price)
  {
//--- if the point's time is not set, it will be on the current bar
   if(!time)
      time=TimeCurrent();
//--- if the point's price is not set, it will have Bid value
   if(!price)
      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
  }

The original code works except when you add

      //--- create the texts
   i = limit;
   if(!TextCreate(   0, "TextHigh_"+(string)i, 0, time[i], high[i], DoubleToString(high[i],5), 
                     TextFont, TextFontSize, TextColor, TextAngle, TextAnchor, TextBack, TextSelection, TextHidden, TextZOrder))
   {
      Print("Error creating text.");
   }

   

 where it's shown in the above code.  The debugger won't step into that if condition / function call.  So I can't look any further.  Any ideas why it's crashing?

enjoysmath
64
enjoysmath 2015.07.13 20:42  
That is code for an indicator.
Keith Watford
Moderator
7955
Keith Watford 2015.07.13 23:25  
   int limit = prev_calculated - 1;
   double maxH, minL;
   int i;
   
      //--- create the texts
   i = limit;
   if(!TextCreate(   0, "TextHigh_"+(string)i, 0, time[i], high[i], DoubleToString(high[i],5), 
                     TextFont, TextFontSize, TextColor, TextAngle, TextAnchor, TextBack, TextSelection, TextHidden, TextZOrder))
   {
      Print("Error creating text.");
   }

 What does it say in the Experts tab?

Probably you are getting a fatal error "Array out of range"

When the indicator starts

prev_calculated=0

so

limit=-1

i=-1

time[-1] etc does not exist 

whroeder1
13627
whroeder1 2015.07.14 02:24  
  if(!TextCreate(   0, "TextHigh_"+(string)i
Don't use indexes in object names. When the next bar forms you will already have a object named TextHigh_0. Always use Time[i]
enjoysmath
64
enjoysmath 2015.07.14 02:30  
@WHRoeder I'm not sure what you're saying.   Thanks @GumRai, that worked!
/
To add comments, please log in or register