Missing price when retrieve all symbols using SymbolsTotal() and SymbolName()

 

Hi,

I'm trying to cycle through all the symbols that are available in MT4. Not just the symbols that are currently displayed in MarketWatch.

I use the following (abridged) code:

int numSymbols=SymbolsTotal(false); 
string symbol=SymbolName(PositionIndex,false); 
double price=MarketInfo(symbol,MODE_BID);

I find that this always returns the same number of symbols, regardless of what is displayed in MarketWatch, and I can loop through them all (PositionIndex in the code). So that works fine.

The problem is that the price (and presumably other info) is not returned when the symbol is not displayed in MarketWatch, even though the symbol is available and returned by SymbolName.

This seems very odd? Is it really the case that you cannot look up the price for a symbol in MQL unless the symbol is displayed in MarketWatch? Surely not, that would be bizarre.

Am I missing something?

Thanks..

 
On MT4: Unless the current chart is the specific pair/TF referenced, you must handle 4066/4073 errors.
          Download history in MQL4 EA - MQL4 and MetaTrader 4 - MQL4 programming forum
 
whroeder1:
On MT4: Unless the current chart is the specific pair/TF referenced, you must handle 4066/4073 errors.
          Download history in MQL4 EA - MQL4 and MetaTrader 4 - MQL4 programming forum

I'm confused, I'm not requesting history data, I am requesting the current price of a symbol.

I'm finding the symbol DOES return price data if the symbol is included in the MarketWatch window, regardless of whether it is in the current chart or not.

 
BoredMember: I'm confused, I'm not requesting history data, I am requesting the current price of a symbol.
  1. You are confused. current price is history data.
  2. The first time you access a symbol, the terminal has to get the data. Then it will be continuously updated for 10 minutes after the last request before being unloaded.
  3. You are seeing price data because you are continuously requesting it. Stop for 15 minutes and try then.
 
whroeder1:
  1. You are confused. current price is history data.
  2. The first time you access a symbol, the terminal has to get the data. Then it will be continuously updated for 10 minutes after the last request before being unloaded.
  3. You are seeing price data because you are continuously requesting it. Stop for 15 minutes and try then.

Terrible way of doing things (compare Bloomberg formula in excel - always returns a price for any symbol no matter what).

So are you saying if I have two lines of code that request the price twice, the first line will force the terminal to get the data but return a price of zero, then the second line doing exactly the same thing will actually return the price? Surely not?

It seems the most basic thing to have a symbol and ask for the price yet this has turned into a hugely complicated issue.Not impressed.

 
BoredMember:

Terrible way of doing things (compare Bloomberg formula in excel - always returns a price for any symbol no matter what).

So are you saying if I have two lines of code that request the price twice, the first line will force the terminal to get the data but return a price of zero, then the second line doing exactly the same thing will actually return the price? Surely not?

It seems the most basic thing to have a symbol and ask for the price yet this has turned into a hugely complicated issue.Not impressed.


Would it be possible for someone to show some code that is 100% guaranteed to return a price for a symbol that exists in MT4?

 
BoredMember:

So are you saying if I have two lines of code that request the price twice, the first line will force the terminal to get the data but return a price of zero, then the second line doing exactly the same thing will actually return the price? Surely not?

Would it be possible for someone to show some code that is 100% guaranteed to return a price for a symbol that exists in MT4?

  1. Surely not! It takes time to fetch the data from the broker. Not the nanoseconds between two lines of code.
  2. I already did.
 
whroeder1:
  1. Surely not! It takes time to fetch the data from the broker. Not the nanoseconds between two lines of code.
  2. I already did.

I'm playing around with that code now.

I believe it doesn't do anything except check whether the price is "up to date" alternatively stated as "download complete".

However, each symbol will need to be "seeded", as it were, beforehand by requesting at least one price (?)

 
BoredMember:

I'm playing around with that code now.

I believe it doesn't do anything except check whether the price is "up to date" alternatively stated as "download complete".

However, each symbol will need to be "seeded", as it were, beforehand by requesting at least one price (?)


Here's the code:


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[])
{


   int numSymbols=SymbolsTotal(false); // find number of symbols in MT4
   // loop through all symbols one by one using history function test
   for(int i = 0; i < numSymbols; i++)  
   {
      string symbolTest=SymbolName(i,false);
      if(!download_history(symbolTest,PERIOD_M15) )
      {
         bool testAvailable=IsPriceAvailable(symbolTest);	// if no history then "seed" by requesting a single bid price, then return and wait for next tick
         return prev_calculated;
      }
   }
   

// carry on to main part of function that wishes to use the prices for each symbol

So this code never carries on to main part of the function, in fact the download+history function never returns true at all...!

 
BoredMember:

Would it be possible for someone to show some code that is 100% guaranteed to return a price for a symbol that exists in MT4?

enum ENUM_LIVE_RATES{BID,ASK};
double SymbolLiveRates(const string symbol,ENUM_LIVE_RATES info_param)
{
   static string last_symbol = "";
   if(last_symbol != symbol)
   {
      bool found=false;
      for(int i=SymbolsTotal(false);i>=0;i--)
      {
         if(symbol==SymbolName(i,false))
         {
            found=true;
            break;
         }
      }
      if(!found)
      {
         Print("Symbol Input Error - MySymbolInfoDouble: Symbol does not exist");
         return 0.0;
      }
      last_symbol=symbol;
      SymbolSelect(symbol,true);
   } 
   ENUM_SYMBOL_INFO_DOUBLE param = info_param==BID?SYMBOL_BID:SYMBOL_ASK;
   const static uint time_out    = 10000; //10 second time-out
   uint              ms          = GetTickCount();
   uint              milliseconds= 0;
   double            res         = 0.0;
   int               error;
   do
   {
      ResetLastError();
      res         = SymbolInfoDouble(symbol,param);
      error       = GetLastError();
      milliseconds= GetTickCount()-ms;
   }
   while((error != ERR_NO_ERROR || res <=0.0) && !IsStopped() && milliseconds < time_out);   
   return res;     
}
 
nicholishen:


Nice, but surely only going to work for an EA not an Indicator

Reason: