//+------------------------------------------------------------------+
//|                                                        Feb10.mq4 |
//|                                             Komgrit Sungkhaphong |
//|                               http://iamforextrader.blogspot.com |
//+------------------------------------------------------------------+

//version50
// -allow user to run multiple instance of bot for the same pair, by specifying the MAGIC number

//version60
// -reduce chan

//v66ba
//-make it compatible to mt4 build 6XX
//-4-digit broker compatible

#property copyright "Komgrit Sungkhaphong"
#property link      "http://iamforextrader.blogspot.com"
/*
#include "libraries\Trade.mq4"
#include "libraries\OAmq4"
#include "libraries\Lib.mq4"
*/
#include <Trade-cf.mqh>
#include <OA-cf.mqh>
#include <Lib-cf.mqh>

#define currentversion "66c"

#define state_idle         0
#define state_await_buy    500
#define state_await_sell    600
#define state_buy1          1000
#define state_sell1         2000
#define state_buy2          1800
#define state_sell2         2800

#define state_buy2_hold     1900
#define state_sell2_hold    2900

#define state_revbuy_tradesell  1500
#define state_revsell_tradebuy  2500

#define state_revbuy_tradesell_trail  1599
#define state_revsell_tradebuy_trail  2599


//+------------------------------------------------------------------+
//| User Define variables                                   |
//+-----------------------------------------------------------------+
extern bool UseAutoID=true;
extern int User_define_Bot_ID=1000;
extern int UserDefine_SpreadTooHigh=60;   //Points
extern double init_lot_size=0.1;
extern double exponent=1.44;
extern double squeeze_factor=0.3;

extern int TradeTF = 15;
extern int atr_range=24;
extern int candles_range=12;
extern int Calm_candles=8;
extern string Calm_range_info="unit in point";
extern int Calm_range=200;

//extern int D1_Candles=5;
extern int D1_atr_range=10;

extern double HoldMinutes=60;
extern int  High_Or_Low_Diff=40;


int atr_period=60;
//+------------------------------------------------------------------+
//| Order Issue Interlocking                                                 |
//+------------------------------------------------------------------+

datetime timestamp_buy;
datetime timestamp_sell;
datetime timestamp_close;
int MinutesToUnlock_buy;
int MinutesToUnlock_sell;
//+------------------------------------------------------------------+
//| Multiple Orders Control                                                 |
//+------------------------------------------------------------------+
//    [0][]=ticket number
//    [1][]=lots
//    [2][]=price
double OrderAcc_buy[25][3];
double OrderAcc_sell[25][3];
int lastticket;
double pl;              //pips
double cummpl;
double thisBreakEven;   //price
double distance_Loss;   //pips
double distance_Gain;   //pips
double lots;
double propose_new_stoploss;
double expect_stoploss;
double target_gain;
double new_target_price;
double new_stop_loss;
bool calbreak_flag;
bool TP_is_too_low=false;

double max_gain;
double max_loss;
double estimate_max_loss;
double RRR;
int bbb; //bar count in Isnewbar
datetime laststamp;
datetime BlockBuyUntilTime;
datetime BlockSellUntilTime;
datetime MultiOrderStateTimeStamp;
datetime MultiOrderStateTimeStamp_buy;
datetime MultiOrderStateTimeStamp_sell;
int      MultiOrderState_Age;
double ThisOpenPrice;
double PercentileSafetyLevel;
int CMD;
double newMark;
//+------------------------------------------------------------------+
//| State machine variables                                                  |
//+------------------------------------------------------------------+
int state;
string now;
double tickcount,_tickcount;
//+------------------------------------------------------------------+
//| General variables                                                  |
//+------------------------------------------------------------------+
static int MAGIC;
string comment_string;
string comments;
int RetError;
double SPREAD;
double X45;
string units;
double DECPIP;
string BROKER45;
//+------------------------------------------------------------------+
//| Indicators                                                 |
//+------------------------------------------------------------------+
double ATR;
double fastATR;
double ATR_Slope;
double dailyATR;
double lowerbound;
double upperbound;

int     iPip2Pnt;    // slippage  3 pips    3=points    30=points
double  dPip2Dbl;       // Stoploss 15 pips    0.0015      0.00150
int     Digits_pips;    // DoubleToStr(dbl/pips2dbl, Digits_pips)
   string mesg;
double   newBarTFc;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   if(UseAutoID==true)
   {
      MAGIC=MAGIC_LIST_BY_SYMBOL();
   }
   else
   {
      MAGIC=User_define_Bot_ID;
   }
   //MAGIC=MAGIC_LIST_BY_SYMBOL();
   
   //v66ba 
   //create one point to pip for 4 digit broker
   DECPIP=MathPow(10,Digits);
   units=" Point";
   X45=1;
   switch(Digits) {
      case  5: {
         BROKER45="5-digits";
         Print("v66cf: You are running with 5 digit broker server.");
         break;
      }
      case  4: {
         BROKER45="4-digits";
         X45=0.1;
         units=" Pip";
         Print("v66cf: You are running with 4 digit broker server.");
         break;
      }  
      case  3: {
         BROKER45="3-digits";
         Print("v66cf: You are running with 3 digit broker server.");
         break;
      }      
      case  2: {
         BROKER45="2-digits";
         units=" Pip";
         Print("v66cf: You are running with 3 digit broker server.");
         break;
      }
      case  1: {
         BROKER45="1-digits";
         units=" Pip";
         Print("v66cf: You are running with 3 digit broker server.");
         break;
      }
     }
   VerifyTkt();
      
   if(IsDemo())   comment_string="DEMO"+"\n";
   else comment_string="LIVE"+"\n";
   comment_string=comment_string+"Magic Number="+MAGIC+"\n";   
//----  Account detail
   string _account_string;
   _account_string="Broker:"+AccountCompany()+"\n";
   _account_string=_account_string+"ID:"+AccountNumber()+"\n";
   _account_string=_account_string+"Name:"+AccountName()+"\n";
   
   comment_string=comment_string+_account_string;
   Comment(comment_string);
   
   BlockBuyUntilTime=TimeCurrent()-1*60*60;
   BlockSellUntilTime=TimeCurrent()-1*60*60;
   
//---- init the state
   state=state_idle;
//----
 if(Symbol() == "EURAUD-")
  {
    mesg = " pt "+DoubleToStr(Point, Digits)+" tk "+lastticket+" dg "+DoubleToStr(Digits, 0);
    StatLabs("ndyFmkt", mesg, 1, 50, 100, 8, LawnGreen);
//    mesg = " HL "+DoubleToStr((HP(candles_range)-LP(candles_range))*DECPIP, Digits)+" HL "+DoubleToStr(RangeHighLow, 0)+" R "+DoubleToStr(HP(candles_range)-LP(candles_range), Digits);
//    StatLabs("ndyFmkt1", mesg, 1, 50, 115, 8, LawnGreen);
// StatLabs("ndySPlk",  " Dig "+Digits+" pt "+DoubleToStr(Point,Digits)+" X45 "+DoubleToStr(X45,Digits), 3, 55, 20, 8, LawnGreen);
   }
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }

void  VerifyTkt() {
   //+-------------
   //v66c
   //scan for opened tickets
   OrderAccounting();
   
   
   //find last ticket
   for(int i=0;i<OrdersTotal();i++) {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
         //is this order ours
         if(OrderSymbol()==Symbol()) {
            if(OrderMagicNumber()==MAGIC) {
               if(OrderTicket()>lastticket) {
                  //get lastticket number
                  lastticket=OrderTicket();
                  switch(OrderType()) {
                     case  OP_BUY:
                       timestamp_buy=OrderOpenTime();
                       break;
                     case  OP_SELL:
                       timestamp_sell=OrderOpenTime();
                       break;
     } } } } } }
   //after scan thru all orders

   //end v66c
   //+-------------
   }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   RefreshRates();
   
   //v66ba
   SPREAD=Ask-Bid;   
   //SPREAD=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD);
   status("You are running "+BROKER45);
   
   int power;

//----Info
   comments="";
   tickcount=GetTickCount();


//----Graphics
    if (Digits == 5 || Digits == 3){    // Adjust for five (5) digit brokers.
                dPip2Dbl    = Point*10; iPip2Pnt = 10;   Digits_pips = 1; 
    } else {    dPip2Dbl    = Point;    iPip2Pnt =  1;   Digits_pips = 0;  }
   if(Digits == 6) {
    mesg = " dPip2Dbl "+DoubleToStr(dPip2Dbl, Digits)+" iPip2Pnt "+iPip2Pnt+" Digits_pips "+DoubleToStr(Digits_pips, 0);
    MkLabel("ndyFmkt", mesg, 3, 50, 50, 8, LawnGreen);
    mesg = " Point "+DoubleToStr(Point, Digits)+" Digits "+Digits+" X45 "+DoubleToStr(X45, Digits)+" lim "+DoubleToStr(UserDefine_SpreadTooHigh*Point*X45,Digits);
    MkLabel("ndyFmkt1", mesg, 3, 50, 35, 8, LawnGreen);
 StatLabs("ndySPlk",  " Dig "+Digits+" pt "+DoubleToStr(Point,Digits)+" X45 "+DoubleToStr(X45,Digits), 3, 55, 20, 8, LawnGreen);
   }

//----Time Control
   MinutesToUnlock_buy=timestamp_buy+HoldMinutes*60-TimeCurrent();
   MinutesToUnlock_buy=MinutesToUnlock_buy/60;
   if(MinutesToUnlock_buy<0)   MinutesToUnlock_buy=0;
   
   MinutesToUnlock_sell=timestamp_sell+HoldMinutes*60-TimeCurrent();
   MinutesToUnlock_sell=MinutesToUnlock_sell/60;
   if(MinutesToUnlock_sell<0)   MinutesToUnlock_sell=0;
//----name of State Machine   
//    This will be shown on the trading comment view

   //#statenamecode #stateshort #abbr
   Run_CurrentStateShortCode();   
   //set tate order command for new order either OP_BUY or OP_SELL
   //#ordercommand
   Run_OrderCommand();
   //#statetransition #transition
   Run_State_Transition();
   //#timestampcontrol
   Run_TimeStampControl();
   //Comment message generating sections
   //#commentary #commentmessage
   Run_Comment();
