def get_ticker_object( self, contract_object_with_ib_data: futuresContract, trade_list_for_multiple_legs: tradeQuantity = None ) -> tickerWithBS: specific_log = contract_object_with_ib_data.specific_log(self.log) ibcontract = self.ib_futures_contract( contract_object_with_ib_data, trade_list_for_multiple_legs=trade_list_for_multiple_legs, ) 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 self.ib.reqMktData(ibcontract, "", False, False) ticker = self.ib.ticker(ibcontract) ib_BS_str, ib_qty = resolveBS_for_list(trade_list_for_multiple_legs) ticker_with_bs = tickerWithBS(ticker, ib_BS_str) return ticker_with_bs
def mark_existing_contract_as_sampling(contract_to_add: futuresContract, data: dataBlob): data_contracts = dataContracts(data) data_contracts.mark_contract_as_sampling(contract_to_add) log = contract_to_add.specific_log(data.log) log.msg("Contract %s now sampling" % str(contract_to_add))
def broker_get_historical_futures_data_for_contract( self, contract_object_with_ib_broker_config: futuresContract, bar_freq="D") -> pd.DataFrame: """ Get historical daily data :param contract_object_with_ib_broker_config: contract where instrument has ib metadata :param freq: str; one of D, H, 5M, M, 10S, S :return: futuresContractPriceData """ specific_log = contract_object_with_ib_broker_config.specific_log( self.log) ibcontract = self.ib_futures_contract( contract_object_with_ib_broker_config) if ibcontract is missing_contract: specific_log.warn("Can't resolve IB contract %s" % str(contract_object_with_ib_broker_config)) return missing_data price_data = self._get_generic_data_for_contract(ibcontract, log=specific_log, bar_freq=bar_freq, whatToShow="TRADES") return price_data
def update_expiry_for_contract(contract_object: futuresContract, data: dataBlob): """ Get an expiry from IB, check if same as database, otherwise update the database :param contract_object: contract object :param data: dataBlob :param log: log :return: None """ log = contract_object.specific_log(data.log) broker_expiry_date = get_contract_expiry_from_broker(contract_object, data=data) db_expiry_date = get_contract_expiry_from_db(contract_object, data=data) if broker_expiry_date is missing_contract: log.msg( "Can't find expiry for %s, could be a connection problem but could be because contract has already expired" % (str(contract_object))) ## don't warn as probably expired we'll remove it from the sampling list elif broker_expiry_date == db_expiry_date: log.msg("No change to contract expiry %s to %s" % (str(contract_object), str(broker_expiry_date))) else: # Different! update_contract_object_with_new_expiry_date( data=data, broker_expiry_date=broker_expiry_date, contract_object=contract_object)
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 update_contract_object_with_new_expiry_date( data: dataBlob, broker_expiry_date: expiryDate, contract_object: futuresContract): data_contracts = dataContracts(data) data_contracts.update_expiry_date(contract_object, new_expiry_date=broker_expiry_date) log = contract_object.specific_log(data.log) log.msg("Updated expiry of contract %s to %s" % (str(contract_object), str(broker_expiry_date)))
def add_new_contract_with_sampling_on(contract_to_add: futuresContract, data: dataBlob): data_contracts = dataContracts(data) # Mark it as sampling contract_to_add.sampling_on() # Add it to the database # Should not be any duplication to ignore data_contracts.add_contract_data(contract_to_add, ignore_duplication=False) log = contract_to_add.specific_log(data.log) log.msg("Contract %s now added to database and sampling" % str(contract_to_add))
def update_expiry_for_single_contract(self, original_contract: futuresContract) -> futuresContract: actual_expiry = self.get_actual_expiry_date_for_single_contract( original_contract ) if actual_expiry is missing_contract: log = original_contract.specific_log(self.data.log) log.warn("Contract %s is missing from IB probably expired - need to manually close on DB" % str( original_contract)) new_contract = copy(original_contract) else: expiry_date_as_str = actual_expiry.as_str() instrument_code = original_contract.instrument_code new_contract = futuresContract(instrument_code, expiry_date_as_str) return new_contract
def check_and_stop_expired_contract_sampling(contract: futuresContract, data: dataBlob): data_contracts = dataContracts(data) db_contract = data_contracts.get_contract_from_db(contract) contract_expired = db_contract.expired() contract_sampling = db_contract.currently_sampling if contract_expired and contract_sampling: # Mark it as stop sampling in the database data_contracts.mark_contract_as_not_sampling(contract) log = contract.specific_log(data.log) log.msg( "Contract %s has expired so now stopped sampling" % str(contract), contract_date=contract.date_str, )
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 cancel_market_data_for_contract_object( self, contract_object_with_ib_data: futuresContract, trade_list_for_multiple_legs: tradeQuantity = None): specific_log = contract_object_with_ib_data.specific_log(self.log) ibcontract = self.ib_futures_contract( contract_object_with_ib_data, trade_list_for_multiple_legs=trade_list_for_multiple_legs, ) 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 self.ib.cancelMktData(ibcontract)
def ib_get_min_tick_size(self, contract_object_with_ib_data: futuresContract) -> float: specific_log = contract_object_with_ib_data.specific_log(self.log) ib_contract = self.ib_futures_contract( contract_object_with_ib_data, always_return_single_leg=True ) if ib_contract is missing_contract: specific_log.warn("Can't get tick size as contract missing") return missing_contract ib_contract_details = self.ib.reqContractDetails(ib_contract)[0] try: min_tick = ib_contract_details.minTick except Exception as e: specific_log.warn("%s when getting min tick size from %s!" % (str(e), str(ib_contract_details))) return missing_contract return min_tick
def ib_get_trading_hours(self, contract_object_with_ib_data: futuresContract) -> list: specific_log = contract_object_with_ib_data.specific_log(self.log) ib_contract = self.ib_futures_contract( contract_object_with_ib_data, always_return_single_leg=True ) if ib_contract is missing_contract: specific_log.warn("Can't get trading hours as contract is missing") return missing_contract # returns a list but should only have one element ib_contract_details_list = self.ib.reqContractDetails(ib_contract) ib_contract_details = ib_contract_details_list[0] try: trading_hours = get_trading_hours(ib_contract_details) except Exception as e: specific_log.warn("%s when getting trading hours from %s!" % (str(e), str(ib_contract_details))) return missing_contract return trading_hours
def check_and_update_sampling_status(contract: futuresContract, data: dataBlob, contract_chain: listOfFuturesContracts): unsample = False reason = "" data_contracts = dataContracts(data) db_contract = data_contracts.get_contract_from_db(contract) if db_contract.expired(): unsample = True reason = "has expired" elif db_contract not in contract_chain: unsample = True reason = "not in chain" if unsample: # Mark it as stop sampling in the database data_contracts.mark_contract_as_not_sampling(contract) log = contract.specific_log(data.log) log.msg( "Contract %s %s so now stopped sampling" % (str(contract), reason), contract_date=contract.date_str, )
def _update_positions_for_individual_contract_leg( self, contract: futuresContract, trade_done: int, time_date: datetime.datetime): current_position = self.diag_positions.get_position_for_contract( contract) new_position = current_position + trade_done self.db_contract_position_data.update_position_for_contract_object( contract, new_position, date=time_date) # check new_position_db = self.diag_positions.get_position_for_contract( contract) log = contract.specific_log(self.log) log.msg( "Updated position of %s from %d to %d; new position in db is %d" % ( str(contract), current_position, new_position, new_position_db, ))