开云体育

ctrl + shift + ? for shortcuts
© 2025 开云体育

How do you combine multiple responses from reqMktData into a single quote with Bid / Ask / Size


 

When subscribing to live data for specific assets, e.g. MSFT and AAPL, it comes in multiple pieces into different callbacks, specifically, tickPrice and tickSize.?
How do I combine all responses into a single quote for each asset
?

struct Quote?
{
? double AskPrice;
? double BidPrice;
? double AskSize;
? double BidSize;
}
var msftQuotes = new List<Quote>();
var applQuotes = new List<Quote>();
var msft = new Contract
{
? Symbol = "MSFT",
? Exchange = "NYSE",
? SecType = "STK",
? Currency = "USD"
};
var aapl = new Contract
{
? Symbol = "AAPL",
? Exchange = "NYSE",
? SecType = "STK",
? Currency = "USD"
};
_client.TickSize += message => { if (message.RequestId == 1) msftQuotes.Add( ??? ); };
_client.TickPrice += message => { if (message.RequestId == 1) msftQuotes.Add( ??? ); };
_client.ClientSocket.reqMktData(1, contract, string.Empty, false, false, null);
_client.ClientSocket.reqMktData(2, contract, string.Empty, false, false, null);


bdcoder
 

It looks like you are using C#, but regardless, you could do the following (there are many ways) ...
?
Create two dictionaries, one to store request IDs associated with a stock symbol (Key = request ID, Value = Stock Symbol ), i.e.:
?
System.Collections.Generic.Dictionary<Int32, String> requests_dict;
?
... and another to store your market data (Key = Stock Symbol, Value = market data), i.e.:
?
System.Collections.Generic.Dictionary<String, Quote> market_data_dict;
?
?
... Populate the requests dictionary?
?
requests_dict = new();
?
requests_dict.Add( 1, "AAPL" );
requests_dict.Add( 2, "MSFT" );
?
... Iterate through the dictionary to create the contracts and issue your market data requests
?
var contract = new Contract
{
? ?Exchange = "NYSE";
? ?SecType = "STK";
? ?Currency = "USD";
}
?
foreach ( KeyValuePair<Int32, String> kvp in requests_dict )
{
?
? ?contract.Symbol = kvp.Value;
?
? ?_client.ClientSocket.reqMktData( kvp.Key, contract, String.Empty, false, false, null );
?
}
?
... In your event handlers, do the following:
?
// Check if the request ID is one of ours ...
?
if ( requests_dict.ContainsKey( message.RequestId )
{
?
? ?String stock_symbol = requests_dict[ message.RequestId ];
?
? ?Quote quote = market_data_dict[ stock_symbol ]
?
? ?// Check tick type and update quote fields accordingly ...
?
}
?
?
Hope that provides a starting point.
?
B


 

In python, I have found storing these to dictionaries is slower and prone to race. It seems the fastest way in python is to just throw the data into a double-ended queue, and do nothing else in the api thread. Then in a separate thread, I get the data from the deque for further manipulation.
I wonder if there's a more efficient way to do this, and not slow down the api thread.


 

Thanks, I was thinking about grouping into dictionary but I was planning to use reqMktData request for live updates, not a one-time call. In this case, RequestId is always the same because request is sent only once and I just keep listening to responses. In other words, dictionary where RequestId is used as a key will keep accepting those ticks that are coming now and those that will come in a couple of minutes, there is no time stamp or any flag that would allow to group responses into quotes or bars, e.g. this tick price and size belong to the trade that happened on the exchange at 11:45, this price and size belong to the trade happened at 11:46, etc.?
?
What I would really like to have is something like an "End" event available in some other endpoints, so I receive 2 responses in "tickPrice" even, Bid and Ask, then 2 responses in "tickSize" event, BidSize and AskSize, and then something should tell me that the "quote" or "bar" received all fields, all responses after this will be related to the next "quote".?
?
I would assume that the next suggestion will be to manually track time when I receive price and size, so if I want to group bars by 1 second interval, I need to form a struct or dictionary with all responses and once time changes I send current dictionary to the queue as a "1 second bar" and start filling new dictionary. This begs another question: is it guaranteed that I will receive all 4 responses and will be able to fill the whole dictionary within 1 second OR there is a chance that "1 second bar" will miss some fields, e.g.
?
Dictionary1 / Quote1 { Bid = 5, Ask = 10, BidSize = 100, AskSize = NULL }
Dictionary1 / Quote2 { Bid = 6, Ask = NULL, BidSize = 100, AskSize = 25 }
?
?


 

Actually, after thinking about it a bit more I realized that missing fields in the next quote would mean that this field hasn't changed, so I can take the previous value or the last value that was saved for this field in the dictionary.?