Skip to content

Commit 3966fef

Browse files
committed
Fix backtest summary tests
1 parent 8888556 commit 3966fef

File tree

2 files changed

+150
-125
lines changed

2 files changed

+150
-125
lines changed

tests/domain/models/backtesting/test_backtest_summary_metrics.py

Lines changed: 0 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -54,128 +54,3 @@ def test_open(self):
5454

5555
loaded_metrics = BacktestSummaryMetrics.open(file_path)
5656
self.assertEqual(backtest_metrics.to_dict(), loaded_metrics.to_dict())
57-
58-
def test_add(self):
59-
metrics = BacktestMetrics(
60-
backtest_start_date=datetime(2020, 1, 1),
61-
backtest_end_date=datetime(2020, 12, 31),
62-
equity_curve=[
63-
(0.0, datetime(2020, 1, 1)),
64-
(1.0, datetime(2020, 12, 31)),
65-
(0.5, datetime(2020, 6, 30)),
66-
(0.2, datetime(2020, 3, 31))
67-
],
68-
total_growth=0.0,
69-
total_growth_percentage=0.0,
70-
total_net_gain=100,
71-
total_net_gain_percentage=0.0,
72-
final_value=0.0,
73-
cagr=0.0,
74-
sharpe_ratio=0.0,
75-
rolling_sharpe_ratio=[
76-
(0.0, datetime(2020, 1, 1)),
77-
(1.0, datetime(2020, 12, 31)),
78-
(0.5, datetime(2020, 6, 30)),
79-
(0.2, datetime(2020, 3, 31))
80-
],
81-
sortino_ratio=0.0,
82-
calmar_ratio=0.0,
83-
profit_factor=0.0,
84-
gross_profit=0.0,
85-
gross_loss=0.0,
86-
annual_volatility=0.0,
87-
monthly_returns=[
88-
(0.0, datetime(2020, 1, 1)), (0.0, datetime(2020, 2, 1)),
89-
(0.0, datetime(2020, 3, 1)),
90-
(0.0, datetime(2020, 4, 1)), (0.0, datetime(2020, 5, 1)),
91-
(0.0, datetime(2020, 6, 1)),
92-
(0.0, datetime(2020, 7, 1)), (0.0, datetime(2020, 8, 1)),
93-
(0.0, datetime(2020, 9, 1)),
94-
(0.0, datetime(2020, 10, 1)), (0.0, datetime(2020, 11, 1)),
95-
(0.0, datetime(2020, 12, 1))
96-
],
97-
yearly_returns=[
98-
(0.0, date(2020, 1, 1)), (0.0, date(2020, 12, 31))
99-
],
100-
drawdown_series=[
101-
(0.0, datetime(2020, 1, 1)), (0.0, datetime(2020, 2, 1)),
102-
(0.0, datetime(2020, 3, 1)),
103-
(0.0, datetime(2020, 4, 1)), (0.0, datetime(2020, 5, 1)),
104-
(0.0, datetime(2020, 6, 1)),
105-
(0.0, datetime(2020, 7, 1)), (0.0, datetime(2020, 8, 1)),
106-
(0.0, datetime(2020, 9, 1)),
107-
(0.0, datetime(2020, 10, 1)), (0.0, datetime(2020, 11, 1)),
108-
(0.0, datetime(2020, 12, 1))
109-
],
110-
max_drawdown=0.0,
111-
max_drawdown_absolute=0.0,
112-
max_daily_drawdown=0.0,
113-
max_drawdown_duration=0,
114-
trades_per_year=0.0,
115-
trade_per_day=0.0,
116-
exposure_ratio=0.0,
117-
average_trade_gain=0.0,
118-
average_trade_gain_percentage=0.0,
119-
average_trade_loss=0.0,
120-
average_trade_loss_percentage=0.0,
121-
best_trade=Trade(
122-
id=10,
123-
open_price=0.0,
124-
opened_at=datetime(2020, 1, 1),
125-
closed_at=datetime(2020, 12, 31),
126-
orders=[],
127-
target_symbol="BTC",
128-
trading_symbol="EUR",
129-
amount=10.0,
130-
cost=1.0,
131-
available_amount=1.0,
132-
remaining=9.0,
133-
filled_amount=1,
134-
status="closed"
135-
),
136-
worst_trade=Trade(
137-
id=10,
138-
open_price=0.0,
139-
opened_at=datetime(2020, 1, 1),
140-
closed_at=datetime(2020, 12, 31),
141-
orders=[],
142-
target_symbol="BTC",
143-
trading_symbol="EUR",
144-
amount=10.0,
145-
cost=1.0,
146-
available_amount=1.0,
147-
remaining=9.0,
148-
filled_amount=1,
149-
status="closed"
150-
),
151-
average_trade_duration=0.0,
152-
number_of_trades=0,
153-
win_rate=0.0,
154-
win_loss_ratio=0.0,
155-
percentage_winning_months=0.0,
156-
percentage_winning_years=0.0,
157-
average_monthly_return=0.0,
158-
average_monthly_return_losing_months=0.0,
159-
average_monthly_return_winning_months=0.0,
160-
best_month=(0.0, datetime(2020, 1, 1)),
161-
best_year=(0.0, date(2020, 1, 1)),
162-
worst_month=(0.0, datetime(2020, 1, 1)),
163-
worst_year=(0.0, date(2020, 1, 1))
164-
)
165-
summary = BacktestSummaryMetrics(
166-
total_net_gain=0.0,
167-
cagr=0.0,
168-
sharpe_ratio=0.0,
169-
sortino_ratio=0.0,
170-
calmar_ratio=0.0,
171-
profit_factor=0.0,
172-
annual_volatility=0.0,
173-
max_drawdown=0.0,
174-
max_drawdown_duration=0,
175-
trades_per_year=0.0,
176-
number_of_trades=0,
177-
win_rate=0.0,
178-
win_loss_ratio=0.0,
179-
)
180-
summary.add(metrics)
181-
self.assertEqual(summary.total_net_gain, 100)
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
from unittest import TestCase
2+
from investing_algorithm_framework.domain import BacktestMetrics, \
3+
BacktestSummaryMetrics, Trade, generate_backtest_summary_metrics
4+
from datetime import datetime, date
5+
6+
class TestCombine(TestCase):
7+
8+
def test_add(self):
9+
# Metrics one: a winning backtest
10+
metrics_one = BacktestMetrics(
11+
backtest_start_date=datetime(2020, 1, 1),
12+
backtest_end_date=datetime(2020, 12, 31),
13+
equity_curve=[(1000, datetime(2020, 1, 1)),
14+
(1500, datetime(2020, 12, 31))],
15+
total_growth=500,
16+
total_growth_percentage=50.0,
17+
total_net_gain=500,
18+
total_net_gain_percentage=50.0,
19+
final_value=1500.0,
20+
cagr=0.1,
21+
sharpe_ratio=1.2,
22+
rolling_sharpe_ratio=[],
23+
sortino_ratio=1.0,
24+
calmar_ratio=0.8,
25+
profit_factor=1.5,
26+
gross_profit=700,
27+
gross_loss=-200,
28+
annual_volatility=0.15,
29+
monthly_returns=[],
30+
yearly_returns=[],
31+
drawdown_series=[],
32+
max_drawdown=0.15,
33+
max_drawdown_absolute=100,
34+
max_daily_drawdown=-50,
35+
max_drawdown_duration=10,
36+
trades_per_year=12,
37+
trade_per_day=0.05,
38+
exposure_ratio=0.6,
39+
average_trade_gain=50,
40+
average_trade_gain_percentage=5.0,
41+
average_trade_loss=-20,
42+
average_trade_loss_percentage=-2.0,
43+
best_trade=Trade(id=1, open_price=100,
44+
opened_at=datetime(2020, 1, 1),
45+
closed_at=datetime(2020, 2, 1), orders=[],
46+
target_symbol="BTC", trading_symbol="EUR",
47+
amount=1, cost=100, available_amount=1,
48+
remaining=0, filled_amount=1, status="closed"),
49+
worst_trade=Trade(id=2, open_price=100,
50+
opened_at=datetime(2020, 3, 1),
51+
closed_at=datetime(2020, 4, 1), orders=[],
52+
target_symbol="BTC", trading_symbol="EUR",
53+
amount=1, cost=100, available_amount=1,
54+
remaining=0, filled_amount=1, status="closed"),
55+
average_trade_duration=5.0,
56+
number_of_trades=10,
57+
win_rate=0.7,
58+
win_loss_ratio=1.5,
59+
percentage_winning_months=0.6,
60+
percentage_winning_years=1.0,
61+
average_monthly_return=0.04,
62+
average_monthly_return_losing_months=-0.02,
63+
average_monthly_return_winning_months=0.08,
64+
best_month=(0.10, datetime(2020, 5, 1)),
65+
best_year=(0.5, date(2020, 12, 31)),
66+
worst_month=(-0.05, datetime(2020, 3, 1)),
67+
worst_year=(-0.1, date(2020, 12, 31)),
68+
)
69+
70+
# Metrics two: a losing backtest
71+
metrics_two = BacktestMetrics(
72+
backtest_start_date=datetime(2021, 1, 1),
73+
backtest_end_date=datetime(2021, 12, 31),
74+
equity_curve=[(2000, datetime(2021, 1, 1)),
75+
(1800, datetime(2021, 12, 31))],
76+
total_growth=-200,
77+
total_growth_percentage=-10.0,
78+
total_net_gain=-200,
79+
total_net_gain_percentage=-10.0,
80+
final_value=1800.0,
81+
cagr=-0.05,
82+
sharpe_ratio=-0.5,
83+
rolling_sharpe_ratio=[],
84+
sortino_ratio=-0.4,
85+
calmar_ratio=-0.3,
86+
profit_factor=0.7,
87+
gross_profit=300,
88+
gross_loss=-500,
89+
annual_volatility=0.25,
90+
monthly_returns=[],
91+
yearly_returns=[],
92+
drawdown_series=[],
93+
max_drawdown=0.2,
94+
max_drawdown_absolute=400,
95+
max_daily_drawdown=-150,
96+
max_drawdown_duration=30,
97+
trades_per_year=24,
98+
trade_per_day=0.1,
99+
exposure_ratio=0.8,
100+
average_trade_gain=20,
101+
average_trade_gain_percentage=2.0,
102+
average_trade_loss=-50,
103+
average_trade_loss_percentage=-5.0,
104+
best_trade=Trade(id=3, open_price=200,
105+
opened_at=datetime(2021, 1, 1),
106+
closed_at=datetime(2021, 2, 1), orders=[],
107+
target_symbol="ETH", trading_symbol="EUR",
108+
amount=2, cost=200, available_amount=2,
109+
remaining=0, filled_amount=2, status="closed"),
110+
worst_trade=Trade(id=4, open_price=200,
111+
opened_at=datetime(2021, 3, 1),
112+
closed_at=datetime(2021, 4, 1), orders=[],
113+
target_symbol="ETH", trading_symbol="EUR",
114+
amount=2, cost=200, available_amount=2,
115+
remaining=0, filled_amount=2, status="closed"),
116+
average_trade_duration=7.0,
117+
number_of_trades=20,
118+
win_rate=0.3,
119+
win_loss_ratio=0.6,
120+
percentage_winning_months=0.3,
121+
percentage_winning_years=0.0,
122+
average_monthly_return=-0.02,
123+
average_monthly_return_losing_months=-0.05,
124+
average_monthly_return_winning_months=0.03,
125+
best_month=(0.07, datetime(2021, 7, 1)),
126+
best_year=(0.2, date(2021, 12, 31)),
127+
worst_month=(-0.15, datetime(2021, 6, 1)),
128+
worst_year=(-0.2, date(2021, 12, 31)),
129+
)
130+
131+
summary: BacktestSummaryMetrics = generate_backtest_summary_metrics(
132+
[metrics_one, metrics_two])
133+
134+
# --- Assertions ---
135+
# Sum metrics
136+
self.assertEqual(summary.total_net_gain, 300) # 500 + (-200)
137+
self.assertEqual(summary.total_loss, -700) # -200 + -500
138+
self.assertEqual(summary.number_of_trades, 30) # 10 + 20
139+
140+
# Mean metrics
141+
self.assertAlmostEqual(summary.cagr, (0.1 + -0.05) / 2, places=2)
142+
self.assertAlmostEqual(summary.sharpe_ratio, (1.2 + -0.5) / 2, places=2)
143+
self.assertAlmostEqual(summary.sortino_ratio, (1.0 + -0.4) / 2, places=2)
144+
self.assertAlmostEqual(summary.calmar_ratio, (0.8 + -0.3) / 2, places=2)
145+
self.assertAlmostEqual(summary.profit_factor, (1.5 + 0.7) / 2, places=2)
146+
self.assertAlmostEqual(summary.win_rate, (0.7 + 0.3) / 2, places=2)
147+
148+
# Extreme metrics
149+
self.assertEqual(summary.max_drawdown, 0.2) # worst of the two
150+
self.assertEqual(summary.max_drawdown_duration, 30) # longest

0 commit comments

Comments
 (0)