Download MetaTrader 5

A Virtual Order Manager to track orders within the position-centric MetaTrader 5 environment

13 May 2010, 10:00
Paul
21
9 383


1. Introduction

Arguably the biggest change in the transition from MetaTrader 4 to MetaTrader 5 is the management of open trades as positions. At any one time there can be one position only open for each symbol, and the size of this position adjusts up and down each time orders are processed by the broker. This aligns with the NFA 2-43(b) FIFO rule introduced in the US, and also fits with the mode of trading in many other entities such as futures, commodities and CFDs.

A clear example of the difference would be when two EAs running against the same symbol issue orders in opposite directions.  This can be a common situation with two EAs working in different timeframes, such as a scalper and a trend-follower.  In MetaTrader 4, the open trade list would show buy and sell open orders with zero margin used. In MetaTrader 5, no position would be open at all.

Looking in the EA code itself, functions such as the commonly used MQL4 OpenOrders() below, or similar variant, will not function as expected when migrated to MQL5.

int OpenOrders()  // MetaTrader 4 code to count total open orders for this EA
{
  int nOpenOrders=0;
  for (int i=OrdersTotal()-1; i>=0; i--)
  {
    OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
    if (OrderMagicNumber()==magic)
      if (OrderType()==OP_BUY || OrderType()==OP_SELL)
        if (OrderSymbol()==Symbol())
          nOpenOrders++;
  }
  return(nOpenOrders);
}

So the MetaTrader 5 position-centric environment presents unfamiliar challenges for the programmer used to the order processing approach used in MetaTrader 4. What were simple order management functions in MetaTrader 4 become more complex in MetaTrader 5 when multiple orders can get merged into the one position, such as multiple EAs trading the one symbol, or multiple orders from the one EA on a symbol.


2. Ways to work with positions in MetaTrader 5  

There are a number of ways to manage this position-centric environment in MetaTrader 5, depending on the complexity of trading strategies.

Firstly, note that MetaTrader 5’s handling of pending orders is similar to MetaTrader 4, so MQL5 code written for pending orders alone could be a relatively simple migration from MQL4 code.

2.1 Straightforward EA; one EA per symbol per account

The simplest approach is to limit trading on the one account to one straightforward EA per symbol.  “Straightforward EA” in this case means one which only issues a single order at a time, which is a common method but excludes strategies such as pyramiding and grid trading.  Straightforward EAs can be written in MQL5 in a similar way to MQL4, perhaps using the CTrade library wrapper provided in include\trade\trade.mqh.

2.2 Complex EA; one EA per symbol per account

For complex EAs, such as those which have a strategy such as pyramiding or grid trading which can require more than one open order for a symbol, some relatively simple order tracking code added to the EA may be all that is necessary to manage the strategy.  This will only be possible if the EA will never share positions with another EA trading the same symbol.

2.3 More than one EA of any type per symbol per account

This presents the most complex trading and coding requirement, and is the reason for the development of the Virtual Order Manager (VOM) library.  This library is intended to simplify greatly the development of robust EA code which is fully sociable with other EAs.

The rest of this article describes the Virtual Order Manager library in detail.


3. Design goals, benefits and disadvantages of the Virtual Order Manager 

The VOM has four main design goals:

  1. Sociability: the behaviour of EAs written correctly using the VOM trading functions will be isolated from other EA activity
  2. Robustness: elegant handling of abnormal events such as errors, breaks in client-server communication and incomplete order fills.
  3. Ease of use: provision of well documented and simple trading functions
  4. Ability to use in the Strategy Tester

These goals are implemented as follows:

  • Use of virtual open orders, pending orders, stoplosses and takeprofits.  “Virtual” in this context means that their status is maintained at the client terminal independently of positions at the server.  These orders have horizontal lines drawn on the terminal in a similar fashion to positions
  • A protective server-based stop maintained a distance away from the virtual stops for disaster protection in the event of PC or internet link failure

The VOM approach allows an MQL5 EA programmer to:

  • Code EAs in an “order-centric” fashion, ie similar to the MetaTrader 4 approach
  • Implement what many in the Metatrader community refer to as “hedge trading” or, more accurately, simultaneous trades in the opposite direction against a single symbol 
  • Code other advanced trading strategies relatively easily such as grid trading, pyramiding and money management approaches
  • Issue stops and pending orders tighter than the minimum stop level

