TradeLibraryMT5Example

Author: Copyright 2022, Yuriy Bykov
Price Data Components
Orders Execution
Checks for the total of open orders
0 Views
0 Downloads
0 Favorites
TradeLibraryMT5Example
ÿþ//+------------------------------------------------------------------+

//|                                       TradeLibraryMT5Example.mq4 |

//|                                       TradeLibraryMT5Example.mq5 |

//|                                      Copyright 2022, Yuriy Bykov |

//|                               https://www.mql5.com/ru/code/38861 |

//|                               https://www.mql5.com/en/code/39161 |

//+------------------------------------------------------------------+

#property copyright "Copyright 2022, Yuriy Bykov"

#property link      "https://www.mql5.com/ru/users/antekov"

#property version   "1.07"

#property strict



#include <Trade\OrderInfo.mqh>

#include <Trade\PositionInfo.mqh>

#include <Trade\SymbolInfo.mqh>

#include <Trade\Trade.mqh>



input int inp_magicN = 12345;              // 1. Magic Number

input double inp_lot = 0.01;               // 2. Lot Size

input double inp_profitLevel = 3;          // 3. Profit, $

input double inp_stopLossLevel = 300;      // 4. Stop Loss, $

input int inp_pendingDistance = 70;        // 5. Distance between pending orders

input int inp_pendingDelta = 300;          // 6. Distance between first orders and current price



enum ENUM_EXPERT_STATE {

   EXPERT_STATE_WAITING,

   EXPERT_STATE_OPENING,

   EXPERT_STATE_WORKING,

   EXPERT_STATE_TRALING,

   EXPERT_STATE_CLOSING

};



int m_magicN;           // Magic Number

double m_lot;           // Lot Size

double m_profitLevel;   // Profit, $

double m_stopLossLevel; // Stop Loss, $

int m_days;             // Days for lookup

int m_pendingDistance;  // Distance between pending orders

int m_pendingDelta;     // Distance between first orders and current price



string m_symbol;

ENUM_TIMEFRAMES m_period;

ENUM_EXPERT_STATE m_state;

int m_pendingCount;

datetime m_startTime;

double m_startEquity;



bool m_signalLow;

bool m_signalHigh;



CSymbolInfo m_symbolInfo;

CTrade m_trade;



//+------------------------------------------------------------------+

//| Checking that there are opened orders                            |

//+------------------------------------------------------------------+

ENUM_EXPERT_STATE getLastState() {

   int total;

   

   COrderInfo o;

   total = OrdersTotal();



   for(int i = total - 1; i >= 0; i--) {

      if(o.SelectByIndex(i)) {

         ulong magic = o.Magic();

         string symbol = o.Symbol();

         if(magic != m_magicN || symbol != m_symbol) {

            continue;

         }



         return EXPERT_STATE_WORKING;

      }

   }



   CPositionInfo p;

   total = PositionsTotal();



   for(int i = total - 1; i >= 0; i--) {

      if(p.SelectByIndex(i)) {

         ulong magic = p.Magic();

         string symbol = p.Symbol();

         if(magic != m_magicN || symbol != m_symbol) {

            continue;

         }



         return EXPERT_STATE_WORKING;

      }

   }



   return EXPERT_STATE_WAITING;

}



//+------------------------------------------------------------------+

//| Waiting signal for open                                          |

//+------------------------------------------------------------------+

bool processWaiting(void) {

   GetSignal();



   if(m_signalLow || m_signalHigh) {

      m_state = EXPERT_STATE_OPENING;

   }



   return true;

}



//+------------------------------------------------------------------+

//| Opening pending orders after receiving signal for open           |

//+------------------------------------------------------------------+

bool processOpening() {

   Print("OPENING: Start opening Pending Orders");

   m_symbolInfo.RefreshRates();



   bool res;



   double delta = MathMax(m_pendingDelta * Point(), m_symbolInfo.FreezeLevel());

   double currentBidPrice = m_symbolInfo.Bid() - delta;

   double currentAskPrice = m_symbolInfo.Ask() + delta;

   double point = m_symbolInfo.Point();



   for(int i = 0; i < m_pendingCount; i++) {

      double distance = m_pendingDistance * m_symbolInfo.Point() * (i + 1);



      double lowPrice = NormalizeDouble(currentBidPrice - distance, m_symbolInfo.Digits());

      double highPrice = NormalizeDouble(currentAskPrice + distance, m_symbolInfo.Digits());



      res = m_trade.OrderOpen(m_symbol, ORDER_TYPE_BUY_LIMIT, m_lot, lowPrice, lowPrice, 0, 0, ORDER_TIME_GTC, 0);

      res = m_trade.OrderOpen(m_symbol, ORDER_TYPE_SELL_LIMIT, m_lot, highPrice, highPrice, 0, 0, ORDER_TIME_GTC, 0);

   }



   Print("WORKING: Start working with open orders");

   m_state = EXPERT_STATE_WORKING;



   return true;

}



