def update_multiple_adjusted_prices(): """ Do a daily update for multiple and adjusted prices :return: Nothing """ with dataBlob(log_name="Update-Multiple-Adjusted-Prices") as data: update_multiple_adjusted_prices_object = updateMultipleAdjustedPrices( data) instrument_code = get_valid_instrument_code_from_user( all_code=ALL_INSTRUMENTS, allow_all=True) update_multiple_adjusted_prices_object.update_multiple_adjusted_prices( instrument_code=instrument_code) if instrument_code is ALL_INSTRUMENTS: ## done return success ## else go into a loop do_another = True while do_another: EXIT_CODE = "EXIT" instrument_code = get_valid_instrument_code_from_user( allow_exit=True, exit_code="EXIT") if instrument_code is EXIT_CODE: do_another = False else: update_multiple_adjusted_prices_object.update_multiple_adjusted_prices( instrument_code=instrument_code) return success
def update_sampled_contracts(): """ Update the active contracts, according to what is available in IB for a given instrument These are stored in mongoDB The active contracts list is used to see what contracts have historical data sampled for It does not tell you what the current priced, forward, or carry contract are - that is in multiple prices (DRY) However we base the list of theoretical active contracts on the current priced, forward, and carry contracts We will end up adding to this list when we roll; this will change the current priced, forward, and carry contract When we add a new contract (because one has become available), we get the exact expiry date from IB and save this with the contract data. We do not sample contracts on the list when they have passed their expiry date Contracts are never deleted from the database We don't check IB for contracts; since we can't reverse engineer a YYYYMM identifier from a YYYYMMDD :returns: None """ with dataBlob(log_name="Update-Sampled_Contracts") as data: update_contracts_object = updateSampledContracts(data) instrument_code = get_valid_instrument_code_from_user( allow_all=True, all_code=ALL_INSTRUMENTS ) update_contracts_object.update_sampled_contracts( instrument_code=instrument_code ) if instrument_code is ALL_INSTRUMENTS: return success do_another = True while do_another: EXIT_CODE = "EXIT" instrument_code = get_valid_instrument_code_from_user( allow_exit=True, exit_code=EXIT_CODE ) if instrument_code is EXIT_CODE: do_another = False else: update_contracts_object.update_sampled_contracts( instrument_code=instrument_code )
def change_position_limit_for_instrument_strategy(data): view_position_limit(data) data_position_limits = dataPositionLimits(data) strategy_name = get_valid_strategy_name_from_user(data, allow_all=False, source="positions") instrument_code = get_valid_instrument_code_from_user(data, allow_all=False) new_position_limit = get_and_convert( "New position limit?", type_expected=int, allow_default=True, default_value=-1, default_str="No limit", ) instrument_strategy = instrumentStrategy(instrument_code=instrument_code, strategy_name=strategy_name) if new_position_limit == -1: data_position_limits.delete_position_limit_for_instrument_strategy( instrument_strategy) else: new_position_limit = abs(new_position_limit) data_position_limits.set_position_limit_for_instrument_strategy( instrument_strategy, new_position_limit)
def enter_manual_instrument_order(data): strategy_name = get_valid_strategy_name_from_user(data=data, source="positions") instrument_code = get_valid_instrument_code_from_user(data) qty = get_and_convert("Quantity (-ve for sell, +ve for buy?)", type_expected=int, allow_default=False) order_type = input("Order type (one of %s)?" % str(possible_order_types)) limit_price = get_and_convert( "Limit price? (if you put None you can still add one to the contract order)", type_expected=float, default_value=None, default_str="None", ) if limit_price is None: limit_contract = None else: print("Enter contractid that limit price is referenced to") _, contract_date = get_valid_instrument_code_and_contractid_from_user( data, instrument_code=instrument_code) limit_contract = contract_date instrument_order = instrumentOrder( strategy_name, instrument_code, qty, order_type=order_type, limit_price=limit_price, limit_contract=limit_contract, manual_trade=True, roll_order=False, ) return instrument_order
def reset_limit_for_instrument(data): trade_limits = dataTradeLimits(data) instrument_code = get_valid_instrument_code_from_user(data) period_days = get_and_convert("Period of days?", type_expected=int, allow_default=True, default_value = 1) ans = input("Reset means trade 'clock' will restart. Are you sure? (y/other)") if ans =="y": trade_limits.reset_instrument_limit(instrument_code, period_days)
def interactive_manual_check_historical_prices(): """ Do a daily update for futures contract prices, using IB historical data If any 'spikes' are found, run manual checks :return: Nothing """ with dataBlob(log_name="Update-Historical-prices-manually") as data: cleaning_config = interactively_get_config_overrides_for_cleaning( data=data) do_another = True while do_another: EXIT_STR = "Finished: Exit" instrument_code = get_valid_instrument_code_from_user( data, source="single", allow_exit=True, exit_code=EXIT_STR) if instrument_code is EXIT_STR: do_another = False else: check_instrument_ok_for_broker(data, instrument_code) data.log.label(instrument_code=instrument_code) update_historical_prices_for_instrument( instrument_code=instrument_code, cleaning_config=cleaning_config, data=data, interactive_mode=True) return success
def view_instrument_config(data): instrument_code = get_valid_instrument_code_from_user(data) diag_instruments = diagInstruments(data) meta_data = diag_instruments.get_meta_data(instrument_code) print(meta_data) return None
def get_valid_instrument_code_and_contractid_from_user(data, instrument_code=None): diag_contracts = diagContracts(data) invalid_input = True while invalid_input: if instrument_code is None: instrument_code = get_valid_instrument_code_from_user(data) all_contracts = diag_contracts.get_all_contract_objects_for_instrument_code( instrument_code) sampled_contract = all_contracts.currently_sampling() sampled_dates = sampled_contract.list_of_dates() all_dates = all_contracts.list_of_dates() if len(all_dates) == 0: print("%s is not an instrument with contract data" % instrument_code) instrument_code = None continue print("Currently sampled contract dates %s" % str(sampled_dates)) contract_date = input("Contract date?") if contract_date in all_dates: break else: print("%s is not in list %s" % (contract_date, all_dates)) continue # not required return instrument_code, contract_date
def multiple_prices(data): instrument_code = get_valid_instrument_code_from_user(data) diag_prices = diagPrices(data) prices = diag_prices.get_multiple_prices(instrument_code) print(prices) return None
def create_instrument_balance_trade(data): data_broker = dataBroker(data) default_account = data_broker.get_broker_account() print( "Use to fix breaks between instrument strategy and contract level positions" ) strategy_name = get_valid_strategy_name_from_user(data=data) instrument_code = get_valid_instrument_code_from_user(data) fill_qty = get_and_convert("Quantity ", type_expected=int, allow_default=False) filled_price = get_and_convert("Filled price", type_expected=float, allow_default=False) fill_datetime = get_datetime_input("Fill datetime", allow_default=True) instrument_order = instrumentOrder( strategy_name, instrument_code, fill_qty, fill=fill_qty, order_type="balance_trade", filled_price=filled_price, fill_datetime=fill_datetime, ) print(instrument_order) ans = input("Are you sure? (Y/other)") if ans != "Y": return None stack_handler = stackHandlerCreateBalanceTrades(data) stack_handler.create_balance_instrument_trade(instrument_order)
def adjusted_prices(data): instrument_code = get_valid_instrument_code_from_user(data) diag_prices = diagPrices(data) prices = diag_prices.get_adjusted_prices(instrument_code) print(prices) return None
def interactive_update_roll_status(): """ Update the roll state for a particular instrument This includes the option, where possible, to switch the adjusted price series on to a new contract :param instrument_code: str :return: None """ with dataBlob(log_name="Interactive_Update-Roll-Status") as data: do_another = True while do_another: instrument_code = get_valid_instrument_code_from_user(data=data) data.log.setup(instrument_code=instrument_code) # First get the roll info # This will also update to console run_roll_report(data, instrument_code) roll_data = get_required_roll_state(data, instrument_code) if roll_data is no_state_available: exit() roll_state_required = roll_data.required_state modify_roll_state(data, instrument_code, roll_state_required) if roll_state_required is roll_adj_state: roll_adjusted_prices(data, instrument_code, roll_data.original_roll_status) ans = input("Another <type anything> ? or <RETURN> to exit: ") if ans == "": do_another = False return success
def roll_report(data): instrument_code = get_valid_instrument_code_from_user( data, allow_all=True, all_code=ALL_ROLL_INSTRUMENTS ) report_config = email_or_print_or_file(roll_report_config) report_config.modify_kwargs(instrument_code=instrument_code) run_report(report_config, data=data)
def update_instrument_override(data): update_overrides = updateOverrides(data) instrument_code = get_valid_instrument_code_from_user(data) new_override = get_overide_object_from_user() ans = input("Are you sure? (y/other)") if ans =="y": update_overrides.update_override_for_instrument(instrument_code, new_override)
def spreads(data): instrument_code = get_valid_instrument_code_from_user(data) diag_prices = diagPrices(data) spreads = diag_prices.get_spreads(instrument_code) print(spreads) return None
def view_instrument_config(data): instrument_code = get_valid_instrument_code_from_user(data) diag_instruments = diagInstruments(data) meta_data = diag_instruments.get_meta_data(instrument_code) print(meta_data) data_broker = dataBroker(data) instrument_broker_data = data_broker.get_brokers_instrument_with_metadata(instrument_code) print(instrument_broker_data)
def change_limit_for_instrument(data): trade_limits = dataTradeLimits(data) instrument_code = get_valid_instrument_code_from_user(data) period_days = get_and_convert("Period of days?", type_expected=int, allow_default=True, default_value = 1) new_limit = get_and_convert("Limit (in contracts?)", type_expected=int, allow_default=False) ans = input("Update will change number of trades allowed in periods, but won't reset 'clock'. Are you sure? (y/other)") if ans =="y": trade_limits.update_instrument_limit_with_new_limit(instrument_code, period_days, new_limit)
def update_strategy_instrument_override(data): view_overrides(data) update_overrides = updateOverrides(data) instrument_code = get_valid_instrument_code_from_user(data) strategy_name = get_valid_strategy_name_from_user(data=data) new_override = get_overide_object_from_user() ans = input("Are you sure? (y/other)") if ans == "y": update_overrides.update_override_for_strategy_instrument( strategy_name, instrument_code, new_override)
def change_position_limit_for_instrument(data): data_position_limits = dataPositionLimits(data) instrument_code = get_valid_instrument_code_from_user(data, allow_all=False) new_position_limit = get_and_convert("New position limit?", type_expected=int, allow_default=True, default_str="No limit", default_value=-1) if new_position_limit==-1: data_position_limits.delete_position_limit_for_instrument(instrument_code) else: new_position_limit = abs(new_position_limit) data_position_limits.set_abs_position_limit_for_instrument(instrument_code, new_position_limit)
def update_strategy_instrument_override(data): view_overrides(data) update_overrides = updateOverrides(data) instrument_code = get_valid_instrument_code_from_user(data) strategy_name = get_valid_strategy_name_from_user(data=data, source="positions") instrument_strategy = instrumentStrategy(instrument_code=instrument_code, strategy_name=strategy_name) new_override = get_overide_object_from_user() ans = input("Are you sure? (y/other)") if ans == "y": update_overrides.update_override_for_instrument_strategy( instrument_strategy=instrument_strategy, new_override=new_override)
def update_roll_status_manual_cycle(data: dataBlob): do_another = True while do_another: instrument_code = get_valid_instrument_code_from_user( data=data, allow_exit=True, exit_code=EXIT_CODE ) if instrument_code is EXIT_CODE: # belt and braces do_another = False else: manually_report_and_update_roll_state_for_code(data, instrument_code) return success
def instrument_locking(data): data_locks = dataLocks(data) list_of_locks = data_locks.get_list_of_locked_instruments() print("Locked %s" % list_of_locks) instrument_code = get_valid_instrument_code_from_user(data) if data_locks.is_instrument_locked(instrument_code): print("Unlock (careful probably locked for a reason, position mismatch!)") ans = input("[Y]es/no ?") if ans == "Y": data_locks.remove_lock_for_instrument(instrument_code) else: print("Lock (Won't create new orders until unlocked!)") ans = input("[Y]es/no ?") if ans == "Y": data_locks.add_lock_for_instrument(instrument_code)
def update_multiple_adjusted_prices(): """ Do a daily update for multiple and adjusted prices :return: Nothing """ with dataBlob(log_name="Update-Multiple-Adjusted-Prices") as data: update_multiple_adjusted_prices_object = updateMultipleAdjustedPrices( data) instrument_code = get_valid_instrument_code_from_user( all_code=ALL_INSTRUMENTS, allow_all=True) update_multiple_adjusted_prices_object.update_multiple_adjusted_prices( instrument_code=instrument_code) return success
def interactive_manual_check_historical_prices(): """ Do a daily update for futures contract prices, using IB historical data If any 'spikes' are found, run manual checks :return: Nothing """ with dataBlob(log_name="Update-Historical-prices-manually") as data: instrument_code = get_valid_instrument_code_from_user(data) check_instrument_ok_for_broker(data, instrument_code) data.log.label(instrument_code=instrument_code) update_historical_prices_with_checks_for_instrument( instrument_code, data) return success
def reset_limit_for_instrument_strategy(data): trade_limits = dataTradeLimits(data) instrument_code = get_valid_instrument_code_from_user(data) period_days = get_and_convert( "Period of days?", type_expected=int, allow_default=True, default_value=1 ) strategy_name = get_valid_strategy_name_from_user(data=data, source="positions") ans = input("Reset means trade 'clock' will restart. Are you sure? (y/other)") if ans == "y": instrument_strategy = instrumentStrategy( instrument_code=instrument_code, strategy_name=strategy_name ) trade_limits.reset_instrument_strategy_limit( instrument_strategy=instrument_strategy, period_days=period_days )
def interactive_update_roll_status(): """ Update the roll state for a particular instrument This includes the option, where possible, to switch the adjusted price series on to a new contract :param instrument_code: str :return: None """ with dataBlob(log_name="Interactive_Update-Roll-Status") as data: instrument_code = get_valid_instrument_code_from_user(data=data) # First get the roll info # This will also update to console config = roll_report_config.new_config_with_modified_output("console") config.modify_kwargs(instrument_code=instrument_code) report_results = run_report_with_data_blob(config, data) if report_results is failure: print("Can't run roll report, so can't change status") return failure current_roll_status, roll_state_required = get_required_roll_state( data, instrument_code) if roll_state_required is no_state_available: return failure update_positions = updatePositions(data) update_positions.set_roll_state(instrument_code, roll_state_required) if roll_state_required is roll_adj_state: # Going to roll adjusted prices roll_result = _roll_adjusted_and_multiple_prices( data, instrument_code) if roll_result is success: # Return the state back to default (no roll) state data.log.msg( "Successful roll! Returning roll state of %s to %s" % (instrument_code, default_state)) update_positions.set_roll_state(instrument_code, default_state) else: data.log.msg( "Something has gone wrong with rolling adjusted of %s! Returning roll state to previous state of %s" % (instrument_code, current_roll_status)) update_positions.set_roll_state(instrument_code, current_roll_status) return success
def get_valid_instrument_code_and_contractid_from_user( data: dataBlob, instrument_code: str = None, only_include_priced_contracts: bool = False, ) -> (str, str): diag_contracts = dataContracts(data) invalid_input = True while invalid_input: if instrument_code is None: instrument_code = get_valid_instrument_code_from_user( data, source="single") dates_to_choose_from = get_dates_to_choose_from( data=data, instrument_code=instrument_code, only_priced_contracts=only_include_priced_contracts, ) if len(dates_to_choose_from) == 0: print("%s is not an instrument with contract data" % instrument_code) instrument_code = None continue dates_to_display = ( diag_contracts. get_labelled_list_of_contracts_from_contract_date_list( instrument_code, dates_to_choose_from)) print("Available contract dates %s" % str(dates_to_display)) print("p = currently priced, c=current carry, f= current forward") contract_date = input( "Contract date? [yyyymm or yyyymmdd] (ignore suffixes)") if len(contract_date) == 6: contract_date = contract_date + "00" if contract_date in dates_to_choose_from: break else: print("%s is not in list %s" % (contract_date, dates_to_choose_from)) continue # not required return instrument_code, contract_date
def get_valid_instrument_code_and_contractid_from_user( data, instrument_code=None, include_priced_contracts=False): diag_contracts = diagContracts(data) diag_prices = diagPrices(data) invalid_input = True while invalid_input: if instrument_code is None: instrument_code = get_valid_instrument_code_from_user( data, source='single') if include_priced_contracts: dates_to_choose_from = diag_prices.contract_dates_with_price_data_for_instrument_code( instrument_code) else: contract_list = diag_contracts.get_all_contract_objects_for_instrument_code( instrument_code) dates_to_choose_from = contract_list.list_of_dates() dates_to_display = diag_contracts.get_labelled_list_of_contracts_from_contract_date_list( instrument_code, dates_to_choose_from) if len(dates_to_choose_from) == 0: print("%s is not an instrument with contract data" % instrument_code) instrument_code = None continue print("Available contract dates %s" % str(dates_to_display)) print("p = currently priced, c=current carry, f= current forward") contract_date = input( "Contract date? [yyyymm or yyyymmdd] (ignore suffixes)") if len(contract_date) == 6: contract_date = contract_date + "00" if contract_date in dates_to_choose_from: break else: print("%s is not in list %s" % (contract_date, dates_to_choose_from)) continue # not required return instrument_code, contract_date
def interactive_manual_check_historical_prices(): """ Do a daily update for futures contract prices, using IB historical data If any 'spikes' are found, run manual checks :return: Nothing """ with dataBlob(log_name="Update-Historical-prices-manually") as data: do_another = True while do_another: instrument_code = get_valid_instrument_code_from_user( data, source='single') check_instrument_ok_for_broker(data, instrument_code) data.log.label(instrument_code=instrument_code) update_historical_prices_with_checks_for_instrument( instrument_code, data) ans = input("Another <type anything> ? or <RETURN> to exit: ") if ans == "": do_another = False return success
if input_prices is arg_not_supplied: prices = arcticFuturesContractPriceData() else: prices = input_prices dict_of_all_futures_contract_prices = prices.get_all_prices_for_instrument( instrument_code) dict_of_futures_contract_prices = dict_of_all_futures_contract_prices.final_prices( ) print(roll_calendar) # checks - this might fail roll_calendar.check_if_date_index_monotonic() # this should never fail roll_calendar.check_dates_are_valid_for_prices( dict_of_futures_contract_prices) return roll_calendar if __name__ == "__main__": input("Will overwrite existing prices are you sure?! CTL-C to abort") instrument_code = get_valid_instrument_code_from_user(source="single") ## MODIFY DATAPATH IF REQUIRED # build_and_write_roll_calendar(instrument_code, output_datapath=arg_not_supplied) build_and_write_roll_calendar(instrument_code, output_datapath="/home/rob/")