Discussion of article "The Implementation of a Multi-currency Mode in MetaTrader 5" - page 5

 
Lazarev:

tell me,

1. if I need only Bid and Ask from other currencies, is it fair to use "spies"?

2. it's just an idea, is there no possibility in the onChartEvent function to check events from other currencies and not only from the current currency?

3. is it possible to set the timer value less than one in the onTimer event, so that it would download the quotes value much more often and accordingly lag behind the time of the last tick by the minimum time?

4. or is it possible to use "CHARTEVENT_CUSTOM+n" to check, in my case, the crossing of mashes on other graphs?

1. Using.

2. There is an option. The event from another currency should be sent to the chart where the EA with OnChartEvent() is set.

3. No. One is the minimum.

4. Can.

 

I created a simple "spy indicator" SendEvent.mq5, which sends an event when a new quote arrives:

#property indicator_chart_window
#property indicator_plots 0
int OnInit()
  {
   return(0);
  }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   EventChartCustom(0,1,0,0,_Symbol);
   return(rates_total);
  }

I created a simple Expert Advisor that receives events from this indicator and tries to make a trade operation (here is a part, the full text is in the attached file):

void OnChartEvent(const int id, // ChartEvent event handler
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)            // sparam contains the name of the instrument
  {
      // request Digit,Point,Ask,Bid for the instrument for which the event has occurred
      if(!SymbolInfoInteger(sparam,SYMBOL_DIGITS,dig)) Print("SymbolInfoInteger(SYMBOL_DIGITS) ERROR!");
      if(!SymbolInfoDouble(sparam,SYMBOL_POINT,p)) Print("SymbolInfoDouble(SYMBOL_POINT) ERROR!");
      if(!SymbolInfoDouble(sparam,SYMBOL_BID,Bid)) Print("SymbolInfoDouble(SYMBOL_BID) ERROR!");
      if(!SymbolInfoDouble(sparam,SYMBOL_ASK,Ask)) Print("SymbolInfoDouble(SYMBOL_ASK) ERROR!");
      d=(int)dig;
      if(1>0) // we always buy
        {
         q.action=TRADE_ACTION_DEAL; // fill the MqlTradeRequest structure and try to make a trade operation
         q.symbol=sparam; // sparam contains the name of the tool
         q.volume=Lot;
         q.price=NormalizeDouble(Ask,d);
         q.sl=NormalizeDouble(Ask-p*StopLoss,d);
         q.tp=NormalizeDouble(Ask+p*TakeProfit,d);
         q.deviation=0;
         q.type=ORDER_TYPE_BUY;
         q.type_filling=ORDER_FILLING_FOK;
         // check the current tool properties
         Print("Bid=",DoubleToString(Bid,8),", Ask=",DoubleToString(Ask,8),", Digits=",d,", Points=",DoubleToString(p,8));
         // check the structure of the trade request we will send
         Print("q.action=",q.action,", q.symbol=",q.symbol,", q.volume=",q.volume,", q.price=",DoubleToString(q.price,d),", q.sl=",DoubleToString(q.sl,d),", q.tp=",DoubleToString(q.tp,d),", q.deviation=",q.deviation,", q.type=",q.type,", q.type_filling=",q.type_filling);
         Print(OrderCheck(q,ch));                                  // check whether a trade operation can be performed
         Print("ch.retcode=",ch.retcode,", ch.comment=",ch.comment); // result
         Print("OrderSend:",OrderSend(q,s));                        // attempt to make a trade operation
         Print("s.retcode=",s.retcode,", s.comment=",s.comment);     // result
        }
      if(0>0) // if the condition is corrected, we will sell
        {
         // аналогично для продажи
        }
     }
  }

The Expert Advisor receives events from the indicator, but in the tester (both with and without visualisation) cannot perform a trade operation - the error "Invalid Request" is returned, return code 10013. In real time it works normally. If the trade operation in the Expert Advisor is performed from OnTick() instead of OnChartEvent() - also works fine.

I inserted the sending of trade request into the Expert Advisor template offered by the author of the article in CodeBase - also trade operations do not work (same error).

Can anyone tell me what the reason is? I read in this thread that OnChartEvent() is not processed in the tester, but in this case the events sent by the indicator are processed in the tester, but it is impossible to execute a trade operation from OnChartEvent() in the tester.

Files:
ea.mq5  4 kb
SendEvent.mq5  1 kb
 
zdd:

I created a simple "indicator-spy" SendEvent.mq5, which sends an event when a new quote arrives:

Created a simple Expert Advisor that receives events from this indicator and tries to make a trade operation (I give a part of it, the full text is in the attached file):

The Expert Advisor receives events from the indicator, but in the tester (both with and without visualisation) cannot perform a trade operation - the error "Invalid Request" is returned, return code 10013. In real time it works normally. If a trade operation in the Expert Advisor is performed from OnTick() instead of OnChartEvent() - also works fine.

I inserted the sending of trade request into the Expert Advisor template offered by the author of the article in CodeBase - trade operations do not work either (same error).

Can anyone tell me what the reason is? I read in this thread that OnChartEvent() is not processed in the tester, but in this case the events sent by the indicator are processed in the tester, but it is impossible to execute a trade operation from OnChartEvent() in the tester.

