Best way to share data between indicators (.csv vs. array)

 

I'm attempting to solve an issue but I'd like to have an opinion which solution is more efficient/appropriate in the MQL4 way of thinking.


I wrote an indicator that, once a minute, reads a website and extracts a certain value.

It will then write that value and the time into a .csv file.


Another indicator relies to have that information up to date in the onCalculate function.

My first thought was it should just read the .csv file (and maybe create its own array saving the values) to do its calculations.

Can another indicator read that file while the other one is still writing to it?


The other way could be that the indicator doesn't write to a .csv at all, but saves the data in an array.

The other indicator would then access that array (I guess that should be possible, but I need to read up on how to do it).


Any suggestion very welcome!

 
ZetaTrader:
I wrote an indicator that, once a minute, reads a website and extracts a certain value.

Can another indicator read that file while the other one is still writing to it?

The other indicator would then access that array (I guess that should be possible, but I need to read up on how to do it).
  1. How did you do that? Indicator's can not use blocking calls.
  2. Not unless you specify shared, and do your own coordination.
              FileOpen - File Functions - MQL4 Reference
  3. Shared memory, named pipes/quick channel. Off topic here.
 
whroeder1:
  1. How did you do that? Indicator's can not use blocking calls.
  2. Not unless you specify shared, and do your own coordination.
              FileOpen - File Functions - MQL4 Reference
  3. Shared memory, named pipes/quick channel. Off topic here.

Thank you for the reply.

1. Do the once a minute thing, do the website reading or do the extraction?

2. I take that as a yes. Thanks for the link.

3. I take that as a yes as well. Where would that be on topic?

 

ZetaTrader:

1. Do the once a minute thing, do the website reading or do the extraction?

2. I take that as a yes. Thanks for the link.

3. I take that as a yes as well. Where would that be on topic?

  1. Perhaps you should read the manual.
    Since the delays in receiving a response can be large, the function is not available for calls from the indicators, ... The function can be called only from Expert Advisors and scripts,
              WebRequest - Common Functions - MQL4 Reference
  2. :
  3. The internet. Do your own research.
 
whroeder1:
  1. Perhaps you should read the manual.
  2. :
  3. The internet. Do your own research.

1. I'm not using that function, I'm loading the web site into a string and search that string, which does work. It's happening in an indicator. I'd prefer to have this happening asynchronously, which I'll be looking into.

2. :

3. I've already stated in my initial posting, that I'd need to read up on it. My question merely was, whether that was possible at all. Apart from that, this forum is the part of the internet which would be most appropriate to state a question about MQL4 programs.


Which leaves the main premise of my post unaddressed, which I was hoping to get insight by a more experienced MQL4 programmer than myself:

"I'm attempting to solve an issue but I'd like to have an opinion which solution is more efficient/appropriate in the MQL4 way of thinking."


I'm not asking for any code here, but if anyone feels offended by my post it is their prerogative to ignore it.

 
ZetaTrader: I'm not using that function, I'm loading the web site into a string and search that string, which does work. It's happening in an indicator.

How are you "loading the web site" without using a web request?

 
The best way is to use your app collecting and parsing data to generate a custom chart event and pass the data through the args (can also serialize all data and pass through sparam) the moment the data is ready so your indicator can process it immediately. 
 
whroeder1:

How are you "loading the web site" without using a web request?.

I'm using this function courtesy of Hanover over at ForexFactory, I've adapted it slightly to work in my context.

I'd rather you'd give me an opinion on my question, though.

#import "wininet.dll"
#define INTERNET_FLAG_PRAGMA_NOCACHE    0x00000100 // Forces the request to be resolved by the origin server, even if a cached copy exists on the proxy.
#define INTERNET_FLAG_NO_CACHE_WRITE    0x04000000 // Does not add the returned entity to the cache. 
#define INTERNET_FLAG_RELOAD            0x80000000 // Forces a download of the requested file, object, or directory listing from the origin server, not from the cache.
  int InternetAttemptConnect (int x);
  int InternetOpenW(string sAgent, int lAccessType, string sProxyName = "", string sProxyBypass = "", int lFlags = 0);
  int InternetOpenUrlW(int hInternetSession, string sUrl, string sHeaders = "", int lHeadersLength = 0, int lFlags = 0, int lContext = 0);
  int InternetReadFile(int hFile, int& sBuffer[], int lNumBytesToRead, int& lNumberOfBytesRead[]);
  int InternetCloseHandle(int hInet);
