//+------------------------------------------------------------------+
//|                                                  Small Hours.mq4 |
//|                                      Copyright © 2011, Ido Kasse |
//|              http://www.forexfactory.com/showthread.php?t=280540 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, Ido Kasse"
#property link      "http://www.forexfactory.com/showthread.php?t=280540"

extern int corner=1;
extern int y=15;
extern string slevel = "Show Entry, SL and TP2 levels";
extern bool showlevels = false;
extern string onsl = "True = new (tight) SL, False=Original SL";
extern bool newsl = false;
extern string ontp = "True = new TP, False=Original TP";
extern bool newtp = true;
extern string lecolor = "Textcolor";
extern color lcolor = Silver;
extern string dbox = "Draw box around the 5 bars range";
extern bool box = true;
extern string devtest = "Draw arrows on signal";
extern bool arrows = true;
extern string hmessage = "Show rules onscreen";
extern bool help = true;
extern string alertm = "Show Alert message on valid signal";
extern bool usealert = true;
extern string inbar = "Enable inside bar detection";
extern bool insidebar = true;
extern string smail = "Send e-mail on valid signal";
extern bool mail = false;
double atrvalue, atrcalc, tp1;
double hhll5, hhll5calc, hh5, ll5, hh3, ll3, hhll3;
double setuphigh, setuplow, setupclose, insidehigh, insidelow;
double sma20, sma40;
double buyentry, buytp1, buytp2, buysl, sellentry, selltp1, selltp2, sellsl, spread;
static datetime barStart;

//++++ These are adjusted for 5 digit brokers.
double  pips2points,    // slippage  3 pips    3=points    30=points
        pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)
 
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators

   ObjectCreate("rule1", OBJ_LABEL, 0, 0, 0);
   ObjectSet("rule1", OBJPROP_CORNER, corner);
   ObjectSet("rule1", OBJPROP_XDISTANCE, 15);
   ObjectSet("rule1", OBJPROP_YDISTANCE, y);   

   ObjectCreate("rule2", OBJ_LABEL, 0, 0, 0);
   ObjectSet("rule2", OBJPROP_CORNER, corner);
   ObjectSet("rule2", OBJPROP_XDISTANCE, 15);
   ObjectSet("rule2", OBJPROP_YDISTANCE, y+25);  

   ObjectCreate("rule3", OBJ_LABEL, 0, 0, 0);
   ObjectSet("rule3", OBJPROP_CORNER, corner);
   ObjectSet("rule3", OBJPROP_XDISTANCE, 15);
   ObjectSet("rule3", OBJPROP_YDISTANCE, y+50);

   if (help==true)
   {
    ObjectCreate("rule1help", OBJ_LABEL, 0, 0, 0);
    ObjectSet("rule1help", OBJPROP_CORNER, corner);
    ObjectSet("rule1help", OBJPROP_XDISTANCE, 40);
    ObjectSet("rule1help", OBJPROP_YDISTANCE, y+2);

    ObjectCreate("rule2help1", OBJ_LABEL, 0, 0, 0);
    ObjectSet("rule2help1", OBJPROP_CORNER, corner);
    ObjectSet("rule2help1", OBJPROP_XDISTANCE, 40);
    ObjectSet("rule2help1", OBJPROP_YDISTANCE, y+25);

    ObjectCreate("rule2help2", OBJ_LABEL, 0, 0, 0);
    ObjectSet("rule2help2", OBJPROP_CORNER, corner);
    ObjectSet("rule2help2", OBJPROP_XDISTANCE, 40);
    ObjectSet("rule2help2", OBJPROP_YDISTANCE, y+35);

    ObjectCreate("rule3help1", OBJ_LABEL, 0, 0, 0);
    ObjectSet("rule3help1", OBJPROP_CORNER, corner);
    ObjectSet("rule3help1", OBJPROP_XDISTANCE, 45);
    ObjectSet("rule3help1", OBJPROP_YDISTANCE, y+50);
   
    ObjectCreate("rule3help2", OBJ_LABEL, 0, 0, 0);
    ObjectSet("rule3help2", OBJPROP_CORNER, corner);
    ObjectSet("rule3help2", OBJPROP_XDISTANCE, 40);
    ObjectSet("rule3help2", OBJPROP_YDISTANCE, y+60);
   }

   if (showlevels==true)
   {
    ObjectCreate("stats1", OBJ_LABEL, 0, 0, 0);
    ObjectSet("stats1", OBJPROP_CORNER, corner);
    ObjectSet("stats1", OBJPROP_XDISTANCE, 15);
    ObjectSet("stats1", OBJPROP_YDISTANCE, y+85);

    ObjectCreate("stats2", OBJ_LABEL, 0, 0, 0);
    ObjectSet("stats2", OBJPROP_CORNER, corner);
    ObjectSet("stats2", OBJPROP_XDISTANCE, 15);
    ObjectSet("stats2", OBJPROP_YDISTANCE, y+100);

    ObjectCreate("label", OBJ_LABEL, 0, 0, 0);
    ObjectSet("label", OBJPROP_CORNER, corner);
    ObjectSet("label", OBJPROP_XDISTANCE, 15);
    ObjectSet("label", OBJPROP_YDISTANCE, y+125);

    ObjectCreate("entry", OBJ_LABEL, 0, 0, 0);
    ObjectSet("entry", OBJPROP_CORNER, corner);
    ObjectSet("entry", OBJPROP_XDISTANCE, 15);
    ObjectSet("entry", OBJPROP_YDISTANCE, y+150);

    ObjectCreate("tp1", OBJ_LABEL, 0, 0, 0);
    ObjectSet("tp1", OBJPROP_CORNER, corner);
    ObjectSet("tp1", OBJPROP_XDISTANCE, 15);
    ObjectSet("tp1", OBJPROP_YDISTANCE, y+165);

    ObjectCreate("tp2", OBJ_LABEL, 0, 0, 0);
    ObjectSet("tp2", OBJPROP_CORNER, corner);
    ObjectSet("tp2", OBJPROP_XDISTANCE, 15);
    ObjectSet("tp2", OBJPROP_YDISTANCE, y+180);

    ObjectCreate("sl", OBJ_LABEL, 0, 0, 0);
    ObjectSet("sl", OBJPROP_CORNER, corner);
    ObjectSet("sl", OBJPROP_XDISTANCE, 15);
    ObjectSet("sl", OBJPROP_YDISTANCE, y+195);
   }
   
   if (insidebar==true)
   {
    ObjectCreate("inside", OBJ_LABEL, 0, 0, 0);
    ObjectSet("inside", OBJPROP_CORNER, corner);
    ObjectSet("inside", OBJPROP_XDISTANCE, 15);
    ObjectSet("inside", OBJPROP_YDISTANCE, y+210);
   }
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   ObjectsDeleteAll();
   Comment("");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//----

