My approach. The core is the engine. - page 92

 
Maxim Kuznetsov:

The only and only GlobalVariables and files for data exchange between EAs, indicators and scripts are

All 4 points above are local "hacks" for want of fish. All 4 points above use mechanisms not designed for exchanging arbitrary data, much less arrays of data.

You'd think GlobalVariables was designed specifically for messaging. That's a silly thing to say. In fact it's the same hack as any other item.

 
fxsaber:


...Roughly speaking,a full write/read tick cycle through a resource runs at a rate of 4 million ticks per second.

The read/write to the resource is very fast. But to what extent is this suitable for such a transmission:

1. Line A. Timer Event. Collect all parameter values that were changed at the event and translate them into a string. Translate string to Char, write to resource. Send message to B side.

2. Party B. OnChartEvent() event, receives a message signal, opens the resource, reads it, fills the parameter kernel with new values, redraws the required elements.

What if this event is executed continuously, at the timer frequency?

The question is how best to use resources for this, if there are other options.

//---------------------------------------------------------------------------------------------------------------------

  • The EventChartCustom() option has two drawbacks.

  1. The parcel becomes in the event queue.
  2. The parcel can't be more than 127 characters long. Consequently, a 1000 character message has to be split and then reassembled. And each part of the message will be in the event queue.
  • The variant with passing through graph objects, requires splitting the message into 64-character bundles, writing them into object descriptions and then reassembling them. It's interesting that this variant is the fastest, but as the length of the string increases, its speed decreases. That is, each call to ObjectSetString() takes 3 microseconds. But if a string is 1000 characters long, we need to split it into 64 characters, which means that we need to call ObjectSetString() about 8 times. 8*3 = 24 ms. Then it takes the same amount of time to assemble the string. That's why if the string was 10 000 characters long, this method would definitely approach the speed of the method working through resources. (I'm talking about time of saving and reading the resource + transferring strings to uint and back).
The resource variant remains untested to the end. I'll test it in the tester today and it will be finally clear if it can be universal.
 
Реter Konow:

What if this event is executed continuously, at the timer frequency?

The question is how best to use resources for this, if there are other options.

Forum on trading, automated trading systems and strategy testing

Data exchange between programs

fxsaber, 2018.11.21 13:12

Probably have a lot of time to describe in such detail the various options for interactions. Unfortunately, I don't possess such a resource.

Here's an article on the subject where a full interaction is going on. Each building is built from bricks and for specific tasks. All the possible bricks are shown at the beginning of the thread. The rest is up to the builder.

 
fxsaber:

The article does not test the communication of two programmes via resources, one of which is in the tester.

 

What's the problem with the union? Please, an example:

union UZ{
   double d;
   int i[2];
};

void OnStart(){

   UZ u1;
   UZ u2;
   
   u1.d=12345.678;
   
   ArrayCopy(u2.i,u1.i);
   
   Alert(u2.d);

}
 
Реter Konow:

The article does not test the communication of two programmes via resources, one of which is in the tester.

Read the sentence about bricks.

 
fxsaber:

...

This article is firing a cannon at sparrows. Like many articles. I'd sooner solve the problem myself than understand the article.

Everything can be done 10 times easier and clearer. But the article is a hell of a lot easier...


And what good is the article if you say you haven't checked the operation of resources in the tester?

 
Реter Konow:

And what good is this article if you say you haven't checked the resource operation in the tester?

Got out of the discussion.

 

There is something wrong with this solution. Maybe I'm doing something wrong.

To make it short:

The StringToCharArray() function takes ONLY an array of char.

The ResourceCreate() function accepts ONLY a uint array.

Hence, it is necessary to intermediate rewrite the contents of the char array (filled with the converted string), into the uint array.

 
//+------------------------------------------------------------------+
//|                                                    Tester EA.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   //----------------------------------------------
   ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0);
   ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   uchar Arr[];
   uint  Data[];
   //---------------------------
   string price = (string)Bid;
   //---------------------------
   int width = StringToCharArray(price,Arr);
   //---------------------------
   ArrayResize(Data,width);
   //---------------------------
   ArrayCopy(Arr,Data);
   //---------------------------
   if(!ResourceCreate("::Resource",Data,width,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA))Print("Resource is not created!");
   //---------------------------
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+

Indicator on a normal chart:

//+------------------------------------------------------------------+
//|                                              Resource reader.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   EventSetMillisecondTimer(25); 
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   uint Data[50],width,height;
   //-----------------------------
   if(!ResourceReadImage("::Resource",Data,width,height))Print("Failed to read resource!");
   else Print("Resource is readable!");
   //-----------------------------
   
  }
//+------------------------------------------------------------------+