Include strike and expiry in option quotes
parent
9f3a316ccf
commit
9c7ca84fef
|
@ -124,6 +124,7 @@ class Client:
|
||||||
self._reload_config(config)
|
self._reload_config(config)
|
||||||
self._symbol_cache: Dict[str, int] = {}
|
self._symbol_cache: Dict[str, int] = {}
|
||||||
self._contracts2expiries = {}
|
self._contracts2expiries = {}
|
||||||
|
self._optids2contractinfo = {}
|
||||||
|
|
||||||
def _reload_config(self, config=None, **kwargs):
|
def _reload_config(self, config=None, **kwargs):
|
||||||
log.warn("Reloading access config data")
|
log.warn("Reloading access config data")
|
||||||
|
@ -323,6 +324,16 @@ class Client:
|
||||||
item['strikePrice']: item for item in
|
item['strikePrice']: item for item in
|
||||||
byroot['chainPerRoot'][0]['chainPerStrikePrice']
|
byroot['chainPerRoot'][0]['chainPerStrikePrice']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# fill out contract id to strike expiry map
|
||||||
|
for key, bystrikes in by_key.items():
|
||||||
|
for strike, ids in bystrikes.items():
|
||||||
|
for elem in ('callSymbolId', 'putSymbolId'):
|
||||||
|
self._optids2contractinfo[
|
||||||
|
ids[elem]] = {
|
||||||
|
'strike': strike,
|
||||||
|
'expiry': key.expiry,
|
||||||
|
}
|
||||||
return by_key
|
return by_key
|
||||||
|
|
||||||
async def option_chains(
|
async def option_chains(
|
||||||
|
@ -339,6 +350,12 @@ class Client:
|
||||||
# index by .symbol, .expiry since that's what
|
# index by .symbol, .expiry since that's what
|
||||||
# a subscriber (currently) sends initially
|
# a subscriber (currently) sends initially
|
||||||
quote['key'] = (key[0], key[2])
|
quote['key'] = (key[0], key[2])
|
||||||
|
# update with expiry and strike (Obviously the
|
||||||
|
# QT api designers are using some kind of severely
|
||||||
|
# stupid disparate table system where they keep
|
||||||
|
# contract info in a separate table from the quote format
|
||||||
|
# keys. I'm really not surprised though - windows shop..)
|
||||||
|
quote.update(self._optids2contractinfo[quote['symbolId']])
|
||||||
batch.extend(quotes)
|
batch.extend(quotes)
|
||||||
|
|
||||||
return batch
|
return batch
|
||||||
|
@ -471,9 +488,7 @@ async def option_quoter(client: Client, tickers: List[str]):
|
||||||
if isinstance(tickers[0], tuple):
|
if isinstance(tickers[0], tuple):
|
||||||
datetime.fromisoformat(tickers[0][1])
|
datetime.fromisoformat(tickers[0][1])
|
||||||
else:
|
else:
|
||||||
log.warn(f"Ignoring option quoter call with {tickers}")
|
raise ValueError(f'Option subscription format is (symbol, expiry)')
|
||||||
# TODO make caller always check that a quoter has been set
|
|
||||||
return
|
|
||||||
|
|
||||||
@async_lifo_cache(maxsize=128)
|
@async_lifo_cache(maxsize=128)
|
||||||
async def get_contract_by_date(sym_date_pairs: Tuple[Tuple[str, str]]):
|
async def get_contract_by_date(sym_date_pairs: Tuple[Tuple[str, str]]):
|
||||||
|
|
|
@ -53,6 +53,7 @@ _ex_quotes = {
|
||||||
'bidSize': 0,
|
'bidSize': 0,
|
||||||
'delay': 0,
|
'delay': 0,
|
||||||
'delta': -0.212857,
|
'delta': -0.212857,
|
||||||
|
"expiry": "2021-01-15T00:00:00.000000-05:00",
|
||||||
'gamma': 0.003524,
|
'gamma': 0.003524,
|
||||||
'highPrice': 0,
|
'highPrice': 0,
|
||||||
'isHalted': False,
|
'isHalted': False,
|
||||||
|
@ -66,6 +67,7 @@ _ex_quotes = {
|
||||||
'openInterest': 1,
|
'openInterest': 1,
|
||||||
'openPrice': 0,
|
'openPrice': 0,
|
||||||
'rho': -0.891868,
|
'rho': -0.891868,
|
||||||
|
"strike": 8,
|
||||||
'symbol': 'WEED15Jan21P54.00.MX',
|
'symbol': 'WEED15Jan21P54.00.MX',
|
||||||
'symbolId': 22739148,
|
'symbolId': 22739148,
|
||||||
'theta': -0.012911,
|
'theta': -0.012911,
|
||||||
|
|
Loading…
Reference in New Issue