Ejemplo n.º 1
0
 def _start_oc_bridge(self, oc_ip, oc_port, user, password, version):
     self._oc_bridge = OCBridge(self, oc_ip, oc_port, user, password, version)
     self._greenlets.append(gevent.spawn(self._oc_bridge.start))
     log.info("OCBridge initialized")
Ejemplo n.º 2
0
class OCGateway(object):
    def __init__(self, oc_ip='10.10.1.53', oc_port='9031', user='******',
                 password='******', version='v3.2', api_port='6001', publish_port='6002'):
        self._oc_ip = oc_ip
        self._oc_port = oc_port
        self._user = user
        self._password = password
        self._version = version
        self._api_port = api_port
        self._publish_port = publish_port
        self._supported_instruments_list = []
        self._expiry_set = set()
        self._parent_symbol_set = set()
        self._month_id_to_parent_symbol_dict = {}
        self._oc_inst_id_to_internal_asset_id_dict = {}
        self._oc_month_id_to_oc_class_id_dict = {}
        self._internal_asset_id_to_oc_inst_id_dict = {}
        self._internal_asset_id_to_oc_class_id_dict = {}
        self._oc_inst_id_to_OCInst_dict = {}
        self._internal_asset_id_to_OCInst_dict = {}
        self._month_id_to_expiry_dict = {}
        self._month_id_to_instruments_list_dict = defaultdict(list)
        self._parent_symbol_to_instruments_list_dict = defaultdict(list)
        self._lookup_dicts_initialized = Event()
        self._oc_position_manager = OCPositionManager(self)
        self._oc_curve_manager = OCCurveManager(self)
        self._greenlets = []

    def start(self):
        self._start_oc_bridge(self._oc_ip, self._oc_port, self._user, self._password, self._version)
        # wait to start api server until initial data download complete
        self._lookup_dicts_initialized.wait()
        self._start_zerorpc_api(self._api_port)
        log.info("startup complete")
        gevent.joinall(self._greenlets)

    def _start_oc_bridge(self, oc_ip, oc_port, user, password, version):
        self._oc_bridge = OCBridge(self, oc_ip, oc_port, user, password, version)
        self._greenlets.append(gevent.spawn(self._oc_bridge.start))
        log.info("OCBridge initialized")

    def _start_zerorpc_api(self, api_port):
        self._api_server = zerorpc.Server(PublicAPI(self))
        self._api_server.bind("tcp://*:{}".format(api_port))
        self._api_server.bind("inproc://*:{}".format(api_port))
        self._greenlets.append(gevent.spawn(self._api_server.run))
        log.info("public api started")

    def shutdown(self):
        self._oc_bridge.shutdown()

    #######################
    # message forwarding
    def send_message(self, message):
        self._oc_bridge.send_message(message)

    def async_request(self, async_req_message):
        return self._oc_bridge.async_request(async_req_message)

    #######################
    # public table lookups
    def get_oc_class_id_from_internal_asset_id(self, asset_id):
        return self._internal_asset_id_to_oc_class_id_dict[asset_id]

    def get_oc_inst_id_from_internal_asset_d(self, asset_id):
        return self._internal_asset_id_to_oc_inst_id_dict[asset_id]

    def get_internal_asset_id_from_oc_inst_id(self, instrument_id):
        return self._oc_inst_id_to_internal_asset_id_dict.get(instrument_id, None)

    def get_oc_class_id_from_oc_month_id(self, month_id):
        return self._oc_month_id_to_oc_class_id_dict[month_id]

    def get_parent_symbol_from_month_id(self, month_id):
        return self._month_id_to_parent_symbol_dict[month_id]

    def get_instruments_by_month_id(self, month_id):
        return self._month_id_to_instruments_list_dict[month_id]

    def get_instruments_by_parent_symbol(self, parent_symbol):
        return self._parent_symbol_to_instruments_list_dict[parent_symbol]

    def get_expiry_from_month_id(self, month_id):
        return self._month_id_to_expiry_dict[month_id]

    def add_supported_instruments(self, new_instruments):
        self._supported_instruments_list.extend(new_instruments)
        self._save_supported_instruments(new_instruments)
        self._update_lookup_dicts(new_instruments)
        # initialize position manager
        for parent_symbol in self._parent_symbol_set:
            log.info("initializing position: {}".format(parent_symbol))
            self.get_position_by_product(parent_symbol)

    #######################
    # initialization methods
    def _update_lookup_dicts(self, new_instruments):
        self._log_parent_symbols(new_instruments)
        self._build_internal_ids_to_oc_ids_dicts()
        self._update_derivative_lookup_dicts(new_instruments)
        self._build_OCInst_lookup_dicts(new_instruments)
        self._build_parent_symbol_to_instruments_list_dict(new_instruments)
        self._lookup_dicts_initialized.set()

    def _build_OCInst_lookup_dicts(self, new_instruments):
        for inst in new_instruments:
            asset_id = self.get_internal_asset_id_from_oc_inst_id(inst.instrument_id)
            if asset_id is not None:
                self._internal_asset_id_to_OCInst_dict[asset_id] = inst
            self._oc_inst_id_to_OCInst_dict[inst.instrument_id] = inst

    def _log_parent_symbols(self, new_instruments):
        for inst in new_instruments:
            parent_symbol = inst.parent_symbol
            if parent_symbol not in self._parent_symbol_set:
                self._parent_symbol_set.add(parent_symbol)
                self.get_position_by_product(parent_symbol)

    def _build_parent_symbol_to_instruments_list_dict(self, new_instruments):
        for inst in new_instruments:
            self._parent_symbol_to_instruments_list_dict[inst.parent_symbol].append(inst)

    def _update_derivative_lookup_dicts(self, new_instruments):
        new_derivatives = [instrument for instrument in new_instruments if isinstance(instrument, OCDerivative)]
        for new_derivative in new_derivatives:
            expiry = new_derivative.get_expiry()
            self._expiry_set.add(expiry)
            self._month_id_to_expiry_dict[expiry.month_id] = expiry
            self._oc_month_id_to_oc_class_id_dict[expiry.month_id] = expiry.class_id
            self._month_id_to_parent_symbol_dict[expiry.month_id] = expiry.parent_symbol
            self._month_id_to_instruments_list_dict[expiry.month_id].append(new_derivative)

    #######################
    # persistence handlers
    def _save_supported_instruments(self, new_instruments):
        # save all supported instruments to file
        save_instruments_to_file(self._supported_instruments_list)
        # convert new OCInstruments to internal Assets and save new Assets in database
        save_assets_to_db(new_instruments)

    def _build_internal_ids_to_oc_ids_dicts(self):
        assetid_classid_instid_tuples = get_assetid_occlassid_ocid_tuples()
        asset_ids = [acit[0] for acit in assetid_classid_instid_tuples]
        oc_class_ids = (acit[1] for acit in assetid_classid_instid_tuples)
        oc_inst_ids = [acit[2] for acit in assetid_classid_instid_tuples]
        self._internal_asset_id_to_oc_class_id_dict = dict(izip(asset_ids, oc_class_ids))
        self._internal_asset_id_to_oc_inst_id_dict = dict(izip(asset_ids, oc_inst_ids))
        self._oc_inst_id_to_internal_asset_id_dict = dict(izip(oc_inst_ids, asset_ids))
        self._lookup_dicts_initialized.set()

    #######################
    # market data request handlers
    # TODO: refactor into market data handler object
    def get_parent_symbols(self):
        return list(self._parent_symbol_set)

    def get_expiries(self, parent_symbol=None):
        if parent_symbol:
            expiries = [exp for exp in self._expiry_set if exp.parent_symbol == parent_symbol]
        else:
            expiries = list(self._expiry_set)
        return expiries

    def get_instruments(self):
        return self._supported_instruments_list

    def get_market_snapshot(self, asset_id):
        class_id = self.get_oc_class_id_from_internal_asset_id(asset_id)
        instrument_id = self.get_oc_inst_id_from_internal_asset_d(asset_id)
        market_data = self._get_market_snapshot(class_id, instrument_id)
        return market_data

    def _get_market_snapshot(self, class_id, instrument_id):
        snapshot_message = MarketSnapshotReqMessage(class_id, instrument_id)
        market_data = snapshot_message.get_result(self._oc_bridge)
        return market_data

    def get_theo_values(self, asset_id, underlying_price=None):
        instrument_id = self.get_oc_inst_id_from_internal_asset_d(asset_id)
        result = self._get_theo_values(instrument_id, underlying_price)
        return result

    def _get_theo_values(self, instrument_id, underlying_price=None):
        tvr_message = TheoValuesReqMessage(instrument_id, underlying_price)
        result = tvr_message.get_result(self._oc_bridge)
        return result

    def get_theo_values_bulk(self, month_id, underlying_price=None):
        if underlying_price is None:
            underlying_price = self.get_underlying_price_for_month(month_id)
        instrument_list = self._month_id_to_instruments_list_dict[month_id]
        greenlets = [gevent.spawn(self._get_theo_values, instrument.instrument_id, underlying_price) for instrument in instrument_list]
        gevent.joinall(greenlets)
        results = {greenlet.value['instrument_id']: greenlet.value for greenlet in greenlets}
        return results

    def get_underlying_price_for_month(self, month_id):
        instrument_list = self._month_id_to_instruments_list_dict[month_id]
        theo_value_result = self._get_theo_values(instrument_list[0].instrument_id)
        underlying_price = theo_value_result["underlying_price"]
        return underlying_price

    def get_theo_values_with_risk(self, asset_id, underlying_price=None):
        inst_id = self.get_oc_inst_id_from_internal_asset_d(asset_id)
        tvwrr_message = TheoValuesReqWithRiskMessage(inst_id, underlying_price)
        result = tvwrr_message.get_result(self._oc_bridge)
        return result

    def on_market_data_update(self, asset_id, market_data):
        pass

    def get_underlying_price_for_instrument(self, instrument_id):
        return self._get_theo_values(instrument_id)["underlying_price"]

    #######################
    # model settings update implementations
    def on_model_update_notification(self):
        self._oc_curve_manager.on_model_update_notification()

    def get_model_settings(self, month_id):
        model_settings = self._oc_curve_manager.get_model_settings(month_id)
        return model_settings

    def get_model_settings_bulk(self, parent_symbol):
        # request expiry settings for individual expiries matching parent symbol
        expiries = self.get_expiries(parent_symbol)
        greenlets = [gevent.spawn(self._oc_curve_manager.get_model_settings, expiry.month_id) for expiry in expiries]
        gevent.joinall(greenlets)
        model_settings_list = [greenlet.value for greenlet in greenlets]
        return model_settings_list

    def set_model_settings(self, **kwargs):
        new_settings = self._oc_curve_manager.set_model_settings(**kwargs)
        return new_settings

    def move_model_inputs_by_price(self, **kwargs):
        new_settings = self._oc_curve_manager.move_model_inputs_by_price(**kwargs)
        return new_settings

    #######################
    # position reporting functionality
    def get_position_by_product(self, parent_symbol):
        instruments = self._parent_symbol_to_instruments_list_dict[parent_symbol]
        greenlets = [gevent.spawn(self._oc_position_manager.get_position_by_instrument_id, inst.instrument_id)
                     for inst in instruments]
        gevent.joinall(greenlets)
        positions = [greenlet.value for greenlet in greenlets]
        return positions

    def log_trade(self, trade_message):
        self._oc_position_manager.log_trade(trade_message)