def ib_get_recent_bid_ask_tick_data( self, contract_object_with_ib_data: futuresContract, tick_count=200, ) -> list: """ :param contract_object_with_ib_data: :return: """ specific_log = self.log.setup( instrument_code=contract_object_with_ib_data.instrument_code, contract_date=contract_object_with_ib_data.date_str, ) if contract_object_with_ib_data.is_spread_contract(): error_msg = "Can't get historical data for combo" specific_log.critical(error_msg) raise Exception(error_msg) ibcontract = self.ib_futures_contract(contract_object_with_ib_data) if ibcontract is missing_contract: specific_log.warn( "Can't find matching IB contract for %s" % str(contract_object_with_ib_data) ) return missing_contract recent_ib_time = self.ib.reqCurrentTime() - datetime.timedelta(seconds=60) tick_data = self.ib.reqHistoricalTicks( ibcontract, recent_ib_time, "", tick_count, "BID_ASK", useRth=False ) return tick_data
def _get_ib_futures_contract_from_broker( self, contract_object_with_ib_data: futuresContract, trade_list_for_multiple_legs: tradeQuantity = None ) -> ibcontractWithLegs: """ 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 contract_object_with_ib_data: contract, containing instrument metadata suitable for IB :return: a single ib contract object """ # Convert to IB world futures_instrument_with_ib_data = contract_object_with_ib_data.instrument contract_date = contract_object_with_ib_data.contract_date if contract_object_with_ib_data.is_spread_contract(): ibcontract_with_legs = self._get_spread_ib_futures_contract( futures_instrument_with_ib_data, contract_date, trade_list_for_multiple_legs=trade_list_for_multiple_legs, ) else: ibcontract_with_legs = self._get_vanilla_ib_futures_contract_with_legs( futures_instrument_with_ib_data=futures_instrument_with_ib_data, contract_date=contract_date) return ibcontract_with_legs
def broker_get_single_contract_expiry_date( self, futures_contract_with_ib_data: futuresContract, allow_expired: bool = False, ) -> str: """ Return the exact expiry date for a given contract :param futures_contract_with_ib_data: contract where instrument has ib metadata :return: YYYYMMDD str """ specific_log = futures_contract_with_ib_data.specific_log(self.log) if futures_contract_with_ib_data.is_spread_contract(): specific_log.warn("Can only find expiry for single leg contract!") return missing_contract ibcontract = self.ib_futures_contract( futures_contract_with_ib_data, allow_expired=allow_expired, always_return_single_leg=True, ) if ibcontract is missing_contract: specific_log.warn("Contract is missing can't get expiry") return missing_contract expiry_date = ibcontract.lastTradeDateOrContractMonth return expiry_date
def _get_actual_expiry_date_given_single_contract_with_ib_metadata( self, futures_contract_with_ib_data: futuresContract) -> expiryDate: log = futures_contract_with_ib_data.specific_log(self.log) if futures_contract_with_ib_data.is_spread_contract(): log.warn("Can't find expiry for multiple leg contract here") return missing_contract expiry_date = self.ib_client.broker_get_single_contract_expiry_date( futures_contract_with_ib_data) if expiry_date is missing_contract: return missing_contract else: expiry_date = expiryDate.from_str(expiry_date) return expiry_date
def get_actual_expiry_date_for_single_contract(self, futures_contract: futuresContract) -> expiryDate: """ Get the actual expiry date of a contract from IB :param futures_contract: type futuresContract :return: YYYYMMDD or None """ log = futures_contract.specific_log(self.log) if futures_contract.is_spread_contract(): log.warn("Can't find expiry for multiple leg contract here") return missing_contract contract_object_with_ib_data = self.get_contract_object_with_IB_data(futures_contract) expiry_date = contract_object_with_ib_data.expiry_date return expiry_date
def _get_contract_cache_key( self, contract_object_to_use: futuresContract, trade_list_for_multiple_legs: tradeQuantity = None) -> str: if not contract_object_to_use.is_spread_contract(): trade_list_suffix = "" else: # WANT TO TREAT EG -2,2 AND -4,4 AS THE SAME BUT DIFFERENT FROM # -2,1 OR -1,2,-1... trade_list_suffix = str( list_of_ints_with_highest_common_factor_positive_first( trade_list_for_multiple_legs)) key = contract_object_to_use.key + trade_list_suffix return key