It should also be noted that a side-effect of the VOM approach is that its virtual stoplosses, takeprofits and pending orders inherently have “stealth” behaviour, ie they cannot be seen at the broker server.  Hiding stoploss levels is seen by some as necessary to prevent the broker from being able to engage in stop-hunting.

The VOM also has disadvantages.  The amount of equity risk is increased due to the possibility of relying on the more distant protective server stop during an extended PC or internet link failure.  Also, slippage when hitting a virtual pending order, stoploss or takeprofit could be much higher than for its server-based equivalent during times of high volatility such as news events.  The impact of these disadvantages can be minimised if VOM EAs are traded from a high reliability virtual desktop with a short ping time to the broker’s server.


4. The VOM in practice – a simple EA

Before going further, it’s time to show how a VOM EA can be written.  We’ll write a simple MA cross EA, starting with the template EA provided in the distribution package.  We will use the Fractal Moving Average, which has the potential to reduce pointless trades during sideways markets, a notorious problem with MA cross strategies. It should be stressed that this EA has been provided as a simple example and is not recommended for live trading – the backtest is profitable but the low number of trades means that the result is not statistically significant.

The EA is stored in experts\Virtual Order Manager\VOM EAs.

//+------------------------------------------------------------------+
//|                                           FraMA Cross EA VOM.mq5 |
//+------------------------------------------------------------------+
#property copyright "Paul Hampton-Smith"
#property link      "http://paulsfxrandomwalk.blogspot.com"
#property version   "1.00"

// this is the only include required.  It points to the parent folder
#include "..\VirtualOrderManager.mqh"

input double   Lots=0.1;
input int      Fast_MA_Period=2;
input int      Slow_MA_Period=58;
/* 
Because the broker is 3/5 digit, stoplosses and takeprofits should be x10.  
It seems likely that all brokers offering MetaTrader 5 will be 3/5 digit brokers, 
but if this turns out to be incorrect it will not be a major task to add 
digit size detection. */
input int      Stop_Loss=5000;
input int      Take_Profit=0;
/*
We can also change the level of logging.  LOG_VERBOSE is the most prolific 
log level.  Once an EA has been fully debugged the level can be reduced to 
LOG_MAJOR.  Log files are written under the files\EAlogs folder and are 
automatically deleted after 30 days.  */
input ENUM_LOG_LEVEL Log_Level=LOG_VERBOSE;

// The following global variables will store the handles and values for the MAs 
double g_FastFrAMA[];
double g_SlowFrAMA[];
int g_hFastFrAMA;
int g_hSlowFrAMA;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   LogFile.LogLevel(Log_Level);

// Need to include this line in all EAs using CVirtualOrderManager  
   VOM.Initialise();
   Comment(VOM.m_OpenOrders.SummaryList());

   g_hFastFrAMA = iFrAMA(_Symbol,_Period,Fast_MA_Period,0,PRICE_CLOSE);
   g_hSlowFrAMA = iFrAMA(_Symbol,_Period,Slow_MA_Period,0,PRICE_CLOSE);
   ArraySetAsSeries(g_FastFrAMA,true);
   ArraySetAsSeries(g_SlowFrAMA,true);

   return(0);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// Need to include this line in all EAs using CVirtualOrderManager  
   VOM.OnTick();
   Comment(VOM.m_OpenOrders.SummaryList());

// We now obtain copies of the most recent two FrAMA values in the 
// g_FastFrAMA and  g_SlowFrAMA arrays.  
   if(CopyBuffer(g_hFastFrAMA,0,Shift,2,g_FastFrAMA)!=2) || 
      CopyBuffer(g_hSlowFrAMA,0,Shift,2,g_SlowFrAMA)!=2)
     {
      Print("Not enough history loaded");
      return;
     }

// And now we detect a cross of the fast FrAMA over the slow FrAMA,
// close any opposite orders and Buy a single new one
   if(g_FastFrAMA[0]>g_SlowFrAMA[0] && g_FastFrAMA[1]<=g_SlowFrAMA[1])
     {
      VOM.CloseAllOrders(_Symbol,VIRTUAL_ORDER_TYPE_SELL);
      if(VOM.OpenedOrdersInSameBar()<1 && VOM.OpenOrders()==0)
        {
         VOM.Buy(_Symbol,Lots,Stop_Loss,Take_Profit);
        }
     }