//DIGIT FIX
   if (Digits == 5 || Digits == 3)
   {    // Adjust for five (5) digit brokers.
               pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
   } else {    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; }

//PLACE TEXT
   ObjectSetText("rule1", CharToStr(129), 15, "Wingdings", lcolor);
   ObjectSetText("rule2", CharToStr(130), 15, "Wingdings", Orange);
   ObjectSetText("rule3", CharToStr(131), 15, "Wingdings", lcolor);
   
   if (help==true)
   {
    ObjectSetText("rule1help","HH5-LL5 < ATRx1.5 from setup bar", 8, "Arial", lcolor);
    ObjectSetText("rule2help1","BUY: High of previous bar < hh5", 8, "Arial", lcolor);
    ObjectSetText("rule2help2","SELL: Low of previous bar > ll5", 8, "Arial", lcolor);
    ObjectSetText("rule3help1","BUY: Close of previous bar > 20SMA or 40SMA", 8, "Arial Bold", lcolor);
    ObjectSetText("rule3help2","SELL: Close of previous bar < 20SMA or 40SMA", 8, "Arial", lcolor);
   }

//CALCULATIONS
    atrvalue=iATR(NULL,0,20,1)/pips2dbl;
    atrcalc=atrvalue*1.5;
    tp1=atrvalue*0.75;
    hh5=High[iHighest(NULL,0,MODE_HIGH,5,1)];
    ll5=Low[iLowest(NULL,0,MODE_LOW,5,1)];
    hhll5=(hh5-ll5)/pips2dbl;
    hh3=High[iHighest(NULL,0,MODE_HIGH,3,1)];
    ll3=Low[iLowest(NULL,0,MODE_LOW,3,1)];
    hhll3=(hh3-ll3)/pips2dbl;
    setuphigh=iHigh(NULL,0,1); 
    setuplow=iLow(NULL,0,1); 
    setupclose=iClose(NULL,0,1);
    sma20=iMA(NULL,0,20,0,MODE_SMA,PRICE_CLOSE,1);
    sma40=iMA(NULL,0,40,0,MODE_SMA,PRICE_CLOSE,1);
    
//INSIDE BAR DETECTION
   insidehigh=iHigh(NULL,0,2);
   insidelow=iLow(NULL,0,2);
   ObjectSetText("inside", "", 9, "Arial Bold", lcolor);
   if (setuphigh<insidehigh&&setuplow>insidelow&&setupclose>sma20||setupclose>sma40) ObjectSetText("inside", "Inside bar detected - BUY setup", 9, "Arial Bold", White); 
   if (setuphigh<insidehigh&&setuplow>insidelow&&setupclose<sma20||setupclose<sma40) ObjectSetText("inside", "Inside bar detected - SELL setup", 9, "Arial Bold", White);  
  
//ORDER LEVELS
    spread=MathCeil(MarketInfo(Symbol(),MODE_SPREAD)*Point/pips2dbl)*(pips2points*Point);
    //BUY
    buyentry=hh5+(3*pips2dbl)+spread*pips2dbl;
    if (newtp==true) 
    {
     buytp1=buyentry+(atrvalue*0.75)*pips2dbl;
     buytp2=buyentry+(atrvalue*0.95)*pips2dbl;
    }
    if (newtp==false) 
    {
     buytp1=buyentry+(atrvalue*0.75)*pips2dbl;
     buytp2=buyentry+(atrvalue*1.5)*pips2dbl;
    }
    if (newsl==true) buysl=buyentry-(hhll3*0.764)*pips2dbl;
    if (newsl==false) buysl=ll5-(3*pips2dbl)-spread*pips2dbl;
    //SELL
    sellentry=ll5-(3*pips2dbl)-spread*pips2dbl;
    if (newtp==true) 
    {
     selltp1=sellentry-atrvalue*0.75*pips2dbl;
     selltp2=sellentry-atrvalue*0.95*pips2dbl;
    }
    if (newtp==false) 
    {
     selltp1=sellentry-atrvalue*0.75*pips2dbl;
     selltp2=sellentry-atrvalue*1.5*pips2dbl;
    }
    if (newsl==true) sellsl=sellentry+(hhll3*0.764)*pips2dbl;
    if (newsl==false) sellsl=hh5+(3*pips2dbl)+spread*pips2dbl;
   
//RULE 1
   if (hhll5<atrcalc) ObjectSetText("rule1", CharToStr(129), 15, "Wingdings", Orange);

//RULE 2
   if (setuphigh<hh5&&setupclose>sma20||setupclose>sma40) ObjectSetText("rule2", CharToStr(130), 15, "Wingdings", Orange);
   if (setuplow>ll5&&setupclose<sma20||setupclose<sma40) ObjectSetText("rule2", CharToStr(130), 15, "Wingdings", Orange);

//RULE 3
   if (setupclose>sma20||setupclose>sma40) ObjectSetText("rule3", CharToStr(131), 15, "Wingdings", Lime);
   if (setupclose<sma20||setupclose<sma40) ObjectSetText("rule3", CharToStr(131), 15, "Wingdings", Red);

//SET RULE 1&2 LIGHT SAME AS RULE 3 LIGHT IF VALID
   if (hhll5<atrcalc&&setupclose>sma20||setupclose>sma40) ObjectSetText("rule1", CharToStr(129), 15, "Wingdings", Lime);
   if (hhll5<atrcalc&&setupclose<sma20||setupclose<sma40) ObjectSetText("rule1", CharToStr(129), 15, "Wingdings", Red);
   if (setuphigh<hh5&&setupclose>sma20||setupclose>sma40) ObjectSetText("rule2", CharToStr(130), 15, "Wingdings", Lime);
   if (setuplow>ll5&&setupclose<sma20||setupclose<sma40) ObjectSetText("rule2", CharToStr(130), 15, "Wingdings", Red);

