Skip to content

Commit 5c7248f

Browse files
committed
feat: NEW EfficientFrontier is based on EfficientFrontierReb
1 parent 8f8ee17 commit 5c7248f

File tree

8 files changed

+253
-207
lines changed

8 files changed

+253
-207
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,13 @@ pf.dividend_yield.plot()
130130
![](../images/images/readmi05.png?raw=true)
131131

132132
### 3. Draw an Efficient Frontier for 2 popular ETF: SPY and GLD
133+
133134
```python
134135
ls = ['SPY.US', 'GLD.US']
135136
curr = 'USD'
136-
last_date='2020-10'
137+
last_date = '2020-10'
137138
# Rebalancing periods is one year (default value)
138-
frontier = ok.EfficientFrontierReb(ls, last_date=last_date, ccy=curr, rebalancing_strategy=ok.Rebalance(period='year'))
139+
frontier = ok.EfficientFrontier(ls, last_date=last_date, ccy=curr, rebalancing_strategy=ok.Rebalance(period='year'))
139140
frontier.names
140141
```
141142
![](../images/images/readmi06.jpg?raw=true)
@@ -156,9 +157,10 @@ ax.plot(points.Risk, points.CAGR)
156157
<nowiki>*</nowiki> - *rebalancing period is one year*.
157158

158159
### 4. Get a Transition Map for allocations
160+
159161
```python
160162
ls = ['SPY.US', 'GLD.US', 'BND.US']
161-
map = ok.EfficientFrontier(ls, ccy='USD').plot_transition_map(x_axe='risk')
163+
map = ok.EfficientFrontierSingle(ls, ccy='USD').plot_transition_map(x_axe='risk')
162164
```
163165
![](../images/images/readmi08.jpg?v23-11-2020,raw=true "Transition map")
164166

main.py

Lines changed: 21 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -12,146 +12,29 @@
1212

1313
pd.set_option("display.float_format", lambda x: "%.2f" % x)
1414

15-
# weights_div = [.07, 0.08, .10, .35, .15, .05, .20]
16-
reb = ok.Rebalance(period='year', abs_deviation=None, rel_deviation=None)
17-
assets = ['SBGB.MOEX', 'BOND.MOEX', 'OBLG.MOEX', 'EQMX.MOEX', 'GC.COMM', 'BTC-USD.CC', 'RUS_PR.RE']
18-
19-
portf_div = ok.Portfolio(
20-
assets,
21-
ccy='RUB',
22-
# weights=weights_div,
23-
symbol="portf_div.PF",
24-
rebalancing_strategy=reb,
25-
inflation=True
26-
)
27-
28-
print(portf_div.mean_return_monthly)
29-
30-
31-
32-
# pf.dcf.discount_rate = 0.09
33-
# # Percentage CF strategy
34-
# cf_strategy = ok.PercentageStrategy(pf) # create PercentageStrategy linked to the portfolio
35-
#
36-
# cf_strategy.initial_investment = 83_000_000 # initial investments size
37-
# cf_strategy.frequency = "year" # withdrawals frequency
38-
# cf_strategy.percentage = -0.09
39-
40-
# Indexation CF strategy
41-
# cf_strategy = ok.IndexationStrategy(pf)
42-
#
43-
# cf_strategy.initial_investment = 10_000_000
44-
# cf_strategy.frequency = "year"
45-
# cf_strategy.amount = 10_000_000 * 0.05
46-
# cf_strategy.indexation = 0.09
47-
#
48-
# pf.dcf.cashflow_parameters = cf_strategy
49-
#
50-
# pf.dcf.mc.period = 50
51-
# pf.dcf.mc.number = 100
52-
# pf.dcf.mc.distribution = "norm"
53-
54-
55-
# print(pf.dcf.monte_carlo_survival_period().describe())
56-
57-
58-
# Cut Whithdrawals if Drawdown CWID strategy
59-
# cf_strategy = ok.CutWithdrawalsIfDrawdown(pf)
60-
#
61-
# cf_strategy.initial_investment = 10_000_000
62-
# cf_strategy.frequency = "none"
63-
# cf_strategy.amount = -10_000_000 * 0.05 / 12
64-
# cf_strategy.indexation = 0.09
65-
# cf_strategy.crash_threshold_reduction = [
66-
# (.10, .20),
67-
# (.20, .50),
68-
# (.40, 1),
69-
# ]
70-
71-
# d = {
72-
# "2015-06": -35_000_000,
73-
# }
74-
#
75-
# cf_strategy.time_series_dic = d
76-
# cf_strategy.time_series_discounted_values = False
77-
78-
# # VDS strategy
79-
# cf_strategy = ok.VanguardDynamicSpending(pf)
80-
# cf_strategy.initial_investment = 1_000_000
81-
# cf_strategy.percentage = -0.08
82-
# cf_strategy.indexation = 0.09
83-
# # cf_strategy.min_max_annual_withdrawal = 10_000_000 / 5, 10_000_000 / 10 # 20%, 10%
84-
# cf_strategy.floor_ceiling = -0.10, 0.20
85-
# # cf_strategy.time_series_dic = d
86-
# # cf_strategy.time_series_discounted_values = False
87-
88-
# pf.dcf.cashflow_parameters = cf_strategy # assign the cash flow strategy to portfolio
89-
90-
# w = cf_strategy.calculate_withdrawal_size(
91-
# last_withdrawal=0,
92-
# balance=cf_strategy.initial_investment,
93-
# number_of_periods=1
94-
# )
95-
96-
# print(pf.dcf.cashflow_parameters)
97-
# # pf.dcf.set_mc_parameters(
98-
# # distribution="norm",
99-
# # period=15,
100-
# # number=100
101-
# # )
102-
# print(pf.dcf.cashflow_parameters._crash_threshold_reduction_series)
103-
104-
# pf.dcf.set_mc_parameters(
105-
# distribution="t",
106-
# parameters=(3, None, None),
107-
# period=100,
108-
# number=1_000,
109-
# )
110-
111-
# wi = pf.dcf.wealth_index(discounting="pv", include_negative_values=False)
112-
# cf = pf.dcf.cash_flow_ts(discounting="pv", remove_if_wealth_index_negative=True).resample("Y").sum()
113-
# cf = pf.dcf.cash_flow_ts(discounting="pv", remove_if_wealth_index_negative=True)
114-
# wi = pf.dcf.monte_carlo_wealth(discounting="fv", include_negative_values=False)
115-
# cf = pf.dcf.monte_carlo_cash_flow(discounting="pv", remove_if_wealth_index_negative=True)
116-
# print(cf)
117-
# print(cf.pct_change())
118-
# wi.plot(
119-
# # kind="bar",
120-
# legend=False
121-
# )
122-
# plt.yscale('linear') # linear or log
123-
# plt.show()
124-
#
125-
# df = cf[0]
126-
# cf.plot(
127-
# kind="bar",
128-
# legend=False
15+
ls_m = ["SPY.US", "GLD.US", "PGJ.US", "RGBITR.INDX", "MCFTR.INDX"]
16+
curr_rub = "RUB"
17+
18+
# x = ok.EfficientFrontier(
19+
# assets=ls_m,
20+
# first_date="2005-01",
21+
# last_date="2020-11",
22+
# ccy=curr_rub,
23+
# # rebalancing_strategy=ok.Rebalance(period="year"), # set rebalancing period to one year
24+
# n_points=20,
25+
# verbose=False,
12926
# )
130-
# plt.yscale('linear') # linear or log
131-
# plt.show()
13227