//----Actions State Machine
   switch(state)
   {
      case state_idle:
      {
      //----State's action
         //create range upper and lower bounds
         max_gain=0;
         max_loss=0;
         
         //#spreadlock
         //if spread is more than 60, this bot would do nothing. 
         if(SPREAD>UserDefine_SpreadTooHigh*Point*X45)
         {
            //v66ba
            
            Comment("Point="+DoubleToStr(Point,Digits)+" Spread is too high ="+IntegerToString(SPREAD)+" (limit="+DoubleToStr(UserDefine_SpreadTooHigh*Point*X45,Digits)+")");
            return(0);
         }   
         //#entry #entries
         if(IsNoPosition() && TimeCurrent()>timestamp_close+HoldMinutes*60  )
         {
         //-----trigger trade buy
            if(CandleRange(5)>Calm_range*Point*X45)
            {
               expect_stoploss=0;
               if(TimeCurrent()>BlockBuyUntilTime)
               {
                  PercentileSafetyLevel=PercentileSafetyLevel(OP_BUY,24);
                  if(PercentileSafetyLevel<30)
                  {
                     //if(iClose(Symbol(),PERIOD_M1,1)>HP(3))
                     
                     if(Bid<LP(3))
                     {
                        lastticket=Trade_Market(OP_BUY,timestamp_buy,init_lot_size,expect_stoploss,0,"MB");
                     }   
                  }   
               }   
            }   
         //-----trigger trade sell
            if(CandleRange(5)>Calm_range*Point*X45)
            {
               expect_stoploss=0;
               if(TimeCurrent()>BlockSellUntilTime)
               {
                  PercentileSafetyLevel=PercentileSafetyLevel(OP_SELL,24);
                  if(PercentileSafetyLevel<30)
                  {
                     //if(iClose(Symbol(),PERIOD_M1,1)<LP(3))
                     
                     if(Ask>HP(3))
                     {
                        lastticket=Trade_Market(OP_SELL,timestamp_sell,init_lot_size,expect_stoploss,0,"MS");
                     }   
                  }   
               }   
            }   
         }   
      
      //----transition
         if(IsBuy()) state=state_buy1;
         if(IsSell()) state=state_sell1;
         
         
      //----v66c
         if(IsBuys()) state=state_buy2;
         if(IsSells()) state=state_sell2;
      //----end v66c
         break;
      }
      case state_await_buy:
      {
         break;
      }   
      case state_await_sell:
      {
         break;
      }
      case state_buy1:
      {
      //----state's action
         CommonSingleOrderState();

         if(pl<=-xpips(ATR) && TimeCurrent()-laststamp>hr_sec(10))
         //else if(pl<=-20)
         {
 
            if(HP(Calm_candles)-LP(Calm_candles)<Calm_range*Point*X45||(MathAbs(Low[2]-Low[1])<High_Or_Low_Diff*Point*X45))
            {
               Remove_StopLoss(lastticket);
               lastticket=Trade_Market(OP_BUY,timestamp_buy,init_lot_size,0,0,"Recovery");
               
            }   

         }
      //----transition
         if(IsNoPosition() && Bid>LP(5))
         {            
            state=state_idle;
            timestamp_close=TimeCurrent();
         }   
         if(IsNoPosition() && Bid<LP(5))
         {
            state=state_revbuy_tradesell;
            timestamp_close=TimeCurrent();
         }   
         if(IsBuys()){   state=state_buy2;   calbreak_flag=true;  MultiOrderStateTimeStamp_buy=TimeCurrent();}
         break;
      }
      case state_sell1:
      {
      //----state's action
         CommonSingleOrderState();
         
         if(pl<=-xpips(ATR)&& TimeCurrent()-laststamp>hr_sec(10))
         //else if(pl<=-20)
         {

            if(HP(Calm_candles)-LP(Calm_candles)<Calm_range*Point*X45||(MathAbs(High[2]-High[1])<High_Or_Low_Diff*Point*X45))
            {
               Remove_StopLoss(lastticket);
               lastticket=Trade_Market(OP_SELL,timestamp_sell,init_lot_size,0,0,"Recovery");
            }   

         }
      //----transition
         if(IsNoPosition() && Bid<HP(5))
         {            
            state=state_idle;
            timestamp_close=TimeCurrent();
         }   
         if(IsNoPosition() && Bid>HP(5))
         {
            state=state_revsell_tradebuy;
            timestamp_close=TimeCurrent();
         }   
         if(IsSells()){   state=state_sell2; calbreak_flag=true; MultiOrderStateTimeStamp_sell=TimeCurrent();}
         break;
      }
      case state_buy2:
      {
         power=OACount(MAGIC,OP_BUY,Symbol());

         if(calbreak_flag==true)
         {
            lots=init_lot_size*MathPow(exponent,power);
            lots=NormalizeLotSize(lots);
            status("Next Lot Size="+DoubleToStr(lots,2));
            target_gain=squeeze_factor*ATR;
            if(target_gain<30*Point*X45) target_gain=30*Point*X45;
            new_target_price=thisBreakEven+target_gain;

            //enforce if recovery orders are more than xx number, just got all of them close ASAP
            if(power>=4 && power<8) new_target_price=thisBreakEven+0.5*target_gain;
            if(power>=8 ) new_target_price=thisBreakEven+0.1*target_gain;
            
            ModifyTakeProfit(OP_BUY,new_target_price);
            calbreak_flag=false;

         }

         
         
         if(pl<=-xpips(2*ATR)&& pl<=-xpips(0.2*dailyATR) )
         //if(pl<=-20)
         {
            if(IsTimeUnlocked_buy())
            {
               if(CandleRange(Calm_candles)<Calm_range*Point*X45||Close[2]-Close[1]>0.3*ATR)
               {
                  lastticket=Trade_Market(OP_BUY,timestamp_buy,lots,0,0,"Recovery");
                  if(OrderSelect(lastticket,SELECT_BY_TICKET)) calbreak_flag=true;
               }   
            }
         }

         //the state is more than 7 hours old
         if(MultiOrderState_Age>hr_sec(24))
         {
            if(cummpl>=8)
            {
               //ModifyStopLoss(OP_BUY,thisBreakEven+10*Point*X45);
               OrderCloseAll(OP_BUY);
            }
         }

      //----transition
         if(IsNoPosition() && Bid>LP(4))
         {
            timestamp_close=TimeCurrent();
            state=state_idle;
         }   
         if(IsNoPosition() && Bid<LP(4))   state=state_revsell_tradebuy;
         
         //Is new bar?
         if(iBars(Symbol(),TradeTF)>bbb)
         {
            if(cummpl>0)
            {
               state=state_buy2_hold;
               //ModifyStopLoss(CMD,thisBreakEven);
               ModifyTakeProfit(CMD,High[1]+100*Point*X45);
            }   
            bbb=iBars(Symbol(),TradeTF);
         }
         
         break;
      }

      case state_sell2:
      {        

         power=OACount(MAGIC,OP_SELL,Symbol());
         if(calbreak_flag==true)
         {         
            lots=init_lot_size*MathPow(exponent,power);
            lots=NormalizeLotSize(lots);
            status("Next Lot Size="+DoubleToStr(lots,2));
            target_gain=squeeze_factor*ATR;
            if(target_gain<30*Point*X45) target_gain=30*Point*X45;
            new_target_price=thisBreakEven-target_gain;
            //enforce if recovery orders are more than xx number, just got all of them close ASAP
            if(power>=4 && power<8) new_target_price=thisBreakEven-0.5*target_gain;
            if(power>=8) new_target_price=thisBreakEven-0.1*target_gain;

            
            ModifyTakeProfit(OP_SELL,new_target_price);
            calbreak_flag=false;
            TP_is_too_low=false;
         }
         
         
         if(pl<=-xpips(2*ATR)&& pl<=-xpips(0.2*dailyATR) )
         //if(pl<=-20)
         {
            if(IsTimeUnlocked_sell())
            {
               if(CandleRange(Calm_candles)<Calm_range*Point*X45||Close[1]-Close[2]>0.3*ATR)
               {
                  lastticket=Trade_Market(OP_SELL,timestamp_sell,lots,0,0,"Recovery");
                  if(OrderSelect(lastticket,SELECT_BY_TICKET)) calbreak_flag=true;
               }   
            }   

         }


         if(MultiOrderState_Age>hr_sec(24))
         {
            if(cummpl>=8)
            {
               //ModifyStopLoss(OP_BUY,thisBreakEven-10*Point*X45);
               OrderCloseAll(OP_SELL);
            }
         }

      //----transition
         if(IsNoPosition() && Bid<HP(4))
         {
            timestamp_close=TimeCurrent();
            state=state_idle;
         }   
         if(IsNoPosition() && Bid>HP(4))   state=state_revsell_tradebuy;
         
         
         //Is new bar?
         if(iBars(Symbol(),TradeTF)>bbb)
         {
            if(cummpl>0)
            {
               state=state_sell2_hold;
               //ModifyStopLoss(CMD,thisBreakEven);
               ModifyTakeProfit(CMD,Low[1]-100*Point*X45);
            }   
            bbb=iBars(Symbol(),TradeTF);
         }
         
         
         break;
      }
      case state_buy2_hold:
      {
         newMark=LP(2);
         if(iBars(Symbol(),TradeTF)>bbb)
         {
            if(newMark>thisBreakEven)
            {
               ModifyStopLoss(CMD,newMark);
               ModifyTakeProfit(CMD,High[1]+100*Point*X45);
            }
            bbb=iBars(Symbol(),TradeTF);
         }
         if(IsNoPosition())
         {
            timestamp_close=TimeCurrent();
            state=state_idle;
         }   
         break;
      }   
      case state_sell2_hold:
      {
         newMark=HP(2);
         if(IsNoPosition())
         {
            if(newMark<thisBreakEven)
            {
               ModifyStopLoss(CMD,newMark);
               ModifyTakeProfit(CMD,Low[1]-100*Point*X45);
            }
            timestamp_close=TimeCurrent();
            state=state_idle;
         } 
         break;
      }
      case state_revbuy_tradesell:
      {
         //lastticket=Trade_Market(OP_SELL,timestamp_sell,2*init_lot_size,lowerbound,0,"Reverse_buy");
         lastticket=Trade_Market(OP_SELL,timestamp_sell,2*init_lot_size,Ask+0.4*ATR,0,"Reverse_buy");
         Print(state+":Reverse Order has been placed, SELL ticket #"+lastticket);
         
      //---- transition
         if(IsSell() && IsNoBuy())   state=state_revsell_tradebuy_trail;
         if(IsNoPosition())   
         {
            timestamp_close=TimeCurrent();
            state=state_idle;
         }   
         break;
      }
      case state_revsell_tradebuy:
      {
         //lastticket=Trade_Market(OP_BUY,timestamp_buy,2*init_lot_size,upperbound,0,"Reverse_trail");
         lastticket=Trade_Market(OP_BUY,timestamp_buy,2*init_lot_size,Bid-0.4*ATR,0,"Reverse_trail");
         Print(state+":Reverse Order has been placed, BUY ticket #"+lastticket);
      
      //---- transition
         if(IsBuy() && IsNoSell())    state=state_revsell_tradebuy_trail;
         if(IsNoPosition())
         {
            timestamp_close=TimeCurrent();
            state=state_idle;
         }   
         break;
      }
      
      case  state_revbuy_tradesell_trail:
      {

         ftx(lastticket);
      
      //---- transition
         if(IsNoPosition())   
         {
            timestamp_close=TimeCurrent();
            state=state_idle;
         } 
         break;
      }
      case  state_revsell_tradebuy_trail:
      {

         ftx(lastticket);
         
      
      //---- transition
         if(IsNoPosition())   
         {
            timestamp_close=TimeCurrent();
            state=state_idle;
         } 
         break;
      }
   }
   _tickcount=GetTickCount()-tickcount;
   status("processing time="+DoubleToStr(_tickcount,2)+"ms");
   Comment(comment_string+comments);
