def _get_spread_ib_futures_contract( self, futures_instrument_with_ib_data: futuresInstrumentWithIBConfigData, contract_date: contractDate, trade_list_for_multiple_legs: tradeQuantity = None, ) -> ibcontractWithLegs: """ 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 """ if trade_list_for_multiple_legs is None: raise Exception("Multiple leg order must have trade list") # 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 ] ibcontract_with_legs = _add_legs_to_ib_contract( ibcontract=ibcontract, resolved_legs=resolved_legs, trade_list_for_multiple_legs=trade_list_for_multiple_legs) return ibcontract_with_legs
def _get_vanilla_ib_futures_contract( self, futures_instrument_with_ib_data: futuresInstrumentWithIBConfigData, 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.date_str)[: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: futuresInstrumentWithIBConfigData, 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 get_ib_contract_with_specific_expiry(futures_instrument_with_ib_data: futuresInstrumentWithIBConfigData, contract_date: contractDate) ->Contract: ibcontract = ib_futures_instrument(futures_instrument_with_ib_data) contract_date_string = str(contract_date.date_str) contract_day_was_passed = contract_date.is_day_defined() if contract_day_was_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_string = contract_date_string[:6] ibcontract.lastTradeDateOrContractMonth = contract_date_string return ibcontract
def broker_get_futures_contract_list( self, futures_instrument_with_ib_data: futuresInstrumentWithIBConfigData, allow_expired: bool = False) -> list: ## Returns list of contract date strings YYYYMMDD specific_log = self.log.setup( instrument_code=futures_instrument_with_ib_data.instrument_code ) ibcontract_pattern = ib_futures_instrument( futures_instrument_with_ib_data) contract_list = self.ib_get_contract_chain(ibcontract_pattern, allow_expired=allow_expired) # 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
def broker_get_futures_contract_list( self, futures_instrument_with_ib_data: futuresInstrumentWithIBConfigData ): specific_log = self.log.setup( instrument_code=futures_instrument_with_ib_data.instrument_code) ibcontract_pattern = ib_futures_instrument( futures_instrument_with_ib_data) 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