<jupyter_start><jupyter_text>**EfficientFrontier** class can be used for "classic" frontiers where all portfolios are **rebalanced mothly**. It's the most easy and fast way to draw an Efficient Frontier.  Simple efficient frontier for 2 ETF<jupyter_code>ls2 = ['SPY.US', 'BND.US']
curr='USD'
two_assets = ok.EfficientFrontier(symbols=ls2, curr=curr, n_points=100)  # n_points - specifies a number of points in the Efficient Frontier chart (default is 20)
two_assets<jupyter_output><empty_output><jupyter_text>**ef_points** property returns the dataframe (table).  Each row has properties of portfolio or point in the frontier:  _Risk_ - the volatility or standard deviation  _Mean return_ - the expectation or arithmetic mean  _CAGR_ - Compound annual growth rateAll the properties have annualized values.  Last columns are weights for each asset.<jupyter_code>df = two_assets.ef_points
df
fig = plt.figure()

# Plotting the assets
ok.Plots(ls2, curr=curr).plot_assets(kind='cagr')
ax = plt.gca()

# Plotting the Efficient Frontier
ax.plot(df['Risk'], df['CAGR']);<jupyter_output><empty_output><jupyter_text>It's possible to draw both efficient frontiers: for mean return and for CAGR with the same dataframe.<jupyter_code>fig = plt.figure()

# Plotting the assets
ok.Plots(ls2, curr=curr).plot_assets(kind='cagr')
ax = plt.gca()

# Plotting the Efficient Frontiers
# EF with mean return
ax.plot(df['Risk'], df['Mean return'])
# EF with CAGR
ax.plot(df['Risk'], df['CAGR']);<jupyter_output><empty_output><jupyter_text>Several assets Let's add a popular fisical gold and real estate ETFs...<jupyter_code>ls4 = ['SPY.US', 'BND.US', 'GLD.US', 'VNQ.US']
curr = 'USD'
four_assets = ok.EfficientFrontier(symbols=ls4, curr=curr, n_points=100)
four_assets
df4 = four_assets.ef_points
fig = plt.figure()

# Plotting the assets
ok.Plots(ls4, curr=curr).plot_assets(kind='cagr')
ax = plt.gca()

# Plotting the Efficient Frontier
ax.plot(df4['Risk'], df4['CAGR']);<jupyter_output><empty_output><jupyter_text>Efficient Frontier for each pair of assets Sometimes it can be helpful to see how each pair of assets "contributes" to the common efficient frontier by drawing all the pair frontiers.<jupyter_code>ok.Plots(ls4, curr=curr).plot_pair_ef();<jupyter_output><empty_output><jupyter_text>We can see all efficent frontiers (pairs and 4 assets) in a common chart ...<jupyter_code>fig = plt.figure()

# Plotting the assets
ok.Plots(ls4, curr=curr).plot_pair_ef()

ax = plt.gca()

# Plotting the Efficient Frontier
ax.plot(df4['Risk'], df4['Mean return'], color = 'black', linestyle='--');<jupyter_output><empty_output><jupyter_text>Global Minimum Variance (GMV) portfolio GMV weights and values could be found with **gmv_weights**, **gmv_monthly** and **gmv_annualized** methods. Weights of GMV portfolio:<jupyter_code>four_assets.gmv_weights<jupyter_output><empty_output><jupyter_text>Risk and mean return on monthly basis:<jupyter_code>four_assets.gmv_monthly<jupyter_output><empty_output><jupyter_text>Risk and mean return annualized:<jupyter_code>four_assets.gmv_annualized<jupyter_output><empty_output><jupyter_text>With annualized values it's easy to draw the GMV point on the chart.<jupyter_code>fig = plt.figure()
ax = plt.gca()

# Plotting the Efficient Frontier
ax.plot(df4['Risk'], df4['CAGR']);

# plotting GMV point
ax.scatter(four_assets.gmv_annualized[0], four_assets.gmv_annualized[1])

# annotations for GMV point
ax.annotate("GMV",  # this is the text
            (four_assets.gmv_annualized[0], four_assets.gmv_annualized[1]),  # this is the point to label
            textcoords="offset points",  # how to position the text
            xytext=(0, 10),  # distance from text to points (x,y)
            ha='center');  # horizontal alignment can be left, right or center<jupyter_output><empty_output><jupyter_text>Monte Carlo simulation for efficient frontier Monte Carlo simulation is useful to visualize portfolios allocation inside the Efficient Frontier. It generates N random weights and calculates their properties (risk and return metrics). Let's create a list of popular German stocks, add US bonds ETF (AGG) and spot gold prices (GC.COMM). Portfolios currency is EUR.<jupyter_code>ls5 = ['DBK.XETR', 'SIE.XETR', 'TKA.XETR', 'AGG.US', 'GC.COMM']
curr = 'EUR'
gr = ok.EfficientFrontier(symbols=ls5, curr=curr, n_points=100)
gr
gr.names<jupyter_output><empty_output><jupyter_text>To create a "cloud" of random portfolios **get_monte_carlo** method is used.<jupyter_code>mc = gr.get_monte_carlo(n=5000, kind='cagr')  # it is possible to choose whether mean return or CAGR is used with "kind" attribute
mc<jupyter_output><empty_output><jupyter_text>We can plot the random portfolios with matplotlib **scatter** method. To add the assets point to the chart **plot_assets** is used (with Plots class).<jupyter_code>fig = plt.figure(figsize=(12,6))
fig.subplots_adjust(bottom=0.2, top=1.5)
ok.Plots(ls5, curr='EUR').plot_assets(kind='cagr')  # plot the assets points
ax = plt.gca()

ax.scatter(mc.Risk, mc.CAGR, linewidth=0, color='green');<jupyter_output><empty_output><jupyter_text>As the random portfolios "cloud" usually does not have an obvious shape, sometimes it's worth to draw Monte Carlos simulation together with the Efficient Frontier.<jupyter_code>ef = gr.ef_points  # calculate Efficient Frontier points
fig = plt.figure(figsize=(12,6))
fig.subplots_adjust(bottom=0.2, top=1.5)
ok.Plots(ls5, curr='EUR').plot_assets(kind='cagr')  # plot the assets points
ax = plt.gca()

ax.plot(ef.Risk, ef['CAGR'], color='black', linestyle='dashed', linewidth=3) # plot the Efficient Frontier

ax.scatter(mc.Risk, mc.CAGR, linewidth=0, color='green');  # plot the Monte Carlo simulation results<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11854050279329609, 'fraction_numerical': 0.010649441340782122, 'mean_word_length': 6.2427307206068265, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '10166', 'license': 'MIT', 'n_tokens_mistral': 2026, 'n_tokens_neox': 1956, 'n_words': 549, 'path': 'notebooks/03 efficient frontier.ipynb', 'repo_name': 'avpak/okama', 'size': '5728'}