import%20marimo%0A%0A__generated_with%20%3D%20%220.14.17%22%0Aapp%20%3D%20marimo.App()%0A%0Awith%20app.setup%3A%0A%20%20%20%20from%20pathlib%20import%20Path%0A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20plotly.io%20as%20pio%0A%20%20%20%20import%20polars%20as%20pl%0A%0A%20%20%20%20pd.options.plotting.backend%20%3D%20%22plotly%22%0A%0A%20%20%20%20%23%20Ensure%20Plotly%20works%20with%20Marimo%0A%20%20%20%20pio.renderers.default%20%3D%20%22plotly_mimetype%22%0A%0A%20%20%20%20path%20%3D%20Path(__file__).parent%20%2F%20%22public%22%20%2F%20%22stock-prices.csv%22%0A%0A%20%20%20%20%23%20from%20cvxsimulator.builder%20import%20polars2pandas%0A%20%20%20%20date_col%20%3D%20%22date%22%0A%20%20%20%20dframe%20%3D%20pl.read_csv(str(path)%2C%20try_parse_dates%3DTrue)%0A%0A%20%20%20%20dframe%20%3D%20dframe.with_columns(pl.col(date_col).cast(pl.Datetime(%22ns%22)))%0A%20%20%20%20dframe%20%3D%20dframe.with_columns(%5Bpl.col(col).cast(pl.Float64)%20for%20col%20in%20dframe.columns%20if%20col%20!%3D%20date_col%5D)%0A%20%20%20%20prices%20%3D%20dframe.to_pandas().set_index(date_col)%0A%0A%20%20%20%20from%20cvxsimulator%20import%20Builder%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%22%22%22Display%20the%20introduction%20and%20overview%20of%20the%201%2Fn%20portfolio%20family.%0A%0A%20%20%20%20This%20cell%20provides%20an%20introduction%20to%20the%201%2Fn%20portfolio%20strategy%20and%20outlines%0A%20%20%20%20the%20different%20approaches%20that%20will%20be%20explored%20in%20this%20notebook%3A%0A%20%20%20%20-%20Vanilla%20implementation%20with%20daily%20rebalancing%0A%20%20%20%20-%20Formulation%20as%20convex%20optimization%20problems%20with%20different%20objectives%0A%20%20%20%20-%20Sparse%20updating%20strategy%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%20The%201%2Fn%20family%0A%0A%20%20%20%20We%20play%20with%20the%20%241%2Fn%24%20portfolio.%20We%20start%20with%20a%20vanilla%20implementation%20using%20daily%20rebalancing.%0A%20%20%20%20Every%20portfolio%20should%20be%20the%20solution%20of%20a%20convex%20optimization%20problem%2C%0A%20%20%20%20see%20https%3A%2F%2Fwww.linkedin.com%2Fpulse%2Fstock-picking-convex-programs-thomas-schmelzer.%0A%20%20%20%20We%20do%20that%20and%20show%20methods%20to%20construct%20the%20portfolio%20with%0A%0A%20%20%20%20*%20the%20minimization%20of%20the%20Euclidean%20norm%20of%20the%20weights.%0A%20%20%20%20*%20the%20minimization%20of%20the%20%24%5Cinfty%24%20norm%20of%20the%20weights.%0A%20%20%20%20*%20and%20the%20maximization%20of%20the%20Entropy%20of%20the%20weights.%0A%20%20%20%20*%20the%20minimization%20of%20the%20tracking%20error%20to%20an%20%241%2Fn%24%20portfolio.%0A%0A%20%20%20%20We%20also%20play%20with%20sparse%20updates%2C%20e.g.%20rather%20than%20rebalancing%20daily%2C%0A%20%20%20%20we%20act%20only%20once%20the%20deviation%20of%20our%20drifted%20portfolio%20got%20too%20large%20from%20the%20target%20%241%2Fn%24%20portfolio.%0A%0A%20%20%20%20This%20problem%20has%20been%20discussed%20https%3A%2F%2Fwww.linkedin.com%2Ffeed%2Fupdate%2Furn%3Ali%3Aactivity%3A7149432321388064768%2F%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%22%22%22Implement%20a%20simple%201%2Fn%20portfolio%20strategy%20with%20daily%20rebalancing.%0A%0A%20%20%20%20This%20cell%20creates%20a%20portfolio%20that%20allocates%20equal%20weight%20to%20each%20asset%0A%20%20%20%20and%20rebalances%20daily%20to%20maintain%20these%20equal%20weights.%20It%20then%20builds%20the%0A%20%20%20%20portfolio%20and%20displays%20a%20snapshot%20of%20its%20performance.%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20_builder%20%3D%20Builder(prices%3Dprices%2C%20initial_aum%3D1000000.0)%0A%20%20%20%20for%20_%2C%20_state%20in%20_builder%3A%0A%20%20%20%20%20%20%20%20_n%20%3D%20len(_state.assets)%0A%20%20%20%20%20%20%20%20_builder.weights%20%3D%20np.ones(_n)%20%2F%20_n%0A%20%20%20%20%20%20%20%20_builder.aum%20%3D%20_state.aum%0A%0A%20%20%20%20_portfolio%20%3D%20_builder.build()%0A%20%20%20%20_portfolio.snapshot()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%22%22%22Display%20the%20introduction%20to%20the%20cvxpy%20implementation%20section.%0A%0A%20%20%20%20This%20cell%20introduces%20the%20concept%20of%20formulating%20the%201%2Fn%20portfolio%20problem%0A%20%20%20%20as%20a%20convex%20optimization%20problem%20using%20cvxpy.%20It%20explains%20the%20benefits%20of%0A%20%20%20%20this%20approach%2C%20particularly%20for%20adding%20constraints%20and%20understanding%20the%0A%20%20%20%20relationship%20to%20Tikhonov%20regularization.%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%23%20With%20cvxpy%0A%0A%20%20%20%20Formulating%20the%20problem%20above%20as%20a%20convex%20program%20is%20most%20useful%20when%20additional%20constraints%20have%0A%20%20%20%20to%20be%20reflected.%20It%20also%20helps%20to%20link%20the%201%2Fn%20portfolio%20to%20Tikhonov%20regularization%20and%20interpret%0A%20%20%20%20its%20solution%20as%20a%20cornercase%20for%20more%20complex%20portfolios%20we%20are%20building%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%22%22%22Import%20the%20cvxpy%20library%20for%20convex%20optimization.%0A%0A%20%20%20%20This%20cell%20imports%20the%20cvxpy%20library%2C%20which%20will%20be%20used%20to%20formulate%0A%20%20%20%20and%20solve%20the%201%2Fn%20portfolio%20optimization%20problems%20in%20subsequent%20cells.%0A%0A%20%20%20%20Returns%3A%0A%20%20%20%20-------%0A%20%20%20%20tuple%0A%20%20%20%20%20%20%20%20A%20tuple%20containing%20the%20cvxpy%20module%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20import%20cvxpy%20as%20cp%0A%0A%20%20%20%20return%20(cp%2C)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%22%22%22Display%20the%20introduction%20to%20the%20Euclidean%20norm%20minimization%20approach.%0A%0A%20%20%20%20This%20cell%20introduces%20the%20first%20convex%20optimization%20approach%3A%20minimizing%0A%20%20%20%20the%20Euclidean%20norm%20of%20the%20weight%20vector.%20This%20approach%20produces%20the%20same%0A%20%20%20%20results%20as%20the%20simple%201%2Fn%20portfolio%20but%20opens%20the%20door%20to%20more%20complex%0A%20%20%20%20convex%20optimization%20formulations.%0A%0A%20%20%20%20Parameters%0A%20%20%20%20----------%0A%20%20%20%20mo%20%3A%20marimo.Module%0A%20%20%20%20%20%20%20%20The%20marimo%20module%20object%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%23%23%20Minimization%20of%20the%20Euclidean%20norm%0A%0A%20%20%20%20We%20minimize%20the%20Euclidean%20norm%20of%20the%20weight%20vector.%20Same%20results%20as%20above%20but%20we%0A%20%20%20%20open%20door%20to%20the%20world%20of%20convex%20paradise.%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_(cp)%3A%0A%20%20%20%20%22%22%22Implement%20a%201%2Fn%20portfolio%20using%20Euclidean%20norm%20minimization.%0A%0A%20%20%20%20This%20cell%20creates%20a%20portfolio%20by%20formulating%20and%20solving%20a%20convex%20optimization%0A%20%20%20%20problem%20that%20minimizes%20the%20Euclidean%20norm%20(L2%20norm)%20of%20the%20weight%20vector%2C%0A%20%20%20%20subject%20to%20the%20constraints%20that%20weights%20are%20non-negative%20and%20sum%20to%201.%0A%20%20%20%20This%20approach%20produces%20the%20same%20results%20as%20the%20simple%201%2Fn%20portfolio.%0A%0A%20%20%20%20Parameters%0A%20%20%20%20----------%0A%20%20%20%20Builder%20%3A%20class%0A%20%20%20%20%20%20%20%20The%20Builder%20class%20from%20cvx.simulator%0A%20%20%20%20cp%20%3A%20module%0A%20%20%20%20%20%20%20%20The%20cvxpy%20module%0A%20%20%20%20prices%20%3A%20pd.DataFrame%0A%20%20%20%20%20%20%20%20DataFrame%20of%20asset%20prices%20with%20dates%20as%20index%20and%20assets%20as%20columns%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20_builder%20%3D%20Builder(prices%3Dprices%2C%20initial_aum%3D1000000.0)%0A%20%20%20%20for%20_%2C%20_state%20in%20_builder%3A%0A%20%20%20%20%20%20%20%20_n%20%3D%20len(_state.assets)%0A%20%20%20%20%20%20%20%20_weights%20%3D%20cp.Variable(_n)%0A%20%20%20%20%20%20%20%20_objective%20%3D%20cp.norm(_weights%2C%202)%0A%20%20%20%20%20%20%20%20_constraints%20%3D%20%5B_weights%20%3E%3D%200%2C%20cp.sum(_weights)%20%3D%3D%201%5D%0A%20%20%20%20%20%20%20%20cp.Problem(objective%3Dcp.Minimize(_objective)%2C%20constraints%3D_constraints).solve(solver%3Dcp.CLARABEL)%0A%20%20%20%20%20%20%20%20_builder.weights%20%3D%20_weights.value%0A%20%20%20%20%20%20%20%20_builder.aum%20%3D%20_state.aum%0A%20%20%20%20_portfolio%20%3D%20_builder.build()%0A%20%20%20%20_portfolio.snapshot()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%22%22%22Display%20the%20introduction%20to%20the%20infinity%20norm%20minimization%20approach.%0A%0A%20%20%20%20This%20cell%20introduces%20the%20second%20convex%20optimization%20approach%3A%20minimizing%0A%20%20%20%20the%20infinity%20norm%20of%20the%20weight%20vector.%20This%20approach%20is%20based%20on%20an%20idea%0A%20%20%20%20by%20Vladimir%20Markov%20and%20provides%20another%20way%20to%20formulate%20the%201%2Fn%20portfolio%0A%20%20%20%20problem.%0A%0A%20%20%20%20Parameters%0A%20%20%20%20----------%0A%20%20%20%20mo%20%3A%20marimo.Module%0A%20%20%20%20%20%20%20%20The%20marimo%20module%20object%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%23%23%20Minimization%20of%20the%20%24%5Cinfty%24%20norm%0A%0A%20%20%20%20Based%20on%20an%20idea%20by%20Vladimir%20Markov%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_(cp)%3A%0A%20%20%20%20%22%22%22Implement%20a%201%2Fn%20portfolio%20using%20infinity%20norm%20minimization.%0A%0A%20%20%20%20This%20cell%20creates%20a%20portfolio%20by%20formulating%20and%20solving%20a%20convex%20optimization%0A%20%20%20%20problem%20that%20minimizes%20the%20infinity%20norm%20(L%E2%88%9E%20norm)%20of%20the%20weight%20vector%2C%0A%20%20%20%20subject%20to%20the%20constraints%20that%20weights%20are%20non-negative%20and%20sum%20to%201.%0A%20%20%20%20This%20approach%2C%20based%20on%20Vladimir%20Markov's%20idea%2C%20is%20another%20way%20to%20achieve%0A%20%20%20%20equal%20weighting%20across%20assets.%0A%0A%20%20%20%20Parameters%0A%20%20%20%20----------%0A%20%20%20%20Builder%20%3A%20class%0A%20%20%20%20%20%20%20%20The%20Builder%20class%20from%20cvx.simulator%0A%20%20%20%20cp%20%3A%20module%0A%20%20%20%20%20%20%20%20The%20cvxpy%20module%0A%20%20%20%20prices%20%3A%20pd.DataFrame%0A%20%20%20%20%20%20%20%20DataFrame%20of%20asset%20prices%20with%20dates%20as%20index%20and%20assets%20as%20columns%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20_builder%20%3D%20Builder(prices%3Dprices%2C%20initial_aum%3D1000000.0)%0A%20%20%20%20for%20_%2C%20_state%20in%20_builder%3A%0A%20%20%20%20%20%20%20%20_n%20%3D%20len(_state.assets)%0A%20%20%20%20%20%20%20%20_weights%20%3D%20cp.Variable(_n)%0A%20%20%20%20%20%20%20%20_objective%20%3D%20cp.norm_inf(_weights)%0A%20%20%20%20%20%20%20%20_constraints%20%3D%20%5B_weights%20%3E%3D%200%2C%20cp.sum(_weights)%20%3D%3D%201%5D%0A%20%20%20%20%20%20%20%20cp.Problem(objective%3Dcp.Minimize(_objective)%2C%20constraints%3D_constraints).solve(solver%3Dcp.CLARABEL)%0A%20%20%20%20%20%20%20%20_builder.weights%20%3D%20_weights.value%0A%20%20%20%20%20%20%20%20_builder.aum%20%3D%20_state.aum%0A%20%20%20%20_portfolio%20%3D%20_builder.build()%0A%20%20%20%20_portfolio.snapshot()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%22%22%22Display%20the%20introduction%20to%20the%20entropy%20maximization%20approach.%0A%0A%20%20%20%20This%20cell%20introduces%20the%20third%20convex%20optimization%20approach%3A%20maximizing%0A%20%20%20%20the%20entropy%20of%20the%20weight%20vector.%20This%20approach%20provides%20yet%20another%20way%0A%20%20%20%20to%20formulate%20the%201%2Fn%20portfolio%20problem%20and%20arrives%20at%20the%20same%20result%0A%20%20%20%20as%20the%20previous%20methods.%0A%0A%20%20%20%20Parameters%0A%20%20%20%20----------%0A%20%20%20%20mo%20%3A%20marimo.Module%0A%20%20%20%20%20%20%20%20The%20marimo%20module%20object%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%23%23%20Maximization%20of%20the%20entropy%0A%0A%20%20%20%20One%20can%20also%20maximize%20the%20entropy%20to%20arrive%20at%20the%20same%20result%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_(cp)%3A%0A%20%20%20%20%22%22%22Implement%20a%201%2Fn%20portfolio%20using%20entropy%20maximization.%0A%0A%20%20%20%20This%20cell%20creates%20a%20portfolio%20by%20formulating%20and%20solving%20a%20convex%20optimization%0A%20%20%20%20problem%20that%20maximizes%20the%20entropy%20of%20the%20weight%20vector%2C%20subject%20to%20the%0A%20%20%20%20constraints%20that%20weights%20are%20non-negative%20and%20sum%20to%201.%20Entropy%20maximization%0A%20%20%20%20is%20a%20well-known%20approach%20that%20leads%20to%20equal%20weighting%20when%20no%20other%0A%20%20%20%20information%20is%20available.%0A%0A%20%20%20%20Parameters%0A%20%20%20%20----------%0A%20%20%20%20Builder%20%3A%20class%0A%20%20%20%20%20%20%20%20The%20Builder%20class%20from%20cvx.simulator%0A%20%20%20%20cp%20%3A%20module%0A%20%20%20%20%20%20%20%20The%20cvxpy%20module%0A%20%20%20%20prices%20%3A%20pd.DataFrame%0A%20%20%20%20%20%20%20%20DataFrame%20of%20asset%20prices%20with%20dates%20as%20index%20and%20assets%20as%20columns%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20_builder%20%3D%20Builder(prices%3Dprices%2C%20initial_aum%3D1000000.0)%0A%20%20%20%20for%20_%2C%20_state%20in%20_builder%3A%0A%20%20%20%20%20%20%20%20_n%20%3D%20len(_state.assets)%0A%20%20%20%20%20%20%20%20_weights%20%3D%20cp.Variable(_n)%0A%20%20%20%20%20%20%20%20_objective%20%3D%20cp.sum(cp.entr(_weights))%0A%20%20%20%20%20%20%20%20_constraints%20%3D%20%5B_weights%20%3E%3D%200%2C%20cp.sum(_weights)%20%3D%3D%201%5D%0A%20%20%20%20%20%20%20%20cp.Problem(objective%3Dcp.Maximize(_objective)%2C%20constraints%3D_constraints).solve(solver%3Dcp.CLARABEL)%0A%20%20%20%20%20%20%20%20_builder.weights%20%3D%20_weights.value%0A%20%20%20%20%20%20%20%20_builder.aum%20%3D%20_state.aum%0A%20%20%20%20_portfolio%20%3D%20_builder.build()%0A%20%20%20%20_portfolio.snapshot()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%22%22%22Display%20the%20introduction%20to%20the%20tracking%20error%20minimization%20approach.%0A%0A%20%20%20%20This%20cell%20introduces%20the%20fourth%20convex%20optimization%20approach%3A%20minimizing%0A%20%20%20%20the%20tracking%20error%20to%20a%201%2Fn%20target%20portfolio.%20This%20approach%20explicitly%0A%20%20%20%20formulates%20the%20problem%20as%20minimizing%20the%20distance%20to%20the%20equal-weight%0A%20%20%20%20portfolio.%0A%0A%20%20%20%20Parameters%0A%20%20%20%20----------%0A%20%20%20%20mo%20%3A%20marimo.Module%0A%20%20%20%20%20%20%20%20The%20marimo%20module%20object%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20mo.md(r%22%22%22%23%23%23%20Minimization%20of%20the%20tracking%20error%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(cp)%3A%0A%20%20%20%20%22%22%22Implement%20a%201%2Fn%20portfolio%20using%20tracking%20error%20minimization.%0A%0A%20%20%20%20This%20cell%20creates%20a%20portfolio%20by%20formulating%20and%20solving%20a%20convex%20optimization%0A%20%20%20%20problem%20that%20minimizes%20the%20tracking%20error%20(Euclidean%20distance)%20between%20the%0A%20%20%20%20portfolio%20weights%20and%20a%20target%201%2Fn%20portfolio%2C%20subject%20to%20the%20constraints%0A%20%20%20%20that%20weights%20are%20non-negative%20and%20sum%20to%201.%20This%20approach%20explicitly%0A%20%20%20%20targets%20the%20equal-weight%20portfolio.%0A%0A%20%20%20%20Parameters%0A%20%20%20%20----------%0A%20%20%20%20Builder%20%3A%20class%0A%20%20%20%20%20%20%20%20The%20Builder%20class%20from%20cvx.simulator%0A%20%20%20%20cp%20%3A%20module%0A%20%20%20%20%20%20%20%20The%20cvxpy%20module%0A%20%20%20%20np%20%3A%20module%0A%20%20%20%20%20%20%20%20The%20numpy%20module%0A%20%20%20%20prices%20%3A%20pd.DataFrame%0A%20%20%20%20%20%20%20%20DataFrame%20of%20asset%20prices%20with%20dates%20as%20index%20and%20assets%20as%20columns%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20_builder%20%3D%20Builder(prices%3Dprices%2C%20initial_aum%3D1000000.0)%0A%20%20%20%20for%20_%2C%20_state%20in%20_builder%3A%0A%20%20%20%20%20%20%20%20_n%20%3D%20len(_state.assets)%0A%20%20%20%20%20%20%20%20_weights%20%3D%20cp.Variable(_n)%0A%20%20%20%20%20%20%20%20_objective%20%3D%20cp.norm(_weights%20-%20np.ones(_n)%20%2F%20_n%2C%202)%0A%20%20%20%20%20%20%20%20_constraints%20%3D%20%5B_weights%20%3E%3D%200%2C%20cp.sum(_weights)%20%3D%3D%201%5D%0A%20%20%20%20%20%20%20%20cp.Problem(objective%3Dcp.Minimize(_objective)%2C%20constraints%3D_constraints).solve(solver%3Dcp.CLARABEL)%0A%20%20%20%20%20%20%20%20_builder.weights%20%3D%20_weights.value%0A%20%20%20%20%20%20%20%20_builder.aum%20%3D%20_state.aum%0A%20%20%20%20_portfolio%20%3D%20_builder.build()%0A%20%20%20%20_portfolio.snapshot()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%22%22%22Display%20the%20introduction%20to%20the%20sparse%20updates%20approach.%0A%0A%20%20%20%20This%20cell%20introduces%20a%20more%20practical%20approach%20to%20implementing%20the%201%2Fn%0A%20%20%20%20portfolio%20strategy%3A%20using%20sparse%20updates%20instead%20of%20daily%20rebalancing.%0A%20%20%20%20This%20approach%20acknowledges%20that%20in%20practice%2C%20frequent%20rebalancing%20is%0A%20%20%20%20costly%20and%20unnecessary%2C%20and%20that%20small%20deviations%20from%20the%20target%0A%20%20%20%20weights%20can%20be%20tolerated.%0A%0A%20%20%20%20Parameters%0A%20%20%20%20----------%0A%20%20%20%20mo%20%3A%20marimo.Module%0A%20%20%20%20%20%20%20%20The%20marimo%20module%20object%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%23%20With%20sparse%20updates%0A%0A%20%20%20%20In%20practice%20we%20do%20not%20want%20to%20rebalance%20the%20portfolio%20every%20day.%20We%20tolerate%20our%20portfolio%0A%20%20%20%20is%20not%20an%20exact%20%241%2Fn%24%20portfolio.%20We%20may%20expect%20slightly%20weaker%20results%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_builder%20%3D%20Builder(prices%3Dprices%2C%20initial_aum%3D1000000.0)%0A%20%20%20%20for%20_%2C%20_state%20in%20_builder%3A%0A%20%20%20%20%20%20%20%20_n%20%3D%20len(_state.assets)%0A%20%20%20%20%20%20%20%20target%20%3D%20np.ones(_n)%20%2F%20_n%0A%20%20%20%20%20%20%20%20drifted%20%3D%20_state.weights%5B_state.assets%5D.fillna(0.0)%0A%20%20%20%20%20%20%20%20delta%20%3D%20(target%20-%20drifted).abs().sum()%0A%20%20%20%20%20%20%20%20if%20delta%20%3E%200.2%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_builder.weights%20%3D%20target%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_builder.position%20%3D%20_state.position%0A%20%20%20%20%20%20%20%20_builder.aum%20%3D%20_state.aum%0A%20%20%20%20_portfolio%20%3D%20_builder.build()%0A%20%20%20%20_portfolio.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
c1c86db8f02dbf87afcab4381ca3bc7c31173dc0131effcc86167e0ce0c16d73