#import

string readWebPage(string url)   {
   if (!IsDllsAllowed()) { 
      Alert("'Allow DLL imports' on the 'Common' tab must be checked ON");              
      return("");  
   }

   int rv = InternetAttemptConnect(0);
   if (rv != 0) { 
      Alert("Unknown error attempting to connect to Internet");                         
      return("");  
   }

   int hInternetSession = InternetOpenW("Microsoft Internet Explorer", 0, "", "", 0);
   if (hInternetSession <= 0) { 
      Alert("Unknown error while attempting to acquire internet session");              
      return("");  
   }

   int hURL = InternetOpenUrlW(hInternetSession, url, "", 0, INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD, 0);
   if (hURL <= 0) { 
      Alert("Unable to find requested URL");   
      InternetCloseHandle(hInternetSession);   
      return("");  
   }      

   int cBuffer[256], dwBytesRead[1]; 
   string TXT = "";
   while (!IsStopped())   {
      for (int i = 0; i < 256; i++) {
         cBuffer[i] = 0;
      }
      
      bool bResult = InternetReadFile(hURL, cBuffer, 1024, dwBytesRead);
      if (dwBytesRead[0] == 0) {
         break;
      }
      
      string text = "";   
      for (int i = 0; i < 256; i++) {
         text = text + CharToStr(cBuffer[i] & 0x000000FF);             if (StringLen(text) == dwBytesRead[0])    break;
         text = text + CharToStr(cBuffer[i] >> 8 & 0x000000FF);        if (StringLen(text) == dwBytesRead[0])    break;
         text = text + CharToStr(cBuffer[i] >> 16 & 0x000000FF);       if (StringLen(text) == dwBytesRead[0])    break;
         text = text + CharToStr(cBuffer[i] >> 24 & 0x000000FF);
      }
      TXT = TXT + text;
      Sleep(1);
  }
  
  if (TXT == "")   Alert("No news events meet your selected criteria");
  InternetCloseHandle(hInternetSession);
  return(TXT);
}
 
Emma Schwatson:
The best way is to use your app collecting and parsing data to generate a custom chart event and pass the data through the args (can also serialize all data and pass through sparam) the moment the data is ready so your indicator can process it immediately. 

Thank you for helping out, Emma!

I have never created my own custom chart events before, I will look into how to do that.

So the first indicator  gets the value from the web and would then would pass the new value in said event to the other indicator which would do further analysis or save it in its own array etc.?

I take it both indicators would have to be used on the same chart window?

 
ZetaTrader:

Thank you for helping out, Emma!

I have never created my own custom chart events before, I will look into how to do that.

So the first indicator  gets the value from the web and would then would pass the new value in said event to the other indicator which would do further analysis or save it in its own array etc.?

I take it both indicators would have to be used on the same chart window?

I assume you're using an ea to process webrequests. If so the most efficient method is to run that ea on an offline chart with a timer. No you don't need to run it on the same chart.
 
Emma Schwatson:
I assume you're using an ea to process webrequests. If so the most efficient method is to run that ea on an offline chart with a timer. No you don't need to run it on the same chart.

At the moment I'm using the function I posted above in an indicator in an M1 chart. On each new candle it will read the website once.

In the end I'll probably combine everything into one EA but until no automated trading is live yet using this data, I'd like to keep it separated.


'If so the most efficient method is to run that ea on an offline chart with a timer.'

Would this be processed asynchronously?

The way I'm doing it now, the chart updates are blocked during the web interaction, for approx. 0.5-1 second, which, of course, should be fixed.

Reason: