Author: Copyright � 2011, Erich Pribitzer
Orders Execution
Checks for the total of open ordersIt automatically opens orders when conditions are reachedIt can change open orders parameters, due to possible stepping strategyIt Closes Orders by itself
0 Views
0 Downloads
0 Favorites
OrderLib
/*=============================================================
 Info:    Order Library 
 Name:    OrderLib.mq4
 Author:  Eric Pribitzer
 Version: 0.94
 Update:  2011-11-03
 Notes:   MAX_ORDERS issue. OL_ClearBuffer()removed (Thx Valentin!)
 Version: 0.93
 Update:  2011-05-24
 Notes:   StopLoss calculation for LOT and RISK, OL_ postfix added
 Version: 0.92
 Update:  2011-05-05
 Notes:   add OP_ALL at OL_enumOrderList(...), OL_PROFITPIPS (calc TP+SL)
 Version: 0.9
 Update:  2011-03-30
 Notes:   LotSize Calculation Update, CUSTOM_TICKVALUE
 Version: 0.8
 Update:  2011-03-28
 Notes:   Bug WriteBuffer removed in TestingMode
          OL_RISK_PIPS and OL_PROFIT_PIPS added and tested
          OL_MAX_ORDERS added 
 Version: 0.7
 Update:  2010-02-11 
 Notes:   ---
  
 Copyright (C) 2010 Erich Pribitzer
=============================================================*/

#property copyright "Copyright © 2011, Erich Pribitzer"
#property link      "http://www.wartris.com"
#property library

#include <BasicH.mqh>
#include <OrderLibH.mqh>


bool   OL_ALLOW_ORDER           = true;
double OL_RISK_PERC             = 0;                                  // in %
int    OL_RISK_PIPS             = 0;                                  // 0=auto (calc price-stoploss)
int    OL_PROFIT_PIPS           = 0;
int    OL_TRAILING_STOP         = 0;
double OL_LOT_SIZE              = 1;                                  // 0=auto lot depends on risk pips and risk percent per trade
double OL_INITIAL_LOT           = 0;
double OL_CUSTOM_TICKVALUE      = 0;                                  // 0=no custom tickvalue
int    OL_SLIP_PAGE             = 0;
bool   OL_STOPSBYMODIFY         = false;                              // true = sl,tp will set by modify order
double OL_MAX_LOT               = 2;
int    OL_MAGIC                 = 0xA1200;                           // 0xA12xx Note: the first two digits must be zero
int    OL_MAX_ORDERS            = 3;
bool   OL_ORDER_DUPCHECK        = true;
bool   OL_OPPOSITE_CLOSE        = false;                             // oder will only closed when the new TP lies between SL and Price of an active order    
bool   OL_ORDER_COLOR           = true;
bool   OL_MYSQL_LOG             = true;    

double OL_orderInfo[OL_SIZE][OL_ORDER_BUFFER_SIZE];
string OL_orderInfoDesc[OL_ORDER_BUFFER_SIZE];
double OL_orderProp[OL_SIZE];
string OL_orderDesc;

#define OL_ORDER_OPEN_CLR Red
#define OL_ORDER_CLOSE_CLR Green
#define OL_ORDER_MODIFY_CLR Violet

#define OL_CL_OPPOSITCLOSE 1
#define OL_CL_TIMEEXPIRE 2
#define OL_CL_STOPLOSS 3
#define OL_CL_TAKEPROFIT 4
#define OL_CL_UNKNOWN 5
#define OL_CL_BYEA 6
#define OL_CL_DUPCHECK 7
#define OL_CL_SIZE 8

string OL_CL_STRING[OL_CL_SIZE]={"","Opposit","Expire","StopLoss","TakePorfit","Unknown","ByEA","Dupcheck"};

double OL_BUFFER_COUNT = 0;

bool OrderLib_Initialized;

int OL_Init(bool ALLOW_ORDER,double RISK_PERC,int RISK_PIPS,int PROFIT_PIPS,int TRAILING_STOP, double LOT_SIZE,double INITIAL_LOT,double CUSTOM_TICKVALUE, int SLIPPAGE, bool STOPSBYMODIFY, double MAX_LOT, int MAX_ORDERS, int MAGIC, bool ORDER_DUPCHECK, bool OPPOSITE_CLOSE, bool ORDER_COLOR, bool MYSQL_LOG)
{
   OL_ALLOW_ORDER           = ALLOW_ORDER;
   OL_RISK_PERC             = RISK_PERC;
   OL_RISK_PIPS             = RISK_PIPS;
   OL_PROFIT_PIPS           = PROFIT_PIPS;
   OL_TRAILING_STOP         = TRAILING_STOP;
   OL_LOT_SIZE              = LOT_SIZE;
   OL_INITIAL_LOT           = INITIAL_LOT;
   OL_CUSTOM_TICKVALUE      = CUSTOM_TICKVALUE;
   OL_SLIP_PAGE             = SLIPPAGE;
   OL_STOPSBYMODIFY          = STOPSBYMODIFY;
   OL_MAX_LOT               = MAX_LOT;
   OL_MAX_ORDERS            = MAX_ORDERS;
   OL_MAGIC                 = MAGIC;
   OL_ORDER_DUPCHECK        = ORDER_DUPCHECK;
   OL_OPPOSITE_CLOSE        = OPPOSITE_CLOSE;
   OL_ORDER_COLOR           = ORDER_COLOR;
   OL_MYSQL_LOG             = MYSQL_LOG;
   
   BA_Init();


   if(IsTesting()==true)
   {
      //OL_ClearBuffer();
      //Print("Testing Mode: Clear Order Buffer");
   }

   if(OrderLib_Initialized==false)
   {         
     Print("Init OrderLib V0.94");
     OL_ReadBuffer();
     OL_SyncBuffer();
     OrderLib_Initialized=true; 
   }   

}