//----
   return(0);
  }
//+------------------------------------------------------------------+
/*
int MAGIC_LIST_BY_SYMBOL()
{
//---
   int _magic;
   if(Symbol()=="GBPUSD")  _magic=100;
   if(Symbol()=="EURUSD")  _magic=110;
   if(Symbol()=="USDCHF")  _magic=120;
   if(Symbol()=="AUDUSD")  _magic=130;
   if(Symbol()=="NZDUSD")  _magic=140;
   if(Symbol()=="USDCAD")  _magic=150;
   if(Symbol()=="USDJPY")  _magic=160;
   
   if(Symbol()=="GBPAUD")  _magic=200;
   if(Symbol()=="GBPNZD")  _magic=210;
   if(Symbol()=="GBPCAD")  _magic=220;
   if(Symbol()=="GBPCHF")  _magic=230;
   if(Symbol()=="GBPJPY")  _magic=240;
   if(Symbol()=="EURGBP")  _magic=250;
   
   if(Symbol()=="EURAUD")  _magic=300;
   if(Symbol()=="EURNZD")  _magic=310;
   if(Symbol()=="EURCAD")  _magic=320;
   if(Symbol()=="EURCHF")  _magic=330;
   if(Symbol()=="EURJPY")  _magic=340;
   
   
//---   
   return(_magic);
}

bool IsNoPosition()
{
   if(OACount(MAGIC,OP_BUY,Symbol())==0 && OACount(MAGIC,OP_SELL,Symbol())==0) return(true);
   else return(false);
}

bool IsBuy()
{
   if(OACount(MAGIC,OP_BUY,Symbol())==1) return(true);
   else return(false);
}

bool IsBuys()
{
   if(OACount(MAGIC,OP_BUY,Symbol())>=2) return(true);
   else return(false);
}

bool IsNoBuy()
{
   if(OACount(MAGIC,OP_BUY,Symbol())==0) return(true);
   else return(false);
}

bool IsSell()
{
   if(OACount(MAGIC,OP_SELL,Symbol())==1) return(true);
   else return(false);
}

bool IsSells()
{
   if(OACount(MAGIC,OP_SELL,Symbol())>=2) return(true);
   else return(false);
}

bool IsNoSell()
{
   if(OACount(MAGIC,OP_SELL,Symbol())==0) return(true);
   else return(false);
}
*/
void status(string msg)
{
   comments=comments+">>"+now+">>"+msg+"\n";
   return;
}

void OrderAccounting()
{
   ArrayInitialize(OrderAcc_buy,0);
   ArrayInitialize(OrderAcc_sell,0);
   int countb=0;
   int counts=0;

   for(int i=0;i<OrdersTotal();i++)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
      {
         if(OrderMagicNumber()==MAGIC)
         {
            if(OrderType()==OP_BUY)
            {
               OrderAcc_buy[countb][0]=OrderTicket();
               OrderAcc_buy[countb][1]=OrderLots();
               OrderAcc_buy[countb][2]=OrderOpenPrice();
               countb++;
            }
            if(OrderType()==OP_SELL)
            {
               OrderAcc_sell[counts][0]=OrderTicket();
               OrderAcc_sell[counts][1]=OrderLots();
               OrderAcc_sell[counts][2]=OrderOpenPrice();
               counts++;
            }
         }
      }
   }
   return;
}

double BreakEvenPrice(int side)
{
   int size;
   int i;
   double SumLots=0;
   double SumPriceLots=0;
   double breakeven;
   switch(side)
   {
      case OP_BUY:
      {
         size=ArraySize(OrderAcc_buy);
         for(i=0;i<size;i++)
         {
            if(OrderAcc_buy[i][0]!=0)
            {
               SumLots=SumLots+OrderAcc_buy[i][1];
               SumPriceLots=SumPriceLots+(OrderAcc_buy[i][1]*OrderAcc_buy[i][2]);
               if(SumLots>0) breakeven=SumPriceLots/SumLots;
               else Print("BreakEvenPrice:OP_BUY: error SumLots is zero!");
            }
         }
         break;
      }
      case OP_SELL:
      {
         size=ArraySize(OrderAcc_sell);
         for(i=0;i<size;i++)
         {
            if(OrderAcc_sell[i][0]!=0)
            {
               SumLots=SumLots+OrderAcc_sell[i][1];
               SumPriceLots=SumPriceLots+(OrderAcc_sell[i][1]*OrderAcc_sell[i][2]);
               if(SumLots>0) breakeven=SumPriceLots/SumLots;
               else Print("BreakEvenPrice:OP_SELL: error SumLots is zero!");
            }
         }

         break;
      }
   }
   return(breakeven);
}



//#ft
void ftx(int ticketnumber)
{
   double quote;
   double distance;
   double master_distance;
   double propose_stop;
   bool  price_ok=true;
   double MarkedDistance;
   double offset1,offset2;
   MarkedDistance=80*Point*X45;
   offset1=30*Point*X45;
   offset2=70*Point*X45;
   if(offset2>=MarkedDistance-30*Point*X45)   offset2=30*Point*X45;
   
   double minstop=MarketInfo(OrderSymbol(),MODE_STOPLEVEL)*Point*X45;
   master_distance=150*Point*X45;
   if(OrderSelect(ticketnumber,SELECT_BY_TICKET)==true && OrderCloseTime()==0)
     {      
      if(OrderType()==OP_BUY)
        {
         quote=Bid;
         if(OrderStopLoss()==0 || OrderStopLoss()<OrderOpenPrice())
           {
            distance=Bid-OrderOpenPrice();
            if(distance>MarkedDistance)
              {
               propose_stop=OrderOpenPrice()+offset1;
              }
           }
         if(OrderStopLoss()>OrderOpenPrice())
           {
            distance=Bid-OrderStopLoss();
            if(distance>MarkedDistance)
              {
               propose_stop=Bid-offset2;
              }
           }
         propose_stop=NormalizeDouble(propose_stop,Digits);
         if(propose_stop!=0 && propose_stop<Bid && (propose_stop<OrderOpenPrice()-minstop||propose_stop>OrderOpenPrice()))
         {
            if(OrderModify(OrderTicket(),OrderOpenPrice(),propose_stop,OrderTakeProfit(),OrderExpiration(),CLR_NONE)==true)
            {
               Print("Modify order stoploss success.");
            }
         }   
        }
      else if(OrderType()==OP_SELL)
        {
         quote=Ask;
         if(OrderStopLoss()==0 || OrderStopLoss()>OrderOpenPrice())
           {
            distance=OrderOpenPrice()-Ask;
            if(distance>MarkedDistance)
              {
               propose_stop=OrderOpenPrice()-offset1;
              }
           }
         if(OrderStopLoss()<OrderOpenPrice())
           {
            distance=OrderStopLoss()-Ask;
            if(distance>MarkedDistance)
              {
               propose_stop=Ask+offset2;
              }
           }
         propose_stop=NormalizeDouble(propose_stop,Digits);
         if(propose_stop!=0 && propose_stop>Ask && (propose_stop>OrderOpenPrice()+minstop||propose_stop<OrderOpenPrice()))
         {
         
            if(OrderModify(OrderTicket(),OrderOpenPrice(),propose_stop,OrderTakeProfit(),OrderExpiration(),CLR_NONE)==true)
            {
               Print("Modify order stoploss success.");
            }
         }   
        }
         
         
     }
}




