def test_create_tca_report(fill_market_trade_databases): """Tests the creation of a TCAResults, checking they are fichecking it generates the right document """ Mediator.get_volatile_cache().clear_cache() tca_request = TCARequest( start_date=start_date, finish_date=finish_date, ticker=ticker, trade_data_store=trade_data_store, trade_data_database_name=trade_data_database_name, market_data_store=market_data_store, market_data_database_table=market_data_database_table, trade_order_mapping=trade_order_mapping, metric_calcs=MetricSlippage(), results_form=TimelineResultsForm(metric_name='slippage', by_date='datehour'), use_multithreading=use_multithreading) tca_engine = TCAEngineImpl(version=tcapy_version) tca_results = TCAResults(tca_engine.calculate_tca(tca_request=tca_request), tca_request) tca_results.render_computation_charts() assert tca_results.timeline is not None and tca_results.timeline_charts is not None tca_report = TCAReport(tca_results) html = tca_report.create_report() # Quick check to see that the html has been generated by checking existance of HTML head _tag assert '<head>' in html
def multiple_ticker_tca_aggregated_with_results_example(): """Example of how to do TCa analysis on multiple tickers with TCAResults """ tca_engine = TCAEngineImpl(version=tca_version) # Run a TCA computation for multiple tickers, calculating slippage tca_request = TCARequest(start_date=start_date, finish_date=finish_date, ticker=mult_ticker, tca_type='aggregated', trade_data_store=trade_data_store, market_data_store=market_data_store, results_form=[ TimelineResultsForm(metric_name='slippage', by_date='datehour', scalar=10000.0) ], metric_calcs=MetricSlippage(), reporting_currency='EUR', summary_display='candlestick') dict_of_df = tca_engine.calculate_tca(tca_request) # Show the output of objects print(dict_of_df.keys()) ### Generate TCA report using high level object # Use higher level TCAResults object to encapsulate results (easier to deal with than a dictionary of DataFrames) tca_results = TCAResults(dict_of_df, tca_request) tca_results.render_computation_charts() print(tca_results.sparse_market_charts.keys()) print(tca_results.sparse_market.keys())
def single_ticker_tca_example_1600LDN_benchmark(): tca_engine = TCAEngineImpl(version=tca_version) trade_order_type = 'trade_df' trade_order_list = ['trade_df', 'order_df'] # specify the TCA request tca_request = TCARequest( start_date=start_date, finish_date=finish_date, ticker=ticker, tca_type='detailed', dummy_market=False, trade_data_store=trade_data_store, market_data_store=market_data_store, metric_calcs=[ # Calculate the slippage for trades/order MetricSlippage(trade_order_list=trade_order_list, bid_benchmark='twap1600LDN', ask_benchmark='twap1600LDN', metric_post_fix='twap1600LDN') ], results_form=[ # Aggregate the slippage average by date and hour TimelineResultsForm(metric_name='slippagetwap1600LDN', by_date='date', scalar=10000.0) ], benchmark_calcs=[ # At the arrival price for every trade/order BenchmarkArrival(), # Calculate TWAP over 16:00 LDN BenchmarkTWAP(start_time_before_offset={'m': 2}, finish_time_after_offset={'s': 30}, overwrite_time_of_day='16:00', overwrite_timezone='Europe/London', benchmark_post_fix="1600LDN"), # At the spread at the time of every trade/order BenchmarkMarketSpreadToMid() ], extra_lines_to_plot='twap1600LDN', trade_order_mapping=trade_order_list, use_multithreading=True) # Dictionary of dataframes as output from TCA calculation dict_of_df = tca_engine.calculate_tca(tca_request) print(dict_of_df['trade_df'].head(5)) tca_results = TCAResults(dict_of_df, tca_request) tca_results.render_computation_charts() from tcapy.vis.report.computationreport import JinjaRenderer tca_report = TCAReport(tca_results, renderer=JinjaRenderer()) tca_report.create_report(output_filename='test_tca_twap_report.htm', output_format='html', offline_js=False)
def single_ticker_tca_example(): """Example for doing detailed TCA analysis on the trades of a single ticker, calculating metrics for slippage, transient market impact & permanent market impact. It also calculates benchmarks for arrival price of each trade and spread to mid). Creates a TCAReport which generates standalone HTML and PDF files Also on a lower level it collects results for slippage into a daily timeline and also average by venue (by default weights by reporting currency) """ # Note: running Orca might not work in WSL, also when generating Plotly charts, might get an error with WSL, if # it doesn't have silent_display=True, as it will try to open a web page in a browser (which isn't supported in WSL1 # but is in WSL2) PLOT = True # clear entire cache # Mediator.get_volatile_cache().clear_cache() tca_engine = TCAEngineImpl(version=tca_version) trade_order_type = 'trade_df' trade_order_list = ['trade_df', 'order_df'] # Ensure orca is started, if want to convert to PDF (sometimes you may need to specify the path) # Can be slow to start if PLOT: from chartpy.engine import EnginePlotly EnginePlotly().start_orca() # constants.orca_server_path) # specify the TCA request tca_request = TCARequest( start_date=start_date, finish_date=finish_date, ticker=ticker, tca_type='detailed', dummy_market=False, trade_data_store=trade_data_store, market_data_store=market_data_store, metric_calcs=[ # Calculate the slippage for trades/order MetricSlippage(trade_order_list=trade_order_list), # Calculate the shorter and longer term market impact after every trade/order MetricTransientMarketImpact( transient_market_impact_gap={'ms': 100}, trade_order_list=trade_order_list), MetricPermanentMarketImpact(permanent_market_impact_gap={'h': 1}, trade_order_list=trade_order_list) ], results_form=[ # Aggregate the slippage average by date and hour TimelineResultsForm(metric_name='slippage', by_date='datehour', scalar=10000.0), # Aggregate the total executed notional in reporting currency (usually USD) # for every hour TimelineResultsForm( metric_name='executed_notional_in_reporting_currency', by_date='datehour', aggregation_metric='sum', scalar=1.0), # Aggregate the average slippage on trades by venue HeatmapResultsForm( metric_name=['slippage', 'transient_market_impact'], aggregate_by_field=['venue', 'ticker'], scalar=10000.0, trade_order_list='trade_df'), # Aggregate the average slippage on trades by venue BarResultsForm(metric_name='slippage', aggregate_by_field='venue', scalar=10000.0, trade_order_list='trade_df'), # Aggregate the average slippage on trades/orders by broker_id BarResultsForm(metric_name='slippage', aggregate_by_field='broker_id', scalar=10000.0), # Aggregate the average slippage on trades/orders by broker_id DistResultsForm(metric_name='slippage', aggregate_by_field='side', scalar=10000.0), # Create a scatter chart of slippage vs. executed notional ScatterResultsForm(scatter_fields=[ 'slippage', 'executed_notional_in_reporting_currency' ], scalar={'slippage': 10000.0}) ], benchmark_calcs=[ # At the arrival price for every trade/order BenchmarkArrival(), # At the spread at the time of every trade/order BenchmarkMarketSpreadToMid() ], trade_order_mapping=trade_order_list, use_multithreading=True) # Dictionary of dataframes as output from TCA calculation dict_of_df = tca_engine.calculate_tca(tca_request) print(dict_of_df['trade_df']) print(dict_of_df.keys()) # Heatmap of slippage and transient market impact broken down by venue and ticker heatmap_slippage_market_impact_df = dict_of_df[ 'heatmap_' + trade_order_type + '_slippage#transient_market_impact_by/mean/venue#ticker'] print(heatmap_slippage_market_impact_df) # Average slippage per date/hour timeline_slippage_df = dict_of_df['timeline_' + trade_order_type + '_slippage_by/mean_datehour/all'] # Total executed notional per date/hour timeline_executed_notional_df = dict_of_df[ 'timeline_' + trade_order_type + '_executed_notional_in_reporting_currency_by/sum_datehour/all'] # Permanent market impact for every trade metric_df = dict_of_df[trade_order_type]['permanent_market_impact'] print(metric_df.head(500)) from tcapy.vis.report.computationreport import JinjaRenderer if PLOT: ### Generate TCA report using high level object # Use higher level TCAResults object to encapsulate results (easier to deal with than a dictionary of DataFrames) tca_results = TCAResults(dict_of_df, tca_request) tca_results.render_computation_charts() tca_report = TCAReport(tca_results, renderer=JinjaRenderer()) tca_report.create_report(output_filename='test_tca_report.htm', output_format='html', offline_js=False) # Note needs plotly orca + wkhtmltopdf installed to render PDFs try: tca_report.create_report(output_filename='test_tca_report.pdf', output_format='pdf') except Exception as e: print(str(e)) ### Lower level creation of TCA report ### Plot charts individually # Plot slippage by timeline Chart(engine='plotly').plot(timeline_slippage_df) # Plot total executed notional by timeline Chart(engine='plotly').plot(timeline_executed_notional_df) # Plot market impact (per trade) Chart(engine='plotly').plot(metric_df.head(500))
def run_tcapy_computation(): start = time.time() # Collect inputs from Excel & create a reference to the calling Excel Workbook trade_df_sht = xw.Book.caller().sheets[1] trade_df_out_sht = xw.Book.caller().sheets[2] results_sht = xw.Book.caller().sheets[3] # Get the ticker and the API key from Excel start_date = trade_df_sht.range('start_date').value finish_date = trade_df_sht.range('finish_date').value ticker = trade_df_sht.range('ticker').value use_multithreading = trade_df_sht.range('use_multithreading').value pdf_path = trade_df_sht.range('pdf_path').value if "," in ticker: ticker = ticker.split(",") market_data_store = trade_df_sht.range('market_data_store').value # Get the trade_df table as a DataFrame (careful to parse the dates) trade_df = trade_df_sht.range('trade_df_input').options(pd.DataFrame, index=False).value trade_df = trade_df.dropna(subset=['date']) trade_df = trade_df.loc[:, trade_df.columns.notnull()] # Let Pandas parse the date (not Excel, which might miss off some of the field # which is important calculation of metrics etc.) trade_df['date'] = pd.to_datetime(trade_df['date']) trade_df = trade_df.set_index('date') # Push trades as DataFrame to tcapy data_frame_trade_order_mapping = {'trade_df' : trade_df} trade_order_list = ['trade_df'] # Create TCARequest object tca_request = TCARequest(start_date=start_date, finish_date=finish_date, ticker=ticker, trade_data_store='dataframe', trade_order_mapping=data_frame_trade_order_mapping, market_data_store=market_data_store, tca_type='aggregated', metric_calcs=[ # Calculate the slippage for trades/order MetricSlippage(trade_order_list=trade_order_list), # Calculate the shorter and longer term market impact after every trade/order MetricTransientMarketImpact(transient_market_impact_gap={'ms': 100}, trade_order_list=trade_order_list), MetricPermanentMarketImpact(permanent_market_impact_gap={'h': 1}, trade_order_list=trade_order_list)], results_form=[ # Aggregate the slippage average by date and hour TimelineResultsForm(metric_name='slippage', by_date='datehour', scalar=10000.0), # Aggregate the total executed notional in reporting currency (usually USD) # for every hour TimelineResultsForm(metric_name='executed_notional_in_reporting_currency', by_date='datehour', aggregation_metric='sum', scalar=1.0), # Aggregate the average slippage on trades by venue HeatmapResultsForm(metric_name=['slippage', 'transient_market_impact'], aggregate_by_field=['venue', 'ticker'], scalar=10000.0, trade_order_list='trade_df'), # Aggregate the average slippage on trades by venue BarResultsForm(metric_name='slippage', aggregate_by_field='venue', scalar=10000.0, trade_order_list='trade_df'), # Aggregate the average slippage on trades/orders by broker_id BarResultsForm(metric_name='slippage', aggregate_by_field='broker_id', scalar=10000.0), # Aggregate the average slippage on trades/orders by broker_id DistResultsForm(metric_name='slippage', aggregate_by_field='side', scalar=10000.0), # Create a scatter chart of slippage vs. executed notional ScatterResultsForm( scatter_fields=['slippage', 'executed_notional_in_reporting_currency'], scalar={'slippage': 10000.0})], benchmark_calcs=[ # At the arrival price for every trade/order BenchmarkArrival(), # At the spread at the time of every trade/order BenchmarkSpreadToMid()], summary_display='candlestick', use_multithreading=use_multithreading, dummy_market=True) # Kick off calculation and get results dict_of_df = tca_engine.calculate_tca(tca_request) # Create PDF report tca_results = TCAResults(dict_of_df, tca_request) tca_results.render_computation_charts() tca_report = TCAReport(tca_results, renderer=JinjaRenderer()) tca_report.create_report(output_filename=pdf_path, output_format='pdf', offline_js=False) tca_report = TCAReport(tca_results, renderer=XlWingsRenderer(xlwings_sht=results_sht)) tca_report.create_report(output_format='xlwings') finish = time.time() trade_df_sht.range('calculation_status').value = \ 'Calculated ' + str(round(finish - start, 3)) + "s at " + str(datetime.datetime.utcnow()) # Output results trade_df_out_sht.range('trade_df_output').clear_contents() # Print trade_df + additional fields to the spreadsheet (eg. slippage) trade_df_out_sht.range("trade_df_output").value = dict_of_df['trade_df']
def single_ticker_tca_example(): """Example for doing detailed TCA analysis on the trades of a single ticker, calculating metrics for slippage, transient market impact & permanent market impact. It also calculates benchmarks for arrival price of each trade and spread to mid). Creates a TCAReport which generates standalone HTML and PDF files Also on a lower level it collects results for slippage into a daily timeline and also average by venue (by default weights by reporting currency) """ # Note: running Orca might not work in WSL PLOT = False # clear entire cache # Mediator.get_volatile_cache(version='pro').clear_cache() tca_engine = TCAEngineImpl(version=tca_version) trade_order_type = 'trade_df' trade_order_list = ['trade_df'] # Ensure orca is started, if want to convert to PDF (sometimes you may need to specify the path) # Can be slow to start if PLOT: from chartpy.engine import EnginePlotly EnginePlotly().start_orca() # constants.orca_server_path) # specify the TCA request tca_request = TCARequest( start_date=start_date, finish_date=finish_date, ticker=ticker, tca_type='aggregated', dummy_market=False, trade_data_store=trade_data_store, market_data_store=market_data_store, metric_calcs=[ MetricSlippage(trade_order_list=trade_order_list), MetricTransientMarketImpact( transient_market_impact_gap={'ms': 100}, trade_order_list=trade_order_list), MetricPermanentMarketImpact(permanent_market_impact_gap={'h': 1}, trade_order_list=trade_order_list) ], results_form=[ TimelineResultsForm(metric_name='slippage', by_date='datehour', scalar=10000.0), TimelineResultsForm( metric_name='executed_notional_in_reporting_currency', by_date='datehour', aggregation_metric='sum'), BarResultsForm(metric_name='slippage', aggregate_by_field='venue', scalar=10000.0), DistResultsForm(metric_name='slippage', aggregate_by_field='side', scalar=10000.0) ], benchmark_calcs=[BenchmarkArrival(), BenchmarkSpreadToMid()], trade_order_mapping=trade_order_list, use_multithreading=False) # Dictionary of dataframes as output from TCA calculation dict_of_df = tca_engine.calculate_tca(tca_request) print(dict_of_df['trade_df']) print(dict_of_df.keys()) timeline_slippage_df = dict_of_df['timeline_' + trade_order_type + '_slippage_by_all'] timeline_executed_notional_df = dict_of_df[ 'timeline_' + trade_order_type + '_executed_notional_in_reporting_currency_by_all'] # average slippage per day metric_df = dict_of_df[trade_order_type][ 'permanent_market_impact'] # permanent market impact for every trade print(metric_df.head(500)) if PLOT: ### Generate TCA report using high level object # Use higher level TCAResults object to encapsulate results (easier to deal with than a dictionary of DataFrames) tca_results = TCAResults(dict_of_df, tca_request) tca_results.render_computation_charts() tca_report = TCAReport(tca_results) tca_report.create_report(output_filename='test_tca_report.htm', output_format='html') # Note needs plotly orca + wkhtmltopdf installed to render PDFs try: tca_report.create_report(output_filename='test_tca_report.pdf', output_format='pdf') except: pass ### Lower level creation of TCA report from chartpy import Chart, Style, Canvas # Generate HTML file directly Chart(engine='plotly').plot( tca_results.sparse_market_charts['GBPUSD_trade_df'], style=Style(plotly_plot_mode='offline_html')) # Get an HTML string which can be used elsewhere (eg. could use these in other webpages!) html_string = Chart(engine='plotly').plot( tca_results.sparse_market_charts['GBPUSD_trade_df'], style=Style(plotly_plot_mode='offline_embed_js_div')) img_png_string = Chart(engine='plotly').plot( tca_results.sparse_market_charts['GBPUSD_trade_df'], style=Style(plotly_plot_mode='offline_image_png_in_html')) # Using plain template canvas = Canvas([[img_png_string]]) canvas.generate_canvas(silent_display=True, canvas_plotter='plain', page_title='Cuemacro TCA', render_pdf=False) with open('test_tca.html', "w") as text_file: text_file.write(html_string) ### Plot charts individually # Plot slippage by timeline Chart(engine='plotly').plot(timeline_slippage_df) # Plot total executed notional by timeline Chart(engine='plotly').plot(timeline_executed_notional_df) # Plot market impact (per trade) Chart(engine='plotly').plot(metric_df.head(500))