Try to bring my fish to my mind. Of course, the logic is not complete and very dumb, but it seems to be very similar to what you need.

At least positions from the market opens both in the tester and on the demo.

I don't know why (I'm too lazy to figure it out), but your example gave me 10013 at any situation.

PS

It is better to bind to standard objects (such as CAccountInfo and CTrade). But if you have the patience to write everything yourself, I will be only glad.

By the way, the implementation of the spy itself is better to take from the article, or make a modifiable copy (I, for example, suggest replacing this year "(long)_Period" with the date-time of sending the event or other useful information). Your variant is somehow quite "raw".

Files:
DemoEA.mq5  20 kb
 
Interesting:

See if you can get my fish to work. The logic is incomplete and very obtuse, but it seems to be very similar to what you need.

Thanks, got it. If you declare structures MqlTradeRequest and MqlTradeResult at the global level, it works!
 
Thank you so much for the article!
 

I am trying to get prices for three pairs EURUSD, EURGBP, GBPUSD. Everything works fine when selecting "All ticks" or "Open prices only" in the strategy tester. But if I choose "Every tick based on real ticks", then for some reason several "New Bar" events can occur in one minute for one instrument.

To repeat, you can select an interval, for example from 2016.07.15 to 2016.07.19. Here is an example log, watch the 7th minute, 9th minute:

2016.07.15 00:05:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333

2016.07.15 00:05:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.1119

2016.07.15 00:05:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33399

2016.07.15 00:06:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8334

2016.07.15 00:06:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.1119

2016.07.15 00:06:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33394

2016.07.15 00:07:19 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333700000000001

2016.07.15 00:07:19 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11174

2016.07.15 00:07:19 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33382

2016.07.15 00:07:19 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333700000000001

2016.07.15 00:07:19 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11174

2016.07.15 00:07:19 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33381

2016.07.15 00:07:19 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333700000000001

2016.07.15 00:07:19 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11174

2016.07.15 00:07:19 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33384

2016.07.15 00:08:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.83329

2016.07.15 00:08:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11167

2016.07.15 00:08:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33394

2016.07.15 00:09:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.83327

2016.07.15 00:09:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11166

2016.07.15 00:09:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33396

2016.07.15 00:09:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.83327

2016.07.15 00:09:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11166

What is the reason for this behaviour when selecting the "All ticks based on real ticks" mode ?
 
ooparadise:

I am trying to get prices for three pairs EURUSD, EURGBP, GBPUSD. Everything works fine when selecting "All ticks" or "Open prices only" in the strategy tester. But if I choose "Every tick based on real ticks", then for some reason several "New Bar" events can occur in one minute for one instrument.

To repeat, you can select an interval, for example from 2016.07.15 to 2016.07.19. Here is an example log, watch the 7th minute, 9th minute:

What is the reason for this behaviour when selecting the "All ticks based on real ticks" mode ?

How do you catch the "New bar" event ? In build 1375 the accuracy of tick arrival has been improved to milliseconds:

Tester: Added support for time to millisecond accuracy. Previously in the strategy tester the time quantum was one second.

  • The EventSetMillisecondTimer and Sleep functions now work more accurately in the strategy tester.
  • The accuracy of ticks submission in testing multicurrency Expert Advisors has increased. Previously, if several ticks were placed in one second (tick volume of a minute bar is more than 60), all of them were assigned the same time. When testing mono-currency Expert Advisors, it doesn't matter much, as ticks are simply passed to the Expert Advisor sequentially. However, when testing on several pairs, it is important to know which pair tick came first. Previously, ticks for each symbol were transmitted to the Expert Advisor sequentially: first all ticks for one symbol for a second, then all ticks for another symbol. Now they are transmitted taking into account milliseconds.

    When testing on real ticks, milliseconds are taken from the original tick data. When generating ticks, the milliseconds are spelled out according to the tick volume. For example, if there are 3 ticks in one second, they will be assigned the time 000, 333 and 666 milliseconds.
 

I catch anew bar the way it is written in the article. That is, the indicator sends the "New Bar" event in this way (compared to the previous time minutes, hours, days, months):

   double price_current=price[rates_total-1];

   TimeCurrent(time);

   if(prev_calculated==0)

     {

      EventCustom(CHARTEVENT_INIT,price_current);

      prev_time=time; 

      return(rates_total);

     }

//--- new tick

   if((flag_event & CHARTEVENT_TICK)!=0) EventCustom(CHARTEVENT_TICK,price_current);       


//--- check change time

   if(time.min==prev_time.min && 

      time.hour==prev_time.hour && 

      time.day==prev_time.day &&

      time.mon==prev_time.mon) return(rates_total);


//--- new minute

   if((flag_event & CHARTEVENT_NEWBAR_M1)!=0) EventCustom(CHARTEVENT_NEWBAR_M1,price_current); 

UPDATE: The problem went away when installing build 1375.

 

Thanks for this huge article. I haven't heard so far of EventChartCustom. I was trying other chart events but they only took into account events caused by human action. It solves many things.

By the way, I work on MQL4, it was at 98% the same thing.

Cheers

 

Thank you so much for this, it's so useful. Great job!