11. Backtester strategy backtesting engine
The Backtester class is used to backtest operator objects.
This class’s attributes include all parameters required for backtest calculations, as well as the result data generated during the backtest. These result data are stored as ndarrays and retained for the lifetime of the object, and can be refreshed repeatedly.
This class can only be instantiated after the operator object has been created, because the Backtester class depends on the operator object to generate trading signals and execute trades. Typical usage is as follows:
operator = Operator( ... ) # 创建Operator对象
backtested = Operator.backtest( signal_count=100, share_count=10, **kwargs) # 创建Backtester对象
# get backtest raw results:
backtested.cash_investment_array
backtested.own_cashes
...
# get backtest results as DataFrame:
result_df = backtested.value_records()
trade_log_df = backtested.trade_logs()
trade_summary_df = backtested.trade_summary()
- class qteasy.backtest.Backtester(op: Operator, shares: list[str], cash_plan: CashPlan, cash_investment_array: ndarray, cash_inflation_array: ndarray, delivery_day_indicators: ndarray, cost_params: ndarray, signal_parsing_params: dict, trading_moq_params: dict, trading_delivery_params: dict, trade_price_data: ndarray, benchmark_data: Optional[Union[DataFrame, Series]] = None, evaluate_price_data: Optional[DataFrame] = None, enable_tracing: bool = False, logger: Optional[Logger] = None)[source]
The Backtester class is used to backtest an operator object. This class’s attributes include all parameters required for backtest calculations, as well as the result data generated during the backtest. These result data are stored as ndarrays and retained for the lifetime of the object, and can be refreshed repeatedly.
This class can only be instantiated after the operator object has been created, because the Backtester class depends on the operator object to generate trading signals and execute trades. Typical usage is as follows:
operator = Operator( ... ) # 创建Operator对象 backtested = Operator.backtest( signal_count=100, share_count=10, **kwargs) # 创建Backtester对象 # get backtest raw results: backtested.cash_investment_array backtested.own_cashes ... # get backtest results as DataFrame: result_df = backtested.value_records() trade_log_df = backtested.trade_logs() trade_summary_df = backtested.trade_summary()
- op
A trading operation object that includes the logic for generating trading signals and executing trades
- Type:
- clear_backtest_buffers()[source]
Clear the cached backtest results data and reset the backtest results data to an empty array so that the backtest can be recalculated.
- Return type:
None
- evaluate_result(indicators: str) dict[source]
Generates an evaluation report of the trading results and saves it in the self.evaluate_result attribute
- Parameters:
indicators (str) – Backtest result evaluation metrics; see the qteasy.evaluate.evaluate() function for details
- generate_trade_logs(save_to_file_path: Optional[str] = None) DataFrame[source]
Generate a trading log based on the backtest results. The trading log is a complete trade record file that contains the following information for each trading period.
Each trading period contains 8 rows of data, as follows:
0, trade signal: the current-period trading signal for each stock1, price: the current-period trading price for each stock2, traded amounts: the current-period traded quantity for each stock; 0 if there is no trade3, cash changed: the current-period cash change amount for each stock; negative for buys and positive for sells4, trade cost: the current-period trading cost for each stock5, own amounts: the end-of-period holdings quantity for each stock6, available amounts: the end-of-period available quantity for each stock7, summary: the position value of each stock for the current period, also including summary data (cash held at the end of the current period, available cash, total asset value)
The above information is saved in the form of a DataFrame. The row index is a MultiIndex: the first/second levels are the time/strategy group indices, and the third level is the 8 data categories above. The trade log file can be saved in CSV format with the filename
trade_log.csv.- Parameters:
save_to_file_path (str, optional) – If a file path is provided, save the trade log as a CSV file; the default is None.
- Returns:
trade_log – trade simulation result data
- Return type:
pd.DataFrame
- generate_trade_summary(share_names: Optional[list[str]] = None, save_to_file_path: Optional[str] = None) DataFrame[source]
Generate the trade summary table (a more compact trade summary table that contains the key information for each trade, presented in a more human-readable way, and filters out records with no trades). The function input trade_log_df is the return value of the function generate_trade_logs().
- Parameters:
share_names (list[str], optional) – List of trading instrument names; if None, use “N/A” as the name.
save_to_file_path (str, optional) – If a file path is provided, save the trade summary table as a CSV file; the default is None (do not save a file).
- plot_result(plot_title: str, show_positions: bool, buy_sell_markers: bool) None[source]
Generate trading results in chart form
- Parameters:
plot_title (str) – The chart title
show_positions (bool) – Whether to display position interval information. If set to True, show the position type for each interval on the return curve chart as red/green bands (green indicates holding a long position, red indicates holding a short position). The darker the color, the higher the position ratio.
buy_sell_markers (bool) – Whether to show buy/sell points on the return curve chart. If set to True, buy/sell points are marked on the return curve chart with small red/green arrows
- Return type:
None
- report_result(trade_log: Optional[str] = None, trade_summary: Optional[str] = None) str[source]
Generate a detailed report of the backtest results. The report is in plain-text format and can be printed using the print command
- Parameters:
trade_log (str, optional) – Storage path for the trade log file. The default is None. If this path is provided, the storage path of the trade log is printed in the report
trade_summary (str, optional) – Storage path for the trade summary record file. The default is None. If provided, print the storage path of the trade summary record in the report.
- Returns:
report_str – Backtest results report formatted for printing
- Return type:
str
- run() Backtester[source]
Run the backtest calculations, generate the backtest result data, and store it in the object’s attributes
- save_complete_values(save_to_file_path: Optional[str] = None) Optional[str][source]
Save complete_values as a CSV file (called by qt_operator when trade_log=True)
- Parameters:
save_to_file_path (str, optional) – Save path; if None, nothing is written
- Returns:
Return the save path on success; otherwise return None
- Return type:
str or None
- trace_result_df() Optional[DataFrame][source]
Generate a record of the trading process based on the backtest results; the output is in DataFrame format
Alignment between trace rows and op_signal_index is ensured by the Operator when writing (update_trace_step uses the global signal row number). Here we only concat by strategy and then set the index to op_signal_index.
- Returns:
trade_trace – trade simulation process data
- Return type:
pd.DataFrame
- trade_result_df() DataFrame[source]
Generate asset value records based on the backtest results; the output is in DataFrame format.
- Returns:
value_history – trade simulation result data
- Return type:
pd.DataFrame
- trade_result_final_value()[source]
Directly and quickly compute and return the final value result of the backtest.