Download MetaTrader 5

How to copy signals using an EA by your rules?

6 September 2016, 13:56
Karputov Vladimir
0
8 027

Table Of Contents

 

Risk Warning

Before using this method, you need to rely primarily on common sense, as the increase in the copy ratio entails increased risks.

The method for increasing the copy ratio of the signal can be used when the provider trades minimum lot, the deposit load is set to 95% in the settings (maximum utilization of the deposit) and at the same time the trade copy ratio is still too small for a subscription to be meaningful. You can learn the future trade copy rate before subscribing to a signal you like with the help of the article Calculator of signals.

The assistant expert for copying trading signals presented in this article can be downloaded from the Market for free:


1. Preparation

Before you start, please see the tutorial videos:

  1. Selecting a trading signal
  2. Subscription to Signal
  3. Renting a virtual hosting
  4. Migrating subscription and Expert Advisor to virtual hosting


1.1. The idea of the copier

The copier operates on a virtual hosting, on a trade account which is subscribed to a signal. Its main purpose is to increase the positions opened by the Signals service by the specified number of times. Fig. 1 shows the idea of the copier that is attached to a hedging account:


Fig. 1. The idea of the copier on a hedging account

Fig. 2 demonstrates the idea of the copier operation on a trade account with netting position accounting system:

 

Fig. The idea of the copier on a netting account 

Thus, as soon as the Signals service successfully performs a deal on the subscriber account, the copier immediately performs a deal with the volume determined by the formula:

(volume of the deal performed by the Signals service) * "Deal multiply by"

The "Deal multiply by" parameter is responsible for increase ratio of the deals and can be set in the input parameters:

Input Parameters

Fig. 3. Input Parameters 

When working on a netting trade account in MetaTrader 5, the copier actions lead to an increase in the volume of the copied position. On a hedging account in MetaTrader 5, the copier actions cause a new position with an increased volume to be opened. Below is an example of the copier operation for netting and hedging MetaTrader 5 accounts with the "Deal multiply by" parameter for increasing the deals set to 5:

Action of the Signals service Action of the copier on
hedging account
Action of the copier on
netting account
Copied deal BUY EURUSD 0.01 lot Opened new position BUY EURUSD 0.05 lot — thus, subscriber has two positions BUY EURUSD 0.01 lot and BUY EURUSD 0.06 lot Opened deal BUY EURUSD 0.05 lot — thus, subscriber has a position BUY EURUSD 0.06 lot

 

2. Features of the Signals Service

2.1. Friend or foe

As the copier monitors all deals performed by the Signals service, it is necessary to know certain features of the Signals service operation. For example, this service maintains only "friendly" positions — those copied via the service.

When a position is successfully opened at the subscriber, the Signals service writes the name of the signal to the copied deal comment and a unique identifier to the Magic Number field of the deal.

This very identifier is subsequently used for identification of the deal opened via the Signals service in further synchronizations of the subscription.

This is the comment for BUY 0.01 EURUSD deal copied from the "Test3443431" signal. It can be viewed by hovering the mouse over the copied deal in the "History" tab of the "Toolbox" window:

 Comment of the copied deal ("History" tab)

Fig. 4. Comment of the copied deal ("History" tab)

Here:

  1. "#69801797" — deal ticket;
  2. "Test3443431" — name of the signal the deal has been copied from;
  3. "361104976048745684" — Magic Number — deal identifier.

In the "Trade" tab it can be seen that the current position of the subscriber has the same description but without the ticket:

Comment of the copied deal ("Trade" tab)

Fig. 5. Comment of the copied deal ("Trade" tab)

In other words, the Signals service accounts the positions on the subscriber side using the Magic Number field of the deal. The accounted positions will be identified as "friendly". And the Signals service can change the volumes or close only the "friendly" positions.

Unaccounted positions will be identified as "foes". The Signals service has no power over such positions.

2.2. Substitute the Magic Number or not?

The MetaTrader 5 terminal allows to connect both hedging and netting trading accounts of the subscriber. Depending on the type of the connected account the behavior of the copier regarding the substitution of the Magic Number in the copied position will differ drastically. To answer this question, let us consider the following figure:


Fig. 6. Netting account, without substitution of the Magic Number 

As it can be seen, on a netting account the copier increased the position without substituting the Magic Number — this caused the position to become "foe" for the Signals service. That is, operation of the copier without substituting the Magic Number is a mistake. This means that on a netting account the copier must always substitute the Magic Number when increasing the position. But while working on a hedging account everything is the opposite: when increasing the position the copier must substitute the Magic Number with its own.

2.3. What happens to the "foe" position, if provider closes its position?

