//+-----------------------------------------------------------------------------+
//|                                         Manual Trailing for Mauro Bianco    |
//|                                        Copyright © 2009, Yannis and swissly |
//|                                                         All rights reserved |
//|                                                                             |
//+-----------------------------------------------------------------------------+
#property copyright "Copyright © 2009, Yannis & Swissly"
#property link      "jsfero@otenet.gr & swissly@gmx.ch"
//+-----------------------------------------------------------------------------+
//|                       Dez 1 2009                                            |
//+-----------------------------------------------------------------------------+

//+----------------------User interface-----------------------------------------+
extern string  SL_TP_Trail_Options="--------------------------";
extern int     StopLoss.Pips                 = 100;            // static, initial s/l. 
extern int     TakeProfit.Pips               = 100;            // static, initial take profit
extern int     Trail.Pips                    = 20;              // trail.pips. Unused if value=0
extern int     Trail.Start                   = 15;              // trailing starts, if trade is "Trail.Start" positive. Value can be negative
extern double  Move.Trail.Every.xx.Pips      = 0;            // SL is moved in steps of "Move.Trail.Every.xx.Pips"
extern double  Move.To.BreakEven.at.pips     = 10.0;            // trades in profit will move to entry price + Move.To.BreakEven.Lock.pips as soon as trade is at entry price + Move.To.BreakEven.at.pips
extern double  Move.To.BreakEven.Lock.pips   = 1.0;              


//+---------------------- Global Variables Definition --------------------------------------+
int b.ticket, s.ticket, TodaysRange;
string DR, DR1, comment=" Mauro Trailing",ScreenComment="Mauro Trailing";
double avg.rng, rng, sum.rng, x, mPoint;
bool TradingEnabled, LongTradeEnabled, ShortTradeEnabled, ShortTradeShouldClose, LongTradeShouldClose;
double TPPrice;

int init()
{  //HideTestIndicators(true);
   if(Point==0.00001) 
      mPoint=0.0001;
   else if(Point==0.001) 
      mPoint=0.01;
   else 
      mPoint = Point;

   if (Move.To.BreakEven.Lock.pips < 0.0)
      Move.To.BreakEven.Lock.pips = 0.0;

   return(0);
}

int deinit()
{  
   return(0);
}

int start()
{  
/*      int OpenOrders = 0;
      for(int cnt = 0; cnt < OrdersTotal(); cnt++)   
      {
         if (!OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) continue;
//----
         if(OrderSymbol() == Symbol() )
            OpenOrders++;
      }       
      if (OpenOrders == 0)
         OrderSend(Symbol(),OP_BUY, 0.1, Ask, 3, 0,0);
*/
   PosCounter          ();                      // check for open positions. Sets b.ticket, s.ticket
   CheckInitialSLTP    ();
   if (Move.To.BreakEven.at.pips!=0 && (s.ticket>0 || b.ticket>0)) 
      MoveToBreakEven();
   if ((s.ticket>0 || b.ticket>0) && Trail.Pips > 0) 
      Trail.Stop();
   comments();
   return(0);
} 

