//+------------------------------------------------------------------+
//|                                                  Double_Doji.mq4 |
//|                                  Copyright © 2010, Kenny Hubbard |
//|                                       http://www.compu-forex.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, Kenny Hubbard"
#property link      "http://www.compu-forex.com"

#define NO_RESULT -100

extern int     MagicNumber   = 123;
extern double  Min_Length     = 10;   //Length of wick from High to Low
extern double  Max_Body       = 2;    //Max body size in pips
extern double  Order_Buffer   = 2;
extern double  SL_Buffer      = 5;    //buffer from Hi or Lo for SL
extern bool    Use_MM         = false;
extern double  Risk           = 3;
extern double  Fixed_Lots     = 0.1;
extern double  Trail_From     = 10.0;
extern double  Trail_Max      = 50.0;
extern double  Trail_Percent  = 50;
extern bool    Show_Highlight = true;

int   
   D_Factor    = 1,
   LotDigits   = 1,
   Slippage    = 3;
double   
   Pip,
   Stop_Level;

string
   Cmt = "Double Doji";

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
   Pip = Point;
//----
   if (Digits == 3|| Digits == 5){D_Factor = 10; Pip *= 10;}
   Min_Length   *= Pip;
   Max_Body     *= Pip;
   SL_Buffer    *= Pip;
   Order_Buffer *= Pip;
   if (MarketInfo(Symbol(),MODE_LOTSTEP) == 0.01)LotDigits = 2;
   Stop_Level = MarketInfo(OrderSymbol(),MODE_STOPLEVEL)*Pip;
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   ObjectsDeleteAll();
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----
int 
   Doji_Result = 0;
double   
   Hi,
   Lo;
   if(OrdersTotal()>1)Kill_Spare();
   if(New_Bar()){
      for(int Bar_Count = 1;Bar_Count<=2;Bar_Count++)Doji_Result = Doji_Result + Identify_Doji(Bar_Count);
      if(Doji_Result==2){
         Hi = MathMax(High[1],High[2]);
         Lo = MathMin(Low[1],Low[2]);
         Do_Trade(Hi, Lo);
         if(Show_Highlight)Show_Box(Hi,Lo);
      }
   }
   Trail_Stop();
//----
   return(0);
}
//+------------------------------------------------------------------+
int Identify_Doji(int Bar_Ident)
{
double 
   Bar_Height = High[Bar_Ident] - Low[Bar_Ident],
   Body_Height = MathAbs(Open[Bar_Ident] - Close[Bar_Ident]);
   if (Bar_Height < Min_Length) return(NO_RESULT);
   if (Body_Height > Max_Body) return(NO_RESULT);
   return(1);
}
//+------------------------------------------------------------------+
double Get_Lots(double Pip_Loss)
{
   Pip_Loss /= Pip;
double
   Pip_Value = MarketInfo(Symbol(),MODE_TICKVALUE) * D_Factor,
   Money_Loss = Risk/100 * AccountBalance(),
   Trade_Size = (Money_Loss/Pip_Loss)/Pip_Value;
   Trade_Size = MathMax(Trade_Size,MarketInfo(Symbol(),MODE_MINLOT));
   Trade_Size = MathMin(Trade_Size,MarketInfo(Symbol(),MODE_MAXLOT));
   return(Trade_Size);
}
//+------------------------------------------------------------------+
void Do_Trade(double lHi, double lLo)
{
double
   Lots = Fixed_Lots;
   if(Use_MM)Lots = Get_Lots(lHi-lLo);
   int ticket_B = OrderSend(Symbol(),OP_BUYSTOP,NormalizeDouble(Lots,LotDigits),NormalizeDouble(lHi+Order_Buffer,Digits), Slippage,NormalizeDouble(lLo-SL_Buffer,Digits),0,Cmt,MagicNumber,0,Green);
   int ticket_S = OrderSend(Symbol(),OP_SELLSTOP,NormalizeDouble(Lots,LotDigits),NormalizeDouble(lLo-Order_Buffer,Digits), Slippage,NormalizeDouble(lHi+SL_Buffer,Digits),0,Cmt,MagicNumber,0,Red);
   return;
}
//+------------------------------------------------------------------+
void Show_Box(double Top, double Bottom)
{
   if(ObjectFind("D_Doji")>-1)ObjectDelete("D_Doji");
   ObjectCreate("D_Doji",OBJ_RECTANGLE,0,Time[2],Top,Time[1],Bottom);
   ObjectSet("D_Doji",OBJPROP_COLOR,Aqua);
}
//+------------------------------------------------------------------+
void Kill_Spare()
{
bool
   Order_Flag = false;
   for(int i = OrdersTotal()-1;i>=0;i--){
      if(OrderSelect(i,SELECT_BY_POS)){
         if(OrderMagicNumber() == MagicNumber){
            if(OrderType()<=1){
               Order_Flag=true;
               break;
            }
         }
      }
   }
   if(Order_Flag){
      for(i = OrdersTotal()-1;i>=0;i--){
         if(OrderSelect(i,SELECT_BY_POS)){
            if(OrderMagicNumber() == MagicNumber){
               if(OrderType()>1)OrderDelete(OrderTicket());
            }
         }
      }
   }
}
//+------------------------------------------------------------------+
bool New_Bar()
{
   static datetime New_Time=0;
   if(New_Time!=Time[0]){
      New_Time=Time[0];
      return(true);
   }
   return(false);
}
//-------------------------------------------------------------------
void Trail_Stop()
{
bool
   mod;
int err; // for better error reporting
double
   My_Profit,
   My_Trail,
   My_SL,
   lTrail_Max,
   lTrail_From,
   Stop_Level;
//----
   for (int i = OrdersTotal()-1; i >=0; i--){
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
         if(OrderType()>1)continue;
         if(OrderMagicNumber() == MagicNumber){
            lTrail_Max = Trail_Max * Pip;
            lTrail_From = Trail_From * Pip;
            switch(OrderType()){
               case OP_BUY :  My_Profit = Bid - OrderOpenPrice();
                              My_Trail = MathMin(My_Profit * Trail_Percent/100,lTrail_Max);
                              My_SL = NormalizeDouble(Bid-My_Trail,Digits);
                              if(My_Profit > lTrail_From){
                                 if(Bid - My_SL > Stop_Level){
                                    if(OrderStopLoss() < My_SL || OrderStopLoss() == 0) mod = OrderModify(OrderTicket(),OrderOpenPrice(),My_SL,OrderTakeProfit(),0, CLR_NONE);
                                 }
                              }
                              break;
                        
               case OP_SELL : My_Profit = OrderOpenPrice() - Ask;
                              My_Trail = MathMin(My_Profit * Trail_Percent/100,lTrail_Max);
                              My_SL = NormalizeDouble(Ask+My_Trail,Digits);
                              if(My_Profit > lTrail_From){
                                 if(My_SL - Ask > Stop_Level){
                                    if(My_SL < OrderStopLoss() || OrderStopLoss() == 0) mod = OrderModify(OrderTicket(),OrderOpenPrice(),My_SL,OrderTakeProfit(),0,CLR_NONE);
                                 }
                              }
                              break;
               }
               if(!mod)
               {
                  err = GetLastError();
                  if (err > 1) Print("Error entering Trailing Stop - Error (" + err + "} ");
               }
         }
      }
      else Print("Error selecting order");
   } 
//----
   return(0);
  }
//+------------------------------------------------------------------+