Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dc10b30

Browse filesBrowse files
committed
ENH: Add stat 'CAGR [%]' (compound annual growth rate)
1 parent aa2f0f1 commit dc10b30
Copy full SHA for dc10b30

4 files changed

+28-21Lines changed: 28 additions & 21 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎README.md‎

Copy file name to clipboardExpand all lines: README.md
+1Lines changed: 1 addition & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ Return [%] 589.35
6262
Buy & Hold Return [%] 703.46
6363
Return (Ann.) [%] 25.42
6464
Volatility (Ann.) [%] 38.43
65+
CAGR [%] 16.80
6566
Sharpe Ratio 0.66
6667
Sortino Ratio 1.30
6768
Calmar Ratio 0.77
Collapse file

‎backtesting/_stats.py‎

Copy file name to clipboardExpand all lines: backtesting/_stats.py
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ def _round_timedelta(value, _period=_data_period(index)):
9999
gmean_day_return: float = 0
100100
day_returns = np.array(np.nan)
101101
annual_trading_days = np.nan
102-
if isinstance(index, pd.DatetimeIndex):
102+
is_datetime_index = isinstance(index, pd.DatetimeIndex)
103+
if is_datetime_index:
103104
day_returns = equity_df['Equity'].resample('D').last().dropna().pct_change()
104105
gmean_day_return = geometric_mean(day_returns)
105106
annual_trading_days = float(
@@ -115,6 +116,9 @@ def _round_timedelta(value, _period=_data_period(index)):
115116
s.loc['Volatility (Ann.) [%]'] = np.sqrt((day_returns.var(ddof=int(bool(day_returns.shape))) + (1 + gmean_day_return)**2)**annual_trading_days - (1 + gmean_day_return)**(2*annual_trading_days)) * 100 # noqa: E501
116117
# s.loc['Return (Ann.) [%]'] = gmean_day_return * annual_trading_days * 100
117118
# s.loc['Risk (Ann.) [%]'] = day_returns.std(ddof=1) * np.sqrt(annual_trading_days) * 100
119+
if is_datetime_index:
120+
time_in_years = (s.loc['Duration'].days + s.loc['Duration'].seconds / 86400) / annual_trading_days
121+
s.loc['CAGR [%]'] = ((s.loc['Equity Final [$]'] / equity[0])**(1/time_in_years) - 1) * 100 if time_in_years else np.nan # noqa: E501
118122

119123
# Our Sharpe mismatches `empyrical.sharpe_ratio()` because they use arithmetic mean return
120124
# and simple standard deviation
Collapse file

‎backtesting/backtesting.py‎

Copy file name to clipboardExpand all lines: backtesting/backtesting.py
+21-20Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,31 +1145,32 @@ def run(self, **kwargs) -> pd.Series:
11451145
Start 2004-08-19 00:00:00
11461146
End 2013-03-01 00:00:00
11471147
Duration 3116 days 00:00:00
1148-
Exposure Time [%] 93.9944
1149-
Equity Final [$] 51959.9
1150-
Equity Peak [$] 75787.4
1151-
Return [%] 419.599
1152-
Buy & Hold Return [%] 703.458
1153-
Return (Ann.) [%] 21.328
1154-
Volatility (Ann.) [%] 36.5383
1155-
Sharpe Ratio 0.583718
1156-
Sortino Ratio 1.09239
1157-
Calmar Ratio 0.444518
1158-
Max. Drawdown [%] -47.9801
1148+
Exposure Time [%] 96.74115
1149+
Equity Final [$] 51422.99
1150+
Equity Peak [$] 75787.44
1151+
Return [%] 414.2299
1152+
Buy & Hold Return [%] 703.45824
1153+
Return (Ann.) [%] 21.18026
1154+
Volatility (Ann.) [%] 36.49391
1155+
CAGR [%] 14.15984
1156+
Sharpe Ratio 0.58038
1157+
Sortino Ratio 1.08479
1158+
Calmar Ratio 0.44144
1159+
Max. Drawdown [%] -47.98013
11591160
Avg. Drawdown [%] -5.92585
11601161
Max. Drawdown Duration 584 days 00:00:00
11611162
Avg. Drawdown Duration 41 days 00:00:00
1162-
# Trades 65
1163-
Win Rate [%] 46.1538
1164-
Best Trade [%] 53.596
1165-
Worst Trade [%] -18.3989
1166-
Avg. Trade [%] 2.35371
1163+
# Trades 66
1164+
Win Rate [%] 46.9697
1165+
Best Trade [%] 53.59595
1166+
Worst Trade [%] -18.39887
1167+
Avg. Trade [%] 2.53172
11671168
Max. Trade Duration 183 days 00:00:00
11681169
Avg. Trade Duration 46 days 00:00:00
1169-
Profit Factor 2.08802
1170-
Expectancy [%] 8.79171
1171-
SQN 0.916893
1172-
Kelly Criterion 0.6134
1170+
Profit Factor 2.16795
1171+
Expectancy [%] 3.27481
1172+
SQN 1.07662
1173+
Kelly Criterion 0.15187
11731174
_strategy SmaCross
11741175
_equity_curve Eq...
11751176
_trades Size EntryB...
Collapse file

‎backtesting/test/_test.py‎

Copy file name to clipboardExpand all lines: backtesting/test/_test.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ def test_compute_stats(self):
275275
'Return (Ann.) [%]': 21.180255813792282,
276276
'Return [%]': 414.2298999999996,
277277
'Volatility (Ann.) [%]': 36.49390889140787,
278+
'CAGR [%]': 14.159843619607383,
278279
'SQN': 1.0766187356697705,
279280
'Kelly Criterion': 0.1518705127029717,
280281
'Sharpe Ratio': 0.5803778344714113,

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.