def __init__(self, instrument_object, contract_date_object, **kwargs): """ futuresContract(futuresInstrument, contractDate) OR futuresContract("instrument_code", "yyyymm") :param instrument_object: str or futuresInstrument :param contract_date_object: contractDate or contractDateWithRollParameters or str """ if isinstance(instrument_object, str): if isinstance(contract_date_object, str): # create a simple object self.instrument = futuresInstrument(instrument_object) self.contract_date = contractDate(contract_date_object) if isinstance(contract_date_object, list): if len(contract_date_object) == 1: self.instrument = futuresInstrument(instrument_object) self.contract_date = contractDate(contract_date_object[0]) else: self.instrument = futuresInstrument(instrument_object) self.contract_date = [ contractDate(contract_date) for contract_date in contract_date_object ] else: self.instrument = instrument_object self.contract_date = contract_date_object self._is_empty = False self.params = kwargs
def _resolve_args_where_instrument_str_and_contract_date_is_list( instrument_object, contract_date_object_list): instrument_object = futuresInstrument(instrument_object) if len(contract_date_object_list) == 1: contract_date_object = contractDate(contract_date_object_list[0]) else: contract_date_object = [ contractDate(contract_date) for contract_date in contract_date_object_list ] return instrument_object, contract_date_object
def add_phantom_row(roll_calendar, dict_of_futures_contract_prices: dictFuturesContractFinalPrices, roll_parameters: rollParameters): final_row = roll_calendar.iloc[-1] if datetime.datetime.now()<final_row.name: return roll_calendar virtual_datetime = datetime.datetime.now() + datetime.timedelta(days=5) current_contract_date_str = str(final_row.next_contract) current_contract = contractDateWithRollParameters(contractDate(current_contract_date_str), roll_parameters) next_contract = current_contract.next_held_contract() carry_contract = current_contract.carry_contract() list_of_contract_names = dict_of_futures_contract_prices.keys() try: assert current_contract.date_str in list_of_contract_names except: print("Can't add extra row as data missing") return roll_calendar new_row = pd.DataFrame(dict(current_contract = current_contract_date_str, next_contract = next_contract.date_str, carry_contract = carry_contract.date_str), index=[virtual_datetime]) roll_calendar = pd.concat([roll_calendar, new_row], axis=0) return roll_calendar
def _add_carry_calendar(roll_calendar, roll_parameters_object, dict_of_futures_contract_prices): """ :param roll_calendar: pdDataFrame with current_contract and next_contract :param roll_parameters_object: rollData :return: data frame ready to be rollCalendar """ list_of_contract_dates = list(roll_calendar.current_contract.values) contracts_with_roll_data = [ contractDateWithRollParameters(contractDate(str(contract_date)), roll_parameters_object) for contract_date in list_of_contract_dates ] carry_contract_dates = [ contract.carry_contract().date_str for contract in contracts_with_roll_data ] # Special case if first carry contract missing with a negative offset first_carry_contract = carry_contract_dates[0] if first_carry_contract not in dict_of_futures_contract_prices: # drop the first roll entirely carry_contract_dates.pop(0) # do the same with the calendar or will misalign first_roll_date = roll_calendar.index[0] roll_calendar = roll_calendar.drop(first_roll_date) roll_calendar["carry_contract"] = carry_contract_dates return roll_calendar
def _float_to_contract_str(multiple_prices_unique, date_index, column_name): contract_date = contractDate( str(int(multiple_prices_unique.loc[date_index][column_name]))).date_str date_str = contract_date return date_str
def from_two_strings(futuresContract, instrument_code: str, contract_date_str: str): instrument_object = futuresInstrument(instrument_code) contract_date = contractDate(contract_date_str, simple=True) return futuresContract(instrument_object, contract_date, simple=True)
def get_contract_chain(instrument_code, data): diag_contracts = diagContracts(data) diag_prices = diagPrices(data) roll_parameters = diag_contracts.get_roll_parameters(instrument_code) # Get the last contract currently being used multiple_prices = diag_prices.get_multiple_prices(instrument_code) current_contract_dict = multiple_prices.current_contract_dict() current_contract_list = list(current_contract_dict.values()) furthest_out_contract_date = max(current_contract_list) furthest_out_contract = contractDateWithRollParameters( contractDate(furthest_out_contract_date), roll_parameters) # To give us wiggle room, and ensure we start collecting the new forward a # little in advance final_contract = furthest_out_contract.next_priced_contract() contract_date_chain = ( final_contract.get_unexpired_contracts_from_now_to_contract_date()) # We have a list of contract_date objects, need futureContracts # create a 'bare' instrument object instrument_object = futuresInstrument(instrument_code) contract_object_chain_as_list = [ futuresContract(instrument_object, contract_date_object) for contract_date_object in contract_date_chain ] contract_object_chain = listOfFuturesContracts( contract_object_chain_as_list) return contract_object_chain
def _resolve_args_where_both_are_str(instrument_object_str, contract_date_object_str): # create a simple object instrument_object = futuresInstrument(instrument_object_str) contract_date_object = contractDate(contract_date_object_str) return instrument_object, contract_date_object
def get_contract_date_object_with_roll_parameters(self, instrument_code, contract_date_id): roll_parameters = self.get_roll_parameters(instrument_code) contract_date_with_roll_parameters = contractDateWithRollParameters( contractDate(contract_date_id), roll_parameters) return contract_date_with_roll_parameters
def create_empty(futuresContract): fake_instrument = futuresInstrument("EMPTY") fake_contract_date = contractDate("150001") futures_contract = futuresContract(fake_instrument, fake_contract_date) futures_contract._is_empty = True return futures_contract
def simple(futuresContract, instrument_code, contract_date, **kwargs): DeprecationWarning( "futuresContract.simple(x,y) is deprecated, use futuresContract(x,y) instead" ) return futuresContract( futuresInstrument(instrument_code), contractDate( contract_date, **kwargs))
def _resolve_args_for_futures_contract(instrument_object, contract_date_object) -> tuple: if isinstance(instrument_object, str): instrument_object = futuresInstrument(instrument_object) if isinstance(contract_date_object, list) or isinstance(contract_date_object, str) \ or isinstance(contract_date_object, dict): contract_date_object = contractDate(contract_date_object) return instrument_object, contract_date_object
def create_furthest_out_contract_with_roll_parameters_from_contract_date( data: dataBlob, instrument_code: str, furthest_out_contract_date: str): diag_contracts = dataContracts(data) roll_parameters = diag_contracts.get_roll_parameters(instrument_code) furthest_out_contract = contractDateWithRollParameters( contractDate(furthest_out_contract_date), roll_parameters) return furthest_out_contract
def __init__(self, strategy_name: str, instrument_code: str, contract_id): """ :param strategy_name: str :param instrument_code: str :param contract_id: a single contract_order_id YYYYMM, or a list of contract IDS YYYYMM for a spread order """ self._contract_date = contractDate(contract_id) self._instrument = futuresInstrument(instrument_code) self._strategy_name = strategy_name
def last_current_contract(self): """ Returns the oldest contract in the final row of the row calendar :return: contractDate """ final_row = self.tail(1).values last_contract_numeric = final_row.max() last_contract = contractDate(str(last_contract_numeric)) return last_contract
def extend_current_contracts(self, instrument_code, current_contracts): price_contract_date = current_contracts.price forward_contract_date = current_contracts.forward carry_contract_date = current_contracts.carry roll_parameters = self.get_roll_parameters(instrument_code) price_contract = contractDateWithRollParameters( contractDate(price_contract_date), roll_parameters) forward_contract = contractDateWithRollParameters( contractDate(forward_contract_date), roll_parameters) carry_contract = contractDateWithRollParameters( contractDate(carry_contract_date), roll_parameters) preceeding_price_contract_date = price_contract.previous_priced_contract( ) preceeding_forward_contract_date = forward_contract.previous_priced_contract( ) subsequent_forward_contract_date = forward_contract.next_held_contract( ) # Could be up to 6 contracts # HOW TO PAD THESE ? all_contracts = [ price_contract, forward_contract, preceeding_forward_contract_date, preceeding_price_contract_date, subsequent_forward_contract_date, carry_contract, ] all_contracts_dates = [contract.date_str for contract in all_contracts] unique_all_contract_dates = sorted(set(all_contracts_dates)) unique_all_contract_dates = unique_all_contract_dates + \ [missing_contract] * (6 - len(unique_all_contract_dates)) return unique_all_contract_dates
def contract_date_from_numbers(contractDateWithRollData, roll_parameters, new_year_number, new_month_number, new_day_number=NO_DAY_PASSED, **kwargs): ## WHERE USED? ## BETTER WITH EXPLICIT CONTRACT DATE ENTRY? contract_string = from_contract_numbers_to_contract_string( new_year_number, new_month_number, new_day_number) contract_date = contractDate(contract_string, **kwargs) contract_date_with_roll_data_object = contractDateWithRollData( contract_date, roll_parameters) return contract_date_with_roll_data_object
def test_contractDate(self): contract_date201801 = contractDate("201801") contract_date20180115 = contractDate("20180115") contract_date20180100 = contractDate("20180100") self.assertEqual(contract_date20180100.date_str, "20180100") # dictionary contract_date_dict_201801 = contract_date201801.as_dict() self.assertEqual( contract_date_dict_201801, dict(expiry_date=(2018, 1, 1), contract_date="201801", approx_expiry_offset=0), ) contract_date_dict_20180115 = contract_date20180115.as_dict() self.assertEqual( contract_date_dict_20180115, dict( expiry_date=(2018, 1, 15), contract_date="20180115", approx_expiry_offset=0, ), ) new_contractdate20801 = contractDate.create_from_dict( contract_date_dict_201801) self.assertEqual(contract_date201801.date_str, new_contractdate20801.date_str) self.assertEqual(contract_date201801.expiry_date.year, new_contractdate20801.expiry_date.year) # basic functionality self.assertEqual(contract_date201801.date_str, "20180100") self.assertEqual(contract_date20180115.date_str, "20180115") self.assertEqual(contract_date201801.year(), 2018) self.assertEqual(contract_date201801.month(), 1) self.assertEqual(contract_date201801.only_has_month, True) self.assertEqual(contract_date20180115.day(), 15) self.assertEqual(contract_date201801.letter_month(), "F") self.assertEqual(contract_date201801._as_date(), datetime.datetime(2018, 1, 1)) self.assertEqual(contract_date20180115._as_date(), datetime.datetime(2018, 1, 15)) # check date comparision self.assertEqual( contract_date201801.check_if_expiry_after_date( datetime.datetime(2018, 2, 1)), False, ) self.assertEqual( contract_date201801.check_if_expiry_after_date( datetime.datetime(2017, 12, 31)), True, ) # alternative method to define contracts contract_date201801b = contractDate.contract_date_from_numbers(2018, 1) contract_date20180115b = contractDate.contract_date_from_numbers( 2018, 1, 15) self.assertEqual(contract_date201801b.date_str, "20180100") self.assertEqual(contract_date20180115b.date_str, "20180115") # check expiry dates contract_date201803_withexpiry = contractDate("201803", expiry_date=(2008, 3, 15)) contract_date201801b_withexpiry = contractDate.contract_date_from_numbers( 2018, 1, expiry_date=(2008, 1, 16)) self.assertEqual(contract_date201803_withexpiry.expiry_date, datetime.datetime(2008, 3, 15)) self.assertEqual(contract_date201801b_withexpiry.expiry_date, datetime.datetime(2008, 1, 16)) # check expiry dates with contract offset contract_date201803_withexpiry_offset = contractDate( "201803", approx_expiry_offset=40) contract_date201801b_withexpiry_offset = ( contractDate.contract_date_from_numbers(2018, 1, approx_expiry_offset=-20)) self.assertEqual( contract_date201803_withexpiry_offset.expiry_date, datetime.datetime(2018, 4, 10), ) self.assertEqual( contract_date201801b_withexpiry_offset.expiry_date, datetime.datetime(2017, 12, 12), )
def back_out_from_current_and_forward_data(rollCalendar, current_and_forward_data, roll_parameters_object): """ :param current_and_forward_data: output from futuresDataForSim.FuturesData.get_current_and_forward_price_data(instrument_code) columns: PRICE, FORWARD, FORWARD_CONTRACT, PRICE_CONTRACT :return: rollCalendar """ current_and_forward_unique = current_and_forward_data[ ~current_and_forward_data.index.duplicated(keep="last")] roll_dates = current_and_forward_unique.index[1:][ current_and_forward_unique[1:].PRICE_CONTRACT.values > current_and_forward_unique[:-1].PRICE_CONTRACT.values] days_before = current_and_forward_unique.index[:-1][ current_and_forward_unique[:-1].PRICE_CONTRACT.values < current_and_forward_unique[1:].PRICE_CONTRACT.values] # Duplicates are possible (double rolls) current_contracts = [ contractDate( current_and_forward_unique.loc[date_index].PRICE_CONTRACT).date for date_index in days_before ] next_contracts = [ contractDate( current_and_forward_unique.loc[date_index].PRICE_CONTRACT).date for date_index in roll_dates ] carry_contracts = [ contractDate( current_and_forward_unique.loc[date_index].CARRY_CONTRACT).date for date_index in days_before ] roll_calendar = pd.DataFrame( dict( current_contract=current_contracts, next_contract=next_contracts, carry_contract=carry_contracts, ), index=roll_dates, ) extra_row = pd.DataFrame( dict( current_contract=[ contractDate( current_and_forward_data.iloc[-1].PRICE_CONTRACT).date ], next_contract=[ contractDate(current_and_forward_data.iloc[-1]. FORWARD_CONTRACT).date ], carry_contract=[ contractDate( current_and_forward_data.iloc[-1].CARRY_CONTRACT).date ], ), index=[current_and_forward_data.index[-1]], ) roll_calendar = pd.concat([roll_calendar, extra_row], axis=0) roll_calendar_object = rollCalendar(roll_calendar) return roll_calendar_object