void showmycomment_CurrentRange()
{
   double RangeHighLow;
//   lowerbound =LP(candles_range)-100*Point*X45;
//   upperbound =HP(candles_range)+100*Point*X45;
   ATR=iATR(Symbol(),PERIOD_H1,atr_range,1);
//   fastATR=iATR(Symbol(),PERIOD_H1,atr_range/2,1);
   dailyATR=iATR(Symbol(),PERIOD_D1,D1_atr_range,1);
   if(ATR<100*Point*X45)  ATR=100*Point*X45;
   
   double trigger_entry_range=HP(5)-LP(5);
   trigger_entry_range=trigger_entry_range*DECPIP;
   //double val=iCustom(NULL,0,"Candlestop",5,1,0);
   /*
   double array_atr[4];
   array_atr[0]=iATR(Symbol(),0,atr_range,1);
   array_atr[1]=iATR(Symbol(),0,atr_range,2);
   array_atr[2]=iATR(Symbol(),0,atr_range,3);
   array_atr[3]=iATR(Symbol(),0,atr_range,4);
   ATR_Slope=GetSlope(array_atr)*100000;
   */
   RangeHighLow=xpips(HP(candles_range)-LP(candles_range)); //y = HP(candles_range)-LP(candles_range);
   RangeHighLow=(HP(candles_range)-LP(candles_range))*DECPIP;
//   RangeHighLow=RangeHighLow*DECPIP;    <--- I took this out since xpips already did that...
   status("candles_range("+candles_range+")="+DoubleToStr(RangeHighLow,0)+units);
   status("TriggerRange="+DoubleToStr(trigger_entry_range,0)+units);
   status("ATR("+atr_range+")="+DoubleToStr(ATR*DECPIP,0)+units);
   status("dailyATR("+D1_atr_range+")="+DoubleToStr(dailyATR*DECPIP,0)+units);
   if(Symbol() == "EURAUD-")
  {
    mesg = " y "+DoubleToStr(2, Digits)+" xy "+DoubleToStr(2*MathPow(10,Digits), Digits)+" ONE "+DoubleToStr(100*Point*X45, Digits);
    StatLabs("ndyFmkt", mesg, 1, 50, 100, 8, LawnGreen);
    mesg = " H "+DoubleToStr(HP(5), Digits)+" L "+DoubleToStr(LP(5), Digits)+" R "+DoubleToStr(HP(5)-LP(5), Digits);
    StatLabs("ndyFmkt1", mesg, 1, 50, 115, 8, LawnGreen);
// StatLabs("ndySPlk",  " Dig "+Digits+" pt "+DoubleToStr(Point,Digits)+" X45 "+DoubleToStr(X45,Digits), 3, 55, 20, 8, LawnGreen);
   }
   return;
}

void showmycomment_LastTicket()
{
   pl=OAPLPips(lastticket);
   if(OrderSelect(lastticket,SELECT_BY_TICKET)==true)
   {
      ThisOpenPrice=OrderOpenPrice();
   }
   status("Last Ticket="+lastticket);
   status("Profit/Loss="+DoubleToStr(pl,1)+"pips");
   return;
}

void showmycomment_timeunlocked_buy()
{
   status("Last Time Stamp="+TimeToStr(timestamp_buy,TIME_MINUTES)+", Minutes to unlock time="+MinutesToUnlock_buy+" mins");
   return;
}
void showmycomment_timeunlocked_sell()
{
   status("Last Time Stamp="+TimeToStr(timestamp_sell,TIME_MINUTES)+", Minutes to unlock time="+MinutesToUnlock_sell+" mins");
   return;
}

void Remove_StopLoss(int ticketnumber)
{
   //Remove stop loss price first before do martingale to recovery
   status("Remove_StopLoss: Removing stoploss on ticket #"+ticketnumber);
   bool selected=false;
   if(OrderSelect(ticketnumber,SELECT_BY_TICKET))
      selected=true;
   if(OrderModify(OrderTicket(),OrderOpenPrice(),0,OrderTakeProfit(),OrderExpiration(),Gray)==true && selected)
   {
      Print(state+":Remove_StopLoss: Stoploss for order #"+ticketnumber+" is now set to zero");
   }
   else
   {
      Print(state+":Error in Remove_StopLoss: Code="+GetLastError());
   }
   return;
}

// Trade_Market(OP_BUY,0.1,"Main",0,0,timestamp_buy);
int Trade_Market(int side,datetime& _timestamp,double lot_size,double stop_price=0,double target_price=0,string comment="")
{
   int retTicket=0;
   if(side==OP_BUY)  retTicket=Trade_Buy(Symbol(),MAGIC,lot_size,stop_price,target_price,comment);
   if(side==OP_SELL)  retTicket=Trade_Sell(Symbol(),MAGIC,lot_size,stop_price,target_price,comment);
   _timestamp=TimeCurrent();
   
   if(retTicket>0)
   {
      Print(state+":Trade_Market: Placed order successfully, ticket #"+retTicket);
   }
   return(retTicket);
}
void showmycomment_ListOrder_buy()
{
   status("//------------Order List (Ticket, Lots, Price) -----------------//");
   status("// Recovery orders count="+OACount(MAGIC,OP_BUY,Symbol()));
//----state's action
   OrderAccounting();
   for(int index=0;index<25;index++)
   {
      if(OrderAcc_buy[index][0]!=0)
      {
         status("//----  #"+index+" |"+DoubleToStr(OrderAcc_buy[index][0],0)+", "+DoubleToStr(OrderAcc_buy[index][1],2)+", "+DoubleToStr(OrderAcc_buy[index][2],Digits)+"  ----//");
      }
   }
   thisBreakEven=BreakEvenPrice(OP_BUY);
   if(thisBreakEven-Bid>0)
   {
      distance_Loss=MathAbs(thisBreakEven-Bid)*MathPow(10,Digits-1);
      distance_Gain=0;
   }
   else if(thisBreakEven-Bid==0)
   {
      distance_Loss=0;
      distance_Gain=0;
   }
   else
   {
      distance_Loss=0;
      distance_Gain=MathAbs(thisBreakEven-Bid)*MathPow(10,Digits-1);
   } 
   
   status("Current breakeven price="+DoubleToStr(thisBreakEven,Digits));
   status("Distance to breakeven Loss/Gain="+DoubleToStr(distance_Loss,1)+", "+DoubleToStr(distance_Gain,1));
   return;
}

