def format_reconcile_data(results_object): """ Put the results into a printable format :param results_dict: dict, keys are different segments :return: """ formatted_output=[] formatted_output.append(header("Reconcile report produced on %s" % (str(datetime.datetime.now())))) table1_df = results_object['positions_mine'] table1 = table('Positions in DB', table1_df) formatted_output.append(table1) table2_df = results_object['positions_ib'] table2 = table('Positions broker', table2_df) formatted_output.append(table2) body_text("Position breaks %s" % results_object['position_breaks']) table3_df = results_object['trades_mine'] table3 = table('Trades in DB', table3_df) formatted_output.append(table3) table4_df = results_object['trades_ib'] table4 = table('Trades from broker', table4_df) formatted_output.append(table4) formatted_output.append(header("END OF STATUS REPORT")) return formatted_output
def format_pandl_data(results_object): """ Put the results into a printable format :param results_dict: dict, keys are instruments, contains roll information :return: """ formatted_output=[] formatted_output.append(header("P&L report produced on %s from %s to %s" % (str(datetime.datetime.now()), str(results_object.start_date), str(results_object.end_date)))) formatted_output.append(body_text("Total p&l is %.3f%%" % results_object.total_capital_pandl)) table1_df = results_object.pandl_for_instruments_across_strategies table1_df = table1_df.round(2) table1 = table('P&L by instrument for all strategies', table1_df) formatted_output.append(table1) formatted_output.append(body_text("Total futures p&l is %.3f%%" % results_object.futures_total)) formatted_output.append(body_text("Residual p&l is %.3f%%" % results_object.residual)) formatted_output.append(header("END OF P&L REPORT")) return formatted_output
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 body_text_abs_total_all_risk_perc_capital(self): instrument_risk_data = self.instrument_risk_data() all_risk_perc_capital = instrument_risk_data.exposure_held_perc_capital abs_total_all_risk_perc_capital = all_risk_perc_capital.abs().sum() return body_text("Sum of abs(notional exposure %% capital) %.1f" % abs_total_all_risk_perc_capital)
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 body_text_abs_total_all_risk_annualised(self): instrument_risk_data = self.instrument_risk_data() all_risk_annualised = instrument_risk_data.annual_risk_perc_capital abs_total_all_risk_annualised = all_risk_annualised.abs().sum() return body_text("Sum of abs(annualised risk %% capital) %.1f" % abs_total_all_risk_annualised)
def body_text_margin_usage(self) -> body_text: margin_usage = self.get_margin_usage() perc_margin_usage = margin_usage * 100.0 body_text_margin_usage = body_text( "Percentage of capital used for margin %.1f%%" % perc_margin_usage) return body_text_margin_usage
def report_system_classic(data, backtest: interactiveBacktest) -> list: """ :param strategy_name: str :param data: dataBlob :param backtest: dataBacktest object populated with a specific backtest :return: list of report format type objects """ strategy_name = backtest.strategy_name timestamp = backtest.timestamp format_output = [] report_header = header( "Strategy report for %s backtest timestamp %s produced at %s" % (strategy_name, timestamp, str(datetime.datetime.now())) ) format_output.append(report_header) format_output = report_system_classic_no_header_or_footer( data, backtest=backtest, format_output=format_output ) format_output.append(body_text("End of report for %s" % strategy_name)) return format_output
def body_text_suggest_changes_to_duplicate_markets(self) -> body_text: list_of_duplicate_markets = self.list_of_duplicate_market_tables() output_text = text_suggest_changes_to_duplicate_markets( list_of_duplicate_markets) output_body_text = body_text(output_text) return output_body_text
def body_text_net_total_all_risk_annualised(self): instrument_risk_data = self.instrument_risk_data() all_risk_annualised = instrument_risk_data.annual_risk_perc_capital net_total_all_risk_annualised = all_risk_annualised.sum() return body_text("Net sum of annualised risk %% capital %.1f " % net_total_all_risk_annualised)
def table_of_cash_slippage(self): cash_slippage = self.cash_slippage if len(cash_slippage) == 0: return body_text("No trades") table_slippage = table("Slippage (In base currency)", cash_slippage) return table_slippage
def table_of_raw_slippage(self): raw_slippage = self.raw_slippage if len(raw_slippage) == 0: return body_text("No trades") table_of_raw_slippage = table("Slippage (ticks per lot)", raw_slippage) return table_of_raw_slippage
def body_text_portfolio_risk_total(self): portfolio_risk_total = get_portfolio_risk_for_all_strategies(self.data) portfolio_risk_total = portfolio_risk_total * 100.0 portfolio_risk_total = portfolio_risk_total.round(1) portfolio_risk_total_text = body_text( "Total risk across all strategies, annualised percentage %.1f" % portfolio_risk_total) return portfolio_risk_total_text
def format_status_data(results_object): """ Put the results into a printable format :param results_dict: dict, keys are different segments :return: """ formatted_output = [] formatted_output.append( header("Status report produced on %s" % (str(datetime.datetime.now())))) table1_df = results_object["process"] table1 = table("Config for process control", table1_df) formatted_output.append(table1) table1a_df = results_object["process2"] table1a = table("Status of process control", table1a_df) formatted_output.append(table1a) table1b_df = results_object["process3"] table1b = table("Status of process control", table1b_df) formatted_output.append(table1b) table2_df = results_object["method"] table2 = table("Status of methods", table2_df) formatted_output.append(table2) table3_df = results_object["price"] table3 = table("Status of adjusted price / FX price collection", table3_df) formatted_output.append(table3) table4_df = results_object["position"] table4 = table("Status of optimal position generation", table4_df) formatted_output.append(table4) table5_df = results_object["limits"] table5 = table("Status of trade limits", table5_df) formatted_output.append(table5) table6_df = results_object["position_limits"] table6 = table("Status of position limits", table6_df) formatted_output.append(table6) table7_df = results_object["overrides"] table7 = table("Status of overrides", table7_df) formatted_output.append(table7) text1 = body_text(results_object["locks"]) formatted_output.append(text1) formatted_output.append(header("END OF STATUS REPORT")) return formatted_output
def table_of_order_delays(self): broker_orders = self.broker_orders if len(broker_orders) == 0: return body_text("No trades") delays = create_delay_df(broker_orders) table_of_delays = table("Delays", delays) return table_of_delays
def table_of_vol_slippage(self): raw_slippage = self.raw_slippage if len(raw_slippage) == 0: return body_text("No trades") vol_slippage = create_vol_norm_slippage_df(raw_slippage, self.data) table_of_vol_slippage = table( "Slippage (normalised by annual vol, BP of annual SR)", vol_slippage) return table_of_vol_slippage
def filter_data_for_max_value_and_return_table(data_with_field, field_column='field', max_value=0, table_header=""): filtered_data = filter_data_for_max_value(data_with_field, field_column=field_column, max_value=max_value) if len(filtered_data) == 0: return body_text("%s: No constraints" % table_header) else: return table(table_header, filtered_data)
def filter_data_for_delays_and_return_table(data_with_datetime, datetime_colum='last_start', table_header="Only delayed data", max_delay_in_days=3): filtered_data = filter_data_for_delays(data_with_datetime, datetime_colum=datetime_colum, max_delay_in_days=max_delay_in_days) if len(filtered_data) == 0: return body_text("%s: No delays" % table_header) else: return table(table_header, filtered_data)
def list_of_cash_summary_text(self) -> list: cash_slippage = self.cash_slippage if len(cash_slippage) == 0: return [body_text("No trades")] item_list = [ "delay_cash", "bid_ask_cash", "execution_cash", "versus_limit_cash", "versus_parent_limit_cash", "total_trading_cash", ] detailed_cash_results = get_stats_for_slippage_groups( cash_slippage, item_list) list_of_summary_results = [ body_text("%s\n%s" % (key, str(value))) for key, value in detailed_cash_results.items() ] return list_of_summary_results
def roll_info(data, instrument_code=ALL_ROLL_INSTRUMENTS): """ Get some roll info. For all markets which are: - currently rolling - need to have roll status changed now or in the near future We calculate: - Volume data - Curve data - Length to expiry data (contract and/or carry) - Current roll status - Suggested roll status :param: data blob :return: list of pd.DataFrame """ reporting_api = reportingApi(data) formatted_output = [] formatted_output.append(reporting_api.terse_header("Roll report")) formatted_output.append(reporting_api.table_of_roll_data(instrument_code)) formatted_output.append( body_text( "Roll_exp is days until preferred roll set by roll parameters. Prc_exp is days until price contract expires, " "Crry_exp is days until carry contract expires")) formatted_output.append( body_text("Contract suffix: p=price, f=forward, c=carry")) formatted_output.append( body_text( "Contract volumes over recent days, normalised so largest volume is 1.0" )) formatted_output.append(reporting_api.footer()) return formatted_output
def costs_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.std_header("Costs report")) formatted_output.append(COSTS_REPORT_TEXT) 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 format_trades_data(results_object): """ Put the results into a printable format :param results_dict: dict, keys are different segments :return: """ formatted_output = [] formatted_output.append( header("Trades report produced on %s" % (str(datetime.datetime.now())))) if len(results_object["overview"]) == 0: formatted_output.append(body_text("No trades in relevant period")) return formatted_output table1_df = results_object["overview"] table1 = table("Broker orders", table1_df) formatted_output.append(table1) table2_df = results_object["delays"] table2 = table("Delays", table2_df) formatted_output.append(table2) table3_df = results_object["raw_slippage"] table3 = table("Slippage (ticks per lot)", table3_df) formatted_output.append(table3) table4_df = results_object["vol_slippage"] table4 = table("Slippage (normalised by annual vol, BP of annual SR)", table4_df) formatted_output.append(table4) table5_df = results_object["cash_slippage"] table5 = table("Slippage (In base currency)", table5_df) formatted_output.append(table5) summary_results_dict = results_object["summary_dict"] for summary_table_name, summary_table_item in summary_results_dict.items(): summary_table = table("Summary %s" % summary_table_name, summary_table_item) formatted_output.append(summary_table) return formatted_output
def table_of_orders_overview(self): broker_orders = self.broker_orders if len(broker_orders) == 0: return body_text("No trades") overview = broker_orders[[ "instrument_code", "strategy_name", "contract_date", "fill_datetime", "fill", "filled_price", ]] overview = overview.sort_values("instrument_code") overview_table = table("Broker orders", overview) return overview_table
def format_status_data(results_object): """ Put the results into a printable format :param results_dict: dict, keys are different segments :return: """ formatted_output=[] formatted_output.append(header("Status report produced on %s" % (str(datetime.datetime.now())))) table1_df = results_object['process'] table1 = table('Status of processses', table1_df) formatted_output.append(table1) table2_df = results_object['method'] table2 = table('Status of methods', table2_df) formatted_output.append(table2) table3_df = results_object['price'] table3 = table('Status of adjusted price / FX price collection', table3_df) formatted_output.append(table3) table4_df = results_object['position'] table4 = table('Status of optimal position generation', table4_df) formatted_output.append(table4) table5_df = results_object['limits'] table5 = table('Status of trade limits', table5_df) formatted_output.append(table5) table6_df = results_object['overrides'] table6 = table('Status of overrides', table6_df) formatted_output.append(table6) text1 = body_text(results_object['locks']) formatted_output.append(text1) formatted_output.append(header("END OF STATUS REPORT")) return formatted_output
def format_reconcile_data(results_object): """ Put the results into a printable format :param results_dict: dict, keys are different segments :return: """ formatted_output = [] formatted_output.append( header( "Reconcile report produced on %s" % (str( datetime.datetime.now())))) table0_df = results_object["positions_optimal"] table0 = table("Optimal versus actual positions", table0_df) formatted_output.append(table0) table1_df = results_object["positions_mine"] table1 = table("Positions in DB", table1_df) formatted_output.append(table1) table2_df = results_object["positions_ib"] table2 = table("Positions broker", table2_df) formatted_output.append(table2) text1 = body_text(results_object["position_breaks"]) formatted_output.append(text1) table3_df = results_object["trades_mine"] table3 = table("Trades in DB", table3_df) formatted_output.append(table3) table4_df = results_object["trades_ib"] table4 = table("Trades from broker", table4_df) formatted_output.append(table4) formatted_output.append(header("END OF STATUS REPORT")) return formatted_output
def format_costs_data(costs_report_data: dict) -> list: formatted_output = [] formatted_output.append( header("Costs report produced on %s from %s to %s" % (str(datetime.datetime.now()), costs_report_data['start_date'], costs_report_data['end_date']))) formatted_output.append(body_text("* indicates currently held position")) table1_df = costs_report_data['combined_df_costs'] table1 = table("Check of slippage", table1_df) formatted_output.append(table1) table2_df = costs_report_data['table_of_SR_costs'] table2 = table( "SR costs (using stored slippage): more than 0.01 means panic", table2_df) formatted_output.append(table2) return formatted_output
def report_system_dynamic(data: dataBlob, backtest: interactiveBacktest): format_output = [] strategy_name = backtest.strategy_name timestamp = backtest.timestamp optimal_positions_df = get_optimal_positions_table_as_df( data=data, strategy_name=backtest.strategy_name) optimal_positions_table = table("Optimal positions", optimal_positions_df) format_output.append(optimal_positions_table) report_header = header( "Strategy report for %s backtest timestamp %s produced at %s" % (strategy_name, timestamp, str(datetime.datetime.now()))) format_output.append(report_header) format_output = report_system_classic_no_header_or_footer( data, backtest=backtest, format_output=format_output) format_output.append(body_text("End of report for %s" % strategy_name)) return format_output
def format_liquidity_data(liquidity_report_data: dict) -> list: formatted_output = [] all_liquidity_df = liquidity_report_data['all_liquidity_df'] formatted_output.append( header("Liquidity report produced on %s" % (str(datetime.datetime.now())))) formatted_output.append(body_text("* indicates currently held position")) table1_df = all_liquidity_df.sort_values("contracts") table1 = table( " Sorted by contracts: Less than 100 contracts a day is a problem", table1_df) formatted_output.append(table1) table2_df = all_liquidity_df.sort_values("risk") table2 = table( "Sorted by risk: Less than $1.5 million of risk per day is a problem", table2_df) formatted_output.append(table2) return formatted_output
def format_risk_report(results_dict): """ Put the results into a printable format :param results_dict: dict of risk tables :return: """ formatted_output = [] formatted_output.append( header("Risk report produced on %s" % str(datetime.datetime.now()))) result1 = results_dict['portfolio_risk_total'] * 100 result1_text = body_text( "Total risk across all strategies, annualised percentage %.1f" % result1) formatted_output.append(result1_text) table2_df = results_dict['strategy_risk'] * 100 table2_df = table2_df.round(1) table2 = table("Risk per strategy, annualised percentage", table2_df) formatted_output.append(table2) table3_df = results_dict['instrument_risk_data'] table3_df = table3_df.round(1) table3 = table("Instrument risk", table3_df) formatted_output.append(table3) table4_df = results_dict['corr_data'] table4_df = table4_df.round(2) table4 = table("Correlations", table4_df) formatted_output.append(table4) formatted_output.append(header("END OF RISK REPORT")) return formatted_output
def report_system_classic(data, data_backtest): """ :param strategy_name: str :param data: dataBlob :param data_backtest: dataBacktest object populated with a specific backtest :return: list of report format type objects """ strategy_name = data_backtest.strategy_name format_output = [] report_header = header( "Strategy report for %s backtest timestamp %s produced at %s" % (strategy_name, data_backtest.timestamp, str( datetime.datetime.now()))) format_output.append(report_header) unweighted_forecasts_df = get_forecast_matrix( data_backtest, stage_name="forecastScaleCap", method_name="get_capped_forecast") unweighted_forecasts_df_rounded = unweighted_forecasts_df.round(1) unweighted_forecasts_table = table( "Unweighted forecasts", unweighted_forecasts_df_rounded ) format_output.append(unweighted_forecasts_table) # Forecast weights forecast_weights_df = get_forecast_matrix_over_code( data_backtest, stage_name="combForecast", method_name="get_forecast_weights") forecast_weights_df_as_perc = forecast_weights_df * 100 forecast_weights_df_as_perc_rounded = forecast_weights_df_as_perc.round(1) forecast_weights_table = table( "Forecast weights", forecast_weights_df_as_perc_rounded ) format_output.append(forecast_weights_table) # Weighted forecast weighted_forecasts_df = forecast_weights_df * unweighted_forecasts_df weighted_forecast_rounded = weighted_forecasts_df.round(1) weighted_forecast_table = table( "Weighted forecasts", weighted_forecast_rounded) format_output.append(weighted_forecast_table) # Cash target cash_target_dict = data_backtest.system.positionSize.get_daily_cash_vol_target() cash_target_text = body_text( "\nVol target calculation %s\n" % cash_target_dict) format_output.append(cash_target_text) # Vol calc vol_calc_df = get_stage_breakdown_over_codes( data_backtest, method_list=[ daily_returns_vol, daily_denom_price, rawdata_daily_perc_vol], ) vol_calc_df["annual % vol"] = vol_calc_df["Daily % vol"] * \ ROOT_BDAYS_INYEAR vol_calc_df_rounded = vol_calc_df.round(4) vol_calc_table = table("Vol calculation", vol_calc_df_rounded) format_output.append(vol_calc_table) # Subsystem position table subystem_positions_df = get_stage_breakdown_over_codes( data_backtest, method_list=[ get_block_value, get_price_volatility, get_instrument_ccy_vol, get_fx_rate, get_instrument_value_vol, get_daily_cash_vol_target, get_vol_scalar, get_combined_forecast, get_subsystem_position, ], ) subystem_positions_df_rounded = subystem_positions_df.round(2) subystem_positions_table = table( "Subsystem position", subystem_positions_df_rounded ) format_output.append(subystem_positions_table) # Portfolio position table: ss position, instr weight, IDM, position # required portfolio_positions_df = get_stage_breakdown_over_codes( data_backtest, method_list=[ get_subsystem_position, get_instrument_weights, get_idm, get_required_portfolio_position, ], ) portfolio_positions_df_rounded = portfolio_positions_df.round(3) portfolio_positions_table = table( "Portfolio positions", portfolio_positions_df_rounded ) format_output.append(portfolio_positions_table) # position diags position_diags_df = calc_position_diags(portfolio_positions_df, subystem_positions_df) position_diags_df_rounded = position_diags_df.round(2) position_diags_table = table("Position diags", position_diags_df_rounded) format_output.append(position_diags_table) # Position vs buffer table: position required, buffers, actual position versus_buffers_df = get_stage_breakdown_over_codes( data_backtest, method_list=[ get_required_portfolio_position, get_lower_buffer, get_upper_buffer, ], ) instrument_code_list = versus_buffers_df.index timestamp_positions = get_position_at_timestamp_df_for_instrument_code_list( data_backtest, data, instrument_code_list) current_positions = get_current_position_df_for_instrument_code_list( data_backtest, data, instrument_code_list ) versus_buffers_and_positions_df = pd.concat( [versus_buffers_df, timestamp_positions, current_positions], axis=1 ) versus_buffers_and_positions_df_rounded = versus_buffers_and_positions_df.round( 1) versus_buffers_and_positions_table = table( "Positions vs buffers", versus_buffers_and_positions_df_rounded ) format_output.append(versus_buffers_and_positions_table) format_output.append(body_text("End of report for %s" % strategy_name)) return format_output