vdemydiuk / mtapi

MetaTrader API (terminal bridge)
http://mtapi4.net/
MIT License
524 stars 283 forks source link

[MT4] SymbolInfoTick() does not return Last and Volume #231

Open eabase opened 3 years ago

eabase commented 3 years ago

I noticed this before, and thought it was an MT4 issue, but in their docs, it show that this info should be available. I don't see either Volume or Last coming from the SymbolInfoTick() response.

2020.11.14 00:54:38.034 MtApi_debug EURUSD,M15: OnRequest: Response = {"ErrorCode" : 0,"Tick" : {"Ask" : 1.18335,"MtTime" : 1605311819,"Last" : 0,"Volume" : 0,"Bid" : 1.1832}}
eabase commented 3 years ago

@vdemydiuk Can you look into this, please?

TheSnowGuru commented 3 years ago

This works fine for me with this function: Get_instrument_info I used https://github.com/TheSnowGuru/PyTrader-python-mt4-mt5-trading-api-connector-drag-n-drop/blob/master/Pytrader_API_V1_03.py

eabase commented 3 years ago

@TheSnowGuru Hi Shay,

This works fine for me with this ...

Well, are you using this mtapi .NET, or your own TCP/IP connector? (I'm using Python with the .NET DLL and didn't roll my own.)

For quick reference , the lines mentioned above are shown here .

vdemydiuk commented 3 years ago

@eabase This is not might be an issue. You can check MQL function in MtApi.mq4 and find that function void ExecuteRequest_SymbolInfoTick(JSONObject *jo, string &response) fills all the fields of MqlTick (Volume and Last also).

Please check answer #10 to similar question on MQL5 forum: https://www.mql5.com/en/forum/338238

eabase commented 3 years ago

Indeed seem to be a problem with MT4/5 not populating their returned arguments.

void OnTick()
  {
   long        symbol_volume = SymbolInfoInteger(Symbol(),SYMBOL_VOLUME);
   double symbol_volume_real = SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_REAL);
   long tick_volume_array[],real_volume_array[];

   MqlTick m_tick;
   if(!SymbolInfoTick(Symbol(),m_tick) 
      || CopyTickVolume(Symbol(),Period(),0,1,tick_volume_array)!=1 
      || CopyRealVolume(Symbol(),Period(),0,1,real_volume_array)!=1)
      return;

   Print(TimeToString(m_tick.time,TIME_DATE|TIME_MINUTES),",",
         " m_tick.bid ",DoubleToString(m_tick.bid,Digits()),
         " m_tick.ask ",DoubleToString(m_tick.ask,Digits()),
         " m_tick.volume ",IntegerToString(m_tick.volume),
         " m_tick.volume_real ",DoubleToString(m_tick.volume_real,0),
         " SYMBOL_VOLUME ",IntegerToString(symbol_volume),
         " SYMBOL_VOLUME_REAL ",DoubleToString(symbol_volume_real,0),
         " tick_volume_array[0] ",IntegerToString(tick_volume_array[0]),
         " real_volume_array[0] ",IntegerToString(real_volume_array[0]));
  }

For performance consideration, don't really want to triple my API/EA requests just to get that volume for ticks...