diff --git a/README.md b/README.md index 659b9ab..03454e1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,404 @@ -# positionbt -PositionBT is a simple, fast, and customizable backtesting framework that empowers traders to efficiently develop and optimize trading strategies with ease. +# PositionBT + +PositionBT 是一个专注于基于仓位数据进行策略回测的 Python 库。这个库的设计理念是"简单即是美",致力于提供一个轻量级但功能强大的回测框架。 +> 注意:当前版本仅支持单个交易品种的回测。多品种回测功能正在开发中,将在未来版本中推出。 + +## 特点 + +* 简单易用 + - 有别于传统回测框架需要处理繁琐的订单、手续费和滑点模型,PositionBT 采用规范化的仓位数据进行回测,大幅简化了使用流程。 + - 仓位采用标准化设计,从 -1(满仓做空)到 1(满仓做多)的直观刻度,让策略评估更加清晰明确。 + - 专注于策略核心逻辑的验证,避免在交易执行细节上耗费过多精力,提升策略研发效率。 + +* 高性能 + - 基于 Polars 构建,提供极速的数据处理能力。 + - 优化计算流程,避免重复计算,提高回测效率。 + +* 可视化 + - 集成 `plotly` 打造专业的可视化模块,提供丰富的交互式分析功能。 + - 支持多种查看方式:可通过浏览器实时预览回测报告,或导出为 HTML 文件便于分享与存档。 + +* 可扩展性 + - 灵活的指标系统:支持自定义性能评估指标。 + - 丰富的可视化选项:支持自定义图表类型,可实现策略绩效曲线、回撤分析、持仓分布等多维度分析展示。 + - 开放的接口设计:便于用户扩展和集成自己的分析工具,打造个性化的回测分析流程。 + +## 回测速度 + +以 data 目录下的比特币(BTC)收盘价数据集为例。该数据集包含从 2017 年 8 月 17 日至 2024 年 12 月 11 日的 15 分钟级别数据,共计 256,058 条记录。在 M4 芯片的 Mac Mini 上运行简单的"满仓买入并持有"策略,回测计算仅需 0.13 秒,生成交互式 HTML 报告约需 0.896 秒,平均每 10 万行数据的回测耗时仅为 0.051 秒,展现了优异的性能表现。 + +## 安装 + +```bash +pip install positionbt +``` + +## 快速开始 + +### 买入持有策略示例 + +#### 代码 + +下面展示了一个简单的策略回测示例:在整个回测期间保持 BTC 满仓多头持仓。这个示例演示了 PositionBT 的基本用法,包括数据加载、回测执行和结果可视化的完整流程。 + +```python +import polars as pl + +from examples.data_loader import load_close_data +from positionbt import BacktestVisualizer, PositionBacktester + +# Load BTC close data +close_df = load_close_data() + +# Generate position data +position_df = close_df.select(pl.col("time")).with_columns(pl.lit(1).alias("position")) + +# Initialize backtester with parameters +backtester = PositionBacktester( + close_df=close_df, + commission=0.001, # 0.1% commission rate + annual_trading_days=365, # Use 365 trading days per year + indicators="all", # Calculate all available indicators +) + +# Run backtest +backtest_result = backtester.run(position_df) + +# Print backtest results in tabular format +backtest_result.print() + +# Create visualizer and show results in browser +visualizer = BacktestVisualizer(backtest_result, backtester.params) +visualizer.show_in_browser() + +``` + +#### 结果 + +回测结果: + +![回测结果预览](./docs/images/backtest_result.png) + +回测报告: + +![回测报告预览](./docs/images/backtest_report.png) + +### 自定义指标示例 + +#### 代码 + +PositionBT 支持自定义指标,用户可以根据需要添加自己的指标进行回测。打印回测结果,或者输出回测报告时,自定义指标会直接显示。 + +```python +import polars as pl + +from examples.data_loader import load_close_data +from positionbt import BaseIndicator, PositionBacktester, indicator_registry + + +class MonthlyReturn(BaseIndicator): + """Monthly return indicator""" + + @property + def name(self) -> str: + return "monthly_return" + + @property + def requires(self) -> set[str]: + # Depends on annual return + return {"annual_return"} + + def calculate(self, cache: dict) -> float: + """Calculate monthly return + + Calculation method: + 1. Convert from annual return + 2. Using formula: (1 + r_annual)^(1/12) - 1 + + Args: + cache: Dictionary containing calculation cache + + Returns: + Monthly return value + + """ + if "monthly_return" not in cache: + annual_return = cache["annual_return"] + monthly_return = (1 + annual_return) ** (1 / 12) - 1 + cache["monthly_return"] = monthly_return + + return cache["monthly_return"] + + def format(self, value: float) -> str: + """Format monthly return value as percentage + + Args: + value: Monthly return value + + Returns: + Formatted string with percentage + + """ + return f"{value:.2%}" + + +# Register custom indicator +indicator_registry.register(MonthlyReturn()) + +# Load close data +close_df = load_close_data() + +# Generate position data +position_df = close_df.select(pl.col("time")).with_columns(pl.lit(1).alias("position")) + +# Create backtester instance (using all indicators including the newly registered monthly return) +backtester = PositionBacktester( + close_df=close_df, + commission=0.001, # 0.1% commission rate + annual_trading_days=365, # Use 365 trading days per year + indicators=["monthly_return"], # Use all registered indicators +) + +# Run backtest +results = backtester.run(position_df) + +# Print results +results.print() + +``` + +#### 结果 + +回测结果: + +![自定义指标回测结果](./docs/images/custom_indicator_result.png) + +### 自定义可视化示例 + +#### 代码 + +PositionBT 支持自定义可视化,用户可以根据需要添加自己的可视化模块。 + +```python +import plotly.graph_objects as go +import polars as pl + +from examples.data_loader import load_close_data +from positionbt import ( + BacktestVisualizer, + BaseFigure, + PositionBacktester, + figure_registry, +) + + +class DrawdownFigure(BaseFigure): + """Drawdown visualization figure""" + + name = "drawdown" # Unique identifier for the figure + title = "Strategy Drawdown" # Display title for the figure + + def create(self) -> go.Figure: + """Create drawdown figure + + Returns: + Plotly figure object containing drawdown visualization + + """ + # Calculate cumulative maximum of funding curve + cummax = self.funding_curve.get_column("funding_curve").cum_max() + + # Calculate drawdown as percentage from peak + drawdown = (self.funding_curve.get_column("funding_curve") - cummax) / cummax + + # Add drawdown trace to figure + self._fig.add_trace( + go.Scatter( + x=self.funding_curve.get_column("time"), + y=drawdown, + fill="tozeroy", # Fill area from line to zero + name="drawdown", + line=dict(color="red"), + ) + ) + + # Update layout with percentage formatting + self._fig.update_layout( + yaxis=dict( + tickformat=".1%", # Format y-axis ticks as percentages + hoverformat=".2%", # Format hover text as percentages + ), + ) + return self._fig + + +# Register custom figure +figure_registry.register(DrawdownFigure) + +# Load close data +close_df = load_close_data() + +# Generate position data +position_df = close_df.select(pl.col("time")).with_columns(pl.lit(1).alias("position")) + + +# Initialize backtester +backtester = PositionBacktester( + close_df=close_df, + commission=0.001, # 0.1% commission rate + annual_trading_days=365, # Use 365 trading days per year + indicators="all", # Calculate all available indicators +) + +# Run backtest +backtest_result = backtester.run(position_df) + +# Create visualizer and show results in browser +visualizer = BacktestVisualizer(backtest_result, backtester.params, figures=["drawdown"]) +visualizer.show_in_browser() +``` + +#### 结果 + +回测报告: + +![自定义组件回测报告](./docs/images/custom_figure_result.png) + +## 支持的指标 + +| 指标名称 | 说明 | 计算方法 | 展示格式 | 指标ID | +|---------|------|---------|----------|---------| +| 总收益率 (Total Return) | 策略整体收益表现 | 最终净值/初始净值 - 1 | 百分比 (xx.xx%) | total_return | +| 年化收益率 (Annual Return) | 收益率年化后的表现 | (1 + 总收益率)^(365/实际天数) - 1 | 百分比 (xx.xx%) | annual_return | +| 波动率 (Volatility) | 收益率的年化标准差 | 收益率标准差 * √(年化周期) | 百分比 (xx.xx%) | volatility | +| 夏普比率 (Sharpe Ratio) | 风险调整后收益指标 | 年化收益率/年化波动率 | 小数 (xx.xx) | sharpe_ratio | +| 最大回撤 (Max Drawdown) | 最大净值回撤幅度 | (历史最高点 - 当前净值)/历史最高点 的最大值 | 百分比 (xx.xx%) | max_drawdown | +| 最大回撤持续期 (Max Drawdown Duration) | 最大回撤的持续时间 | 最大回撤期间的天数 | xx 天 | max_drawdown_duration | +| 胜率 (Win Rate) | 盈利交易占比 | 盈利交易次数/总交易次数 | 百分比 (xx.xx%) | win_rate | +| 平均回撤 (Avg Drawdown) | 回撤的平均值 | 所有非零回撤的算术平均值 | 百分比 (xx.xx%) | avg_drawdown | +| 盈亏比 (Profit Loss Ratio) | 平均盈利与平均亏损之比 | \|平均盈利\|/\|平均亏损\| | 小数 (xx.xx) 或 ∞ | profit_loss_ratio | + +> 注:所有百分比指标均保留两位小数,比率指标保留两位小数。 + +## 支持的可视化 + +## 回测报告组件 + +### 图表组件 + +| 图表名称 | 组件ID | 说明 | 主要特点 | +|---------|--------|------|----------| +| 净值曲线图 | funding_curve | 展示策略净值变化 | - 显示完整的净值走势
- 标注最大回撤区间
- 标记最大回撤的峰谷点
- 支持交互式缩放查看 | +| 月度收益分布图 | monthly_returns | 展示策略月度收益分布 | - 使用柱状图展示每月收益
- 红绿双色区分盈亏
- 支持收益率精确查看 | + +### 信息面板 + +| 面板类型 | 展示内容 | 说明 | +|---------|---------|------| +| 回测参数信息 | - 手续费率
- 年化交易天数
- 使用的指标 | 展示回测的基本设置参数 | +| 数据信息 | - 起始日期
- 结束日期
- 总天数
- 数据点数
- 数据频率 | 展示回测数据的基本信息 | +| 绩效指标 | - 总收益率
- 年化收益率
- 夏普比率
- 最大回撤
- 其他核心指标 | 以卡片形式展示策略的关键绩效指标 | + +> 注:所有图表组件都支持交互式操作,可以放大、缩小、平移和导出图片。报告以 HTML 格式生成,可以通过浏览器直接查看或保存成 HTML 文件。 + +## API 参考 + +### 核心类 + +#### PositionBacktester +回测引擎的主类,用于执行策略回测。 + +```python +PositionBacktester( + close_df: pl.DataFrame, + commission: float = 0.001, + annual_trading_days: int = 252, + indicators: Union[str, list[str]] = "all" +) +``` + +**参数说明:** +- `close_df`: 包含 `time` 和 `close` 列的 Polars DataFrame +- `commission`: 交易手续费率,默认 0.1% +- `annual_trading_days`: 年化天数,默认 252 +- `indicators`: 需要计算的指标,可以是 "all" 或指标名称列表 + +**主要方法:** +- `run(position_df: pl.DataFrame) -> BacktestResult`: 执行回测并返回结果 + +#### BacktestResult +回测结果的数据类,包含回测的所有结果数据。 + +**主要属性:** +- `funding_curve`: 净值曲线数据 +- `indicator_values`: 指标计算结果 +- `formatted_indicator_values`: 格式化后的指标值 + +**主要方法:** +- `print()`: 以表格形式打印回测结果 + +#### BacktestVisualizer +回测结果可视化器,用于生成交互式回测报告。 + +```python +BacktestVisualizer( + results: BacktestResult, + params: dict, + template_path: Optional[Path] = None, + figures: Optional[list[str]] = None, + notes: Optional[str] = None +) +``` + +**参数说明:** +- `results`: 回测结果对象 +- `params`: 回测参数字典 +- `template_path`: 自定义模板路径(可选) +- `figures`: 需要展示的图表列表(可选) +- `notes`: 报告备注信息(可选) + +**主要方法:** +- `show_in_browser()`: 在浏览器中展示回测报告 +- `generate_html_report(output_path: str)`: 生成 HTML 格式的回测报告 + +### 基类 + +#### BaseIndicator +指标计算的基类,用于自定义新的性能指标。 + +**必须实现的方法:** +- `name(self) -> str`: 返回指标名称 +- `calculate(self, cache: dict) -> float`: 计算指标值 +- `format(self, value: float) -> str`: 格式化指标值 + +**非必须实现的方法:** + +* `requires(self) -> set[str]`: 依赖的指标 + +#### BaseFigure +可视化图表的基类,用于自定义新的图表类型。 + +**必须实现的属性:** +- `name`: 图表唯一标识符 +- `title`: 图表显示标题 + +**必须实现的方法:** +- `create(self) -> go.Figure`: 创建并返回 Plotly 图表对象 + +### 注册器 + +#### indicator_registry +指标注册器,用于管理和获取可用的性能指标。 + +**主要方法:** +- `register(indicator_cls: Type[BaseIndicator])`: 注册新的指标 +- `get(name: str) -> Type[BaseIndicator]`: 获取指标类 +- `available_indicators`: 获取所有可用指标列表 + +#### figure_registry +图表注册器,用于管理和获取可用的可视化图表。 + +**主要方法:** +- `register(figure_cls: Type[BaseFigure])`: 注册新的图表 +- `get(name: str) -> Type[BaseFigure]`: 获取图表类 +- `available_figures`: 获取所有可用图表列表 diff --git a/README_EN.md b/README_EN.md new file mode 100644 index 0000000..54b3000 --- /dev/null +++ b/README_EN.md @@ -0,0 +1,401 @@ +# PositionBT + +PositionBT is a Python library focused on position-based strategy backtesting. The design philosophy is "simplicity is beauty", aiming to provide a lightweight yet powerful backtesting framework. +> Note: The current version only supports single-instrument backtesting. Multi-instrument backtesting functionality is under development and will be available in future releases. + +## Features + +* Easy to Use + - Unlike traditional backtesting frameworks that deal with complex orders, fees, and slippage models, PositionBT uses standardized position data for backtesting, greatly simplifying the workflow. + - Positions use a standardized design with intuitive scales from -1 (full short) to 1 (full long), making strategy evaluation clearer and more straightforward. + - Focus on validating core strategy logic, avoiding excessive time spent on trading execution details, improving strategy development efficiency. + +* High Performance + - Built on Polars, providing ultra-fast data processing capabilities. + - Optimized calculation process, avoiding redundant computations, improving backtesting efficiency. + +* Visualization + - Integrated with `plotly` to create professional visualization modules, offering rich interactive analysis features. + - Supports multiple viewing methods: preview backtest reports in real-time through browsers, or export as HTML files for sharing and archiving. + +* Extensibility + - Flexible indicator system: supports custom performance evaluation indicators. + - Rich visualization options: supports custom chart types, enabling multi-dimensional analysis displays such as strategy performance curves, drawdown analysis, and position distribution. + - Open interface design: facilitates user extension and integration of their own analysis tools to create personalized backtesting analysis workflows. + +## Backtesting Speed + +Taking the Bitcoin (BTC) closing price dataset in the `data` directory as an example. This dataset contains 15-minute level data from August 17, 2017, to December 11, 2024, with a total of 256,058 records. Running a simple "buy and hold" strategy on an M4 chip Mac Mini, the backtest calculation takes only 0.13 seconds, generating an interactive HTML report takes about 0.896 seconds, and the average backtesting time per 100,000 rows of data is just 0.051 seconds, demonstrating excellent performance. + +## Installation + +```bash +pip install positionbt +``` + +## Quick Start + +### Buy and Hold Strategy Example + +#### Code + +Below is a simple strategy backtesting example: maintaining a full long position in BTC throughout the entire backtesting period. This example demonstrates the basic usage of PositionBT, including the complete process of data loading, backtest execution, and result visualization. + +```python +import polars as pl + +from examples.data_loader import load_close_data +from positionbt import BacktestVisualizer, PositionBacktester + +# Load BTC close data +close_df = load_close_data() + +# Generate position data +position_df = close_df.select(pl.col("time")).with_columns(pl.lit(1).alias("position")) + +# Initialize backtester with parameters +backtester = PositionBacktester( + close_df=close_df, + commission=0.001, # 0.1% commission rate + annual_trading_days=365, # Use 365 trading days per year + indicators="all", # Calculate all available indicators +) + +# Run backtest +backtest_result = backtester.run(position_df) + +# Print backtest results in tabular format +backtest_result.print() + +# Create visualizer and show results in browser +visualizer = BacktestVisualizer(backtest_result, backtester.params) +visualizer.show_in_browser() +``` + +#### Results + +Backtest Results: + +![Backtest Results Preview](./docs/images/backtest_result.png) + +Backtest Report: + +![Backtest Report Preview](./docs/images/backtest_report.png) + +### Custom Indicator Example + +#### Code + +PositionBT supports custom indicators, allowing users to add their own indicators for backtesting. Custom indicators will be directly displayed when printing backtest results or outputting backtest reports. + +```python +import polars as pl + +from examples.data_loader import load_close_data +from positionbt import BaseIndicator, PositionBacktester, indicator_registry + + +class MonthlyReturn(BaseIndicator): + """Monthly return indicator""" + + @property + def name(self) -> str: + return "monthly_return" + + @property + def requires(self) -> set[str]: + # Depends on annual return + return {"annual_return"} + + def calculate(self, cache: dict) -> float: + """Calculate monthly return + + Calculation method: + 1. Convert from annual return + 2. Using formula: (1 + r_annual)^(1/12) - 1 + + Args: + cache: Dictionary containing calculation cache + + Returns: + Monthly return value + + """ + if "monthly_return" not in cache: + annual_return = cache["annual_return"] + monthly_return = (1 + annual_return) ** (1 / 12) - 1 + cache["monthly_return"] = monthly_return + + return cache["monthly_return"] + + def format(self, value: float) -> str: + """Format monthly return value as percentage + + Args: + value: Monthly return value + + Returns: + Formatted string with percentage + + """ + return f"{value:.2%}" + + +# Register custom indicator +indicator_registry.register(MonthlyReturn()) + +# Load close data +close_df = load_close_data() + +# Generate position data +position_df = close_df.select(pl.col("time")).with_columns(pl.lit(1).alias("position")) + +# Create backtester instance (using all indicators including the newly registered monthly return) +backtester = PositionBacktester( + close_df=close_df, + commission=0.001, # 0.1% commission rate + annual_trading_days=365, # Use 365 trading days per year + indicators=["monthly_return"], # Use all registered indicators +) + +# Run backtest +results = backtester.run(position_df) + +# Print results +results.print() +``` + +#### Results + +Backtest Results: + +![Custom Indicator Results](./docs/images/custom_indicator_result.png) + +### Custom Visualization Example + +#### Code + +PositionBT supports custom visualization, allowing users to add their own visualization modules as needed. + +```python +import plotly.graph_objects as go +import polars as pl + +from examples.data_loader import load_close_data +from positionbt import ( + BacktestVisualizer, + BaseFigure, + PositionBacktester, + figure_registry, +) + + +class DrawdownFigure(BaseFigure): + """Drawdown visualization figure""" + + name = "drawdown" # Unique identifier for the figure + title = "Strategy Drawdown" # Display title for the figure + + def create(self) -> go.Figure: + """Create drawdown figure + + Returns: + Plotly figure object containing drawdown visualization + + """ + # Calculate cumulative maximum of funding curve + cummax = self.funding_curve.get_column("funding_curve").cum_max() + + # Calculate drawdown as percentage from peak + drawdown = (self.funding_curve.get_column("funding_curve") - cummax) / cummax + + # Add drawdown trace to figure + self._fig.add_trace( + go.Scatter( + x=self.funding_curve.get_column("time"), + y=drawdown, + fill="tozeroy", # Fill area from line to zero + name="drawdown", + line=dict(color="red"), + ) + ) + + # Update layout with percentage formatting + self._fig.update_layout( + yaxis=dict( + tickformat=".1%", # Format y-axis ticks as percentages + hoverformat=".2%", # Format hover text as percentages + ), + ) + return self._fig + + +# Register custom figure +figure_registry.register(DrawdownFigure) + +# Load close data +close_df = load_close_data() + +# Generate position data +position_df = close_df.select(pl.col("time")).with_columns(pl.lit(1).alias("position")) + + +# Initialize backtester +backtester = PositionBacktester( + close_df=close_df, + commission=0.001, # 0.1% commission rate + annual_trading_days=365, # Use 365 trading days per year + indicators="all", # Calculate all available indicators +) + +# Run backtest +backtest_result = backtester.run(position_df) + +# Create visualizer and show results in browser +visualizer = BacktestVisualizer(backtest_result, backtester.params, figures=["drawdown"]) +visualizer.show_in_browser() +``` + +#### Results + +Backtest Report: + +![Custom Figure Results](./docs/images/custom_figure_result.png) + +## Supported Indicators + +| Indicator Name | Description | Calculation Method | Display Format | Indicator ID | +|----------------|-------------|-------------------|----------------|--------------| +| Total Return | Overall strategy return performance | Final NAV/Initial NAV - 1 | Percentage (xx.xx%) | total_return | +| Annual Return | Annualized return performance | (1 + Total Return)^(365/Actual Days) - 1 | Percentage (xx.xx%) | annual_return | +| Volatility | Annualized standard deviation of returns | Return Std Dev * √(Annualization Period) | Percentage (xx.xx%) | volatility | +| Sharpe Ratio | Risk-adjusted return metric | Annual Return/Annual Volatility | Decimal (xx.xx) | sharpe_ratio | +| Max Drawdown | Maximum NAV drawdown magnitude | Max((Historical High - Current NAV)/Historical High) | Percentage (xx.xx%) | max_drawdown | +| Max Drawdown Duration | Duration of maximum drawdown | Number of days in max drawdown period | xx Days | max_drawdown_duration | +| Win Rate | Proportion of profitable trades | Number of Profitable Trades/Total Trades | Percentage (xx.xx%) | win_rate | +| Avg Drawdown | Average of drawdowns | Arithmetic mean of all non-zero drawdowns | Percentage (xx.xx%) | avg_drawdown | +| Profit Loss Ratio | Ratio of average profit to average loss | \|Average Profit\|/\|Average Loss\| | Decimal (xx.xx) or ∞ | profit_loss_ratio | + +> Note: All percentage indicators retain two decimal places, ratio indicators retain two decimal places. + +## Supported Visualizations + +## Backtest Report Components + +### Chart Components + +| Chart Name | Component ID | Description | Key Features | +|------------|--------------|-------------|--------------| +| NAV Curve | funding_curve | Shows strategy NAV changes | - Displays complete NAV trend
- Marks maximum drawdown period
- Marks peak and trough points of max drawdown
- Supports interactive zoom viewing | +| Monthly Returns Distribution | monthly_returns | Shows monthly return distribution | - Uses bar chart for monthly returns
- Red/green colors distinguish profits/losses
- Supports precise return rate viewing | + +### Information Panels + +| Panel Type | Display Content | Description | +|------------|----------------|-------------| +| Backtest Parameters | - Commission rate
- Annual trading days
- Used indicators | Shows basic backtest setup parameters | +| Data Information | - Start date
- End date
- Total days
- Data points
- Data frequency | Shows basic backtest data information | +| Performance Metrics | - Total return
- Annual return
- Sharpe ratio
- Maximum drawdown
- Other core metrics | Displays key strategy performance metrics in card format | + +> Note: All chart components support interactive operations, including zoom, pan, and image export. Reports are generated in HTML format and can be viewed directly through browsers or saved as HTML files. + +## API Reference + +### Core Classes + +#### PositionBacktester +Main class for the backtesting engine, used to execute strategy backtests. + +```python +PositionBacktester( + close_df: pl.DataFrame, + commission: float = 0.001, + annual_trading_days: int = 252, + indicators: Union[str, list[str]] = "all" +) +``` + +**Parameters:** +- `close_df`: Polars DataFrame containing `time` and `close` columns +- `commission`: Trading commission rate, default 0.1% +- `annual_trading_days`: Annual days, default 252 +- `indicators`: Indicators to calculate, can be "all" or list of indicator names + +**Main Methods:** +- `run(position_df: pl.DataFrame) -> BacktestResult`: Execute backtest and return results + +#### BacktestResult +Data class containing all backtest results. + +**Main Attributes:** +- `funding_curve`: NAV curve data +- `indicator_values`: Indicator calculation results +- `formatted_indicator_values`: Formatted indicator values + +**Main Methods:** +- `print()`: Print backtest results in tabular format + +#### BacktestVisualizer +Backtest result visualizer for generating interactive backtest reports. + +```python +BacktestVisualizer( + results: BacktestResult, + params: dict, + template_path: Optional[Path] = None, + figures: Optional[list[str]] = None, + notes: Optional[str] = None +) +``` + +**Parameters:** +- `results`: Backtest result object +- `params`: Backtest parameter dictionary +- `template_path`: Custom template path (optional) +- `figures`: List of figures to display (optional) +- `notes`: Report notes (optional) + +**Main Methods:** +- `show_in_browser()`: Show backtest report in browser +- `generate_html_report(output_path: str)`: Generate HTML format backtest report + +### Base Classes + +#### BaseIndicator +Base class for indicator calculation, used for custom performance indicators. + +**Required Methods:** +- `name(self) -> str`: Return indicator name +- `calculate(self, cache: dict) -> float`: Calculate indicator value +- `format(self, value: float) -> str`: Format indicator value + +**Optional Methods:** +- `requires(self) -> set[str]`: Required indicators + +#### BaseFigure +Base class for visualization charts, used for custom chart types. + +**Required Attributes:** +- `name`: Unique chart identifier +- `title`: Chart display title + +**Required Methods:** +- `create(self) -> go.Figure`: Create and return Plotly figure object + +### Registries + +#### indicator_registry +Indicator registry for managing and accessing available performance indicators. + +**Main Methods:** +- `register(indicator_cls: Type[BaseIndicator])`: Register new indicator +- `get(name: str) -> Type[BaseIndicator]`: Get indicator class +- `available_indicators`: Get list of all available indicators + +#### figure_registry +Chart registry for managing and accessing available visualization charts. + +**Main Methods:** +- `register(figure_cls: Type[BaseFigure])`: Register new chart +- `get(name: str) -> Type[BaseFigure]`: Get chart class +- `available_figures`: Get list of all available charts \ No newline at end of file diff --git a/docs/images/backtest_report.png b/docs/images/backtest_report.png new file mode 100644 index 0000000..a34f69d Binary files /dev/null and b/docs/images/backtest_report.png differ diff --git a/docs/images/backtest_result.png b/docs/images/backtest_result.png new file mode 100644 index 0000000..978a6ac Binary files /dev/null and b/docs/images/backtest_result.png differ diff --git a/docs/images/custom_figure_result.png b/docs/images/custom_figure_result.png new file mode 100644 index 0000000..5a0dcec Binary files /dev/null and b/docs/images/custom_figure_result.png differ diff --git a/docs/images/custom_indicator_result.png b/docs/images/custom_indicator_result.png new file mode 100644 index 0000000..4ca150d Binary files /dev/null and b/docs/images/custom_indicator_result.png differ