import%20marimo%0A%0A__generated_with%20%3D%20%220.15.2%22%0Aapp%20%3D%20marimo.App()%0A%0Awith%20app.setup%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20polars%20as%20pl%0A%0A%20%20%20%20from%20pyhrp.cluster%20import%20Asset%0A%20%20%20%20from%20pyhrp.hrp%20import%20build_tree%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%201%20over%20N%20(the%20hierarchical%20version)%0A%0A%20%20%20%20Inspired%20by%20Thomas%20Raffinot%0A%0A%20%20%20%20-%20Compute%20a%20dendrogram%20using%20the%20'ward'%20distance%20method.%0A%20%20%20%20%20%20Do%20not%20compute%20a%202nd%20Dendrogram.%0A%20%20%20%20-%20Apply%20the%20methods%20level%20by%20level.%20Go%20from%20level%200%20(only%20the%20root)%2C%0A%20%20%20%20%20%20to%20level%201%20(left%20and%20right%20of%20the%20root)%2C%20to%20level%202%20(...)%0A%20%20%20%20-%20On%20level%20n%20evaluate%20the%20function%20f%20for%20all%20leaves%20for%20each%20node.%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%23%20Read%20CSV%20with%20Polars%0A%20%20%20%20prices_pl%20%3D%20pl.read_csv(str(mo.notebook_location()%20%2F%20%22public%22%20%2F%20%22stock_prices.csv%22))%0A%20%20%20%20%23%20Convert%20to%20pandas%20DataFrame%20with%20the%20first%20column%20as%20index%0A%20%20%20%20index_col%20%3D%20prices_pl.columns%5B0%5D%0A%20%20%20%20prices%20%3D%20prices_pl.to_pandas().set_index(index_col)%0A%20%20%20%20returns%20%3D%20prices.pct_change().dropna(axis%3D0%2C%20how%3D%22all%22).fillna(0.0)%0A%20%20%20%20return%20(returns%2C)%0A%0A%0A%40app.cell%0Adef%20_(returns)%3A%0A%20%20%20%20column_names%20%3D%20returns.columns.tolist()%0A%20%20%20%20cor%20%3D%20returns.corr()%0A%20%20%20%20cor.columns%20%3D%20%5BAsset(name%3Dcolumn)%20for%20column%20in%20column_names%5D%0A%20%20%20%20cor.index%20%3D%20%5BAsset(name%3Dcolumn)%20for%20column%20in%20column_names%5D%0A%20%20%20%20cov%20%3D%20returns.cov()%0A%20%20%20%20cov.columns%20%3D%20%5BAsset(name%3Dcolumn)%20for%20column%20in%20column_names%5D%0A%20%20%20%20cov.index%20%3D%20%5BAsset(name%3Dcolumn)%20for%20column%20in%20column_names%5D%0A%20%20%20%20return%20(cor%2C)%0A%0A%0A%40app.cell%0Adef%20_(cor)%3A%0A%20%20%20%20%23%20We%20first%20build%20the%20tree.%20This%20task%20is%20very%20separated%20from%20the%20computations%20of%20weights%20on%20such%20a%20tree.%0A%20%20%20%20%23%20Convert%20column%20names%20to%20Asset%20objects%20for%20build_tree%0A%20%20%20%20dendrogram%20%3D%20build_tree(cor%2C%20method%3D%22ward%22)%0A%20%20%20%20dendrogram.plot()%0A%20%20%20%20plt.show()%0A%20%20%20%20return%20(dendrogram%2C)%0A%0A%0A%40app.cell%0Adef%20_(dendrogram)%3A%0A%20%20%20%20%23%20We%20use%20the%20tree%20from%20the%20previous%20step%20and%20perform%20a%201%2Fn%0A%20%20%20%20%23%20strategy%20in%20an%20iterative%20manner%0A%20%20%20%20from%20pyhrp.algos%20import%20one_over_n%0A%0A%20%20%20%20%23%20Drill%20deeper%2C%20level%20by%20level%0A%20%20%20%20%23%20Root%20is%20level%200%20at%20Level%201%20are%20two%20nodes...%0A%20%20%20%20for%20level%2C%20portfolio%20in%20one_over_n(dendrogram)%3A%0A%20%20%20%20%20%20%20%20print(f%22Level%3A%20%7Blevel%7D%22)%0A%20%20%20%20%20%20%20%20portfolio.plot(names%3Ddendrogram.names)%0A%20%20%20%20%20%20%20%20plt.show()%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
f58534dffee0e41129e8ad98cb4eda781d431cedabf8a8d6255ed3806398e514