// Opposite for Sell
   if(g_FastFrAMA[0]<g_SlowFrAMA[0] && g_FastFrAMA[1]>=g_SlowFrAMA[1])
     {
      VOM.CloseAllOrders(_Symbol,VIRTUAL_ORDER_TYPE_BUY);
      if(VOM.OpenedOrdersInSameBar()<1 && VOM.OpenOrders()==0)
        {
         VOM.Sell(_Symbol,Lots,Stop_Loss,Take_Profit);
        }
     }
  }
//+------------------------------------------------------------------+

And now with the release of the Strategy Tester it can be backtested, see Figure 1 below:

 Figure 1. FrAMA Cross EA backtest

Figure 1. FrAMA Cross EA backtest

The logging section is shown at Figure 2:

 Figure 2. Strategy test log

Figure 2. Strategy test log

 

5. VOM structure

Figure 4 below shows how multiple VOM EAs are configured:

Figure 3. Multiple VOM EAs

Figure 3. Multiple VOM EAs

Then looking inside the VOM, the main components are shown at Figure 4 below:

Figure 4. VOM internal structure

Figure 4. VOM internal structure

 Elements of firgure 4 explained:

  • Configuration - the VOM uses CConfig to store all the main configuration items in one place in a global object Config. To make access simple the member variables are public and no get/set functions are provided.
  • Global variables - these are the variables accessed in MQL5 by functions such as GlobalVariableGet(). The VOM uses the global variables  to
    • Record and increment the last Virtual Order ticket number using CGlobalVariable
    • Maintain a list of all virtual stoplosses so that disaster protection server stops can be maintained
  • Open trades and history files - these are the permanent disk files stored by CVirtualOrderArrays to ensure that order status can be re-established on restart.  A pair of these files is created and stored in Files\\VOM for each EA that uses the VOM.  A CVirtualOrder starts life in the VOM.m_OpenOrders array, and is transferred to the VOM.m_OrderHistory array when closed or deleted.
  • Activity and debug log - most code of any complexity needs the ability to log activity, and this function is encapsulated by the CLog class. This enables logging to be recorded at four different levels of detail and importance, and includes automatic cleanup of old log files to ensure that diskspace is managed.

Expert Advisors that use the VOM interact with the library as shown in Figure 5 below:

 Figure 5. EA interaction with the VOM library

 Figure 5. EA interaction with the VOM library


6. More on the disaster protection stoploss

Virtual stops have been quite common amongst MetaTrader 4 EAs.  If a stoploss is maintained at the client end only, the exit level for a trade is invisible to the broker, a strategy often implemented in the belief that some brokers engage in stop hunting.  On their own, virtual stops greatly increase trade risk, since a broker-client connection must be always be in place for the stop to be actioned. 

The VOM controls this risk by maintaining a server-based stop at a configurable distance away from the tightest virtual stop.  This is termed a disaster protection stoploss (DPSL) because it will normally only be actioned if the broker-client connection is broken for some time, as would be the situation with an internet connection break or a PC failure.  As virtual orders are opened and closed, and converted to a position at the server, the maintenance of the DPSL at the correct level can be a little complex, as illustrated in the following sequence.

Virtual order
action
Open
price
Virtual SL Position
at server
Stoploss
at server
Comment
0.1 lots BUY #1 2.00000 1.99000 0.1 lots BUY 1.98500 DPSL is 50 pips below virtual SL #1
0.1 lots BUY #2 2.00000 1.99500 0.2 lots BUY 1.99000 Virtual order #2 has a tighter SL so DPSL
is tightened to 50 pips below virtual SL #2
Close #2     0.1 lots BUY 1.98500 Revert to looser DPSL
0.1 lots SELL #3 2.00000 2.00500 none none Virtual orders #1 and #3 have cancelled each
other out at the server
Close #1     0.1 lots SELL 2.01000 Virtual Order #3 remains open - DPSL is
now 50 pips above virtual SL #3

7. Testing the Virtual Order Manager

A project of this size takes time to test thoroughly, so I wrote the EA VirtualOrderManaerTester.mq5 to enable virtual orders to be created, modifed, deleted and closed easily with command buttons on the chart.  

Figure 6 below shows a virtual buy order at 0.1 lot in the M5 window and a virtual buy order of another 0.1 lot open in the H4 window against EURUSD (see comment lines), with the server status correctly showing one position at 0.2 lots bought. Because the overall position is long, the Distaster Protection Stoploss can been seen below the tighter 20.0 pip stop.

Figure 6. Two EAs agreeing on direction

Figure 6. Two EAs agreeing on direction

Figure 7 now shows the two test EAs with opposing virtual orders, and no position is open at the broker:

Figure 7. Two EAs with opposing virtual orders and no position is open at the broker

Figure 7. Two EAs with opposing virtual orders and no position is open at the broker


8. A very simple display of all VOM open orders

Each VOM EA can only see its own orders, so I have written a very simple EA which collates the open orders from all VOMs.  The display is very simple, and when time permits a much better version could be written, perhaps with command buttons to perform modify, delete or close actions as required on each order.  The EA is included in the distribution pack as VOM_OrderDisplay.mq5.


9. Conclusion

At the time of writing this article, the VOM code is in Beta, just like MetaTrader 5 itself, and time will tell if the VOM concept becomes popular or ends up being regarded as just an interesting piece of MQL5 programming.

Let's go back to the design goals in section 3 and see where we have arrived

  1. Sociability: the behaviour of EAs written correctly using the VOM trading functions will be isolated from other EA activity
    • Result - yes, the VOM approach achieved this goal
  2. Robustness: elegant handling of abnormal events such as errors, breaks in client-server communication and incomplete order fills.
    • Result - some robustness is evident but there could be improvement as real trading situations occur and can be analysed 
  3. Ease of use: provision of well documented and simple trading functions
    • Result - As will be seen in the distribution pack of files, a .chm help file is included
  4. Ability to use in the Strategy Tester
    • Result - initial tests in the recently released strategy tester indicate that the VOM does backtest correctly, although the VOM approach slows down the test considerably.  Some work to improve throughput is probably needed  

A number of future changes may be desirable

  • As with any complex software development, it is likely that there are bugs remaining in the code
  • With each MetaTrader 5 Beta build release there may be required VOM changes to maintain compatibility
  • VomGetLastError() and VomErrorDescription() functions
  • Ability to read configuration from a file
  • Trailing stops of various types


10. Files in the zipped distribution pack

The VOM package comes as a number of .mqh files which should be installed in an Experts\Virtual Order Manager folder,

  • ChartObjectsTradeLines.mqh - CEntryPriceLine, CStopLossLine, CTakeProfitLine
  • StringUtilities.mqh - global enum descriptors such as ErrorDescription()
  • Log.mqh - CLog
  • GlobalVirtualStopList.mqh - CGlobalVirtualStopList
  • SimpleChartObject.mqh - CButton, CLabel and CEdit
  • VirtualOrder.mqh - CVirtualOrder
  • GlobalVariable.mqh - CGlobalVariable
  • VirtualOrderArray.mqh - CVirtualOrderArray
  • VirtualOrderManager.mqh - CVirtualOrderManager
  • VirtualOrderManagerConfig.mqh - CConfig
  • VirtualOrderManagerEnums.mqh - the various enums defined for the VOM
  • VOM_manual.mqh - this page of the manual
  • VOM_doc.chm***

Five EA mq5 files are also included under Experts\Virtual Order Manager\VOM EAs:

  • VOM_template_EA.mq5 - clone this to make your own EAs, and store them in Experts\Virtual Order Manage\VOM EAs
  • VirtualOrderManagerTester.mq5
  • Support_Resistance_EA_VOM.mq5
  • FrAMA_Cross_EA_VOM.mq5
  • VOM_OrderDisplay.mq5 

***Note that the VOM_doc.chm file may need to be unlocked:


Attached files |
vom-doc.zip (727.63 KB)
vom2_0.zip (608.43 KB)
vom-sources.zip (40.33 KB)
Last comments | Go to discussion (21)
Automated-Trading
Automated-Trading | 13 Jan 2012 at 13:00
phampton:

I have been using the VOM ever since I first wrote it, have fixed a number of bugs, mostly with the handling of the protective stop, and also changed the code to match changes in MT5.  Attached are the updated files. 

New version is attached to the article.
locan.BBS
locan.BBS | 24 Jul 2012 at 04:48
phampton:

I have been using the VOM ever since I first wrote it, have fixed a number of bugs, mostly with the handling of the protective stop, and also changed the code to match changes in MT5.  Attached are the updated files.  

Comments very welcome.

Paul 


locan.BBS
locan.BBS | 24 Jul 2012 at 04:53

This newer version also doesn't contain a proper file "Supports and Resistances..." but only a second copy of another EA. Also the "...Order Manager Tester" is actually entitled "...Order Tester". Is this the right file?

Thanks!

Marcelo Coutinho
Marcelo Coutinho | 21 Jul 2014 at 21:07

Hi Paul,

Can y please help me here.

I am getting a Lots error but as you see below, the lots is hardcoded and even like this it is not working (pict atached).

Can y please help me if possible ?

Regards,

MRC 

      if(glOrder==-1)
        {
         mrequest.type=ORDER_TYPE_SELL;
         mrequest.price=NormalizeDouble(price_info.bid,_Digits);
         mrequest.sl=NormalizeDouble(price_info.bid+StopLoss,_Digits);
         mrequest.tp=NormalizeDouble(price_info.bid-TakeProfit,_Digits);
         mrequest.comment="SELL";

         VOM.Sell(Ativo,5.0,(int)StopLoss,(int)TakeProfit);

         if(UsaRelatorio==true) Report("B VENDA");
        }

 2014.07.21 16:05:10.497 YouBotG3VOM (WINQ14,H1) CVirtualOrderManager::OrderSend error: failed to adjust position at server, returning -1

2014.07.21 16:05:10.497 YouBotG3VOM (WINQ14,H1) CVirtualOrderManager::PositionChangeSizeAtServer error: Problem with OrderSend TRADE_ACTION_DEAL, return code Autotrading disabled by client terminal. OrderCheck() returned Trading by Expert Advisors prohibited

2014.07.21 16:05:10.495 YouBotG3VOM (WINQ14,H1) CVirtualOrderManager::PositionChangeSizeAtServer(WINQ14,5.00,ORDER_TYPE_BUY,57765)


Henrique Vilela
Henrique Vilela | 13 Jan 2015 at 15:01

"The VOM controls this risk by maintaining a server-based stop at a configurable distance away from the tightest virtual stop."

That's sounds fine at first, but (in some cases) what happen is that the server-based stop end up being tighter than the loosest virtual stop.

It's specially true if you decrease de distance, like:

Config.ServerStopLossMargin=1;

 Also, it would be great to have the same security system to keep the profits, maintaining a server-based take profit. Don't you think?

Step on New Rails: Custom Indicators in MQL5 Step on New Rails: Custom Indicators in MQL5

I will not list all of the new possibilities and features of the new terminal and language. They are numerous, and some novelties are worth the discussion in a separate article. Also there is no code here, written with object-oriented programming, it is a too serous topic to be simply mentioned in a context as additional advantages for developers. In this article we will consider the indicators, their structure, drawing, types and their programming details, as compared to MQL4. I hope that this article will be useful both for beginners and experienced developers, maybe some of them will find something new.

Here Comes the New MetaTrader 5 and MQL5 Here Comes the New MetaTrader 5 and MQL5

This is just a brief review of MetaTrader 5. I can't describe all the system's new features for such a short time period - the testing started on 2009.09.09. This is a symbolical date, and I am sure it will be a lucky number. A few days have passed since I got the beta version of the MetaTrader 5 terminal and MQL5. I haven't managed to try all its features, but I am already impressed.

False trigger protection for Trading Robot False trigger protection for Trading Robot

Profitability of trading systems is defined not only by logic and precision of analyzing the financial instrument dynamics, but also by the quality of the performance algorithm of this logic. False trigger is typical for low quality performance of the main logic of a trading robot. Ways of solving the specified problem are considered in this article.

Using text files for storing input parameters of Expert Advisors, indicators and scripts Using text files for storing input parameters of Expert Advisors, indicators and scripts

The article describes the application of text files for storing dynamic objects, arrays and other variables used as properties of Expert Advisors, indicators and scripts. The files serve as a convenient addition to the functionality of standard tools offered by MQL languages.