Skip to content

Commit 5027290

Browse files
committed
feat: Introduce Position Sizer functionality and enhance Backtester for multi-strategy support
- Added Position Sizer base class and implementations: AllInSizer, FixedFractionSizer, EqualWeightSizer, and VolatilityTargetSizer. - Enhanced Backtester to support multiple strategies and introduced MultiBacktestResults for aggregated results. - Updated strategy comparison metrics and visualizations to accommodate new multi-strategy features. - Removed deprecated StrategyComparator utility and related tests, streamlining the comparison process. - Added tests for multi-strategy backtesting and equal-weight portfolio creation.
1 parent c57808e commit 5027290

13 files changed

Lines changed: 1079 additions & 704 deletions

docs/TUTORIAL_CN.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ data = loader.load_stock('600519', '20200101', '20231231')
2424
### 2.2 运行回测
2525

2626
```python
27-
from quanteval import Backtester, DualMAStrategy
27+
from quanteval import Backtester
28+
from quanteval.strategies import DualMAStrategy
2829

2930
strategy = DualMAStrategy(fast_window=10, slow_window=60)
3031
results = Backtester(strategy=strategy, data=data, transaction_costs=True).run()
@@ -34,23 +35,26 @@ print(results.summary())
3435
### 2.3 策略对比
3536

3637
```python
37-
from quanteval import BollingerMeanReversionStrategy, StrategyComparator
38+
from quanteval import Backtester
39+
from quanteval.strategies import BollingerMeanReversionStrategy, DualMAStrategy
3840

39-
comparison = StrategyComparator(
40-
strategies=[
41-
DualMAStrategy(5, 20),
42-
BollingerMeanReversionStrategy(window=20, num_std=2.0),
43-
],
44-
verbose=False,
45-
).compare(data)
41+
comparison = Backtester(
42+
strategy={
43+
'DualMA(5,20)': DualMAStrategy(5, 20),
44+
'BollingerMR': BollingerMeanReversionStrategy(window=20, num_std=2.0),
45+
},
46+
data=data,
47+
transaction_costs=False,
48+
).run()
4649

4750
print(comparison.metrics_df)
4851
```
4952

5053
### 2.4 参数优化
5154

5255
```python
53-
from quanteval import GridSearch
56+
from quanteval.optimization import GridSearch
57+
from quanteval.strategies import DualMAStrategy
5458

5559
search = GridSearch(
5660
DualMAStrategy,
@@ -69,7 +73,8 @@ print(result.best_params)
6973
### 2.5 Walk-forward 样本外验证
7074

7175
```python
72-
from quanteval import WalkForwardAnalysis
76+
from quanteval.optimization import WalkForwardAnalysis
77+
from quanteval.strategies import DualMAStrategy
7378

7479
wfa = WalkForwardAnalysis(
7580
DualMAStrategy,

docs/TUTORIAL_EN.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ data = loader.load_stock('600519', '20200101', '20231231')
2424
### 2.2 Running Backtests
2525

2626
```python
27-
from quanteval import Backtester, DualMAStrategy
27+
from quanteval import Backtester
28+
from quanteval.strategies import DualMAStrategy
2829

2930
strategy = DualMAStrategy(fast_window=10, slow_window=60)
3031
results = Backtester(strategy=strategy, data=data, transaction_costs=True).run()
@@ -34,23 +35,26 @@ print(results.summary())
3435
### 2.3 Strategy Comparison
3536

3637
```python
37-
from quanteval import BollingerMeanReversionStrategy, StrategyComparator
38+
from quanteval import Backtester
39+
from quanteval.strategies import BollingerMeanReversionStrategy, DualMAStrategy
3840

39-
comparison = StrategyComparator(
40-
strategies=[
41-
DualMAStrategy(5, 20),
42-
BollingerMeanReversionStrategy(window=20, num_std=2.0),
43-
],
44-
verbose=False,
45-
).compare(data)
41+
comparison = Backtester(
42+
strategy={
43+
'DualMA(5,20)': DualMAStrategy(5, 20),
44+
'BollingerMR': BollingerMeanReversionStrategy(window=20, num_std=2.0),
45+
},
46+
data=data,
47+
transaction_costs=False,
48+
).run()
4649

4750
print(comparison.metrics_df)
4851
```
4952

5053
### 2.4 Parameter Optimization
5154

5255
```python
53-
from quanteval import GridSearch
56+
from quanteval.optimization import GridSearch
57+
from quanteval.strategies import DualMAStrategy
5458

5559
search = GridSearch(
5660
DualMAStrategy,
@@ -69,7 +73,8 @@ print(result.best_params)
6973
### 2.5 Walk-forward Out-of-sample Validation
7074

7175
```python
72-
from quanteval import WalkForwardAnalysis
76+
from quanteval.optimization import WalkForwardAnalysis
77+
from quanteval.strategies import DualMAStrategy
7378

7479
wfa = WalkForwardAnalysis(
7580
DualMAStrategy,

examples/03_strategy_comparison.ipynb

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,7 @@
2222
"id": "1",
2323
"metadata": {},
2424
"outputs": [],
25-
"source": [
26-
"import numpy as np\n",
27-
"import pandas as pd\n",
28-
"\n",
29-
"from quanteval import BollingerMeanReversionStrategy, DualMAStrategy, StrategyComparator"
30-
]
25+
"source": "import numpy as np\nimport pandas as pd\n\nfrom quanteval import Backtester\nfrom quanteval.strategies import BollingerMeanReversionStrategy, DualMAStrategy"
3126
},
3227
{
3328
"cell_type": "code",
@@ -67,15 +62,7 @@
6762
"id": "4",
6863
"metadata": {},
6964
"outputs": [],
70-
"source": [
71-
"comparator = StrategyComparator(\n",
72-
" strategies=[DualMAStrategy(5, 20), BollingerMeanReversionStrategy(20, 2.0)],\n",
73-
" strategy_names=['DualMA(5,20)', 'BollingerMR'],\n",
74-
" verbose=False,\n",
75-
")\n",
76-
"comparison = comparator.compare(data)\n",
77-
"comparison.metrics_df"
78-
]
65+
"source": "comparison = Backtester(\n strategy={\n 'DualMA(5,20)': DualMAStrategy(5, 20),\n 'BollingerMR': BollingerMeanReversionStrategy(20, 2.0),\n },\n data=data,\n transaction_costs=False,\n).run()\ncomparison.metrics_df"
7966
},
8067
{
8168
"cell_type": "markdown",
@@ -97,10 +84,7 @@
9784
"id": "6",
9885
"metadata": {},
9986
"outputs": [],
100-
"source": [
101-
"portfolio = comparator.create_equal_weight_portfolio(data)\n",
102-
"portfolio.summary()"
103-
]
87+
"source": "portfolio = comparison.create_equal_weight_portfolio()\nportfolio.summary()"
10488
}
10589
],
10690
"metadata": {

0 commit comments

Comments
 (0)