void showmycomment_ListOrder_sell()
{
   status("//------------Order List (Ticket, Lots, Price) -----------------//");
   status("// Recovery orders count="+OACount(MAGIC,OP_SELL,Symbol()));
//----state's action
   OrderAccounting();
   for(int index=0;index<25;index++)
   {
      if(OrderAcc_sell[index][0]!=0)
      {
         status("//----  #"+index+" |"+DoubleToStr(OrderAcc_sell[index][0],0)+", "+DoubleToStr(OrderAcc_sell[index][1],2)+", "+DoubleToStr(OrderAcc_sell[index][2],Digits)+"  ----//");
      }
   }
   thisBreakEven=BreakEvenPrice(OP_SELL);
   if(thisBreakEven-Ask>0)
   {
      distance_Loss=0;
      distance_Gain=MathAbs(thisBreakEven-Ask)*MathPow(10,Digits-1);
   }
   else if(thisBreakEven-Ask==0)
   {
      distance_Loss=0;
      distance_Gain=0;
   }
   else
   {

      distance_Loss=MathAbs(thisBreakEven-Ask)*MathPow(10,Digits-1);
      distance_Gain=0;

   } 
   
   status("Current breakeven price="+DoubleToStr(thisBreakEven,Digits));
   status("Distance to breakeven Loss/Gain="+DoubleToStr(distance_Loss,1)+", "+DoubleToStr(distance_Gain,1));
   return;
}
void Recovery_Close_All_buy()
{
   bool close_done=false;
   Print(state+":Recovery_Close_All_buy: Commencing closing seqeunce...");
   for(int index=0;index<25;index++)
   {
      if(OrderAcc_buy[index][0]!=0)
      {
         if(OrderSelect(OrderAcc_buy[index][0],SELECT_BY_TICKET)==true)
         {
            status("Selected Order #"+DoubleToStr(OrderAcc_buy[index][0],0)+", OK to close");
            close_done=OrderClose(OrderTicket(),OrderLots(),Bid,5,Salmon);
            while(IsTradeContextBusy())
            {
               status("Trade context is busy... (sleeping zZz)");
               Sleep(20);
            }
            if(close_done==true) Print(state+":Recovery_Close_All_buy: ._closed ticket #"+OrderTicket()+", CloseTime="+TimeToStr(OrderCloseTime(),TIME_MINUTES));
         }
      }
   }
   return;
}

void Recovery_Close_All_sell()
{
   bool close_done=false;
   Print(state+":Recovery_Close_All_sell: Commencing closing seqeunce...");
   for(int index=0;index<25;index++)
   {
      if(OrderAcc_sell[index][0]!=0)
      {
         if(OrderSelect(OrderAcc_sell[index][0],SELECT_BY_TICKET)==true)
         {
            status("Selected Order #"+DoubleToStr(OrderAcc_sell[index][0],0)+", OK to close");
            close_done=OrderClose(OrderTicket(),OrderLots(),Ask,5,PaleGreen);
            while(IsTradeContextBusy())
            {
               status("Trade context is busy... (sleeping zZz)");
               Sleep(20);
            }                  
            if(close_done==true) Print(state+":Recovery_Close_All_sell: ._closed ticket #"+OrderTicket()+", CloseTime="+TimeToStr(OrderCloseTime(),TIME_MINUTES));
         }
      }
   }
   return;
}

bool IsTimeUnlocked_buy()
{
   if(TimeCurrent()>timestamp_buy+HoldMinutes*60 && TimeCurrent()>timestamp_close+HoldMinutes*60)
      return(true);
   else return(false);   
}
bool IsTimeUnlocked_sell()
{
   if(TimeCurrent()>timestamp_sell+HoldMinutes*60 && TimeCurrent()>timestamp_close+HoldMinutes*60)
      return(true);
   else return(false);   
}

void ModifyTakeProfit(int typeorder, double newtakeprofit)
{
   int ticket;
   bool select_ok=false;
   bool price_ok=true;
   bool mod_ok=false;
   int retError=0;
   for(int i=0;i<25;i++)
   {
      if(typeorder==OP_BUY)
      {
         ticket=OrderAcc_buy[i][0];
      }
      else
      if(typeorder==OP_SELL)
      {
         ticket=OrderAcc_sell[i][0];
      }  
         
      select_ok=OrderSelect(ticket,SELECT_BY_TICKET);
      
      
      
      
      newtakeprofit=NormalizeDouble(newtakeprofit,MarketInfo(OrderSymbol(),MODE_DIGITS));
      
      if(MathAbs(newtakeprofit-OrderTakeProfit())<10*Point*X45)   price_ok=false;
      if(MathAbs(newtakeprofit-OrderOpenPrice())<10*Point*X45)   price_ok=false;
      if(MathAbs(newtakeprofit-OrderStopLoss())<10*Point*X45)   price_ok=false;
      
      if(newtakeprofit==OrderTakeProfit() || newtakeprofit==OrderOpenPrice() || newtakeprofit==OrderStopLoss())   price_ok=false;
      
      if(ticket>0 && MathAbs(newtakeprofit-OrderTakeProfit())>10*Point*X45 && select_ok && price_ok)
      {         
         mod_ok=OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),newtakeprofit,OrderExpiration(),PaleGreen);
         retError=GetLastError();
         if(retError!=0)
         {
            Print(now+", ModifyTakeProfit(),"+" Fail ModifyOrder() code"+retError);
         }
      }
      while(IsTradeContextBusy())
      {
         Sleep(100);
      }
      
   }
   return;
}

int hr_sec(int hours)
{
   return(hours*60*60);
}


void ModifyStopLoss(int typeorder, double newstoplosslevel)
{
   int ticket;
   bool select_ok=false;
   bool price_ok=true;
   bool mod_ok=false;
   int retError=0;
   int STOPLEVEL;
   STOPLEVEL=MarketInfo(OrderSymbol(),MODE_STOPLEVEL);
   for(int i=0;i<25;i++)
   {
      if(typeorder==OP_BUY)
      {
         ticket=OrderAcc_buy[i][0];
      }
      else
      if(typeorder==OP_SELL)
      {
         ticket=OrderAcc_sell[i][0];
      }  
         
      select_ok=OrderSelect(ticket,SELECT_BY_TICKET);
      
      newstoplosslevel=NormalizeDouble(newstoplosslevel,MarketInfo(OrderSymbol(),MODE_DIGITS));
      
      if(MathAbs(newstoplosslevel-OrderStopLoss())<10*Point*X45)  price_ok=false;
      if(newstoplosslevel==OrderOpenPrice())  price_ok=false;
      if(newstoplosslevel==OrderTakeProfit())  price_ok=false;
      
      //if(ticket>0 && MathAbs(newtakeprofit-OrderTakeProfit())>pips(1) && select_ok)
      if(
         ticket>0 && select_ok && price_ok
        )
         {            
            if(OrderType()==OP_BUY && newstoplosslevel<OrderOpenPrice() && newstoplosslevel>OrderOpenPrice()-STOPLEVEL*Point)
            {
               newstoplosslevel=OrderOpenPrice()+10*Point*X45;
            }
            if(OrderType()==OP_SELL && newstoplosslevel>OrderOpenPrice() && newstoplosslevel<OrderOpenPrice()+STOPLEVEL*Point)
            {
               newstoplosslevel=OrderOpenPrice()-10*Point*X45;
            }
            
            mod_ok=OrderModify(OrderTicket(),OrderOpenPrice(),newstoplosslevel,OrderTakeProfit(),OrderExpiration(),PaleGreen);
            retError=GetLastError();
            if(retError!=0)
            {
               Print(now+", ModifyStopLoss(),"+" Fail ModifyOrder() code"+retError);
            }
         }
      while(IsTradeContextBusy())
      {
         Sleep(100);
      }
      
   }
   return;
}

