Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

closes #65 (Sourcery refactored) #67

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 34 additions & 8 deletions okama/portfolio.py
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,34 @@ def dividend_yield(self) -> pd.Series:
div_yield_series.rename(self.symbol, inplace=True)
return div_yield_series

@property
def dividends_annual(self) -> pd.DataFrame:
"""
Return calendar year dividends sum time series for each asset.

Returns
-------
DataFrame
Annual dividends time series for each asset.

See Also
--------
dividend_yield : Dividend yield time series.
dividend_yield_annual : Calendar year dividend yield time series.
dividend_paying_years : Number of years of consecutive dividend payments.
dividend_growing_years : Number of years when the annual dividend was growing.
get_dividend_mean_yield : Arithmetic mean for annual dividend yield.
get_dividend_mean_growth_rate : Geometric mean of annual dividends growth rate.

Examples
--------
>>> import matplotlib.pyplot as plt
>>> x = ok.AssetList(['T.US', 'XOM.US'], first_date='2010-01', last_date='2020-12')
>>> x.dividends_annual.plot(kind='bar')
>>> plt.show()
"""
return self._get_assets_dividends().resample("Y").sum()

@property
def assets_dividend_yield(self):
"""
Expand Down Expand Up @@ -1090,9 +1118,7 @@ def recovery_period(self) -> int:
s1 = s.where(s == 0).notnull().astype(int)
s1_1 = s.where(s == 0).isnull().astype(int).cumsum()
s2 = s1.groupby(s1_1).cumsum()
# Max recovery period date should not be in the border (means it's not recovered)
max_period = s2.max() if s2.idxmax().to_timestamp() != self.last_date else np.NAN
return max_period
return s2.max() if s2.idxmax().to_timestamp() != self.last_date else np.NAN

def describe(self, years: Tuple[int] = (1, 5, 10)) -> pd.DataFrame:
"""
Expand Down Expand Up @@ -1304,7 +1330,7 @@ def percentile_inverse_cagr(
"""
if distr == "hist":
cagr_distr = self.get_rolling_cagr(years * settings._MONTHS_PER_YEAR).loc[:, [self.symbol]].squeeze()
elif distr in ["norm", "lognorm"]:
elif distr in {"norm", "lognorm"}:
if not n:
n = 1000
cagr_distr = self._get_cagr_distribution(distr=distr, years=years, n=n)
Expand Down Expand Up @@ -1353,7 +1379,7 @@ def percentile_history_cagr(self, years: int, percentiles: List[int] = [10, 50,
self.get_rolling_cagr(years * 12).loc[:, self.symbol].quantile(percentile / 100)
for years in period_range
]
returns_dict.update({percentile: percentile_returns_list})
returns_dict[percentile] = percentile_returns_list
df = pd.DataFrame(returns_dict, index=list(period_range))
df.index.rename("years", inplace=True)
return df
Expand Down Expand Up @@ -1585,7 +1611,7 @@ def percentile_distribution_cagr(
results = {}
for percentile in percentiles:
value = cagr_distr.quantile(percentile / 100)
results.update({percentile: value})
results[percentile] = value
return results

def percentile_wealth(
Expand Down Expand Up @@ -1641,12 +1667,12 @@ def percentile_wealth(
"""
if distr == "hist":
results = self.percentile_wealth_history(years=years, percentiles=percentiles).iloc[-1].to_dict()
elif distr in ["norm", "lognorm"]:
elif distr in {"norm", "lognorm"}:
results = {}
wealth_indexes = self._monte_carlo_wealth(distr=distr, years=years, n=n)
for percentile in percentiles:
value = wealth_indexes.iloc[-1, :].quantile(percentile / 100)
results.update({percentile: value})
results[percentile] = value
else:
raise ValueError('distr should be "norm", "lognorm" or "hist".')
if today_value:
Expand Down
21 changes: 21 additions & 0 deletions t_test_portfolio_dividends_annual.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pytest
import okama as ok

tickers = [
"BND.US",
"VTI.US",
"VXUS.US"
]

w = [0.34, 0.33, 0.33]

portfolio = ok.Portfolio(tickers, weights=w, rebalancing_period="none", inflation=False)

def test_dividend_yield():
return portfolio.assets_dividend_yield

def test_dividends_annual():
return portfolio.dividends_annual

# portfolio.assets_dividend_yield
# portfolio.dividends_annual
Loading