XP Trade Manager

Author: Copyright MQL BLUE
Price Data Components
Series array that contains open time of each bar
0 Views
0 Downloads
0 Favorites
XP Trade Manager
//+------------------------------------------------------------------+
//|                                              Trading Manager.mq5 |
//|                                               Copyright MQL BLUE |
//|                                           http://www.mqlblue.com |
//+------------------------------------------------------------------+
#property copyright "Copyright MQL BLUE"
#property link      "https://www.mqlblue.com"
#property version   "2.00"
#property strict

//---- definitions
#define Version                           "2.00"

#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>

// **** EA PARAMS *****************
input  string         SLTPParams        = "--- SL & TP -------------------";
input  int            StopLoss          = 20;
input  int            TakeProfit        = 40;
input  string         BEParams          = "--- BreakEven -----------------";
input  bool           UseBreakEven      = true;
input  int            BEActivation      = 50;
input  int            BELevel           = 10;
input  string         TS1Params         = "--- Trailing Stop -------------";
input  bool           UseTrailingStop   = true;
input  int            TSStart           = 10;
input  int            TSStep            = 10;
input  int            TSDistance        = 15;
input  bool           TSEndBE           = false;
input  string         Behavior          = "--- EA Behavior ---------------";
input  bool           StealthMode       = false;
input   bool          OnlyCurrentPairInit   = false; //OnlyCurrentPair
bool OnlyCurrentPair = false;

string         ShortName               = "XP Trade Manager";
string         ObjectSignature         = "";
long           chartID                 = 0;
const string nameProfitPips = "profitPips";  
const string nameProfitCurrency = "profitCurrency";

int ordersHistoryCount=0;

struct HistoryStat
{
   double profitPips;
   double profitCurrency;
};
CPositionInfo  m_position;                   // trade position object
CTrade         m_trade;                      // trading object
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ShortName = MQLInfoString(MQL_PROGRAM_NAME);
   ObjectSignature = "["+ShortName+"]";
   Print ("Init "+ShortName+" ver. "+Version);         

   OnlyCurrentPair = OnlyCurrentPairInit;
   if (StealthMode) OnlyCurrentPair = true;
   
   chartID = ChartID();
   ObjectCreate(chartID, nameProfitPips, OBJ_LABEL,0,0,0,0);
   ObjectSetInteger(chartID, nameProfitPips, OBJPROP_XDISTANCE, 5);
   ObjectSetInteger(chartID, nameProfitPips, OBJPROP_YDISTANCE, 20);
   ObjectSetInteger(chartID, nameProfitPips, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER);
   ObjectSetString(chartID, nameProfitPips, OBJPROP_TEXT, "Profit pips = 0");

   ObjectCreate(chartID, nameProfitCurrency, OBJ_LABEL,0,0,0,0);
   ObjectSetInteger(chartID, nameProfitCurrency, OBJPROP_XDISTANCE, 5);
   ObjectSetInteger(chartID, nameProfitCurrency, OBJPROP_YDISTANCE, 35);
   ObjectSetInteger(chartID, nameProfitCurrency, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER);
   ObjectSetString(chartID, nameProfitCurrency, OBJPROP_TEXT, "Profit currency = 0,00 "+AccountInfoString(ACCOUNT_CURRENCY));

   ordersHistoryCount=0;