void RecordMaxGAINLOSS()
{
   string t;
   
   if(pl>max_gain && pl>0) max_gain=pl;
   if(pl<max_loss && pl<0) max_loss=pl;
   
   if(max_loss!=0)   RRR=MathAbs(max_gain/max_loss);  else RRR=-1;
   t="RRR"+DoubleToStr(RRR,2)+", MAXG"+DoubleToStr(max_gain,1)+", MAXL"+DoubleToStr(max_loss,1);
   
   status(t);
}


void OrderOpenTooLongAndNotMove()
{
   if(TimeCurrent()-laststamp>hr_sec(2) && TimeCurrent()-laststamp>hr_sec(8) && RRR!=0)
   {
      if(1/RRR>=1.5 && -max_loss>=10 && pl>=5)  
      {
         if(OrderClose(lastticket,OrderLots(),Bid,5,DarkGray)==true)
         {
            Print("Close order#"+lastticket+", REASON:OrderOpenTooLongAndNotMove(), LOGIC1");
            if(state==state_buy1) BlockBuyUntilTime=TimeCurrent()+15*60;
            if(state==state_sell1) BlockSellUntilTime=TimeCurrent()+15*60;
         }
      }      
   }
   
   if(TimeCurrent()-laststamp>hr_sec(3) && RRR!=0)
   {
      if(1/RRR>=5 && -max_loss>=10 && pl>=-20)  
      {
         if(OrderClose(lastticket,OrderLots(),Bid,5,Goldenrod)==true)
         {
            Print("Close order#"+lastticket+", REASON:OrderOpenTooLongAndNotMove(), LOGIC2");
            if(state==state_buy1) BlockBuyUntilTime=TimeCurrent()+15*60;
            if(state==state_sell1) BlockSellUntilTime=TimeCurrent()+15*60;
         }
      }      
   }

}

void BuyThenImmediateProfit()
{
   bool stochOBOS=false;
   double piptotake;
   //piptotake=xpips(fastATR);
   piptotake=10;
   //if(xpips(fastATR)<=10)   piptotake=5;
   if(TimeCurrent()-laststamp<hr_sec(1))
   {
      if(pl>=piptotake )
      {         
         if(OrderClose(lastticket,OrderLots(),Bid,5,Olive)==true)
         {
            Print("Close order#"+lastticket+", REASON:BuyThenImmediateProfit()");
            if(state==state_buy1) 
            {
               BlockBuyUntilTime=TimeCurrent()+15*60;
               //state=state_revbuy_tradesell;
            }   
            if(state==state_sell1)
            {
               BlockSellUntilTime=TimeCurrent()+15*60;
               //state=state_revsell_tradebuy;
            }   
         }
         
      }
   }

}

void CummPL()
{
   string t;
   switch(state)
   {
      case state_buy2:
      {
         cummpl=Bid-thisBreakEven;
         break;
      }
      case state_sell2:
      {
         cummpl=thisBreakEven-Ask;
         break;
      }
   }
   switch(Digits)
     {
      case  5:
      {
         cummpl=cummpl*MathPow(10,Digits-1);
         break;
      }
      case  4:
      {
         cummpl=cummpl*MathPow(10,Digits);
         break;
      }  
        
      default:
        break;
     }
   
   
   t="Cumm PL (pips)="+DoubleToStr(cummpl,2);
   status(t);
}
//#common
void CommonSingleOrderState()
{
   ftx(lastticket);
   if(iBars(Symbol(),TradeTF)>bbb)
   {
      OrderOpenTooLongAndNotMove();
      BuyThenImmediateProfit();
      //PositionLossAfterHrsthenClose();  
      bbb=iBars(Symbol(),TradeTF);
   }

}

double PercentileSafetyLevel(int side, int barnumber)
{
   double ceiling=HP(barnumber,2);
   double floorx=LP(barnumber,2);
   double mkt=Bid;
   double percentile;
   double per_b;
   double per_s;
   string t="";
   per_b=(mkt-floorx)/(ceiling-floorx)*100;
   per_s=(ceiling-mkt)/(ceiling-floorx)*100;
   t="(pips)BLK"+DoubleToStr(xpips(ceiling-floorx),1);
   t=t+", PERTB"+DoubleToStr(per_b,1);
   t=t+", PERTS"+DoubleToStr(per_b,1);
   if(side==OP_BUY)
   {
      percentile=per_b;
   }
   if(side==OP_SELL)
   {      
      percentile=per_s;
   }
   status(t);
   percentile=NormalizeDouble(percentile,2);
   return(percentile);
}

void OrderCloseAll(int side)
{
   int ticket;

   for(int i=0;i<25;i++)
   {
      if(side==OP_BUY)  ticket=OrderAcc_buy[i][0];
      if(side==OP_SELL)  ticket=OrderAcc_sell[i][0];
      if(OrderSelect(ticket,SELECT_BY_TICKET)==true)
      {
         if(OrderClose(OrderTicket(),OrderLots(),Bid,5,DarkGray)==true)
         {
            Print("close order, ticket#"+OrderTicket()+", REASON:OrderCloseAll()");
         }
      }
   }

   
}


void PositionLossAfterHrsthenClose()
{
   if(TimeCurrent()-laststamp>hr_sec(1) && TimeCurrent()-laststamp<hr_sec(3))
   {
      if(-max_loss>30 && RRR<0.1 && pl<-10)  
      {
         if(OrderClose(lastticket,OrderLots(),Bid,5,DarkGray)==true)
         {
            Print("Close order#"+lastticket+", REASON:PositionLossAfterHrsthenClose()");
            if(state==state_buy1) BlockBuyUntilTime=TimeCurrent()+HoldMinutes*60;
            if(state==state_sell1) BlockSellUntilTime=TimeCurrent()+HoldMinutes*60;
         }
      }      
   }
}



