Beispiel #1
0
    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()
Beispiel #2
0
    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
Beispiel #3
0
    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:
Beispiel #4
0
    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)