import%20marimo%0A%0A__generated_with%20%3D%20%220.18.4%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0Awith%20app.setup%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20polars%20as%20pl%0A%20%20%20%20from%20cvx.linalg%20import%20pca%0A%0A%20%20%20%20from%20cvx.core.variable%20import%20Variable%0A%20%20%20%20from%20cvx.risk.factor%20import%20FactorModel%0A%20%20%20%20from%20cvx.risk.portfolio%20import%20minrisk_problem%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%23%20Load%20some%20historic%20stock%20prices%0A%20%20%20%20prices%20%3D%20pl.read_csv(str(mo.notebook_location()%20%2F%20%22public%22%20%2F%20%22stock_prices.csv%22)%2C%20try_parse_dates%3DTrue)%0A%0A%20%20%20%20asset_cols%20%3D%20%5Bc%20for%20c%20in%20prices.columns%20if%20c%20!%3D%20%22date%22%5D%0A%0A%20%20%20%20%23%20Compute%20percentage%20returns%20in%20polars%0A%20%20%20%20returns%20%3D%20prices.select(pl.col(asset_cols).pct_change()).drop_nulls()%0A%20%20%20%20return%20asset_cols%2C%20returns%0A%0A%0A%40app.cell%0Adef%20_(returns)%3A%0A%20%20%20%20factors%20%3D%20pca(returns%3Dreturns.to_numpy()%2C%20n_components%3D10)%0A%20%20%20%20return%20(factors%2C)%0A%0A%0A%40app.cell%0Adef%20_(factors%2C%20returns)%3A%0A%20%20%20%20model%20%3D%20FactorModel(assets%3Dlen(returns.columns)%2C%20k%3D10)%0A%0A%20%20%20%20%23%20update%20the%20model%20parameters%0A%20%20%20%20model.update(%0A%20%20%20%20%20%20%20%20cov%3Dfactors.cov%2C%0A%20%20%20%20%20%20%20%20exposure%3Dfactors.exposure%2C%0A%20%20%20%20%20%20%20%20idiosyncratic_risk%3Dfactors.idiosyncratic.std(axis%3D0%2C%20ddof%3D1)%2C%0A%20%20%20%20%20%20%20%20lower_assets%3Dnp.zeros(model.assets)%2C%0A%20%20%20%20%20%20%20%20upper_assets%3Dnp.ones(model.assets)%2C%0A%20%20%20%20%20%20%20%20lower_factors%3D-0.1%20*%20np.ones(model.k)%2C%0A%20%20%20%20%20%20%20%20upper_factors%3D0.1%20*%20np.ones(model.k)%2C%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20test%20the%20risk%20model%20with%20uniform%20weights%0A%20%20%20%20weights%20%3D%200.05%20*%20np.ones(model.assets)%0A%20%20%20%20risk%20%3D%20model.estimate(weights)%0A%20%20%20%20print(risk)%0A%20%20%20%20return%20(model%2C)%0A%0A%0A%40app.cell%0Adef%20_(asset_cols%2C%20model)%3A%0A%20%20%20%20w%20%3D%20Variable(model.assets)%0A%20%20%20%20y%20%3D%20Variable(model.k)%0A%0A%20%20%20%20problem%20%3D%20minrisk_problem(model%2C%20w%2C%20y%3Dy)%0A%20%20%20%20problem.solve()%0A%0A%20%20%20%20print(pl.DataFrame(%7B%22asset%22%3A%20asset_cols%2C%20%22weight%22%3A%20w.value%7D))%0A%20%20%20%20print(model.estimate(w.value))%0A%0A%20%20%20%20%23%20check%20the%20solution%0A%20%20%20%20print(f%22Check%20sum%20of%20weights%3A%20%7Bnp.isclose(w.value.sum()%2C%201.0)%7D%22)%0A%20%20%20%20print(f%22Check%20all%20weights%20non-negative%3A%20%7Bnp.all(w.value%20%3E%20-0.01)%7D%22)%0A%20%20%20%20print(y.value)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
68a3e516526d46e43afa5a59ef7e47f0