<jupyter_start><jupyter_text>Metodo de Newton para solucionar el problema de Markovitz**Responsable:**<NAME>**Infraestructura usada:** Google Colab, para pruebas**Fuente:** código desarrollada en etapas previas Objetivo:Utilizar el método de Newton visto en clase, utilizando tanto diferenciación aproximada y funciones simbólicas, para dar solución al problema de minimización de riesgo en una cartera de inversión. Recordemos que el problema se puede plantear como: $$\min_{w}  \frac{1}{2} w^t \Sigma w$$sujeto a:$$ w^t \mu= r$$$$ w^t 1_{m}= 1$$En donde $\Sigma$ es la matriz de covarianzas asociadas a los rendimientos de los activos en el periodo de interés. Importación de libreríasLas librerías son en su mayoría las construidas para el proyecto, así como numpy y cupy.<jupyter_code>import numpy as np
import cupy as cp
import solver.extraer_datos_yahoo as extrae
import solver.funciones_auxiliares as aux
import solver.line_search as line
import solver.modelo_markowitz as mkv
import solver.utils as utils
import solver.optimizacion_numerica as opt
#from utils import inc_index, dec_index, compute_error, norm_residual, condicion_cupy
#from line_search import line_search_by_backtracking, line_search_for_residual_by_backtracking<jupyter_output><empty_output><jupyter_text>Cargamos la información y calculamos los parámetros Primero cargamos los precios de las acciones que se han escogido para esta implementación<jupyter_code>stocks = ['COP','AMT','LIN','LMT','AMZN','WMT','JNJ','VTI','MSFT','GOOG','XOM','CCI','BHP.AX','UNP',
'BABA','NSRGY','RHHBY','VOO','AAPL','FB','CVX','PLD','RIO.L','HON','HD','PG','UNH','BRK-A','V','0700.HK',
'RDSA.AS','0688.HK','AI.PA','RTX','MC.PA','KO','PFE','JPM','005930.KS','VZ','RELIANCE.NS','DLR','2010.SR',
'UPS','7203.T','PEP','MRK','1398.HK','MA','T']
datos = extrae.extraer_datos_yahoo(stocks)<jupyter_output>[*********************100%***********************]  50 of 50 downloaded<jupyter_text>Usando las fucniones auxiliares definidas previamente calculamos los rendimientos esperados y la matriz de varianza y covarianza para las acciones<jupyter_code>mu = aux.calcular_rendimiento(datos)
S = aux.calcular_varianza(datos)<jupyter_output><empty_output><jupyter_text>Calcularemos cuál fue el rendimiento máximo obtenido (de entre las medias de los datos históricos) y lo usaremos como el rendimiento deseado en el problema de optimización<jupyter_code>r=max(mu).item()
r<jupyter_output><empty_output><jupyter_text>Resolvemos con el Método de Newton usando diferencias finitas La función a optimizar será la siguiente:<jupyter_code>fo = lambda w: w@S@w<jupyter_output><empty_output><jupyter_text>Usamos la solución analítica para tener la solución con la cual comparar.<jupyter_code>w_ast = mkv.markowitz(r,mu,S)<jupyter_output><empty_output><jupyter_text>La matriz $A$ de restricciones está dada por:<jupyter_code>n = mu.shape[0]
A = cp.concatenate((mu,cp.ones(n))).reshape(2,n)
A<jupyter_output><empty_output><jupyter_text>Por otro lado el vector $b$ está dado por:<jupyter_code>b = cp.array([r,1])
b<jupyter_output><empty_output><jupyter_text>Definimos el punto inicial con la función definida anteriormente:<jupyter_code>w_0 = utils.feasible_markowitz(r,mu)<jupyter_output><empty_output><jupyter_text>Definimos los parámetros para el método de Newton de la siguiente manera:<jupyter_code>tol=1e-8
tol_backtracking=1e-14
p_ast=fo(w_ast)
maxiter=50
[w,total_of_iterations,Err_plot,x_plot]=opt.Newtons_method_feasible_init_point(fo,A, w_0,tol, tol_backtracking, w_ast, p_ast, maxiter)<jupyter_output>I	Normgf 	Newton Decrement	Error x_ast	Error p_ast	line search	CondHf
0	0.0019	0.0009	1.1003	4.6964	---		10050.1996
1	0.0019	0.0	0.0424	0.0002	1	10050.1996
2	0.0019	0.0	0.003	0.0	1	10050.1996
Error of x with respect to x_ast: 0.003025598335118704
Approximate solution: [ 1.58428546e-01 -2.08616309e-02  1.58020949e-01 -9.28935082e-02
  3.16991935e-02  5.10945480e-02  8.72922956e-02  1.26346166e-02
  3.73103284e-02  2.86016263e-01 -5.94665541e-03  2.23126418e-03
  2.03110573e-01  9.45805956e-02  2.28799709e-02  1.50331910e-02
  7.62589108e-03  2.97057955e-02  5.77183696e-02  1.98175883e-01
  1.19874923e-01  1.27950342e-01  1.41431816e-01  1.36290060e-02
  8.84466664e-02  1.50547999e-01  1.69210858e-01  7.72068032e-02
  8.09578029e-02  8.25608723e-02  1.92191572e-01 -2.38661332e-02
  2.64704653e-02  7.70401324e-02  2.20865617e-02 -1.08224222e-01
  1.64026211e-01  1.77103658e-02  6.16445527e-02 -1.08192451e-01
 -5.03004393e-02  1.38878495e-01  1.03603985e-01 -4.27834232e-02
  1.08153614e-02[...]<jupyter_text>La solución dada por el Método de Newton usando las diferenciación numérica es muy similar a la del método cerrado. Siendo el error de:<jupyter_code>Err_plot[-1]
w
w_ast<jupyter_output><empty_output><jupyter_text>La varianza entre ambos métodos también es muy similar<jupyter_code>w@S@w
w_ast@S@w_ast
utils.compute_error(w@S@w,w_ast@S@w_ast)<jupyter_output><empty_output><jupyter_text>Además cumple con la restricción del rendimiento y la suma de pesos igual a 1<jupyter_code>w@mu
utils.compute_error(w@mu, r)
sum(x)<jupyter_output><empty_output><jupyter_text>Resolvemos con el Método de Newton usando funciones simbólicas Ahora utilizaremos de nuevo el método de Newton usando las funciones simbólicas:<jupyter_code>import inspect
lines = inspect.getsource(opt.gfo_cp_mark)
print(lines)
lines = inspect.getsource(opt.Hfo_cp_mark)
print(lines)
[w,total_of_iterations,Err_plot,x_plot]=opt.Newtons_method_feasible_init_point(fo,A, w_0,tol, tol_backtracking, w_ast, p_ast, maxiter, opt.gfo_cp_mark, opt.Hfo_cp_mark,S)<jupyter_output>I	Normgf 	Newton Decrement	Error x_ast	Error p_ast	line search	CondHf
0	0.001	0.0004	1.1003	4.6964	---		10080.7985
1	0.001	0.0	0.0	0.0	1	10080.7985
Error of x with respect to x_ast: 6.406978892882662e-12
Approximate solution: [ 1.58450459e-01 -2.08710279e-02  1.58051613e-01 -9.28970852e-02
  3.17093838e-02  5.10824537e-02  8.71800626e-02  1.26389547e-02
  3.72861469e-02  2.86000507e-01 -5.98810147e-03  2.24206232e-03
  2.03075836e-01  9.46030741e-02  2.28766788e-02  1.49919976e-02
  7.60706433e-03  2.96676402e-02  5.76521006e-02  1.98109863e-01
  1.19928144e-01  1.27869501e-01  1.41300419e-01  1.36285005e-02
  8.83904753e-02  1.50479914e-01  1.69293512e-01  7.72037012e-02
  8.09121352e-02  8.24658724e-02  1.92197879e-01 -2.40095431e-02
  2.64375219e-02  7.69647088e-02  2.20741648e-02 -1.08207562e-01
  1.64032748e-01  1.77020932e-02  6.16398087e-02 -1.08210745e-01
 -5.03462807e-02  1.38834320e-01  1.03567400e-01 -4.28198353e-02
  1.06872745e-02 -2.33314798e+00  1.89811544e-01  2.6329645[...]<jupyter_text>La solución dada por el Método de Newton usando las funciones simbólicas es prácticamente igual al método cerrado método cerrado. Siendo el error de:<jupyter_code>Err_plot[-1]
w
w_ast<jupyter_output><empty_output><jupyter_text>La varianza entre ambos métodos también es prácticamente la misma<jupyter_code>w@S@w
w_ast@S@w_ast
utils.compute_error(w@S@w,w_ast@S@w_ast)<jupyter_output><empty_output><jupyter_text>Y de igual manera cumple con la restricción del rendimiento y la suma de pesos igual a 1<jupyter_code>w@mu
utils.compute_error(w@mu, r)
sum(x)
## Conclusiones

Aunque con ambas variabes se obtienen resultados bastante ascertados, como es de esperarce al usar diferenciación analítica, el resultado tiene mayor precisión.<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11569239115692391, 'fraction_numerical': 0.1685880916858809, 'mean_word_length': 5.963172804532578, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '17', 'dir': 'jupyter-structured-clean-dedup', 'id': '338882', 'license': 'RSA-MD', 'n_tokens_mistral': 3829, 'n_tokens_neox': 3144, 'n_words': 640, 'path': 'notebooks/Programacion/5_Solver_sistema_iterativo.ipynb', 'repo_name': 'izmfc/MNO_finalproject', 'size': '7387'}