def ws_cal_option(self, s, x, cp, ed, xd, r, d, v, out='npv'): #spot, strike, callput, evaldate, exdate, rate, div, vol keys = ['npv', 'delta', 'gamma', 'theta', 'vega'] try: rs = optcal.cal_option(float(s), float(x), cp, ed, xd, float(r), float(d), float(v)) if out == 'csv': logging.debug('ws_cal_option: ' + ','.join(str(rs[s]) for s in keys)) return ','.join(str(rs[s]) for s in keys) elif out == 'json': return json.dumps(rs) else: return str(rs[out]) except: #exc_type, exc_value, exc_traceback = sys.exc_info() return traceback.format_exc()
def compute(ts): terms = ts[1] # map(calc, ) results = cal_option(terms['spot'], terms['strike'], terms['callput'], terms['evaldate'], terms['exdate'], terms['rate'], terms['div'], terms['vol']) return results
def tickPrice(self, items): try: contract = self.tickerMap[items.__dict__['tickerId']]['contract'] field = items.__dict__['field'] tick2oc_slot = self.tickerMap[ items.__dict__['tickerId']]['tick2oc_slot'] today = time.strftime('%Y%m%d') price = items.__dict__['price'] # # perform some sanity check # # if field is not bid, ask, last, or close, pass if field not in [1, 2, 4, 9]: logging.debug('tickPrice: discard unwanted msg field:%d' % field) return # if we received a negative price, pass if price == -1: logging.debug('tickPrice: discard unwanted msg price==-1') return logging.debug( 'tickPrice>> %s' % ('[%d:%s:%s:%d] %s=%0.4f [%s]' % \ (items.__dict__['tickerId'], ContractHelper.makeRedisKeyEx(contract),\ tick2oc_slot[0], tick2oc_slot[1],\ 'bid' if field == 1 else ('ask' if field == 2 else ('last' if field == 4 else field)), \ items.__dict__['price'], datetime.datetime.fromtimestamp(items.__dict__['ts']).strftime('%Y-%m-%d %H:%M:%S.%f'))) ) # is an option if tick2oc_slot[1] <> -999: o = self.get_option_in_chain(tick2oc_slot[0], tick2oc_slot[1]) o.set_tick_value(field, items.__dict__['price']) try: spot = self.get_underlying_in_chain( tick2oc_slot[0]).get_tick_value(4) # the underlying price may not be available when we receive tick price for options if spot <> None: rate = self.option_chains[tick2oc_slot[0]].rate div = self.option_chains[tick2oc_slot[0]].div tvol = self.option_chains[tick2oc_slot[0]].trade_vol logging.debug('sp=%0.4f, x=%0.4f, %s, evald=%s, expiryd=%s, r=%0.4f, d=%0.4f, v=%0.4f, px[%d]=%0.4f' % (\ spot, contract.m_strike, contract.m_right, today, contract.m_expiry, rate,\ div, tvol, field, items.__dict__['price'])) results = None iv = optcal.cal_implvol(spot, contract.m_strike, contract.m_right, today, contract.m_expiry, rate,\ div, tvol, items.__dict__['price']) results = optcal.cal_option(spot, contract.m_strike, contract.m_right, today, contract.m_expiry, rate, div, iv['imvol']) results[Option.IMPL_VOL] = iv['imvol'] #print results o.set_analytics(**results) logging.debug(o.get_analytics()) o.set_extra_attributes('spot', spot) o.set_extra_attributes('rate', rate) o.set_extra_attributes('div', div) o.set_extra_attributes('chain_id', tick2oc_slot[0]) except Exception, err: logging.error(traceback.format_exc()) o.set_extra_attributes( 'last_updated', datetime.datetime.now().strftime('%Y%m%d%H%M%S')) self.broadcast_analytics(tick2oc_slot[0], o) logging.debug(o.object2kvstring()) # is an underylying else:
def on_tick_data_changed(self, msg): #print 'omdm %s' % msg if msg.typeName in ['tickPrice', 'tickSize']: if msg.typeName == 'tickPrice': # if self.isTickIdAnOption(msg.tickerId): # # contract = DataMap().get(msg.tickerId)['contract'] # # # # logging.info("OptionsMarketDataManager: on_tick_data_changed: received msg field %s for ticker id %s" % (msg.field, msg.tickerId)) # # last price%Y%m%d # premium = None # if msg.price < 0: # logging.debug("OptionsMarketDataManager: received bogus price from IB feed. %0.4f" % msg.price) # return # # if msg.field == 4: # premium = msg.price # elif msg.field == 1: #bid # if 2 in DataMap().get(msg.tickerId): # if DataMap().get(msg.tickerId)[2] > 0.0: # premium = (DataMap().get(msg.tickerId)[2] + msg.price) / 2 # else: # premium = msg.price # # logging.debug("OptionsMarketDataManager: msgfiled ==1 %0.4f msgfiled ==2 %0.4f" % (msg.price, DataMap().get(msg.tickerId)[2])) # elif msg.field == 2: #ask # if 1 in DataMap().get(msg.tickerId): # if DataMap().get(msg.tickerId)[1] > 0.0: # premium = (DataMap().get(msg.tickerId)[1] + msg.price) / 2 # else: # premium = msg.price # logging.debug("OptionsMarketDataManager: msgfiled ==2 %0.4f msgfiled ==1 %0.4f" % (msg.price, DataMap().get(msg.tickerId)[1])) # if premium is None: # # skip calculation because we don't have a valid value for premium # logging.debug("OptionsMarketDataManager: on_tick_data_changed: unable to derive a usable premium for ticker id %s, skipping computation" % (msg.tickerId)) # return if self.isTickIdAnOption(msg.tickerId): contract = DataMap().get(msg.tickerId)['contract'] logging.info( "OptionsMarketDataManager: on_tick_data_changed: received msg field %s for ticker id %s" % (msg.field, msg.tickerId)) premium = self.determine_premium(msg) if premium == None: return undly = DataMap().get(self.getUndlyId(contract.m_expiry)) if 4 in undly: # the last price spot = undly[4] logging.info( 'OptionsMarketDataManager:on_tick_data_changed: undelying spot %0.4f of month %s' % (spot, contract.m_expiry)) today = time.strftime('%Y%m%d') logging.info( 'OptionsMarketDataManager:on_tick_data_changed: today %s ' % time.strftime('%Y%m%d')) div = self.cal_greeks_config['div'] rate = self.cal_greeks_config['rate'] # vol is not used in the calculation of implv but quantlib requires the parameter to be passed vol = self.cal_greeks_config['vol'] logging.info( 'OptionsMarketDataManager:on_tick_data_changed: symbol %s, spot %s, X %s, right: %s, evaldate: %s, expiry: %s, rate: %0.4f, div: %0.4f, vol: %0.4f, premium: %0.4f' % (contract.m_symbol, spot, contract.m_strike, contract.m_right, today, contract.m_expiry, rate, div, vol, premium)) try: iv = optcal.cal_implvol(spot, contract.m_strike, contract.m_right, today, contract.m_expiry, rate, div, vol, premium) except Exception, err: logging.error(traceback.format_exc()) logging.error( "OptionsMarketDataManager: *******************recovering from a implvol error ******" ) intrinsic = abs(contract.m_strike - spot) iv = optcal.cal_implvol(spot, contract.m_strike, contract.m_right, today, contract.m_expiry, rate, div, vol, premium) logging.error("OptionsMarketDataManager: ******** Using intrinsic value to calculate premium %0.4f instead of the spot premium %0.4f"\ % (intrinsic, premium )) logging.info( 'OptionsMarketDataManager:on_tick_data_changed: implied vol: %0.4f' % iv['imvol']) results = optcal.cal_option(spot, contract.m_strike, contract.m_right, today, contract.m_expiry, rate, div, iv['imvol']) DataMap().get(msg.tickerId)[ OptionsMarketDataManager.IMPL_VOL] = iv['imvol'] DataMap().get(msg.tickerId)[ OptionsMarketDataManager.DELTA] = results['delta'] DataMap().get(msg.tickerId)[ OptionsMarketDataManager.GAMMA] = results['gamma'] DataMap().get(msg.tickerId)[ OptionsMarketDataManager.THETA] = results['theta'] DataMap().get(msg.tickerId)[ OptionsMarketDataManager.VEGA] = results['vega'] DataMap().get(msg.tickerId)[ OptionsMarketDataManager.PREMIUM] = results['npv'] # update Redis store # DataMap().update_rd(msg.tickerId) else: # underlying price changed # check whether new option chains need to be added # # check logic to be implemented # save undly tick to REDIS contract = DataMap().get(msg.tickerId)['contract'] logging.debug( 'OptionsMarketDataManager:on_tick_data_changed: ------- Underlying Price updated: tick id %d datamap contract %s' % (msg.tickerId, ContractHelper.printContract(contract))) DataMap().update_rd(msg.tickerId)