<jupyter_start><jupyter_text>Mejoras de código en simulación y optimización de portafolios > En clases anteriores observamos que la función minimize de scipy.optimize no fue adecuada para calcular la frontera eficiente de portafolios. Para cumplir este objetivo, utilizaremos una librería especializada en optimización convexa para Python llamada `cvxopt`.> Por otra parte, ya entendimos la manera de simular portafolios por montecarlo, así que no es relevante tener que programar estas simulaciones cada vez. Tampoco es relevante tener que programar la obtención de la frontera eficiente por optimización una y otra vez.> Por lo anterior, incluiremos en el script `portfolio_func.py` un compendio de funciones para este objetivo.  0. Librerías necesarias<jupyter_code>#importar los paquetes que se van a usar
import pandas as pd
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
import cvxopt as opt
from cvxopt import blas, solvers
solvers.options['show_progress'] = False
%matplotlib inline
pd.set_option('display.notebook_repr_html', True)
pd.set_option('display.max_columns', 6)
pd.set_option('display.max_rows', 10)
pd.set_option('display.width', 78)
pd.set_option('precision', 3)
#Funciones para portafolios
import portfolio_func<jupyter_output><empty_output><jupyter_text>1. Descargar precios de cierre En el script `portfolio_func.py` se incluyó la función `get_historical_closes(ticker, start_date, end_date)` que hemos venido usando en clase...<jupyter_code>tickers = ['AA', 'AAPL', 'AMZN', 'MSFT']
closes = portfolio_func.get_historical_closes(tickers, '2016-01-01')
closes.plot(figsize=(8,6))<jupyter_output><empty_output><jupyter_text>2. Formulación del riesgo de un portafolio y simulación Montecarlo En el script `portfolio_func.py` se incluyó la función `calc_daily_ret(closes)`<jupyter_code>daily_ret = portfolio_func.calc_daily_ret(closes)
daily_ret.plot(figsize=(8,6));
daily_ret<jupyter_output><empty_output><jupyter_text>De igual forma, se incluyó la función `sim_mont_portfolio(daily_ret, num_portfolios, risk_free)`<jupyter_code>results_mont = portfolio_func.sim_mont_portfolio(daily_ret, 10000, 0.015)
results_mont<jupyter_output><empty_output><jupyter_text>Obtener los portafolios con sharpe máximo y con mínima volatilidad, respectivamente<jupyter_code>min_vol_port = results_mont.iloc[results_mont.SD.idxmin()]
max_sharpe_port = results_mont.iloc[results_mont.Sharpe.idxmax()]<jupyter_output><empty_output><jupyter_text>Graficar **Rendimiento vs. Volatilidad** con `matplotlib.pyplot.scatter`, colorear con el código 'RdYlBu' de acuerdo al sharpe, y resaltar los portafolios de máximo sharpe y mínima volatilidad...<jupyter_code>plt.figure(figsize=(8,6))
plt.scatter(results_mont.SD, results_mont.Rendimiento, cmap = 'RdYlBu', c = results_mont.Sharpe)
plt.xlabel('Volatilidad')
plt.ylabel('Rendimiento')
plt.colorbar()

plt.scatter(max_sharpe_port.SD, max_sharpe_port.Rendimiento, marker=(5,1,0), s=500, c='g')
plt.scatter(min_vol_port.SD, min_vol_port.Rendimiento, marker=(5,1,0), s=500, c='r')<jupyter_output><empty_output><jupyter_text>3. Optimización de portafolios En el script `portfolio_func.py`, se incluyó la función `optimal_portfolio(daily_ret, n_opt, risk_free)`<jupyter_code>results_opt = portfolio_func.optimal_portfolio(daily_ret, 100, 0.015)
results_opt<jupyter_output><empty_output><jupyter_text>Comparar simulación montecarlo con frontera eficiente obtenida por optimización convexa...<jupyter_code>plt.figure(figsize=(8,6))
plt.plot(results_opt.SD, results_opt.Rendimiento, 'r', lw = 5)

plt.scatter(results_mont.SD, results_mont.Rendimiento, cmap = 'RdYlBu', c = results_mont.Sharpe)
plt.scatter(max_sharpe_port.SD, max_sharpe_port.Rendimiento, marker=(5,1,0), s=500, c='g')
plt.scatter(min_vol_port.SD, min_vol_port.Rendimiento, marker=(5,1,0), s=500, c='r')
#plt.colorbar()

plt.xlabel('Volatilidad')
plt.ylabel('Rendimiento')<jupyter_output><empty_output><jupyter_text>Señalar portafolios de mínima volatilidad y de máximo sharpe<jupyter_code>min_vol_port = results_opt.iloc[results_opt.SD.idxmin()]
max_sharpe_port = results_opt.iloc[results_opt.Sharpe.idxmax()]
plt.figure(figsize=(8,6))
plt.plot(results_opt.SD, results_opt.Rendimiento, 'r', lw = 5)

plt.scatter(results_mont.SD, results_mont.Rendimiento, cmap = 'RdYlBu', c = results_mont.Sharpe)
plt.scatter(max_sharpe_port.SD, max_sharpe_port.Rendimiento, marker=(5,1,0), s=500, c='g')
plt.scatter(min_vol_port.SD, min_vol_port.Rendimiento, marker=(5,1,0), s=500, c='r')
#plt.colorbar()

plt.xlabel('Volatilidad')
plt.ylabel('Rendimiento')<jupyter_output><empty_output><jupyter_text>4. Optimización incluyendo bono En el script `portfolio_func.py`, se incluyó la función `optimal_portfolio_b(daily_ret, n_opt, risk_free, c0)`<jupyter_code>results_opt_b = portfolio_func.optimal_portfolio_b(daily_ret, 100, 0.015, 0.01/252)
results_opt_b<jupyter_output><empty_output><jupyter_text>Portafolios de mínima volatilidad y máximo sharpe<jupyter_code>min_vol_port = results_opt_b.iloc[results_opt_b.SD.idxmin()]
max_sharpe_port = results_opt_b.iloc[results_opt_b.Sharpe.idxmax()]<jupyter_output><empty_output><jupyter_text>Gráficos de frontera y portafolios notables<jupyter_code>plt.figure(figsize=(8,6))
plt.plot(results_opt_b.SD, results_opt_b.Rendimiento, 'r', lw = 5)

plt.scatter(max_sharpe_port.SD, max_sharpe_port.Rendimiento, marker=(5,1,0), s=500, c='g')
plt.scatter(min_vol_port.SD, min_vol_port.Rendimiento, marker=(5,1,0), s=500, c='r')
#plt.colorbar()

plt.xlabel('Volatilidad')
plt.ylabel('Rendimiento')
max_sharpe_port
min_vol_port<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11543959971408149, 'fraction_numerical': 0.020014295925661188, 'mean_word_length': 8.683391003460208, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 52, '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': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '434881', 'license': 'MIT', 'n_tokens_mistral': 2272, 'n_tokens_neox': 2192, 'n_words': 415, 'path': 'Modulo2/Clase10_MejorasCodigoFunc.ipynb', 'repo_name': 'esjimenezro/SimRC2018-1', 'size': '5596'}