SYMBOL_BID and SYMBOL_ASK always returning zero

The SYMBOL_BID and SYMBOL_ASK are always returning zero. Did I something wrong?

#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>

CTrade trade;
CSymbolInfo symbolInfo;
CAccountInfo accInfo;

int OnInit(){
   if(!symbolInfo.IsSynchronized()){
      printf(__FUNCTION__+": Symbol is not syncronized!");
      return INIT_FAILED;
   }
   if(!accInfo.TradeAllowed()){
      printf(__FUNCTION__+": Trade is not allowed!");
      return INIT_FAILED;
   }

   if(!accInfo.TradeExpert()){
      printf(__FUNCTION__+": ExpertAdvisor is not allowed!");
      return INIT_FAILED;
   }
   return INIT_SUCCEEDED;
}

void OnTick(){
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   PrintFormat("Symbol %s; Bid %f; Ask %f", _Symbol, bid, ask);
}
2017.08.23 21:12:33.978 login (build 1643)
2017.08.23 21:12:34.023 account info found
2017.08.23 21:12:34.040 1482 bytes of tester parameters loaded
2017.08.23 21:12:34.047 expert file added: Experts\myBot.ex5. 19591 bytes loaded
2017.08.23 21:12:34.066 initial deposit 10000.00 BRL, leverage 1:100
2017.08.23 21:12:34.069 successfully initialized
2017.08.23 21:12:34.069 18 Kb of total initialization data received
2017.08.23 21:12:34.069 Intel Core i5-7200U  @ 2.50GHz, 8061 MB
2017.08.23 21:12:34.187 WDO$D: history synchronization started
2017.08.23 21:12:34.192 WDO$D: load 25 bytes of history data to synchronize in 0:00:00.000
2017.08.23 21:12:34.192 WDO$D: history synchronized from 2013.01.02 to 2017.08.18
2017.08.23 21:12:34.193 WDO$D: ticks synchronization started
2017.08.23 21:12:34.228 WDO$D: load 32 bytes of tick data to synchronize in 0:00:00.000
2017.08.23 21:12:34.228 WDO$D: history ticks synchronized from 2017.05.02 to 2017.08.18
2017.08.23 21:12:34.379 WDO$D,M5: history cache allocated for 122605 bars and contains 44010 bars from 2016.01.04 09:00 to 2017.08.17 17:55
2017.08.23 21:12:34.384 WDO$D,M5: history begins from 2016.01.04 09:00
2017.08.23 21:12:34.418 WDO$D,M5 (XPMT5-Demo): generating based on real ticks
2017.08.23 21:12:34.418 testing with execution delay 14 milliseconds
2017.08.23 21:12:34.418 WDO$D,M5: testing of Experts\myBot.ex5 from 2017.08.18 00:00 to 2017.08.19 00:00 started
2017.08.23 21:12:34.469 WDO$D : real ticks begin from 2017.05.02 00:00:00
2017.08.23 21:12:35.643 2017.08.18 09:00:35   Symbol WDO$D; Bid 0.000000; Ask 0.000000
2017.08.23 21:12:35.843 2017.08.18 09:00:35   Symbol WDO$D; Bid 0.000000; Ask 0.000000
2017.08.23 21:12:36.040 2017.08.18 09:00:35   Symbol WDO$D; Bid 0.000000; Ask 0.000000
2017.08.23 21:12:36.231 2017.08.18 09:00:35   Symbol WDO$D; Bid 0.000000; Ask 0.000000
2017.08.23 21:12:36.422 2017.08.18 09:00:35   Symbol WDO$D; Bid 0.000000; Ask 0.000000

You should use SymbolInfoTick() to get last quote.

I made the following code to get the right prices. Is this code correct?

Do you know why sometimes the ask and bid prices are filled and other times they are empty? I don’t understand how EA handle the price refresh yet.

 /*
    Gets the current price to sell
    */
    double SellPrice(){
        symbolInfo.RefreshRates();
        double value = symbolInfo.Ask();
        if(value == 0) value = SymbolInfoDouble(symbol,SYMBOL_ASK);
        if(value == 0){
            MqlTick tick;
            ResetLastError();
            if(SymbolInfoTick(symbol,tick)){
                value = tick.ask;
            } else {
                PrintFormat("%s: Error: %d",__FUNCTION__, GetLastError());
            }
            if(value == 0) value = tick.last - SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);      
        }
        return value;
    }

    /*
    Gets the current price to buy
    */
    double BuyPrice(){
        symbolInfo.RefreshRates();
        double value = symbolInfo.Bid();
        if(value == 0) value = SymbolInfoDouble(symbol,SYMBOL_BID);
        if(value == 0){
            MqlTick tick;
            ResetLastError();
            if(SymbolInfoTick(symbol,tick)){
                value = tick.bid;
            } else {
                PrintFormat("%s: Error: %d",__FUNCTION__, GetLastError());
            }
            if(value == 0) value = tick.last + SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
        }
        return value;
    }

Hi @htwyford1p

By this way, I always get the price (^̮^)

Hope it helps.

bool NewPositionBuy(......)
{
      ResetLastError();
      ZeroMemory(request);
      ZeroMemory(result);
      int ke=1;
      bool exit=false;
      
      //-- your request entry here --//
      request.action   =TRADE_ACTION_DEAL;                     // trade operation
      request.type     =ORDER_TYPE_BUY;                        // order type
      ...........
      ...........

      //--loop to get better price for current position
      while (!OrderSend(request,result)) //--this loop will ended after request is done
      {
        if(result.retcode==TRADE_RETCODE_REQUOTE)
        {
          if(ke<=1) Print("* Requotes. Wait for better price ...");
        }
        else
        { 
          Print("*! ",getErrorTradeDesc(result.retcode));
          exit=true;
          break; //--exit from current loop
        }

        ke++; //-- read how many times EA read the price

        MqlTick ticknow;
        SymbolInfoTick(symbol,ticknow);
        request.price=SymbolInfoDouble(symbol,SYMBOL_ASK);   // price 
        Sleep(1000); //---- 1 second wait
      }
      
      if(exit)
      {
         Print("*! Can't open new position Buy. >>> (error: ",result.retcode,". Desc : ",getErrorTradeDesc(result.retcode),") ");
         //--do something, entry failed
         return(false);
      }

      //--do something after new position was opened

      return(true);

}//-- eof NewPositionBuy

Btw, many coders have different logic, and code above is my simply logic.

You can try it if you wish ʘ‿ʘ

Yo.