def get_list_of_timer_functions_for_capital_update(): data_total_capital = dataBlob(log_name="update_total_capital") data_strategy_capital = dataBlob(log_name="strategy_allocation") total_capital_update_object = totalCapitalUpdate(data_total_capital) strategy_capital_update_object = updateStrategyCapital( data_strategy_capital) list_of_timer_names_and_functions = [ ("update_total_capital", total_capital_update_object), ("strategy_allocation", strategy_capital_update_object), ] return list_of_timer_names_and_functions
def get_list_of_timer_functions_for_backup(): data_arctic_backups = dataBlob(log_name="backup_arctic_to_csv") data_backup_files = dataBlob(log_name="backup_files") arctic_backup_object = backupArcticToCsv(data_arctic_backups) files_backup_object = backupFiles(data_backup_files) list_of_timer_names_and_functions = [ ("backup_arctic_to_csv", arctic_backup_object), ("backup_files", files_backup_object), ] return list_of_timer_names_and_functions
def liquidity_report(data: dataBlob = arg_not_supplied): if data is arg_not_supplied: data = dataBlob() if data is arg_not_supplied: data = dataBlob() reporting_api = reportingApi(data) formatted_output = [] formatted_output.append(reporting_api.terse_header("Liquidity report")) formatted_output.append(reporting_api.table_of_liquidity_contract_sort()) formatted_output.append(reporting_api.table_of_liquidity_risk_sort()) formatted_output.append(reporting_api.footer()) return formatted_output
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 __init__(self, data=arg_not_supplied): # Check data has the right elements to do this if data is arg_not_supplied: data = dataBlob() data.add_class_object(mongoOptimalPositionData) self.data = data
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)
def __init__(self, start_date=None, end_date=None, log=logtoscreen("csvFuturesSimTestData")): data = dataBlob( log=log, csv_data_paths=dict( csvFuturesAdjustedPricesData="data.test.adjusted_prices_csv", csvFuturesInstrumentData="data.test.csvconfig", ), class_list=[ csvFuturesAdjustedPricesData, csvFuturesMultiplePricesData, csvFuturesInstrumentData, csvFxPricesData, csvRollParametersData, ], ) super().__init__(data=data) if start_date is not None: self._start_date = start_date else: self._start_date = ARBITRARY_START if end_date is not None: self._end_date = end_date else: self._end_date = self.DEFAULT_END_DATE
def risk_report(data: dataBlob = arg_not_supplied): """ Get risk report info """ if data is arg_not_supplied: data = dataBlob() reporting_api = reportingApi(data) formatted_output = [] formatted_output.append(reporting_api.terse_header("Risk report")) list_of_func_names = [ "body_text_portfolio_risk_total", "body_text_margin_usage", "table_of_strategy_risk", "table_of_instrument_risk", "body_text_abs_total_all_risk_perc_capital", "body_text_abs_total_all_risk_annualised", "body_text_net_total_all_risk_annualised", "table_of_correlations", ] for func_name in list_of_func_names: func = getattr(reporting_api, func_name) formatted_output.append(func()) formatted_output.append(reporting_api.footer()) return formatted_output
def get_valid_fx_code_from_user(data=arg_not_supplied): if data is arg_not_supplied: data = dataBlob() all_fx_codes = get_list_of_fxcodes(data) fx_code = print_menu_of_values_and_get_response(all_fx_codes) return fx_code
def reconcile_info(data=arg_not_supplied): """ Report on system status :param: data blob :return: list of formatted output items """ if data is arg_not_supplied: data = dataBlob() reporting_api = reportingApi(data) formatted_output = [] formatted_output.append(reporting_api.terse_header("Reconcile report")) list_of_func_names = [ "body_text_position_breaks", "table_of_my_positions", "table_of_ib_positions", "table_of_my_recent_trades_from_db", "table_of_recent_ib_trades", "table_of_optimal_positions" ] for func_name in list_of_func_names: func = getattr(reporting_api, func_name) formatted_output.append(func()) formatted_output.append(reporting_api.footer()) return formatted_output
def __init__(self, data=arg_not_supplied): # Check data has the right elements to do this if data is arg_not_supplied: data = dataBlob() data.add_class_object(mongoFuturesInstrumentData) self.data = data
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 remove_markets_report(data: dataBlob = arg_not_supplied, ): if data is arg_not_supplied: data = dataBlob() reporting_api = reportingApi(data) formatted_output = [] formatted_output.append( reporting_api.terse_header("Removed markets report")) formatted_output.append(HEADER_TEXT) list_of_func_names = [ "body_text_existing_markets_remove", "body_text_removed_markets_addback", "body_text_expensive_markets", "body_text_markets_without_enough_volume_risk", "body_text_markets_without_enough_volume_contracts", "body_text_too_safe_markets", "body_text_explain_safety" ] for func_name in list_of_func_names: func = getattr(reporting_api, func_name) formatted_output.append(func()) formatted_output.append(body_text("\n\n")) formatted_output.append(reporting_api.footer()) return formatted_output
def duplicate_market_report( data: dataBlob = arg_not_supplied, ): if data is arg_not_supplied: data = dataBlob() reporting_api = reportingApi( data ) formatted_output = [] formatted_output.append(reporting_api.terse_header("Duplicate markets report")) formatted_output.append(HEADER_TEXT) list_of_duplicate_market_tables = reporting_api.list_of_duplicate_market_tables() formatted_output.append(reporting_api.body_text_suggest_changes_to_duplicate_markets()) formatted_output = formatted_output + list_of_duplicate_market_tables formatted_output.append(reporting_api.footer()) return formatted_output
def interactive_update_capital_manual(): """ Interactive session that allows you to manipulate capital manually :return: Nothing """ with dataBlob(log_name="Interactive-Update-Capital-Manual") as data: still_running = True while still_running: # display capital and get input user_option_int = print_capital_and_get_user_input(data) function_list = [ finished, setup_initial_capital, update_capital_from_ib, adjust_capital_for_delta, modify_any_value, delete_capital_since_time, delete_all_capital ] try: function_to_run = function_list[user_option_int] except IndexError: print("%d is not a valid option" % str(user_option_int)) function_to_run(data) # Back to top of while loop return success
def __init__(self, data: dataBlob = arg_not_supplied): # Check data has the right elements to do this if data is arg_not_supplied: data = dataBlob() data.add_class_object(arcticFxPricesData) self.data = data
def run_stack_handler(): process_name = "run_stack_handler" data = dataBlob(log_name=process_name) list_of_timer_names_and_functions = get_list_of_timer_functions_for_stack_handler() price_process = processToRun( process_name, data, list_of_timer_names_and_functions) price_process.run_process()
def get_list_of_timer_functions_for_cleaning(): data_backtests = dataBlob(log_name="clean_backtest_states") data_echos = dataBlob(log_name="clean_echo_files") data_logs = dataBlob(log_name="clean_log_files") backtest_clean_object = cleanTruncateBacktestStates(data_backtests) log_clean_object = cleanTruncateLogFiles(data_logs) echo_clean_object = cleanTruncateEchoFiles(data_echos) list_of_timer_names_and_functions = [ ("clean_backtest_states", backtest_clean_object), ("clean_echo_files", echo_clean_object), ("clean_log_files", log_clean_object), ] return list_of_timer_names_and_functions
def get_list_of_timer_functions_for_backup(): data_arctic_backups = dataBlob(log_name="backup_arctic_to_csv") data_state_files = dataBlob(log_name="backup_files") data_mongo_dump = dataBlob(log_name = "backup_mongo_data_as_dump") arctic_backup_object = backupArcticToCsv(data_arctic_backups) statefile_backup_object = backupStateFiles(data_state_files) mongodump_backup_object = backupMongo(data_mongo_dump) list_of_timer_names_and_functions = [ ("backup_arctic_to_csv", arctic_backup_object), ("backup_mongo_data_as_dump", mongodump_backup_object), ("backup_files", statefile_backup_object) ] return list_of_timer_names_and_functions
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 run_backups(): process_name = "run_backups" data = dataBlob(log_name=process_name) list_of_timer_names_and_functions = get_list_of_timer_functions_for_backup() backup_process = processToRun( process_name, data, list_of_timer_names_and_functions) backup_process.main_loop()
def system_status(data: dataBlob = arg_not_supplied): """ Report on system status :param: data blob :return: list of formatted output items """ if data is arg_not_supplied: data = dataBlob() reporting_api = reportingApi(data) formatted_output = [] formatted_output.append(reporting_api.terse_header("Status report")) list_of_func_names = [ "table_of_control_config_list_for_all_processes", "table_of_control_status_list_for_all_processes", "table_of_process_status_list_for_all_processes", "table_of_control_data_list_for_all_methods", "table_of_last_price_updates", "table_of_last_optimal_position_updates", "table_of_trade_limits", "table_of_position_limits", "table_of_overrides", "body_text_of_position_locks", ] for func_name in list_of_func_names: func = getattr(reporting_api, func_name) formatted_output.append(func()) formatted_output.append(reporting_api.footer()) return formatted_output
def __init__(self, data=arg_not_supplied): # Check data has the right elements to do this if data is arg_not_supplied: data = dataBlob() data.add_class_object(mongoIbBrokerClientIdData) self.data = data
def get_strategy_method(data: dataBlob, strategy_name: str, process_name: str, function_name: str): config_this_process = get_strategy_class_object_config( data, process_name, strategy_name) strategy_class_object = resolve_function(config_this_process.pop("object")) # following are used by run process but not by us _ = config_this_process.pop("max_executions", None) _ = config_this_process.pop("frequency", None) # might be in old config files unused_config_function = config_this_process.pop("function", None) if unused_config_function is not None: #FIXME REMOVE CHECK AT SOME POINT data.log.warn( "Remove function from strategy run_systems configuration no longer uses!" ) other_args = config_this_process strategy_data = dataBlob(log_name=process_name) strategy_data.log.label(strategy_name=strategy_name) strategy_class_instance = strategy_class_object(strategy_data, strategy_name, **other_args) method = getattr(strategy_class_instance, function_name) return method
def instrument_risk_report( data: dataBlob = arg_not_supplied, ): if data is arg_not_supplied: data = dataBlob() reporting_api = reportingApi( data ) formatted_output = [] formatted_output.append( reporting_api.terse_header("Instrument risk report")) formatted_output.append(HEADER_TEXT) formatted_output.append(reporting_api.table_of_risk_all_instruments(sort_by='annual_perc_stdev', table_header="Risk of all instruments with data - sorted by annualised % standard deviation")) formatted_output.append(reporting_api.table_of_risk_all_instruments(sort_by='annual_risk_per_contract', table_header ="Risk of all instruments with data - sorted by annualised currency risk per contract")) formatted_output.append(reporting_api.table_of_risk_all_instruments(sort_by='contract_exposure', table_header ="Risk of all instruments with data - sorted by notional exposure per contract")) formatted_output.append(reporting_api.footer()) return formatted_output
def __init__(self, data=arg_not_supplied): # Check data has the right elements to do this if data is arg_not_supplied: data = dataBlob() data.add_class_object(mongoControlProcessData) self.data = data
def costs_report( data: dataBlob = arg_not_supplied, calendar_days_back: int = 250, end_date: datetime.datetime = arg_not_supplied, start_date: datetime.datetime = arg_not_supplied, ): if data is arg_not_supplied: data = dataBlob() reporting_api = reportingApi( data, start_date=start_date, end_date=end_date, calendar_days_back=calendar_days_back, ) formatted_output = [] formatted_output.append(reporting_api.std_header("Costs report")) formatted_output.append(reporting_api.table_of_slippage_comparison()) formatted_output.append(body_text("* indicates currently held position")) formatted_output.append(reporting_api.table_of_sr_costs()) formatted_output.append(body_text("* indicates currently held position")) formatted_output.append(reporting_api.footer()) return formatted_output
def get_valid_instrument_code_from_user( data: dataBlob=arg_not_supplied, allow_all: bool=False, all_code = "ALL", source = 'multiple') -> str: if data is arg_not_supplied: data = dataBlob() instrument_code_list = get_list_of_instruments(data, source=source) invalid_input = True input_prompt = "Instrument code?" if allow_all: input_prompt = input_prompt + "(Return for ALL)" while invalid_input: instrument_code = input(input_prompt) if allow_all: if instrument_code == "" or instrument_code == "ALL": return all_code if instrument_code in instrument_code_list: break print("%s is not in list %s derived from source: %s" % (instrument_code, instrument_code_list, source)) return instrument_code
def trades_info( data=arg_not_supplied, calendar_days_back=1, end_date=arg_not_supplied, start_date=arg_not_supplied, ): """ Report on system status :param: data blob :return: list of formatted output items """ if data is arg_not_supplied: data = dataBlob() if end_date is arg_not_supplied: end_date = datetime.datetime.now() if start_date is arg_not_supplied: start_date = end_date - datetime.timedelta(days=calendar_days_back) results_object = get_trades_report_data(data, start_date=start_date, end_date=end_date) formatted_output = format_trades_data(results_object) return formatted_output
def run_reports(): process_name = "run_reports" data = dataBlob(log_name=process_name) list_of_timer_names_and_functions = get_list_of_timer_functions_for_reports( data) price_process = processToRun(process_name, data, list_of_timer_names_and_functions) price_process.run_process()