//+------------------------------------------------------------------+

//| Checking that Take Profit or Stop Loss was reached               |

//+------------------------------------------------------------------+

bool processWorking(void) {

   double profit = GetProfit();

   if(profit > m_profitLevel) {

      Print("TAKE PROFIT: Profit = " + DoubleToString(profit, 2));

      m_state = EXPERT_STATE_CLOSING;

   } else if(profit < -m_stopLossLevel) {

      Print("STOP LOSS: Profit = " + DoubleToString(profit, 2));

      m_state = EXPERT_STATE_CLOSING;

   }

   return true;

}



//+------------------------------------------------------------------+

//| Closing all opened orders                                        |

//+------------------------------------------------------------------+

bool processClosing(void) {

   bool res = false;

   Print("CLOSING: Start closing all orders");

   while(!res && !IsStopped()) {

      res = TryCloseAll();

   }



   Print("WAITING: Start waiting new signal");

   m_state = EXPERT_STATE_WAITING;

   return true;

}



//+------------------------------------------------------------------+

//| Attempt to close all pending and market orders                   |

//+------------------------------------------------------------------+

bool TryCloseAll() {

   bool res = true;

   

   int total;

   double profit = 0;

   ulong ticket;

   ulong magic;

   string symbol;

   

   total = OrdersTotal();



   COrderInfo o;



   for(int i = total - 1; i >= 0; i--) {

      if(o.SelectByIndex(i)) {

         magic = o.Magic();

         symbol = o.Symbol();

         if(magic != m_magicN || symbol != m_symbol) {

            continue;

         }

         ticket = o.Ticket();



         res &= m_trade.OrderDelete(o.Ticket());

      }

   }



   total = PositionsTotal();

   

   CPositionInfo p;



   for(int i = total - 1; i >= 0; i--) {

      if(p.SelectByIndex(i)) {

         magic = p.Magic();

         symbol = p.Symbol();

         if(magic != m_magicN || symbol != m_symbol) {

            continue;

         }

         ticket = p.Ticket();



         res &= m_trade.PositionClose(ticket);

      }

   }



   return res;

}



//+------------------------------------------------------------------+

//| Calculate total profit for all market orders                     |

//+------------------------------------------------------------------+

double GetProfit() {

   int total = PositionsTotal();

   double profit = 0;



   CPositionInfo p;



   for(int i = total - 1; i >= 0; i--) {

      if(p.SelectByIndex(i)) {

         ulong magic = p.Magic();

         string symbol = p.Symbol();

         if(magic != m_magicN || symbol != m_symbol) {

            continue;

         }



         profit += p.Profit() + p.Commission() + p.Swap();

      }

   }



   return profit;

}



//+------------------------------------------------------------------+

//| Get simpole signal for open positions                            |

//+------------------------------------------------------------------+

void GetSignal(void) {

   m_symbolInfo.RefreshRates();



   double priceBid = m_symbolInfo.Bid();

   double priceAsk = m_symbolInfo.Ask();



   m_signalLow = false;

   m_signalHigh = false;



   MqlRates rates[];

   if (CopyRates(m_symbol, PERIOD_D1, 0, m_days, rates)) {

      double lowPrice  = rates[0].low;

      double highPrice = rates[0].high;



      for(int i = 0; i < m_days; i++) {

         lowPrice = MathMin(rates[i].low, lowPrice);

         highPrice = MathMax(rates[i].high, highPrice);

      }

      if(priceAsk > highPrice) {

         m_signalHigh = true;

      }

      if(priceBid < lowPrice) {

         m_signalLow = true;

      }

   } else {

      Print(__FUNCTION__, " Error in CopyRates(), error code=", _LastError);

   }

}



//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit() {

//---

   m_magicN = inp_magicN;

   m_profitLevel = inp_profitLevel;

   m_lot = inp_lot;

   m_stopLossLevel = inp_stopLossLevel;

   m_days = 4;

   m_pendingDistance = inp_pendingDistance;

   m_pendingDelta = inp_pendingDelta;



   m_symbol = Symbol();

   m_symbolInfo.Name(m_symbol);

   m_period = (ENUM_TIMEFRAMES) Period();



   m_pendingCount = 5;



   m_trade.SetExpertMagicNumber(m_magicN);



   m_state = getLastState();

//---

   return(INIT_SUCCEEDED);

}

//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason) {

//---

}

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+

void OnTick() {

//---

   if (m_state == EXPERT_STATE_WAITING) {

      processWaiting();

   } else if (m_state == EXPERT_STATE_OPENING) {

      processOpening();

   } else if (m_state == EXPERT_STATE_WORKING) {

      processWorking();

   } else if (m_state == EXPERT_STATE_CLOSING) {

      processClosing();

   }

}

//+------------------------------------------------------------------+

Comments