//#runcomment
void Run_Comment()
{
//----Signal Watchs & Infomartion/Comment
   switch(state)
   {
      case state_idle:
      {
      //----state info
         status("wating for signal...");
         showmycomment_CurrentRange();     
         break;
      }   
      case state_buy1:
      {
         status(".. trailing stop loss for buy pos");
         showmycomment_CurrentRange();
         showmycomment_timeunlocked_buy();
         showmycomment_LastTicket();
         RecordMaxGAINLOSS();

         
         break;
      }   
      case state_sell1:
      {
         status(".. trailing stop loss for sell pos");
         showmycomment_CurrentRange();
         showmycomment_timeunlocked_sell();
         showmycomment_LastTicket();
         RecordMaxGAINLOSS();
         
         break;
      }
      case state_await_buy:
      {
         status(".. trailing stop loss for buy pos");
         showmycomment_CurrentRange();
         showmycomment_timeunlocked_buy();
         showmycomment_LastTicket();         
         break;
      }   
      case state_await_sell:
      {
         status(".. trailing stop loss for sell pos");
         showmycomment_CurrentRange();
         showmycomment_timeunlocked_sell();
         showmycomment_LastTicket();
         break;
      }
      case state_buy2:
      {
         status(".. recovery buy mode");
         showmycomment_CurrentRange();
         showmycomment_timeunlocked_buy();
         showmycomment_LastTicket();
         showmycomment_ListOrder_buy();
         CummPL();
         break;
      }   
      case state_sell2:
      {
         status(".. recovery sell mode");
         showmycomment_CurrentRange();
         showmycomment_timeunlocked_sell();
         showmycomment_LastTicket();
         showmycomment_ListOrder_sell();
         CummPL();
         break;
      }
      case state_buy2_hold:
      {
         status(".. recovery buy mode");
         showmycomment_CurrentRange();
         showmycomment_timeunlocked_buy();
         showmycomment_LastTicket();
         showmycomment_ListOrder_buy();
         CummPL();
         break;
      }   
      case state_sell2_hold:
      {
         status(".. recovery sell mode");
         showmycomment_CurrentRange();
         showmycomment_timeunlocked_sell();
         showmycomment_LastTicket();
         showmycomment_ListOrder_sell();
         CummPL();
         break;
      }

      case state_revbuy_tradesell:
      {
         status(".. reversing from buy to sell mode");
         showmycomment_CurrentRange();
         showmycomment_timeunlocked_sell();
         showmycomment_LastTicket();
         break;
      }
      case state_revsell_tradebuy:
      {
         status(".. reversing from sell to buy mode");
         showmycomment_CurrentRange();
         showmycomment_timeunlocked_buy();
         showmycomment_LastTicket();
         break;
      }
      case  state_revbuy_tradesell_trail:
      {
         status(".. trailing stop loss for reversed-side order, buy mode");
         showmycomment_CurrentRange();
         showmycomment_timeunlocked_buy();
         showmycomment_LastTicket();
         break;
      }
      case  state_revsell_tradebuy_trail:
      {
         status(".. trailing stop loss for reversed-side order, sell mode");
         showmycomment_CurrentRange();
         showmycomment_timeunlocked_sell();
         showmycomment_LastTicket();
         break;
      }
   }

}


void Run_State_Transition()
{
   switch(state)
   {
      case state_idle:
      {         
         break;
      }   
      case state_buy1:
      {         
         break;
      }
      case state_sell1:
      {         
         break;
      }
      case state_await_buy:
      {         
         break;
      }
      case state_await_sell:
      {         
         break;
      }
      case state_buy2:
      {         
         break;
      }
      case state_sell2:
      {         
         break;
      }
      case state_buy2_hold:
      {         
         break;
      }
      case state_sell2_hold:
      {         
         break;
      }
      case state_revbuy_tradesell:
      {         
         break;
      }
      case state_revsell_tradebuy:
      {         
         break;
      }
      case state_revbuy_tradesell_trail:
      {         
         break;
      }
      case state_revsell_tradebuy_trail:
      {         
         break;
      }
   }
}

void Run_TimeStampControl()
{
   switch(state)
   {
      case state_idle:                 laststamp=timestamp_close;    break;
      case state_buy1:                 laststamp=timestamp_buy;      break;
      case state_sell1:                laststamp=timestamp_sell;     break;
      case state_await_buy:            laststamp=timestamp_buy;      break;
      case state_await_sell:           laststamp=timestamp_sell;     break;
      case state_buy2:                 
      {
         laststamp=timestamp_buy;      MultiOrderStateTimeStamp=MultiOrderStateTimeStamp_buy;
         MultiOrderState_Age=TimeCurrent()-MultiOrderStateTimeStamp;
         break;
      }
      case state_sell2:
      {
         laststamp=timestamp_sell;      MultiOrderStateTimeStamp=MultiOrderStateTimeStamp_sell;
         MultiOrderState_Age=TimeCurrent()-MultiOrderStateTimeStamp;
         break;
      }
      case state_buy2_hold:                 
      {
         laststamp=timestamp_buy;      MultiOrderStateTimeStamp=MultiOrderStateTimeStamp_buy;
         MultiOrderState_Age=TimeCurrent()-MultiOrderStateTimeStamp;
         break;
      }
      case state_sell2_hold:
      {
         laststamp=timestamp_sell;      MultiOrderStateTimeStamp=MultiOrderStateTimeStamp_sell;
         MultiOrderState_Age=TimeCurrent()-MultiOrderStateTimeStamp;
         break;
      }
      case state_revbuy_tradesell:          laststamp=timestamp_buy;      break;
      case state_revsell_tradebuy:         laststamp=timestamp_sell;     break;
      case state_revbuy_tradesell_trail:    laststamp=timestamp_buy;      break;
      case state_revsell_tradebuy_trail:   laststamp=timestamp_sell;     break;
   }
}

void Run_CurrentStateShortCode()
{
   switch(state)
   {
      case state_idle:                     now="I";    break;
      case state_buy1:                     now="B1";   break;
      case state_sell1:                    now="S1";   break;
      case state_await_buy:                now="B0";   break;
      case state_await_sell:               now="S0";   break;
      case state_buy2:                     now="B2";   break;
      case state_sell2:                    now="S2";   break;
      case state_buy2_hold:                now="B2H";  break;
      case state_sell2_hold:               now="S2H";  break;
      case state_revbuy_tradesell:         now="RB";   break;
      case state_revsell_tradebuy:         now="RS";   break;
      case state_revbuy_tradesell_trail:   now="RBT";  break;
      case state_revsell_tradebuy_trail:   now="RST";  break;
   }
}


void Run_OrderCommand()
{
   switch(state)
   {
      case state_idle:                     CMD=-1;      break;
      case state_buy1:                     CMD=OP_BUY;  break;
      case state_sell1:                    CMD=OP_SELL; break;
      case state_await_buy:                CMD=OP_BUY;  break;
      case state_await_sell:               CMD=OP_SELL; break;
      case state_buy2:                     CMD=OP_BUY;  break;
      case state_sell2:                    CMD=OP_SELL; break;
      case state_buy2_hold:                CMD=OP_BUY;  break;
      case state_sell2_hold:               CMD=OP_SELL; break;
      case state_revbuy_tradesell:         CMD=OP_SELL; break;
      case state_revsell_tradebuy:         CMD=OP_BUY;  break;
      case state_revbuy_tradesell_trail:   CMD=OP_SELL; break;
      case state_revsell_tradebuy_trail:   CMD=OP_BUY;  break;
   }
}
void MkLabel(string nam,string dsc, int xa, int xx, int xy, int sz, color clr){
   if(ObjectFind(nam) !=0) {
      ObjectCreate(nam, OBJ_LABEL,  0, 0, 0);
      ObjectSet(nam, OBJPROP_CORNER, xa); }
      ObjectSetText(nam, dsc, sz, "Times New Roman", clr);
   ObjectSet(nam, OBJPROP_XDISTANCE, xx);
   ObjectSet(nam, OBJPROP_YDISTANCE, xy);
}

void StatLabs(string nam,string dsc, int xa, int xx, int xy, int sz, color clr){ // Make info labels!!
   if(ObjectFind(nam) !=0) MkLabel(nam, dsc, xa, xx, xy, sz,clr); else {
//      xx = ObjectGet(pfx+nam, OBJPROP_XDISTANCE);
//      xy = ObjectGet(pfx+nam, OBJPROP_YDISTANCE);
      ObjectSetText(nam, dsc, sz, "Times New Roman", clr); }
   }
