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%20jquantstats%20as%20jqs%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%0A%20%20%20%20from%20cvx.core.variable%20import%20Variable%0A%20%20%20%20from%20cvx.risk%20import%20__version__%20as%20risk_version%0A%20%20%20%20from%20cvx.risk.portfolio%20import%20minrisk_problem%0A%20%20%20%20from%20cvx.risk.sample%20import%20SampleCovariance%0A%0A%20%20%20%20print(f%22Risk%20version%3A%20%7Brisk_version%7D%22)%0A%20%20%20%20print(f%22jquantstats%20version%3A%20%7Bjqs.__version__%7D%22)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%23%20Load%20prices%20and%20compute%20returns%20entirely%20in%20polars%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%20%20%20%20returns%20%3D%20prices.select(%5Bpl.col(%22date%22)%2C%20pl.col(asset_cols).pct_change()%5D).drop_nulls()%0A%0A%20%20%20%20%23%20EWM%20covariance%20via%20jquantstats%20(com%3D60%20%E2%86%92%20span%3D121%2C%20warmup%3D100)%0A%20%20%20%20data%20%3D%20jqs.Data.from_returns(returns%2C%20date_col%3D%22date%22)%0A%20%20%20%20cov%20%3D%20data.utils.exponential_cov(window%3D121%2C%20warmup%3D100)%0A%20%20%20%20start%20%3D%20next(iter(cov))%0A%20%20%20%20return%20asset_cols%2C%20cov%2C%20returns%2C%20start%0A%0A%0A%40app.cell%0Adef%20_(asset_cols%2C%20cov%2C%20returns%2C%20start)%3A%0A%20%20%20%20%23%20Minimum-risk%20backtest%20using%20SampleCovariance%0A%20%20%20%20_returns_bt%20%3D%20returns.filter(pl.col(%22date%22)%20%3E%3D%20start)%0A%20%20%20%20_dates%20%3D%20_returns_bt%5B%22date%22%5D.to_list()%0A%20%20%20%20_ret_values%20%3D%20_returns_bt.select(asset_cols).to_numpy()%0A%0A%20%20%20%20_risk_model%20%3D%20SampleCovariance(num%3D20)%0A%20%20%20%20_w%20%3D%20Variable(20)%0A%20%20%20%20_problem%20%3D%20minrisk_problem(_risk_model%2C%20_w)%0A%20%20%20%20_current_w%20%3D%20None%0A%0A%20%20%20%20_port_rets%20%3D%20%5B%5D%0A%20%20%20%20for%20_i%2C%20_date%20in%20enumerate(_dates)%3A%0A%20%20%20%20%20%20%20%20if%20_date%20in%20cov%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_risk_model.update(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cov%3Dcov%5B_date%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lower_assets%3Dnp.zeros(20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20upper_assets%3Dnp.ones(20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20_problem.solve()%0A%20%20%20%20%20%20%20%20%20%20%20%20_current_w%20%3D%20_w.value.copy()%0A%0A%20%20%20%20%20%20%20%20if%20_current_w%20is%20not%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_port_rets.append(float(_ret_values%5B_i%5D%20%40%20_current_w))%0A%0A%20%20%20%20_returns_pl%20%3D%20pl.DataFrame(%7B%22date%22%3A%20_dates%5B-len(_port_rets)%20%3A%5D%2C%20%22SampleCovariance%22%3A%20_port_rets%7D)%0A%20%20%20%20data_sc%20%3D%20jqs.Data.from_returns(_returns_pl%2C%20date_col%3D%22date%22)%0A%20%20%20%20print(data_sc.stats.sharpe())%0A%20%20%20%20return%20(data_sc%2C)%0A%0A%0A%40app.cell%0Adef%20_(data_sc)%3A%0A%20%20%20%20data_sc.plots.snapshot()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(returns%2C%20start)%3A%0A%20%20%20%20from%20cvx.risk.cvar%20import%20CVar%0A%0A%20%20%20%20_returns_bt%20%3D%20returns.filter(pl.col(%22date%22)%20%3E%3D%20start)%0A%20%20%20%20_dates%20%3D%20_returns_bt%5B%22date%22%5D.to_list()%0A%20%20%20%20_ret_values%20%3D%20_returns_bt.select(%5Bc%20for%20c%20in%20_returns_bt.columns%20if%20c%20!%3D%20%22date%22%5D).to_numpy()%0A%0A%20%20%20%20_risk_model%20%3D%20CVar(alpha%3D0.80%2C%20n%3D40%2C%20m%3D20)%0A%20%20%20%20_w%20%3D%20Variable(20)%0A%20%20%20%20_problem%20%3D%20minrisk_problem(_risk_model%2C%20_w)%0A%20%20%20%20_current_w%20%3D%20None%0A%0A%20%20%20%20_port_rets%20%3D%20%5B%5D%0A%20%20%20%20for%20_i%20in%20range(len(_dates))%3A%0A%20%20%20%20%20%20%20%20_hist%20%3D%20_ret_values%5Bmax(0%2C%20_i%20-%2039)%20%3A%20_i%20%2B%201%5D%0A%20%20%20%20%20%20%20%20if%20len(_hist)%20%3D%3D%2040%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_risk_model.update(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20returns%3D_hist%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lower_assets%3Dnp.zeros(20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20upper_assets%3Dnp.ones(20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20_problem.solve()%0A%20%20%20%20%20%20%20%20%20%20%20%20_current_w%20%3D%20_w.value.copy()%0A%0A%20%20%20%20%20%20%20%20if%20_current_w%20is%20not%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_port_rets.append(float(_ret_values%5B_i%5D%20%40%20_current_w))%0A%0A%20%20%20%20_returns_pl%20%3D%20pl.DataFrame(%7B%22date%22%3A%20_dates%5B-len(_port_rets)%20%3A%5D%2C%20%22CVar%22%3A%20_port_rets%7D)%0A%20%20%20%20data_cvar%20%3D%20jqs.Data.from_returns(_returns_pl%2C%20date_col%3D%22date%22)%0A%20%20%20%20print(data_cvar.stats.sharpe())%0A%20%20%20%20return%20(data_cvar%2C)%0A%0A%0A%40app.cell%0Adef%20_(data_cvar)%3A%0A%20%20%20%20data_cvar.plots.snapshot()%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
fc19ac6b91a61bd50fe8c58882f3b7b4