//---
   return(INIT_SUCCEEDED);
   
  }
  
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   ObjectDelete(chartID, nameProfitPips);
   ObjectDelete(chartID, nameProfitCurrency);
  }
  
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//--- 
   m_trade.SetExpertMagicNumber(0);
   for(int i=PositionsTotal()-1;i>=0;i--){ // returns the number of current positions
      if(m_position.SelectByIndex(i))  {   // selects the position by index for further access to its properties
         if(!OnlyCurrentPair || m_position.Symbol()==_Symbol){ 
            ulong ticket = m_position.Ticket(); 
            string symbol = m_position.Symbol();     
            double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
            ulong digits = SymbolInfoInteger(symbol, SYMBOL_DIGITS);
            if (digits==3 || digits==5) point *=10;
            double slCurrentLevel = 0;
            double tpCurrentLevel = 0;
            bool closed = false;
            double bid =  SymbolInfoDouble(symbol, SYMBOL_BID);
            double ask = SymbolInfoDouble(symbol, SYMBOL_ASK);
            if (StealthMode)
            {
               slCurrentLevel = ObjectGetDouble(chartID, ObjectSignature+"sl"+IntegerToString(ticket), OBJPROP_PRICE);
               tpCurrentLevel = ObjectGetDouble(chartID, ObjectSignature+"tp"+IntegerToString(ticket), OBJPROP_PRICE);
               if (m_position.PositionType()==POSITION_TYPE_BUY)
               {
                  if (tpCurrentLevel > 0)
                  {
                     if (bid >= tpCurrentLevel)
                     {
                        closed = m_trade.PositionClose(ticket);
                     }
                  }
                  if (slCurrentLevel > 0)
                  {
                     if (bid <= slCurrentLevel) 
                        closed = m_trade.PositionClose(ticket);
                  } 
               }
               else if (m_position.PositionType()==POSITION_TYPE_SELL)
               {
                  if (tpCurrentLevel > 0)
                  {
                     if (ask <= tpCurrentLevel) 
                        closed = m_trade.PositionClose(ticket);
                  } 
                  if (slCurrentLevel > 0)
                  {
                     if (ask >= slCurrentLevel) 
                        closed = m_trade.PositionClose(ticket);
                  }
               }
               if (closed)
               {
                  ObjectDelete(chartID, ObjectSignature+"sl"+IntegerToString(ticket));
                  ObjectDelete(chartID, ObjectSignature+"tp"+IntegerToString(ticket));
               }
            }
            if (!closed)
            {
               // **************** check SL & TP *********************
               if ((StopLoss > 0 || TakeProfit > 0) && ((!StealthMode && m_position.StopLoss() == 0 && m_position.TakeProfit() == 0) || (StealthMode && slCurrentLevel==0 && tpCurrentLevel==0)))
               {
                  double stopLevel = SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL)*point;
                  double distTP = MathMax(TakeProfit*point, stopLevel);
                  double distSL = MathMax(StopLoss*point, stopLevel);
                  double takeProfit = 0;
                  double stopLoss = 0;
                  if (m_position.PositionType()==POSITION_TYPE_BUY)
                  {
                     if (TakeProfit > 0) takeProfit =m_position.PriceOpen() + distTP;
                     if (StopLoss > 0) stopLoss = m_position.PriceOpen() - distSL;
                  }
                  else if (m_position.PositionType()==POSITION_TYPE_SELL)
                  {
                     if (TakeProfit > 0) takeProfit = m_position.PriceOpen()- distTP;
                     if (StopLoss > 0) stopLoss = m_position.PriceOpen() + distSL;
                  }
                  if (!StealthMode)
                  {
                     ResetLastError();
                     if(!m_trade.PositionModify(ticket, NormalizeDouble(stopLoss, digits), NormalizeDouble(takeProfit, digits)))
                        Print(ShortName +" (OrderModify Error) "+ IntegerToString(GetLastError())); 
                  }
                  else
                  {
                     SetLevel(ObjectSignature+"sl"+IntegerToString(ticket), NormalizeDouble(stopLoss,digits), clrRed, STYLE_DASH, 1);
                     SetLevel(ObjectSignature+"tp"+IntegerToString(ticket), NormalizeDouble(takeProfit,digits), clrGreen, STYLE_DASH,1);
                  }
               }
               // ****** CHECK Trailing Stop && Break Even **************************
               if (UseTrailingStop)
               {
                  int priceDistance = 0;
                  int multi = 0;
                  double stopLoss=0;
                  double be;
                  if (m_position.PositionType()==POSITION_TYPE_BUY)
                  {
                     priceDistance = (int)(NormalizeDouble(bid - m_position.PriceOpen(), digits)/point);
                     if (priceDistance > TSStart)
                     {
                        multi = (int)MathFloor(priceDistance / TSStep);
                        if (multi > 0)
                        {
                           stopLoss = NormalizeDouble(m_position.PriceOpen() + TSStep*multi*point, digits) - TSDistance*point;
                           if (TSEndBE)
                           {
                              be = NormalizeDouble(m_position.PriceOpen() + BELevel*point, digits);
                              if (stopLoss > be) stopLoss = be;
                           }
                        }
                        if (!StealthMode)
                        {
                           if (NormalizeDouble(m_position.StopLoss(), digits) < NormalizeDouble(stopLoss, digits))
                           {
                              ResetLastError();
                              if(!m_trade.PositionModify(ticket, NormalizeDouble(stopLoss, digits), m_position.TakeProfit()))
                                 Print(ShortName +" (OrderModify Error) "+ IntegerToString(GetLastError())); 
                           }
                        }
                        else
                        {
                           if (NormalizeDouble(slCurrentLevel, digits) < NormalizeDouble(stopLoss, digits)) SetLevel(ObjectSignature+"sl"+IntegerToString(ticket), NormalizeDouble(stopLoss,digits), clrRed, STYLE_DASH, 1);
                        }
                     }
                  }
                  else if (m_position.PositionType()==POSITION_TYPE_SELL)
                  {
                     priceDistance = (int)(NormalizeDouble(m_position.PriceOpen()- ask, digits)/point);
                     if (priceDistance > TSStart)
                     {
                        multi = (int)MathFloor(priceDistance / TSStep);
                        if (multi > 0)
                        {
                           stopLoss = NormalizeDouble(m_position.PriceOpen() - TSStep*multi*point, digits) + TSDistance*point;
                        }
                        if (TSEndBE)
                        {
                           be = NormalizeDouble(m_position.PriceOpen() - BELevel*point, digits);
                           if (stopLoss < be) stopLoss = be;
                        }        
                        if (!StealthMode)
                        {                
                           if (NormalizeDouble(m_position.StopLoss(), digits) > NormalizeDouble(stopLoss, digits))
                           {
                              ResetLastError();
                             if(!m_trade.PositionModify(ticket, NormalizeDouble(stopLoss, digits), m_position.TakeProfit()))
                                 Print(ShortName +" (OrderModify Error) "+ IntegerToString(GetLastError())); 
                           }                        
                        }
                        else
                        {
                           if (NormalizeDouble(slCurrentLevel, digits) > NormalizeDouble(stopLoss, digits)) SetLevel(ObjectSignature+"sl"+IntegerToString(ticket), NormalizeDouble(stopLoss,digits), clrRed, STYLE_DASH, 1);
                        }
                     }
                  }
               }
               else if (UseBreakEven)
               {
                  int slDistance = 0;
                  int priceDistance = 0;
                  double stopLoss=0;
                  if (m_position.PositionType()==POSITION_TYPE_BUY)
                  {
                     slDistance = (int)(NormalizeDouble(m_position.StopLoss() - m_position.PriceOpen(), digits)/point);
                     if (slDistance < BELevel)
                     {
                        priceDistance = (int)(NormalizeDouble(bid - m_position.PriceOpen(), digits)/point);
                        if (priceDistance >= BEActivation)
                        {
                           stopLoss = m_position.PriceOpen() + BELevel*point;
                           if (!StealthMode)
                           {
                              ResetLastError();
                             if(!m_trade.PositionModify(ticket, NormalizeDouble(stopLoss, digits), m_position.TakeProfit()))
                                 Print(ShortName +" (OrderModify Error) "+ IntegerToString(GetLastError())); 
                           }
                           else
                           {
                              SetLevel(ObjectSignature+"sl"+IntegerToString(ticket), NormalizeDouble(stopLoss,digits), clrRed, STYLE_DASH, 1);                                                                         
                           }
                        }
                     }
                  }
                  else if (m_position.PositionType()==POSITION_TYPE_SELL)
                  {
                     slDistance = (int)(NormalizeDouble(m_position.PriceOpen()-m_position.StopLoss(),  digits)/point);
                     if (slDistance < BELevel)
                     {
                        priceDistance = (int)(NormalizeDouble(m_position.PriceOpen() - ask, digits)/point);
                        if (priceDistance >= BEActivation)
                        {
                           stopLoss = m_position.PriceOpen() - BELevel*point;
                           if (!StealthMode)
                           {
                              ResetLastError();
                             if(!m_trade.PositionModify(ticket, NormalizeDouble(stopLoss, digits), m_position.TakeProfit()))
                                 Print(ShortName +" (OrderModify Error) "+ IntegerToString(GetLastError())); 
                           }
                           else
                           {
                              SetLevel(ObjectSignature+"sl"+IntegerToString(ticket), NormalizeDouble(stopLoss,digits), clrRed, STYLE_DASH, 1);                           
                           }
                        }
                     }                  
                  }
               }
            }
         }
      }  
   }
}