//SHOW LEVELS
   if (showlevels==true)
   {
    ObjectSetText("stats1", "ATRx1.5 / HH5-LL5 Range: "+DoubleToStr(atrcalc,1)+" / "+DoubleToStr(hhll5,1), 9, "Arial Bold", lcolor);
    ObjectSetText("stats2", "Highest / Lowest: "+DoubleToStr(hh5,Digits)+" / "+DoubleToStr(ll5,Digits), 9, "Arial Bold", lcolor);
    ObjectSetText("label", "BUY / SELL", 13, "Arial Bold", lcolor);
    ObjectSetText("entry", "Entry: "+DoubleToStr(buyentry,Digits)+" / "+DoubleToStr(sellentry,Digits), 9, "Arial Bold", lcolor);
    ObjectSetText("tp1", "TP1: "+DoubleToStr(buytp1,Digits)+" / "+DoubleToStr(selltp1,Digits), 9, "Arial Bold", Green);
    ObjectSetText("tp2", "TP2: "+DoubleToStr(buytp2,Digits)+" / "+DoubleToStr(selltp2,Digits), 9, "Arial Bold", Lime);
    ObjectSetText("sl", "SL: "+DoubleToStr(buysl,Digits)+" / "+DoubleToStr(sellsl,Digits), 9, "Arial Bold", Red);
   }

//CHANGE BUY SELL TEXT
   if (hhll5<atrcalc&&setupclose<sma20||setupclose<sma40&&setuplow>ll5) ObjectSetText("label", "SELL", 16, "Arial Bold", White);
   if (hhll5<atrcalc&&setupclose>sma20||setupclose>sma40&&setuphigh<hh5) ObjectSetText("label", "BUY", 16, "Arial Bold", White);
   
//RUN ONCE PER BAR
if (barStart < Time[0]) //start of new bar 
{
barStart = Time[0];
   
//BUY ALERT 
   if (hhll5<atrcalc&&setupclose>sma20||setupclose>sma40&&setuphigh<hh5) 
   {
     if (usealert==true) Alert(""+Symbol()+" "+Period()+" BUY Alert!");
     if (mail==true) SendMail("Small Hours indicator", "BUY signal for "+Symbol()+" @ "+Period());
     ObjectSetText("label", "BUY", 16, "Arial Bold", White);
   }

//SELL ALERT
   if (hhll5<atrcalc&&setupclose<sma20||setupclose<sma40&&setuplow>ll5) 
   {
    if (usealert==true) Alert(""+Symbol()+" "+Period()+" SELL Alert!");
    if (mail==true) SendMail("Small Hours indicator", "SELL signal for "+Symbol()+" @ "+Period());
    ObjectSetText("label", "SELL", 16, "Arial Bold", White);
   }

//DRAW BOX
   if(box==true)
   {
    ObjectDelete("box");
    ObjectCreate("box", OBJ_RECTANGLE, 0, Time[5], hh5, Time[1], ll5);
    ObjectSet("box", OBJPROP_STYLE, STYLE_DASHDOTDOT);
    ObjectSet("box", OBJPROP_COLOR, MidnightBlue);
    ObjectSet("box", OBJPROP_WIDTH, 1);
   }

//DRAW ARROWS
  if (arrows==true)
  {
//ARROW UP
   if (hhll5<atrcalc&&setupclose>sma20||setupclose>sma40&&setuphigh<hh5) 
   {
    ObjectDelete("uparrow"); ObjectDelete("downarrow");
    ObjectCreate("uparrow", OBJ_ARROW, 0, Time[0], Low[1]-20*pips2dbl);
    ObjectSet("uparrow", OBJPROP_STYLE, STYLE_SOLID);
    ObjectSet("uparrow", OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
    ObjectSet("uparrow", OBJPROP_COLOR,Lime);   
   }
//ARROW DOWN
   if (hhll5<atrcalc&&setupclose<sma20||setupclose<sma40&&setuplow>ll5) 
   {
     ObjectDelete("downarrow"); ObjectDelete("uparrow");
     ObjectCreate("downarrow",OBJ_ARROW, 0, Time[0], High[1]+20*pips2dbl);
     ObjectSet("downarrow", OBJPROP_STYLE, STYLE_SOLID);
     ObjectSet("downarrow", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
     ObjectSet("downarrow", OBJPROP_COLOR,Red);   
   }
  }

} //END BARSTART

//----
   return(0);
  }
//+------------------------------------------------------------------+