void CheckInitialSLTP()
{  
   int sl,tp;
   if (b.ticket>0) 
   {  
      OrderSelect(b.ticket,SELECT_BY_TICKET);
      if (OrderStopLoss()==0 || OrderTakeProfit()==0)
      {  
         if (OrderStopLoss  ()==0)
            sl=StopLoss.Pips;
         if (OrderTakeProfit()==0)
            tp=TakeProfit.Pips;
         if ((sl>0 && OrderStopLoss()==0) || (tp>0 && OrderTakeProfit()==0))  
         {  
            OrderModify(b.ticket, OrderOpenPrice(), OrderOpenPrice()-sl*mPoint,OrderOpenPrice()+tp*mPoint,OrderExpiration(),MediumSpringGreen);
            if (OrderSelect(b.ticket,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("Initial SL or TP is Set for Long Entry");
            else 
               Print("Error setting initial SL or TP for Long Entry");
         }
      }
   }
   if (s.ticket > 0)
   {  
      OrderSelect(s.ticket,SELECT_BY_TICKET);
      if (OrderStopLoss()==0 || OrderTakeProfit()==0)
      {  
         if (OrderStopLoss  ()==0)
            sl=StopLoss.Pips;
         if (OrderTakeProfit()==0)
            tp=TakeProfit.Pips;
         if ((sl>0 && OrderStopLoss()==0) || (tp>0 && OrderTakeProfit()==0))  
         {  
            OrderModify(s.ticket, OrderOpenPrice(), OrderOpenPrice()+sl*mPoint,OrderOpenPrice()-tp*mPoint,OrderExpiration(),MediumVioletRed);
            if (OrderSelect(s.ticket,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("Initial SL or TP is Set for Short Entry");
            else 
               Print("Error setting initial SL or TP for Short Entry");
         }
      }
   }
}


void PosCounter()
{  
   b.ticket=0;s.ticket=0;
   
   for (int cnt=0;cnt<=OrdersTotal();cnt++)
   {  
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol()==Symbol())
      {  
         if (OrderType()==OP_SELL)
            s.ticket=OrderTicket();
         if (OrderType()==OP_BUY)
            b.ticket=OrderTicket();
      }
   }
}


void comments()
{  string s0="", s1="", s2="", s3="", swap="", sCombo="", sStr ;
   int PipsProfit;
   double AmountProfit;
   PipsProfit=0; AmountProfit=0;
   PosCounter();
   if (b.ticket>0) 
   {  OrderSelect(b.ticket,SELECT_BY_TICKET);
      PipsProfit=NormalizeDouble(((Bid - OrderOpenPrice())/mPoint),Digits);
      AmountProfit=OrderProfit();
   }
   else if (s.ticket>0) 
   {  OrderSelect(s.ticket,SELECT_BY_TICKET);
      PipsProfit=NormalizeDouble(((OrderOpenPrice()-Ask)/mPoint),Digits);
      AmountProfit=OrderProfit();
   }
   if (Move.To.BreakEven.at.pips>0) s1="s/l will move to b/e after: "+DoubleToStr(Move.To.BreakEven.at.pips,1)+" pips   and lock: "+DoubleToStr(Move.To.BreakEven.Lock.pips,1)+" pips"+"\n\n";
   else                             s1="";
   Comment( ScreenComment,"\n",
            "s/l: ",StopLoss.Pips,"  tp:",TakeProfit.Pips,"  trail:",Trail.Pips,"\n",
            s1
          );
}


void Trail.Stop()
{  

   if (b.ticket > 0)
      TrailOrders(Trail.Start, Move.Trail.Every.xx.Pips, Trail.Pips, b.ticket);
   else if (s.ticket > 0)
      TrailOrders(Trail.Start, Move.Trail.Every.xx.Pips, Trail.Pips, s.ticket);
      
}

void MoveToBreakEven()
{  
   PosCounter();
   if (b.ticket > 0)
   {  
      OrderSelect(b.ticket,SELECT_BY_TICKET);
      if (OrderStopLoss()<OrderOpenPrice())
      {  
         if (Bid > Move.To.BreakEven.at.pips*mPoint + OrderOpenPrice())
         {  
            OrderModify(b.ticket, OrderOpenPrice(), OrderOpenPrice()+Move.To.BreakEven.Lock.pips*mPoint,OrderTakeProfit(),OrderExpiration(),MediumSpringGreen);
            if (OrderSelect(b.ticket,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("Long StopLoss Moved to BE at : ",DoubleToStr(OrderStopLoss(),Digits));
            else 
               Print("Error moving Long StopLoss to BE: ",GetLastError());
         }
      }
   }
   if (s.ticket > 0)
   {  
      OrderSelect(s.ticket,SELECT_BY_TICKET);
      if (OrderStopLoss()>OrderOpenPrice())
      {  
         if ( Ask < OrderOpenPrice()-Move.To.BreakEven.at.pips*mPoint)
         {  
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-Move.To.BreakEven.Lock.pips*mPoint,OrderTakeProfit(),OrderExpiration(),MediumVioletRed);
            if(OrderSelect(s.ticket,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("Short StopLoss Moved to BE at : ",DoubleToStr(OrderStopLoss(),Digits));
            else 
               Print("Error moving Short StopLoss to BE: ",GetLastError());
         }
      }
   }
}


bool TrailOrders(double start, double step, double value , int ticket)
{
   OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(Profit(OrderType(),OrderOpenPrice()) > start)
   {
      if(OrderType()==OP_BUY && Bid - OrderStopLoss() >= (step+value)*mPoint)
      {
         OrderModify(OrderTicket(),OrderOpenPrice(),Bid-(value*mPoint),OrderTakeProfit(),0,Red);
//         Print("Trailing order ", Bid-(value*mPoint)," Profit ", Profit(OrderType(),OrderOpenPrice()), " Bid ", DoubleToStr(Bid,Digits)," Ask ", DoubleToStr(Ask,Digits));
      }
      if(OrderType()==OP_SELL && OrderStopLoss() - Ask >= (step+value)*mPoint)
         OrderModify(OrderTicket(),OrderOpenPrice(),Ask + (value*mPoint),OrderTakeProfit(),0,Red);
         //Print("Trailing order");
   }  
}


double Profit(int type, double open)
{
   if(type==OP_BUY) return((Bid - open)/mPoint); 
   if(type ==OP_SELL) return((open - Ask)/mPoint);
   return(-1);
}


