def _get_ib_futures_contract(self, futures_contract_object): """ Return a complete and unique IB contract that matches futures_contract_object This is expensive so not called directly, only by ib_futures_contract which does caching :param futures_contract_object: contract, containing instrument metadata suitable for IB :return: a single ib contract object """ # Convert to IB world instrument_object_with_metadata = futures_contract_object.instrument ibcontract = ib_futures_instrument(instrument_object_with_metadata) # Register the contract to make logging and error handling cleaner self.add_contract_to_register( ibcontract, log_tags=dict(instrument_code=instrument_object_with_metadata. instrument_code, contract_date=futures_contract_object.date)) # The contract date might be 'yyyymm' or 'yyyymmdd' contract_day_passed = futures_contract_object.contract_date.is_day_defined( ) if contract_day_passed: ## Already have the expiry contract_date = futures_contract_object.contract_date else: ## Don't have the expiry so lose the days at the end so it's just 'YYYYMM' contract_date = str(futures_contract_object.contract_date)[:6] ibcontract.lastTradeDateOrContractMonth = contract_date ## We allow multiple contracts in case we have 'yyyymm' and not specified expiry date for VIX ibcontract_list = self.ib_get_contract_chain(ibcontract) if len(ibcontract_list) == 0: ## No contracts found return missing_contract if len(ibcontract_list) == 1: ## OK no hassle, only one contract no confusion resolved_contract = ibcontract_list[0] else: ## It might be a contract with weekly expiries (probably VIX) ## We need to find the right one try: resolved_contract = resolve_multiple_expiries( ibcontract_list, instrument_object_with_metadata) except Exception as exception: self.log.warn( "%s could not resolve contracts: %s" % (str(instrument_object_with_metadata), exception.args[0])) return missing_contract return resolved_contract
def _get_vanilla_ib_futures_contract( self, futures_instrument_with_ib_data: futuresInstrumentWithIBData, contract_date): """ Return a complete and unique IB contract that matches contract_object_with_ib_data This is expensive so not called directly, only by ib_futures_contract which does caching :param contract_object_with_ib_data: contract, containing instrument metadata suitable for IB :return: a single ib contract object """ # The contract date might be 'yyyymm' or 'yyyymmdd' ibcontract = ib_futures_instrument(futures_instrument_with_ib_data) contract_day_passed = contract_date.is_day_defined() if contract_day_passed: # Already have the expiry pass else: # Don't have the expiry so lose the days at the end so it's just # 'YYYYMM' contract_date = str(contract_date)[:6] ibcontract.lastTradeDateOrContractMonth = contract_date # We allow multiple contracts in case we have 'yyyymm' and not # specified expiry date for VIX ibcontract_list = self.ib_get_contract_chain(ibcontract) if len(ibcontract_list) == 0: # No contracts found return missing_contract if len(ibcontract_list) == 1: # OK no hassle, only one contract no confusion resolved_contract = ibcontract_list[0] else: # It might be a contract with weekly expiries (probably VIX) # We need to find the right one try: resolved_contract = resolve_multiple_expiries( ibcontract_list, futures_instrument_with_ib_data) except Exception as exception: self.log.warn( "%s could not resolve contracts: %s" % (str(futures_instrument_with_ib_data), exception.args[0])) return missing_contract return resolved_contract
def _get_spread_ib_futures_contract( self, futures_instrument_with_ib_data: futuresInstrumentWithIBData, contract_date, trade_list_for_multiple_legs=[-1, 1], ): """ Return a complete and unique IB contract that matches contract_object_with_ib_data This is expensive so not called directly, only by ib_futures_contract which does caching :param contract_object_with_ib_data: contract, containing instrument metadata suitable for IB :return: a single ib contract object """ # Convert to IB world ibcontract = ib_futures_instrument(futures_instrument_with_ib_data) ibcontract.secType = "BAG" list_of_contract_dates = contract_date.list_of_single_contract_dates resolved_legs = [ self._get_vanilla_ib_futures_contract( futures_instrument_with_ib_data, contract_date) for contract_date in list_of_contract_dates ] ratio_list = list_of_ints_with_highest_common_factor_positive_first( trade_list_for_multiple_legs) def _get_ib_combo_leg(ratio, resolved_leg): leg = ComboLeg() leg.conId = int(resolved_leg.conId) leg.exchange = str(resolved_leg.exchange) action, size = resolveBS(ratio) leg.ratio = int(size) leg.action = str(action) return leg ibcontract.comboLegs = [ _get_ib_combo_leg(ratio, resolved_leg) for ratio, resolved_leg in zip(ratio_list, resolved_legs) ] return ibcontract, resolved_legs
def broker_get_futures_contract_list(self, instrument_object_with_ib_config): specific_log = self.log.setup( instrument_code=instrument_object_with_ib_config.instrument_code) ibcontract_pattern = ib_futures_instrument( instrument_object_with_ib_config) contract_list = self.ib_get_contract_chain(ibcontract_pattern, log=specific_log) # if no contracts found will be empty # Extract expiry date strings from these contract_dates = [ ibcontract.lastTradeDateOrContractMonth for ibcontract in contract_list ] return contract_dates