Skip to content

Commit a323fc3

Browse files
committed
- index_rolling_corr is a new additional methods to compare ETFs with index (benchmarks) in AssetList
- bug fixed in tracking_difference_annualized - howto jupyter notebook for index funds
1 parent d2a5302 commit a323fc3

File tree

5 files changed

+433
-8
lines changed

5 files changed

+433
-8
lines changed

main.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import okama as ok
22

3-
ls4 = ['SPY.US', 'BND.US', 'GLD.US', 'VNQ.US']
4-
curr = 'USD'
5-
four_assets = ok.EfficientFrontier(symbols=ls4, curr=curr, n_points=100)
6-
ok.Plots(ls4, curr=curr).plot_pair_ef()
3+
funds1 = ['MCFTR.INDX', '0177-71671092.PIF', '0890-94127385.PIF']
4+
curr = 'RUB'
5+
x1 = ok.AssetList(funds1, curr=curr)
6+
x1.tracking_difference_annualized

notebooks/Efficient Frontier.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@
302302
"cell_type": "markdown",
303303
"metadata": {},
304304
"source": [
305-
"Lets add a popular fisical gold and real estate ETFs..."
305+
"Let's add a popular fisical gold and real estate ETFs..."
306306
]
307307
},
308308
{

notebooks/index funds perfomance.ipynb

Lines changed: 395 additions & 0 deletions
Large diffs are not rendered by default.

okama/assets.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,12 +598,21 @@ def index_corr(self):
598598
"""
599599
return Index.cov_cor(self.ror, fn='corr')
600600

601+
def index_rolling_corr(self, window=60):
602+
"""
603+
Returns the rolling correlation with the index (or benchmark) time series for the assets.
604+
Index should be in the first position (first column).
605+
The period should be at least 12 months.
606+
window - the rolling window size (default is 5 years).
607+
"""
608+
return Index.rolling_cov_cor(self.ror, window=window, fn='corr')
609+
601610
@property
602611
def index_beta(self):
603612
"""
604613
Returns beta coefficient time series for the assets.
605614
Index (or benchmark) should be in the first position (first column).
606-
The period should be at least 12 months.
615+
Rolling window size should be at least 12 months.
607616
"""
608617
return Index.beta(self.ror)
609618

okama/helpers.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,8 @@ def tracking_difference_annualized(tracking_diff: pd.DataFrame) -> pd.DataFrame:
366366
"""
367367
pwr = 12 / (1. + np.arange(tracking_diff.shape[0]))
368368
y = abs(tracking_diff)
369-
diff = np.sign(tracking_diff) * (y + 1.).pow(pwr, axis=0) - 1.
369+
diff = (y + 1.).pow(pwr, axis=0) - 1.
370+
diff = np.sign(tracking_diff) * diff
370371
return diff.iloc[_MONTHS_PER_YEAR - 1:] # returns for the first 11 months can't be annualized
371372

372373
@staticmethod
@@ -392,12 +393,32 @@ def cov_cor(ror: pd.DataFrame, fn: str) -> pd.DataFrame:
392393
if ror.shape[1] < 2:
393394
raise ValueError('At least 2 symbols should be provided.')
394395
if fn not in ['cov', 'corr']:
395-
raise ValueError('fn should be cor or cov')
396+
raise ValueError('fn should be corr or cov')
396397
cov_matrix_ts = getattr(ror.expanding(), fn)()
397398
cov_matrix_ts = cov_matrix_ts.drop(index=ror.columns[1:], level=1).droplevel(1)
398399
cov_matrix_ts.drop(columns=ror.columns[0], inplace=True)
399400
return cov_matrix_ts.iloc[_MONTHS_PER_YEAR:]
400401

402+
@staticmethod
403+
def rolling_cov_cor(ror: pd.DataFrame, window: int = 60, fn: str = 'corr') -> pd.DataFrame:
404+
"""
405+
Returns the rolling correlation (or covariance) time series.
406+
The period should be at least 12 months.
407+
"""
408+
if ror.shape[1] < 2:
409+
raise ValueError('At least 2 symbols should be provided.')
410+
if fn not in ['cov', 'corr']:
411+
raise ValueError('fn should be corr or cov')
412+
if window < _MONTHS_PER_YEAR:
413+
raise ValueError('window size should be at least 12 months')
414+
if not isinstance(window, int):
415+
raise ValueError('window should be an integer')
416+
cov_matrix_ts = getattr(ror.rolling(window=window), fn)()
417+
cov_matrix_ts = cov_matrix_ts.drop(index=ror.columns[1:], level=1).droplevel(1)
418+
cov_matrix_ts.drop(columns=ror.columns[0], inplace=True)
419+
cov_matrix_ts.dropna(inplace=True)
420+
return cov_matrix_ts
421+
401422
@staticmethod
402423
def beta(ror: pd.DataFrame) -> pd.DataFrame:
403424
"""

0 commit comments

Comments
 (0)