void OnTrade(){   
   
  // Print("TRADE EVENSJ------------------------------------------");
//   if (OrdersHistoryTotal() != ordersHistoryCount)
   {
      // Refresh pips counter
      HistoryStat histStat = {0,0};
      ReadHistory(histStat);
         
      ObjectSetString(chartID, nameProfitPips, OBJPROP_TEXT, "Profit pips = "+DoubleToString(histStat.profitPips,0));   
      ObjectSetString(chartID, nameProfitCurrency, OBJPROP_TEXT, "Profit currency = "+DoubleToString(histStat.profitCurrency,2)+" "+AccountInfoString(ACCOUNT_CURRENCY));

      //ordersHistoryCount = OrdersHistoryTotal();
   }
   
  }
  

  
//+------------------------------------------------------------------+
//| Add or Update level line on chart                                |
//+------------------------------------------------------------------+
void SetLevel(string linename, double level, color col1, int linestyle, int thickness)
{
   int digits= _Digits;

   // create or move the horizontal line   
   if (ObjectFind(chartID, linename) != 0) {
      ObjectCreate(chartID, linename, OBJ_HLINE, 0, 0, level);
      ObjectSetInteger(chartID, linename, OBJPROP_STYLE, linestyle);
      ObjectSetInteger(chartID, linename, OBJPROP_COLOR, col1);
      ObjectSetInteger(chartID, linename, OBJPROP_WIDTH, thickness);
      
      ObjectSetInteger(chartID, linename, OBJPROP_BACK, true);
   }
   else 
   {
      ObjectMove(chartID, linename, 0, Time(PERIOD_CURRENT, 0), level);
   }
}  