133-
# print(df[df != 0])
134-
135-
# df = pf.dcf.monte_carlo_wealth_fv
136-
# print(df)
137-
138-
139-
# sp = pf.dcf.monte_carlo_survival_period()
140-
# print(sp.quantile(25 / 100), " years")
141-
142-
# mc_wealth_pv = pf.dcf.monte_carlo_wealth_pv.iloc[-1].describe([.05, .10, .20, .50])
143-
# print(f"{mc_wealth_pv=}")
144-
145-
# print(pf.dcf.wealth_index.iloc[-1, :])
28+
x = ok.EfficientFrontier(
29+
assets=ls_m,
30+
first_date="2005-01",
31+
last_date="2020-11",
32+
ccy=curr_rub,
33+
n_points=40,
34+
# rebalancing_strategy=ok.Rebalance(period="year"), # set rebalancing period to one year
35+
)
14636

37+
ef_points = x.ef_points
14738

148-
# pf.dcf.mc.plot_qq(bootstrap_size_var=2000, zoom_to_left_tail=50, figsize=(10, 10))
149-
# pf.dcf.set_mc_parameters(
150-
# distribution="norm",
151-
# distribution_parameters=(2, None),
152-
# period=100,
153-
# mc_number=1_000,
154-
# )
155-
# pf.dcf.mc.plot_hist_fit(bins=100)
156-
# plt.show()
39+
print(ef_points[["Mean return", "CAGR"]])
15740

okama/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
from okama.portfolios.dcf import PortfolioDCF
3232
from okama.portfolios.cashflow_strategies import CashFlow, IndexationStrategy, PercentageStrategy, TimeSeriesStrategy, VanguardDynamicSpending, CutWithdrawalsIfDrawdown
3333
from okama.macro import Inflation, Rate, Indicator
34-
from okama.frontier.multi_period import EfficientFrontierReb
35-
from okama.frontier.single_period import EfficientFrontier
34+
from okama.frontier.multi_period import EfficientFrontier
35+
from okama.frontier.single_period import EfficientFrontierSingle
3636
from okama.api.data_queries import QueryData
3737
from okama.api.search import search
3838
from okama.api.api_methods import API

0 commit comments

Comments
 (0)