int OL_Deinit()
{
   OL_WriteBuffer();
   OrderLib_Initialized=false;
   Print("Deinit OrderLib");
}

int OL_SyncBuffer()
{

   if(IsTesting()==true) return;
      
   int total=OrdersTotal();
   int magic=0;
   string symbol="";
   double tp=0;
   double sl=0;
   double lot=0;
   int ma=0;
   int inx=0;
   double buff[OL_ORDER_BUFFER_SIZE];
   
   ArrayInitialize(buff,0);
   
   
   for(int pos=0;pos<total;pos++)
   {
      if(OrderSelect(pos,SELECT_BY_POS)==false) continue;
      magic=OrderMagicNumber();
      symbol=OrderSymbol();
      if( (magic&0xFFFFF00) == OL_MAGIC && Symbol() == symbol)
      {         
         // change local order buffer, mark order as aktive 
         buff[magic&0xFF]=1;
/*
         tp=NormalizeDouble(OrderTakeProfit(),DIGITS);
         sl=NormalizeDouble(OrderTakeProfit(),DIGITS);
         lot=NormalizeDouble(OrderLots(),LOTDIGITS);
         if(OL_orderInfo[OL_TAKEPROFIT][magic&0xFF]!=tp || OL_orderInfo[OL_STOPLOSS][magic&0xFF]!=sl || OL_orderInfo[OL_LOTSIZE][magic&0xFF]!=lot)
         {
*/
         if(OL_orderInfo[OL_ID][magic&0xFF]>0)
         {  
            tp=NormalizeDouble(OrderTakeProfit(),DIGITS);
            sl=NormalizeDouble(OrderStopLoss(),DIGITS);
            
            if(tp>0)
               OL_orderInfo[OL_TAKEPROFIT][magic&0xFF]=tp;
            if(sl>0)
               OL_orderInfo[OL_STOPLOSS][magic&0xFF]=sl;
               
            OL_orderInfo[OL_LOTSIZE][magic&0xFF]=NormalizeDouble(OrderLots(),LOTDIGITS);
         }
//       }
      }      
   }

   for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)
   { 
      // sync local order buffer via real active orders
      if(buff[binx]==0 && OL_orderInfo[OL_ID][binx]>0)     // only running orders
      {
         OL_orderInfo[OL_ID][binx]=0;
         OL_orderInfo[OL_CLOSEREASON][binx]=OL_CL_UNKNOWN;
         Print("Clear Index: ",binx);
      }   
   }

}

int OL_ReadBuffer()
{
      
      string key="";
      int count=0;
      
      ArrayInitialize(OL_orderProp,0);
       
      for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)
      {
         if(IsTesting()==false)
         {
            if(GlobalVariableCheck(OL_FIX + Symbol()  + "_BI" + binx + "I" + OL_ID)==true) 
            {
               count++;
            }
            else
            {
               OL_orderInfo[OL_ID][binx]=0;
               continue;  
            }
         
            for(int inx=0;inx<OL_SIZE;inx++)
            {
               OL_orderInfo[inx][binx]=GlobalVariableGet(OL_FIX + Symbol()  + "_BI" + binx + "I" + inx);
            }
         }
             
         if(OL_orderInfo[OL_ID][binx]!=0)
            OL_Update(binx);
      }
      return (count);
}

