Keyboard Shortcuts
ctrl + shift + ? :
Show all keyboard shortcuts
ctrl + g :
Navigate to a group
ctrl + shift + f :
Find
ctrl + / :
Quick actions
esc to dismiss
Likes
Search
How to retrieve current bid/ask for a combo order?
¿ªÔÆÌåÓý
Assuming that I have a ComboContract consisting of 2 or more option legs, how would I receive the current bid/ask for that combo?
|
¿ªÔÆÌåÓý
Thanks, how do I retrieve the bid/ask for an option leg?
From: [email protected] <[email protected]> on behalf of Despair <boris@...>
Sent: Saturday, March 6, 2021 1:46 AM To: [email protected] <[email protected]> Subject: Re: [TWS API] How to retrieve current bid/ask for a combo order? ?
I think you have to retrieve bid/ask for both legs separately and then calculate the combos bid/ask yourself. This is at least what I do.
|
I was working on it recently, so let me try to put a 1st draft of the answer: [Q] How do I retrieve the bid/ask for an option leg? [A] I found 3 ways so?far. Only one works for me, but I'll mention all 3 here. 1-of-3: Using client.reqTickByTickData(19003, ContractSamples.USStockAtSmart(), "BidAsk", 0, true); Read this article:? The problem here is that you only allowed 3 simultaneous subscriptions, which might work for someone who's training?1-2 instruments, but I wanted to find?more generic way to get bid/ask for more contracts at the same time. 2-of-3: Using EClient.reqMarketDepth (reqMktDepth in Java, C++, and Python). See these 2 docs: In their docs IB says: Beginning in?API v974?and?TWS v974?it is possible to Smart-route a??request to receive aggregated data from all available exchanges, similar to the TWS BookTrader display. (end of quote) And I come to the conclusion that this "aggregated data" is the only right way to get proper bid/ask unless you're always trading some contract that is only traded on 1 particular exchange?and thus you don't need to aggregate?data from many exchanges. If you use "reqMarketDepth" with contract.Exchange set to SMART and set "isSmartDepth" argument to true, then you'll get an error, that you require more subscriptions. In my data subscriptions I didn't have any Level-II except a free one for "IEX exchange". If I try to set contract.Exchange = "IEX" and?set "isSmartDepth" argument to false, then I start getting data, but noticed, for example for "IBM" contract, that the bid/ask during any quiet low volatility day (shown in TWS around $0.02), is reported by IB API often times as a much bigger number (for example $2.45 vs $0.02 expected - see screenshot below). IB support confirmed that what you see in TWS bid/ask (with list of different exchanges) is NOT accessible via API without subscription, but is accessible for your "human naked eye" for free in TWS window (it's time to engage OCR!-)). Here's an example when IB API returned $2.45, while TWS shows aggregated data with bid/ask = $0.02 around?Feb 8, 2021, 2:47 PM You can see IEX Bid is 121.0 and IEX Ask is 123.45, so the spread by "IEX only" version is 2.45! Nasty and useless! If you want to use SMART for the "reqTickByTickData" you'll have to have Level-II subscriptions for ALL exchanges this contract is traded on. To check how much all of them will be login to? -> AccountManagement -> Settings -> User Settings ->?Market Data Subscriptions ->? You'll see "North America: IEX Depth of Book - Trader Workstation? ? - Fee Waived" Along with notes: IEX exchange depth of book service. Requires prior subscriptions to NYSE (Network A/CTA), AMEX (Network B/CTA), and NASDAQ (Network C/UTP) or US Equity and Options Add-On Streaming Bundle. (end of quote) Then click: Current GFIS Subscriptions -> configure gear icon -> North America (as example) ->?Level II (Deep Book) And you'll see the list with prices. 3-of-3: poor-man bid-ask using real-time bars and "ticks" If you subscribe to two real-time 5 seconds bars streams by either: ? a)??request with "keepUpToDate" set to true (see also? )? ? or ? b)??request (see also?a) And specify "what to show" to "BID" for one request and "ASK" for another request, then IB API will call back with 5-second bar updates every few seconds (on average every 3.5 seconds) and each stream "bar.close" price will represent most recent bid and ask. The only problem is that those 2 streams represent 2 events streams (separated in time). I filter out negative calculated bid_ask spreads as well as calculate bid_ask spread only if bid update and ask update are within 500ms distance. As a result on the same "IBM" ticker I got on average (during the whole trading day) calculated bid_ask values coming on average every 3.5 seconds, which is good enough for me :) Note #1: this method is only counted as "one line" out of your 100 available lines, so theoretically you can get 100 bid_ask spreads (along with sampled "real time tick" for price updates) without buying any data-boosters or Level-II subscriptions. Note #2: yes, there is "what to show" type "BID_ASK" (see ), but it will not give you an instant snapshot of the current most latest bid and ask values. Instead you'll get: bar.open = "Time average bid", bar.high = "Max Ask" (useless), bar.low = "Min Bid" (useless) and bar.close = "Time average ask". I'm not sure if the "time average" values for 5-sec bars will be better than the above method, I'll try to check them side-by-side, but my guess is - both approaches will yield similar quality output. I'm not sure how well this method would cope with fast moving markets. I guess it will give quite a random estimate for what really is. But one can always use some safety factor (for example use calculated bid_ask spread value and multiply it by 2.0 just to be sure). Also it would be interesting to see how the spread value correlates with the current volatility. During volatile times the price might jump, the bid/ask might jump, but the high volatility reading will be showing pretty much flat high value, which you can use to estimate the bid/ask max value (and/or to adjust the "safety factor" and make it a bit higher when market goes crazy:). There's some free 15-minutes delayed bid_ask stream if I recall correctly (as 4th option), but I haven't looked into that option since the 15 minutes delay is a bit too far. Cheers, Dmitry Shevkoplyas ps: I'll show here the function I used on every incoming bar to prototype the bid_ask calculations, think of this piece as "meta language": public void on_historical_bar_try_to_calculate_bid_ask_spread( Bar bar, RequestHistoricalData request) { // Check we have both requests in place (not nulls) if (request_historical_data_bid == null) { logger.debug("request_historical_data_bid == null, nothing to do yet..."); return; } if (request_historical_data_ask == null) { logger.debug("request_historical_data_ask == null, nothing to do yet..."); return; } // Both bid / ask "real time" bars requests are present! We can calculate bid/ask spread estimate. // Let's extract most recent bars from 2 streams: Bar bid_bar = request_historical_data_bid.most_recent_bar_received; Bar ask_bar = request_historical_data_ask.most_recent_bar_received; if (bid_bar == null) { logger.debug("bid_bar == null, nothing to do yet..."); return; } if (ask_bar == null) { logger.debug("ask_bar == null, nothing to do yet..."); return; } // Check how far in time they are from each other long bars_received_time_delta_ms = request_historical_data_bid.most_recent_bar_received_time.get_delta_ms(request_historical_data_ask.most_recent_bar_received_time); // Filter out updates with more than 500ms distance if (Math.abs(bars_received_time_delta_ms) > 500) { return; } // Both bid/ask bars are present and close enough, let's calculate the bid/ask spread double bid_ask_spread = ask_bar.close() - bid_bar.close(); // Filter out some obvious BS if (bid_ask_spread <= 0) { return; } logger.info("Calculated synthetic poor man's bid_ask_spread: " + Aid.math_round(bid_ask_spread, 2) + " bars_received_time_delta_ms: " + bars_received_time_delta_ms); } On Sat, Mar 6, 2021 at 1:58 PM Crow <aaroncook394@...> wrote:
|
Boris, does the reqMarketData yield a bid/ask spread for you, which OP is looking for? On Sun, Mar 7, 2021 at 4:28 AM Despair <boris@...> wrote: Why all this effort? I just use reqMarketData to stream the quotes of all legs with exchange = SMART. Am I missing here something? |
to navigate to use esc to dismiss