void RemoveLines()
{
   ObjectsDeleteAll(chartID, ObjectSignature);
   /*int obj_total= ObjectsTotal();
   int signatureLength = StringLen(ObjectSignature);
   for (int i= obj_total; i>=0; i--) {
      string name= ObjectName(i);
      if (StringSubstr(name,0,signatureLength)==ObjectSignature) ObjectDelete(name);
   }*/
}
  
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Read stat from history                                           |
//+------------------------------------------------------------------+
bool ReadHistory(HistoryStat &stat)
{
   stat.profitPips=0;
   stat.profitCurrency=0;

   datetime day = StringToTime(TimeToString(TimeCurrent(), TIME_DATE));
   ulong ticket;
   HistorySelect(day, TimeCurrent());
   for(uint i=0;i<HistoryDealsTotal();i++){ 
      if((ticket=HistoryDealGetTicket(i))>0){ 
            if(Symbol()==HistoryDealGetString(ticket,DEAL_SYMBOL) || !OnlyCurrentPair){
               if(HistoryDealGetInteger(ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT){
                  if(HistoryDealGetInteger(ticket, DEAL_TIME)>=day){
                     double pv = SymbolInfoDouble(HistoryOrderGetString(ticket, ORDER_SYMBOL), SYMBOL_TRADE_TICK_VALUE)/
                                    (SymbolInfoDouble(HistoryOrderGetString(ticket, ORDER_SYMBOL), SYMBOL_TRADE_TICK_SIZE) / 
                                    SymbolInfoDouble(HistoryOrderGetString(ticket, ORDER_SYMBOL), SYMBOL_POINT));
                     if(pv==0) continue;
                     stat.profitPips += (HistoryDealGetDouble(ticket, DEAL_PROFIT)/(pv*HistoryDealGetDouble(ticket, DEAL_VOLUME)));
                     stat.profitCurrency+=HistoryDealGetDouble(ticket, DEAL_PROFIT)+HistoryDealGetDouble(ticket, DEAL_COMMISSION)+HistoryDealGetDouble(ticket, DEAL_SWAP);   
               }   
            }
         }
            
      }     
   }

   
   return (true);
}

datetime Time(ENUM_TIMEFRAMES tf, int i){
   datetime times[1];
   int copied = CopyTime(_Symbol, tf, i, 1,times);
   if(copied < 1){
      //Print("Error: Download date time array problem: "+IntegerToString(GetLastError()));
      return 0;
   }
   return times[0];
}

Comments