On the example of a hedging account: a position BUY 0.01 EURUSD was copied to the subscriber trading account. Then the subscriber decided to intervene in the work of the service and opened a position BUY 0.01 EURUSD. During one of the nearest synchronizations the Signals service generated this error:

Signal  '3447880': local positions do not correspond to signal provider [#85639429 buy 0.04 EURUSD 1.11697]

That is, the position BUY 0.01 EURUSD, manually opened by the subscriber, had been identified as "foe" by the Signals service. And now let us see what happens when the provider closes its position: the Signals service similarly closes the "friendly" position, but the manually opened position BUY 0.01 EURUSD remains in the terminal. By the way, inadmissibility of manual intervention in the work of the Signals service is clearly stated in the rules:

IV. Subscription to Signals

   20. Execution of your own trades in the account which is subscribed to a Signal constitutes an interference and can lead to unpredictable results.


3. How to detect emergence of a deal

The choice of method to identify the emergence of a deal, on the one hand, affects the copying response rate, and on the other - could lead to additional financial costs to cover spread if a deal is opened with an increased volume by mistake.

It should be remembered that we are subscribed to a signal, which means that the trade events of the signal provider are monitored by the Signals service. If necessary, this service will open or close the position/positions. Any opening/closing of a position/positions causes a change in the trading account of the subscriber. This very change should be tracked, and the OnTradeTransaction() event will inform about it.

3.1. Tracking using the OnTradeTransaction()

Why was the OnTradeTransaction() chosen and not the OnTrade()? Because the OnTradeTransaction() contains very useful information — type of the trade transaction. Out of all possible transaction types only one is of interest:

TRADE_TRANSACTION_DEAL_ADD — adding a deal to history. It is performed as a result of order execution or making operations with the account balance.

That is, the copier waits for the deal to be added to history (and this guarantees a successful trade operation on the subscriber account), and only after that it starts processing the situation. 


4. When subscription is possible and when it is not

A subscription can be successful only if both accounts have the same position accounting system:

Subscription Result
Provider — netting accounting, subscriber — hedging accounting

An attempt to subscribe an account with hedging accounting system to a provider with netting accounting system fails. 

2016.05.11 11:15:07.086 Signal  '*******': subscribe to signal [*****] started
2016.05.11 11:15:07.141 Signal  '*******': subscription/renewal prohibited

If the provider has netting account and the subscriber has hedging account, the signal cannot be subscribed to.

Provider — hedging accounting, subscriber — netting accounting

An attempt to subscribe an account with netting accounting system to a provider with hedging accounting system fails. 

2016.05.11 11:39:54.506 Signal  '*******': subscribe to signal [******] started
2016.05.11 11:39:54.560 Signal  '*******': subscription/renewal prohibited

If the provider has hedging account and the subscriber has netting account, the signal cannot be subscribed to.

Provider — hedging accounting, subscriber — hedging accounting Subscription successful.
Provider — netting accounting, subscriber — netting accounting Subscription successful.

5. Store information about copying

What is the best place to store the information about the copying performed? And a more global question — is it necessary to store such information at all? In this version of the copier, the information is stored in a structure. Structure declaration:

//+------------------------------------------------------------------+
//| Structure of congruences of positions of the terminal and        |
//| positions of the copier                                          |
//+------------------------------------------------------------------+
struct correlation
  {
   long              POSITION_IDENTIFIER_terminal; // Position identifier (terminal)
   //+------------------------------------------------------------------+
   //| Position identifier is a unique number that is assigned          |
   //| to every newly opened position and doesn't change during         |
   //| the entire lifetime of the position.                             |
   //| Position turnover doesn't change its identifier.                 |
   //+------------------------------------------------------------------+
   double            POSITION_VOLUME_terminal;     // Volume of the position opened by the Signals service
   long              POSITION_IDENTIFIER_copier;   // Position identifier (copier)
   //+------------------------------------------------------------------+
   //| Position identifier is a unique number that is assigned          |
   //| to every newly opened position and doesn't change during         |
   //| the entire lifetime of the position.                             |
   //| Position turnover doesn't change its identifier.                 |
   //+------------------------------------------------------------------+
   ulong             DEAL_ticket;                  // Deal ticket, if the deal is executed.
  };

The structure contains only four elements:  

  1. "POSITION_IDENTIFIER_terminal" — this structure stores the identifier of the position opened by the terminal (Signals service)
  2. "POSITION_VOLUME_terminal" — this stores the volume of the position opened by the terminal (Signals service)
  3. "POSITION_IDENTIFIER_copier" — this element stores identifier of the position opened by the copier
  4. "DEAL_ticket" — this contains ticket of the deal opened by the copier if that deal succeeded

All actions are performed by the copier only from within the OnTradeTransaction function, and only if the trade transaction type is TRADE_TRANSACTION_DEAL_ADD. When these conditions are met, it always looks for the deal which has generated this transaction, and retrieve its parameters:

//+------------------------------------------------------------------+ 
//| TradeTransaction function                                        | 
//+------------------------------------------------------------------+ 
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value 
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
      long     deal_entry        =0;
      double   deal_volume       =0;
      string   deal_symbol       ="";
      long     deal_type         =0;
      long     deal_magic        =0;
      long     deal_positions_id =0;
      string   deal_comment      ="";
      if(HistoryDealSelect(trans.deal))
        {
         deal_entry=HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         deal_volume=HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
         deal_symbol=HistoryDealGetString(trans.deal,DEAL_SYMBOL);
         deal_type=HistoryDealGetInteger(trans.deal,DEAL_TYPE);
         deal_magic=HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
         deal_positions_id=HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
         deal_comment=HistoryDealGetString(trans.deal,DEAL_COMMENT);
         //if(deal_magic==0 && SignalInfoGetString(SIGNAL_INFO_NAME)!=HistoryDealGetString(trans.deal,DEAL_COMMENT))
         //   return;
        }
      else
         return;
...

The table below shows the operation logic of the copier on a hedging and netting accounts:

the  sign means that a record wad made into this element of the structure

the sign means that the copier did not make any changes to elements of the structure

The client terminal POSITION_IDENTIFIER terminal POSITION_VOLUME terminal POSITION_IDENTIFIER copier deal_ticket
Hedging. Netting. DEAL_ENTRY_IN
Searching the deal_ticket structure elements for the value of trans.deal.
If no matches found: increase the structure by 1 ... 0 0 0 0
... and regard it as a service deal — therefore, open a position (DEAL_VOLUME * coefficient), and if CTrade.ResultDeal() != 0, write to the POSITION_IDENTIFIER_terminal element the value of DEAL_POSITION_ID, the value of CTrade.ResultDeal() is written to the deal_ticket element, and the deal_volume — to POSITION_VOLUME_terminal. 0
If found – then it is a deal opened by the copier, therefore write its DEAL_POSITOIN_ID to the POSITION_IDENTIFIER_copier element.

Hedging. Netting. DEAL_ENTRY_OUT
Searching for DEAL_POSITION_ID in the elements of the POSITION_IDENTIFIER_terminal and POSITION_IDENTIFIER_copier structures. 
Hedging.
... found DEAL_POSITION_ID...
... ... in element POSITION_IDENTIFIER_copier – do nothing and leave  ✔  ✔  ✔  ✔
... ... in element POSITION_IDENTIFIER_terminal –...  ✔  ✔  ✔  ✔
... ... ... does this position still exist? If it exists, close the position opened by the copier...  ✔  ✔  ✔  ✔
... ... ... ... open a position (volume of the found position * coefficient) and if CTrade.ResultDeal() != 0, write the value of CTrade.ResultDeal() to the deal_ticket element.  ✔  ✔  ✔  ✔
... ... ... no, this position no longer exists. Close the position opened by the copier.  ✔  ✔  ✔  ✔
Netting.
... found DEAL_POSITION_ID...
... ... in element POSITION_IDENTIFIER_terminal – (the previous volume opened by the Signals service is currently stored in the structure) calculate the new volume, and if CTrade.ResultDeal() != 0, then write the value of CTrade.ResultDeal() to the deal_ticket element.  ✔  ✔  ✔  ✔

Conclusion

If you subscribed to a signal, rented the built-in virtual hosting, but the provider trades the minimum (or very small) lot — you can send the copier considered in this article to the built-in virtual hosting. That way all deals will be increased in proportion to the copier settings.

Attention: the "copier.mq5" file of the copier and the "languages.mqh" included file must be located in the same folder.


Translated from Russian by MetaQuotes Software Corp.
Original article: https://www.mql5.com/ru/articles/2438

Attached files |
copier.mq5 (37.81 KB)
languages.mqh (6.19 KB)
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.

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.

How to create an indicator of non-standard charts for MetaTrader Market How to create an indicator of non-standard charts for MetaTrader Market

Through offline charts, programming in MQL4, and reasonable willingness, you can get a variety of chart types: "Point & Figure", "Renko", "Kagi", "Range bars", equivolume charts, etc. In this article, we will show how this can be achieved without using DLL, and therefore such "two-for-one" indicators can be published and purchased from the Market.