int OL_WriteBuffer()
{     
      string key="";
      int count=0;
      for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)
      {
         if(OL_orderInfo[OL_ID][binx]!=0) 
         {
            count++;
            OL_Update(binx);
         }
         
         //order has closed state ?? >>
         if(OL_orderInfo[OL_CLOSEREASON][binx]>0)
         {
            int clinx=OL_orderInfo[OL_CLOSEREASON][binx];
            OL_orderInfo[OL_CTIME][binx]=TimeCurrent();
            OL_orderInfo[OL_CBAR][binx]=Bars;
            OL_orderInfo[OL_CSPREAD][binx]=NormalizeDouble(Ask-Bid,DIGITS)/POINT;
            OL_orderInfo[OL_CTICKCOUNT][binx]= GetTickCount() & 0x7FFFFFFF;  

            // was active ?
            if(OL_orderInfo[OL_OID][binx]>0) // yes >>
            {
               // print stats                          
               Print("Close reason: ",OL_CL_STRING[clinx],
               " / Order ID: ",OL_orderInfo[OL_OID][binx],
               " / Minutes: ",NormalizeDouble((OL_orderInfo[OL_CTIME][binx]-OL_orderInfo[OL_OTIME][binx])/60,1),
               " / HiProfit: ",OL_orderInfo[OL_HIPROFIT][binx],
               " / LoProfit: ",OL_orderInfo[OL_LOPROFIT][binx],
               " / Profit: ",OL_orderInfo[OL_PROFIT][binx],
               " / Desc: ",OL_orderInfoDesc[binx]);
             
            } 

            int xx=OL_orderInfo[OL_CLOSEREASON][binx];         
            OL_orderInfo[OL_CLOSEREASON][binx]=0;
            OL_orderInfo[OL_ERRORNO][binx]=0;
            Print("Clear ",binx,",",OL_CL_STRING[xx]);
            
         }

         if(IsTesting()==false )
         {
            for(int inx=0;inx<OL_SIZE;inx++)
            {            
               key=OL_FIX + Symbol()  + "_BI" + binx + "I" + inx;
               if(OL_orderInfo[OL_ID][binx]==0)
               {
                  GlobalVariableDel(key);    
               }
               else
               {
                  //Print("Write Global....",key);
                  GlobalVariableSet( key,  OL_orderInfo[inx][binx]);              
               }
            }
         }
      }
}


void OL_ClearBuffer()
{
   string key;
   for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)
   {
      for(int inx=0;inx<OL_SIZE;inx++)
      {            
         key=OL_FIX + Symbol()  + "_BI" + binx + "I" + inx;
         GlobalVariableDel(key);
         OL_orderInfo[OL_ID][binx]=0;
         OL_orderInfo[OL_CLOSEREASON][binx]=0;   
      }
   }
}


void OL_addOrderProperty(int property,double value)
{
   OL_orderProp[property]=value;      
}

void OL_addOrderDescription(string desc)
{
   OL_orderDesc=desc;      
}

int OL_registerOrder()
{
   
   int buy=OL_orderCount(OP_BUY);
   int sell=OL_orderCount(OP_SELL);
   
   if(buy+sell >= OL_MAX_ORDERS)
   {
      Print("Info: max order limit reached");
      return (0);
   }
   
   int inx;
   int binx=OL_GetFreeIndex();
   if(binx==-1) 
   {
      
      ArrayInitialize(OL_orderProp,0);
      return (-1);
   }
   
   if(OL_OPPOSITE_CLOSE==true)
      OL_processOppositClose(OL_orderProp[OL_TYPE],OL_orderProp[OL_TAKEPROFIT]);
      
   OL_orderProp[OL_OPRICE]=NormalizeDouble(OL_orderProp[OL_OPRICE],DIGITS);
   OL_orderProp[OL_TAKEPROFIT]=NormalizeDouble(OL_orderProp[OL_TAKEPROFIT],DIGITS);
   OL_orderProp[OL_STOPLOSS]=NormalizeDouble(OL_orderProp[OL_STOPLOSS],DIGITS);


   if(OL_orderProp[OL_OPRICE]==0)
   {
      if(OL_orderProp[OL_TYPE]==OP_BUY)
         OL_orderProp[OL_OPRICE]=NormalizeDouble(Ask,DIGITS);
      else
         OL_orderProp[OL_OPRICE]=NormalizeDouble(Bid,DIGITS);
   }

   if(OL_ORDER_DUPCHECK==true)
   {
      for(inx=0;inx<OL_ORDER_BUFFER_SIZE;inx++)
      {
         if(OL_orderInfo[OL_TYPE][inx]==OL_orderProp[OL_TYPE] && OL_orderProp[OL_OPRICE]==OL_orderInfo[OL_OPRICE][inx] )
         {
            if(OL_orderInfo[OL_ID][inx]<0)
            {
               OL_orderInfo[OL_ID][inx]=0;                        // clear pending
               OL_orderInfo[OL_CLOSEREASON][inx]=OL_CL_DUPCHECK;

            }
            else if(OL_orderInfo[OL_ID][inx]>0)
            {
               ArrayInitialize(OL_orderProp,0);
               return (-1);                                    // same order is running!! cancel register order
            }      
         }     
      }
   }

   OL_orderInfo[OL_ID][binx]=OL_SCHEDULED;                     // oder SCHEDULED!!
   for(inx=1;inx<OL_SIZE;inx++)
   {
      OL_orderInfo[inx][binx]=OL_orderProp[inx];      
   }
   OL_orderInfoDesc[binx]=OL_orderDesc;   
   OL_orderDesc="";
   ArrayInitialize(OL_orderProp,0);
   return (binx);   
}

double OL_getOrderProperty(int binx,int property)
{ 
  return (OL_orderInfo[property][binx]);
}

void OL_setOrderProperty(int binx,int property,double value)
{   
   if(OL_orderInfo[OL_ID][binx]>0 && OL_orderInfo[OL_CLOSEREASON][binx]==0)     // change only active and none closed orders
   {
      OL_orderInfo[property][binx]=value;      
   }
}


// Modify or open new order
void OL_processOrder()
{
   OL_processClose(); 
   double price=0;
   
   for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)
   {
      double bid=NormalizeDouble(Bid,DIGITS);
      double ask=NormalizeDouble(Ask,DIGITS);
      
      if(OL_orderInfo[OL_ID][binx]==OL_SCHEDULED) // Open Order
      {
 
         if(OL_ALLOW_ORDER==false) 
         {
            Print("Erro: order disallowed");
            OL_orderInfo[OL_ID][binx]=0;
            return;
         }
         
      // To do: add pending orders, add hidden sl tp
         if(
             ((OL_orderInfo[OL_TYPE][binx]==OP_BUY)  && ( (bid < OL_orderInfo[OL_TAKEPROFIT][binx] || OL_orderInfo[OL_TAKEPROFIT][binx]==0) )) ||
             ((OL_orderInfo[OL_TYPE][binx]==OP_SELL) && ( (ask >= OL_orderInfo[OL_TAKEPROFIT][binx] || OL_orderInfo[OL_TAKEPROFIT][binx]==0) )) ||
             (OL_orderInfo[OL_OTIME][binx]>0 && OL_orderInfo[OL_OTIME][binx] >= TimeCurrent())
           )
         {
             if(OL_orderOpen(binx)==false)
             {             
                  // clear order
                  OL_orderInfo[OL_ID][binx]=0;
             }
             else if(OL_STOPSBYMODIFY==true && OL_orderInfo[OL_TAKEPROFIT][binx]>0 || OL_orderInfo[OL_STOPLOSS][binx]>0)
             {
               
               // set stoploss and takeprofit
               OL_orderModify(binx);

             }
         }

      }
      else if(OL_orderInfo[OL_ID][binx]>0) // Modify active Order
      {
         if(OL_orderInfo[OL_FLAG][binx] == OL_FL_MODIFY)
         {
            // clear flag
            OL_orderInfo[OL_FLAG][binx]=0;
            OL_orderModify(binx);
         }
      }            
   } 

}

int OL_orderCount(int cmd)
{
      int count=0;
      int bx=0;
      while (bx!=-1)
      {   
         bx=OL_enumOrderList(bx,cmd);
         if(bx>=0)
         { 
            count++;
            bx++;
         }
      }
      return (count);
}

// return the order buffer index
// -1 = no elements left
int OL_enumOrderList(int inx, int cmd)
{
   int binx=inx;
   
   while(binx<OL_ORDER_BUFFER_SIZE)
   {     
      if(OL_orderInfo[OL_ID][binx] > 0 && (OL_orderInfo[OL_TYPE][binx]==cmd || (cmd==OL_ALL && (OL_orderInfo[OL_TYPE][binx]==OP_SELL || OL_orderInfo[OL_TYPE][binx]==OP_BUY))) )
      {
         return(binx);      
      }
      binx++;
   }
   return (-1);
}

void OL_processOppositClose(int cmd, double tp)
{
   for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)
   {
      if(
         (cmd==OP_BUY && OL_orderInfo[OL_TYPE][binx]==OP_SELL && OL_orderInfo[OL_ID][binx]!=0 && (tp >= OL_orderInfo[OL_OPRICE][binx] || tp==0) ) ||
         (cmd==OP_SELL && OL_orderInfo[OL_TYPE][binx]==OP_BUY && OL_orderInfo[OL_ID][binx]!=0 && (tp <= OL_orderInfo[OL_OPRICE][binx]|| tp==0) )
        )
      {
            if(OL_orderInfo[OL_ID][binx]>0)
            {
               if(OL_orderClose(binx)==true)
               {              
                  OL_orderInfo[OL_ID][binx]=0;
                  OL_orderInfo[OL_CLOSEREASON][binx]=OL_CL_OPPOSITCLOSE;
               }
               else if(OL_orderInfo[OL_ERRORNO][binx]==ERR_INVALID_TICKET)
               {
                  OL_orderInfo[OL_ID][binx]=0;
                  OL_orderInfo[OL_CLOSEREASON][binx]=OL_CL_UNKNOWN;
               }
               else
                  Print("Error: close opposite order");
            }
            else if(OL_orderInfo[OL_ID][binx]==OL_SCHEDULED)  // scheduled
            {
              OL_orderInfo[OL_ID][binx]=0; 
              OL_orderInfo[OL_CLOSEREASON][binx]=OL_CL_OPPOSITCLOSE;
            }       
      }
   }
}

void OL_processClose()
{  
   double bid=NormalizeDouble(Bid,DIGITS);
   double ask=NormalizeDouble(Ask,DIGITS);
   
   for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)
   {
      if(OL_orderInfo[OL_ID][binx]!=0)
      {
     
         if(OL_orderInfo[OL_TAKEPROFIT][binx]>0 && ((OL_orderInfo[OL_TYPE][binx]==OP_BUY && bid >= OL_orderInfo[OL_TAKEPROFIT][binx]) || (OL_orderInfo[OL_TYPE][binx]==OP_SELL && ask <= OL_orderInfo[OL_TAKEPROFIT][binx])) ) 
         {
            OL_orderInfo[OL_CLOSEREASON][binx]=OL_CL_TAKEPROFIT;
         }
         else if(OL_orderInfo[OL_STOPLOSS][binx]>0 && ((OL_orderInfo[OL_TYPE][binx]==OP_BUY && bid <= OL_orderInfo[OL_STOPLOSS][binx]) || (OL_orderInfo[OL_TYPE][binx]==OP_SELL && ask >= OL_orderInfo[OL_STOPLOSS][binx])) ) 
         {      
            OL_orderInfo[OL_CLOSEREASON][binx]=OL_CL_STOPLOSS;         
         }
         else if( OL_orderInfo[OL_EXPIRATION][binx]>0 && OL_orderInfo[OL_EXPIRATION][binx] <= TimeCurrent() )
         {
            OL_orderInfo[OL_CLOSEREASON][binx]=OL_CL_TIMEEXPIRE;                  
         }
         else if(OL_orderInfo[OL_FLAG][binx]==OL_FL_CLOSE)
         {
            OL_orderInfo[OL_FLAG][binx]=0;
            OL_orderInfo[OL_CLOSEREASON][binx]=OL_CL_BYEA;                              
         }
         else
            continue;

         if(OL_orderInfo[OL_ID][binx]>0)
         {
            if(OL_orderClose(binx)==true)
            {
               OL_orderInfo[OL_ID][binx]=0;
            }
            else if(OL_orderInfo[OL_ERRORNO][binx]==ERR_INVALID_TICKET)
            {

               OL_orderInfo[OL_ID][binx]=0;
            }
            else
               Print("Error: order close failed");
         }
         else
         {                  
           OL_orderInfo[OL_ID][binx]=0;
         }     
      }
   }             
}

int OL_GetFreeIndex()
{
   for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)
   {
      if(OL_orderInfo[OL_ID][binx]==0  && OL_orderInfo[OL_CLOSEREASON][binx]==0  )
         return (binx);
   }
   return (-1);  
}


bool OL_orderOpen(int binx)
{

   double money=AccountFreeMargin();
   double tickvalue=MarketInfo(Symbol(),MODE_TICKVALUE);
   if(OL_CUSTOM_TICKVALUE>0)
      tickvalue=OL_CUSTOM_TICKVALUE;   
   int rp=0;   // risk pips
   
   if(OL_orderInfo[OL_TRAILINGSTOP][binx]==0)
      OL_orderInfo[OL_TRAILINGSTOP][binx]=OL_TRAILING_STOP;
      
   if(OL_orderInfo[OL_SLIPPAGE][binx]==0)
      OL_orderInfo[OL_SLIPPAGE][binx]=OL_SLIP_PAGE;      


   // Calc OL_STOPLOSS only if OL_RISK_PIPS or OL_orderInfo[OL_RISKPIPS][binx] is given
   if(OL_orderInfo[OL_STOPLOSS][binx]==0 && (OL_RISK_PIPS > 0 || OL_orderInfo[OL_RISKPIPS][binx]>0))
   {   
      rp=OL_RISK_PIPS;
      if(OL_orderInfo[OL_RISKPIPS][binx]>0)
         rp=OL_orderInfo[OL_RISKPIPS][binx];

      OL_orderInfo[OL_STOPLOSS][binx]=OL_calcStopLoss(OL_orderInfo[OL_TYPE][binx],rp,OL_OPEN,0);
   }
   
   // Calc OL_STOPLOSS if only RISK and LOT is given
   if((OL_orderInfo[OL_RISKPERC][binx]>0 || OL_RISK_PERC>0) && (OL_RISK_PIPS == 0 || OL_orderInfo[OL_RISKPIPS][binx]==0) && 
      (OL_LOT_SIZE>0 || OL_orderInfo[OL_LOTSIZE][binx]>0) && OL_orderInfo[OL_STOPLOSS][binx]==0)
   {
      double rperc=OL_RISK_PERC;      
      if(OL_orderInfo[OL_RISKPERC][binx]>0)
         rperc=OL_orderInfo[OL_RISKPERC][binx];
      
      double ls=OL_LOT_SIZE;
      if(OL_orderInfo[OL_LOTSIZE][binx]>0)
         ls=OL_orderInfo[OL_LOTSIZE][binx];
               
      rp=0;
      rp=(money/100*rperc)/(ls*tickvalue);
      OL_orderInfo[OL_STOPLOSS][binx]=OL_calcStopLoss(OL_orderInfo[OL_TYPE][binx],rp,OL_OPEN,0);
   }
   

   // Calc TAKEPROFIT only if OL_PROFIT_PIPS or OL_orderInfo[OL_PROFITPIPS][binx] is given
   if(OL_orderInfo[OL_TAKEPROFIT][binx]==0 && (OL_PROFIT_PIPS > 0 || OL_orderInfo[OL_PROFITPIPS][binx]>0))
   {
      int pp=OL_PROFIT_PIPS;
      
      if(OL_orderInfo[OL_PROFITPIPS][binx]>0)
         pp=OL_orderInfo[OL_PROFITPIPS][binx];//+MarketInfo(Symbol(),MODE_SPREAD);

      OL_orderInfo[OL_TAKEPROFIT][binx]=OL_calcTakeProfit(OL_orderInfo[OL_TYPE][binx],pp,OL_OPEN,0);                              
   }
   
   
   int profitPip=MathAbs(OL_orderInfo[OL_TAKEPROFIT][binx]-OL_orderInfo[OL_OPRICE][binx]);

   
   // Calc LOTSIZE 
   if((OL_orderInfo[OL_LOTSIZE][binx]==0 || OL_LOT_SIZE==0) && (OL_orderInfo[OL_RISKPERC][binx]>0 || OL_RISK_PERC>0) && (OL_RISK_PIPS>0 || OL_orderInfo[OL_RISKPIPS][binx]>0))
   {
      int    riskPip;
      double riskPerc;
      
      if(OL_orderInfo[OL_RISKPERC][binx]>0)
         riskPerc=OL_orderInfo[OL_RISKPERC][binx];
      else      
         riskPerc=OL_RISK_PERC;
            
      if(OL_orderInfo[OL_RISKPIPS][binx]>0)
         riskPip=OL_orderInfo[OL_RISKPIPS][binx];   
      else if(OL_RISK_PIPS>0)
         riskPip=OL_RISK_PIPS;
      else
         riskPip=NormalizeDouble(MathAbs(OL_orderInfo[OL_STOPLOSS][binx]-OL_orderInfo[OL_OPRICE][binx]),DIGITS)/POINT;   
         
      OL_orderInfo[OL_LOTSIZE][binx]=NormalizeDouble(OL_INITIAL_LOT,LOTDIGITS)+NormalizeDouble(1.0/tickvalue*(money/100*riskPerc/(riskPip)),LOTDIGITS);
   }
   else
   {      
      if(OL_orderInfo[OL_LOTSIZE][binx]>0)
      {      
         OL_orderInfo[OL_LOTSIZE][binx]=NormalizeDouble(OL_INITIAL_LOT,LOTDIGITS)+NormalizeDouble(OL_orderInfo[OL_LOTSIZE][binx],LOTDIGITS);
      }
      else if(OL_LOT_SIZE>0)
      {
         OL_orderInfo[OL_LOTSIZE][binx]=NormalizeDouble(OL_INITIAL_LOT,LOTDIGITS)+NormalizeDouble(OL_LOT_SIZE,LOTDIGITS);
      }
      else if(OL_INITIAL_LOT>0)
      {
         OL_orderInfo[OL_LOTSIZE][binx]=NormalizeDouble(OL_INITIAL_LOT,LOTDIGITS);
      }   
      else
      {
         Print("Error: wrong lotsize");
         return (false);
      }
   }   
   
   if(OL_orderInfo[OL_LOTSIZE][binx]>OL_MAX_LOT) OL_orderInfo[OL_LOTSIZE][binx]=OL_MAX_LOT;

          
   int      ticketID =0;
   
   color    col=CLR_NONE;
   if(OL_ORDER_COLOR)
      col=OL_ORDER_OPEN_CLR;

   if(OL_orderInfo[OL_TYPE][binx]==OP_SELL)
   {
      if(OL_orderInfo[OL_OPRICE][binx]==0)
         OL_orderInfo[OL_OPRICE][binx]=NormalizeDouble(Bid,DIGITS);
   }
   else
   {
      if(OL_orderInfo[OL_OPRICE][binx]==0)
         OL_orderInfo[OL_OPRICE][binx]=NormalizeDouble(Ask,DIGITS);   
   }

   int      start    = GetTickCount()& 0x7FFFFFFF;
   int      stop;
   int      loop     = 1;
   int      cmd      = OL_orderInfo[OL_TYPE][binx];
   double   sl       = 0;
   double   tp       = 0;
   
   if(OL_STOPSBYMODIFY==false)
   {
     sl=OL_orderInfo[OL_STOPLOSS][binx];
     tp=OL_orderInfo[OL_TAKEPROFIT][binx];
   }
   
   while(loop>=0)
   {
      ticketID=OrderSend(Symbol(),cmd,OL_orderInfo[OL_LOTSIZE][binx],OL_orderInfo[OL_OPRICE][binx],OL_orderInfo[OL_SLIPPAGE][binx],sl,tp,NULL,(OL_MAGIC|binx),0);

      if(loop>0 && ticketID<1 && IsTradeBusy(4,100)==false)
      {
         RefreshRates();
      }
      else
         break;
               
      loop--;
   }

   if(ticketID<1)
   {     
      Print("Error: ",ErrorDescription(GetLastError())); 
      OL_orderInfo[OL_ERRORNO][binx]=GetLastError();
      return(false);
   }
   else
      stop=(GetTickCount()& 0x7FFFFFFF)-start;
      
	OL_orderInfo[OL_OTICKCOUNT][binx]= GetTickCount() & 0x7FFFFFFF;   
   OL_orderInfo[OL_ID][binx]=ticketID;
   OL_orderInfo[OL_OID][binx]=ticketID;
   OL_orderInfo[OL_OBAR][binx]=Bars;
   OL_orderInfo[OL_OSPREAD][binx]=NormalizeDouble(Ask-Bid,DIGITS);
      
   if(OrderSelect(ticketID,SELECT_BY_TICKET)==true)
   {
      OL_orderInfo[OL_OPRICE][binx]=NormalizeDouble(OrderOpenPrice(),DIGITS);
      OL_orderInfo[OL_OTIME][binx]=OrderOpenTime();
      OL_orderInfo[OL_HIPROFITTIME][binx]=OL_orderInfo[OL_OTIME][binx];
      OL_orderInfo[OL_LOPROFITTIME][binx]=OL_orderInfo[OL_OTIME][binx];   
   }
   else
   {
      OL_orderInfo[OL_OTIME][binx]=TimeCurrent();
      OL_orderInfo[OL_HIPROFITTIME][binx]=OL_orderInfo[OL_OTIME][binx];
      OL_orderInfo[OL_LOPROFITTIME][binx]=OL_orderInfo[OL_OTIME][binx];

   }
 
   OL_orderInfo[OL_ERRORNO][binx]=0;
          
   return(true); 
}


// mode=OL_OPEN or OL_CLOSE
double OL_calcStopLoss(int cmd, int pips, int mode, double price=0)
{
   price=NormalizeDouble(price,DIGITS);
   
   if(cmd==OP_BUY)
   {
      if(price==0)
      {
         if(mode==OL_OPEN)
            price=NormalizeDouble(Ask,DIGITS);
         else
            price=NormalizeDouble(Bid,DIGITS);
      }            
      return (NormalizeDouble(price-(pips*POINT),DIGITS));
   }
   else if(cmd==OP_SELL)
   {
      if(price==0) 
      {
         if(mode==OL_OPEN)
            price=NormalizeDouble(Bid,DIGITS);
         else
            price=NormalizeDouble(Ask,DIGITS);         
      }
      return (NormalizeDouble(price+(pips*POINT),DIGITS));  
   }
   
   return (0);
}

double OL_calcTakeProfit(int cmd, int pips, int mode, double price=0)
{
   price=NormalizeDouble(price,DIGITS);
 
 
   if(cmd==OP_BUY)
   {
      if(price==0) 
      {
         if(mode==OL_OPEN)         
            price=NormalizeDouble(Ask,DIGITS);
         else
            price=NormalizeDouble(Bid,DIGITS);         
      }
      return (NormalizeDouble(price+(pips*POINT),DIGITS));
   }
   else if(cmd==OP_SELL)
   {
      if(price==0) 
      {
         if(mode==OL_OPEN)
            price=NormalizeDouble(Bid,DIGITS);                  
         else
            price=NormalizeDouble(Ask,DIGITS);                  
      }
      return (NormalizeDouble(price-(pips*POINT),DIGITS));  
   }
   
   return (0);
}



bool OL_orderModify(int binx)
{

   double sl,tp;   
   bool ret=true;
   color col=CLR_NONE;
   
   if(OL_ORDER_COLOR)
      col=OL_ORDER_MODIFY_CLR;
   
   if(OL_orderInfo[OL_ID][binx]<1) 
   {
      OL_orderInfo[OL_ERRORNO][binx]=ERR_INVALID_TICKET;
      return (false);
   }
 
   int      ticketID = OL_orderInfo[OL_ID][binx];
   int      loop     = 1;
        
   while(loop>=0)
   {
      ret=OrderModify(ticketID,OL_orderInfo[OL_OPRICE][binx],OL_orderInfo[OL_STOPLOSS][binx],OL_orderInfo[OL_TAKEPROFIT][binx],NULL,col);
      OL_orderInfo[OL_ERRORNO][binx]=GetLastError();
      
      if(loop>0 && ret==false && OL_orderInfo[OL_ERRORNO][binx]!=ERR_INVALID_TICKET && IsTradeBusy(4,100)==false) 
      {
         RefreshRates();
      }
      else
         break;
      
      loop--;
   }
   
   if(ret==false)
      Print("Error: ",ErrorDescription(OL_orderInfo[OL_ERRORNO][binx]));
      
   return(ret);
}

bool OL_orderClose(int binx)
{
   Print("OL_Close");
   double price;
   bool ret    = false;
   int ticket  = OL_orderInfo[OL_ID][binx];
 
   
   if(OL_orderInfo[OL_ID][binx]<1) 
   {
      OL_orderInfo[OL_ERRORNO][binx]=ERR_INVALID_TICKET;
      return (false);
   }

   int start=GetTickCount()& 0x7FFFFFFF;

   color col=CLR_NONE;
   if(OL_ORDER_COLOR)
      col=OL_ORDER_CLOSE_CLR;   


   if(OL_orderInfo[OL_TYPE][binx]==OP_SELL)
   {
      if(OL_orderInfo[OL_CPRICE][binx]==0)
         OL_orderInfo[OL_CPRICE][binx]=NormalizeDouble(Ask,DIGITS);
   }
   else
   {
      if(OL_orderInfo[OL_CPRICE][binx]==0)
         OL_orderInfo[OL_CPRICE][binx]=NormalizeDouble(Bid,DIGITS);   
   }
   
   int loop=1;
   while(loop>=0)
   {
   
      
      ret=OrderClose(ticket,OL_orderInfo[OL_LOTSIZE][binx],OL_orderInfo[OL_CPRICE][binx],OL_orderInfo[OL_SLIPPAGE][binx],col);
   
      OL_orderInfo[OL_ERRORNO][binx]=GetLastError();

      if(loop>0 && ret==false && OL_orderInfo[OL_ERRORNO][binx]!=ERR_INVALID_TICKET && IsTradeBusy(4,100)==false) 
      {
         RefreshRates();
      }
      else
         break;
               
      loop--;
   }
   
   if(ret==true /* || OL_orderInfo[OL_ERRORNO][binx]==ERR_INVALID_TICKET */ )
   {
      if(OrderSelect(ticket,SELECT_BY_TICKET)==true)
         OL_orderInfo[OL_CPRICE][binx]=OrderClosePrice();
   }
   else
      Print("Error: ",ErrorDescription(OL_orderInfo[OL_ERRORNO][binx]));

   return(ret);
}

bool IsTradeBusy(int retries,int sleep)
{ 
   while(retries>0)
   {  
      if(IsTradeContextBusy() || !IsTradeAllowed())
      {
         Print("Sleep ",sleep);
         Sleep(sleep);
      }
      else return (false);
      
      retries--;
   }
   Print("Trade Busy");
   return (true);
}


void OL_Update(int binx)
{
   if(OL_orderInfo[OL_ID][binx]==0)
   {
      return;
   }

   // activ order?
   if(OL_orderInfo[OL_ID][binx]>0)
   {           
      if(OL_orderInfo[OL_TYPE][binx]==OP_SELL)
      {
         OL_orderInfo[OL_PROFIT][binx]=NormalizeDouble(OL_orderInfo[OL_OPRICE][binx]-Ask,DIGITS)/POINT;
      }
      else
      {
         OL_orderInfo[OL_PROFIT][binx]=NormalizeDouble(Bid-OL_orderInfo[OL_OPRICE][binx],DIGITS)/POINT;
      }
   
      if(OL_orderInfo[OL_PROFIT][binx] > 0 && OL_orderInfo[OL_PROFIT][binx]>OL_orderInfo[OL_HIPROFIT][binx])
      {

         OL_orderInfo[OL_HIPROFITTIME][binx]=TimeCurrent();
         OL_orderInfo[OL_HIPROFIT][binx]=OL_orderInfo[OL_PROFIT][binx];      
               
      }
      
      if(OL_orderInfo[OL_PROFIT][binx] < 0 && OL_orderInfo[OL_PROFIT][binx] < OL_orderInfo[OL_LOPROFIT][binx])
      {
         OL_orderInfo[OL_LOPROFITTIME][binx]=TimeCurrent();
         OL_orderInfo[OL_LOPROFIT][binx]=OL_orderInfo[OL_PROFIT][binx];
      }
      
      // TRAILINGSTOP UPDATES==================
      if(OL_orderInfo[OL_PROFIT][binx]>0)
      {
         if(OL_orderInfo[OL_TRAILINGSTOP][binx]>0)
         {
               double ask=NormalizeDouble(Ask,DIGITS);
               double bid=NormalizeDouble(Bid,DIGITS);

               if(OL_orderInfo[OL_TYPE][binx]==OP_SELL)
               { 
                  if(OL_orderInfo[OL_TRAILING][binx]==0 || ask<OL_orderInfo[OL_TRAILING][binx])
                  {              
                     OL_orderInfo[OL_TRAILING][binx]=ask;
                     OL_orderInfo[OL_STOPLOSS][binx]=NormalizeDouble(ask+(OL_orderInfo[OL_TRAILINGSTOP][binx]*POINT),DIGITS);
                     OL_orderModify(binx);
                  }                   
               }
               else
               {               
                  if(OL_orderInfo[OL_TRAILING][binx]==0 || bid>OL_orderInfo[OL_TRAILING][binx])
                  {
                     OL_orderInfo[OL_TRAILING][binx]=bid;
                     OL_orderInfo[OL_STOPLOSS][binx]=NormalizeDouble(bid-(OL_orderInfo[OL_TRAILINGSTOP][binx]*POINT),DIGITS);
                     OL_orderModify(binx);
                  }                                  
               }
         }
      }


   }

   //active && inactiv orders 
   OL_orderInfo[OL_CTIME][binx]=TimeCurrent();   
    
   return;   
}


Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---