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

 
BoredMember:

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


Why not indicator?

//+------------------------------------------------------------------+
//|                                              DownloadHistory.mq4 |
//|                                      Copyright 2017, nicholishen |
//|                         https://www.forexfactory.com/nicholishen |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, nicholishen"
#property link      "https://www.forexfactory.com/nicholishen"
#property version   "1.00"
#property strict
#property indicator_chart_window
#include <stdlib.mqh>
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
  
//---
   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[])
{
//---
   string comm = "Gathering Data\n";
   string comm2;
   for(int s=SymbolsTotal(false);s>=0;s--)
   {
      string symbol = SymbolName(s,false);
      if(symbol==NULL)
         continue;
      comm2 = symbol+" BID= "+(string)SymbolLiveRates(symbol,BID);
      Print(comm+comm2);
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+

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: Why not indicator?

While the indicator is running, nothing else in the terminal can happen.

 
whroeder1:

While the indicator is running, nothing else in the terminal can happen.


This is pretty fail-safe. Tested and working

  1. Initialize with array of symbols to be used (Not necessary, but more efficient)
  2. Susses out inactive symbols and corrects symbol array to use ECN symbols if available.

Demo

//+------------------------------------------------------------------+
//|                                              DownloadHistory.mq4 |
//|                                      Copyright 2017, nicholishen |
//|                         https://www.forexfactory.com/nicholishen |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, nicholishen"
#property link      "https://www.forexfactory.com/nicholishen"
#property version   "1.00"
#property strict
#property indicator_chart_window
#include <SymbolInfoFailSafe.mqh>

CSymbolLiveRates live_rates;
string symbols[]={ "EURUSD","GBPUSD","EURJPY","USDCAD","AUDCHF","AUDCAD","AUDNZD","USDILS"};
int OnInit()
{
   live_rates.InitSymbols(symbols);
   EventSetMillisecondTimer(50);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
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 rates_total;
}
//+------------------------------------------------------------------+
void OnTimer()
{
   string comm="";
   for(int i=0;i<ArraySize(symbols);i++)
      comm+="\n"+symbols[i]+" Bid = "+(string)live_rates.Bid(symbols[i])+"\n";
   //uninitialized symbol
   double wild_card = live_rates.Ask("USDJPY");
   comm+="\n"+"USDJPY Ask = "+(string)wild_card;
   Comment(comm);
}

void OnDeinit(const int reason)
{
   EventKillTimer();
}


Files:
 
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.

This is incorrect information. In order to access SymbolInfoDouble...bid/ask you need to have the Symbol selected in the MarketWatch. It won't matter if you have history downloaded because if it's not selected then it won't return any value.

 
  1. nicholishen: In order to access SymbolInfoDouble...bid/ask you need to have the Symbol selected in the MarketWatch.
    OPs first post said:

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

  2. #include <SymbolInfoFailSafe.mqh>
    
    Where do you find that in MT4?

 
whroeder1:
  1. OPs first post said:

  2. Where do you find that in MT4?


here
 

Here is a more simplified (non-OOP) lib that will also work. 

 
nicholishen:

Here is a more simplified (non-OOP) lib that will also work. 


I'll take a look, I see the idea.

TBH I'm simply working with "Show All" in MarketWatch which guarantees access to a complete list of priced symbols.

Just a shame there's not a simple, intuitive programmatic way to do this.

E.g. GetTotalNumberOfSymbols() (regardless of what's displayed in MarketWatch or the GUI)

GetListOfAllSymbols() (Regardless of what's displayed in MarketWatch or the GUI)

GetPriceOfSymbol() (Regardless of what's displayed in MarketWatch or the GUI)

etc.

Seems like the functions are too tied in with what's going on on the screen, rather than directly linking to the underlying market data...

 
BoredMember:

Just a shame there's not a simple, intuitive programmatic way to do this.


There is, now... no need to worry about history or whether the symbol is in the market watch - this handles all that automatically. Save the mqh file I posted into your include folder and call it like this. It really doesn't get any easier. 

#include <multi_symbol_timeframe.mqh>
void OnStart()
{
//---
   // easy call 
   double bid = iBid(_Symbol);   
   // fail-safe call
   if(!iBid(bid,_Symbol))
      Print("FAILED TO GET BID");
}

...and for future reference...

https://docs.mql4.com/marketinformation/symbolselect

SymbolSelect - Market Info - MQL4 Reference
SymbolSelect - Market Info - MQL4 Reference
  • docs.mql4.com
[in] Switch. If the value is false, a symbol should be removed from MarketWatch, otherwise a symbol should be selected in this window. A symbol can't be removed if the symbol chart is open, or there are open orders for this symbol. To get symbol data using functions for accessing timeseries and indicators, make sure that the symbol exists in...
Reason: