%23%20%2F%2F%2F%20script%0A%23%20requires-python%20%3D%20%22%3E%3D3.12%22%0A%23%20dependencies%20%3D%20%5B%0A%23%20%20%20%20%20%22marimo%3D%3D0.23.9%22%2C%0A%23%20%20%20%20%20%22numpy%3D%3D2.4.6%22%2C%0A%23%20%20%20%20%20%22plotly%3D%3D6.8.0%22%2C%0A%23%20%20%20%20%20%22polars%3D%3D1.41.2%22%2C%0A%23%20%20%20%20%20%22jquantstats%3D%3D0.9.6%22%2C%0A%23%20%20%20%20%20%22tinycta%3D%3D0.13.2%22%0A%23%20%5D%0A%23%20%2F%2F%2F%0A%0A%22%22%22Experiment%204%3A%20CTA%20strategy%20with%20optimization%20and%20risk%20scaling.%0A%0AThis%20module%20demonstrates%20a%20more%20advanced%20trend-following%20strategy%20that%0Aincorporates%20portfolio%20optimization%20techniques%20and%20risk%20scaling%20to%0Aimprove%20performance%20and%20risk-adjusted%20returns.%0A%22%22%22%0A%0Aimport%20marimo%0A%0A__generated_with%20%3D%20%220.23.9%22%0Aapp%20%3D%20marimo.App()%0A%0Awith%20app.setup%3A%0A%20%20%20%20import%20sys%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%20polars%20as%20pl%0A%20%20%20%20from%20jquantstats%20import%20Portfolio%0A%20%20%20%20from%20tinycta.osc%20import%20osc%0A%20%20%20%20from%20tinycta.util%20import%20vol_adj%0A%0A%20%20%20%20sys.path.insert(0%2C%20str(Path(__file__).parent))%0A%0A%20%20%20%20from%20preamble%20import%20date_col%2C%20load_prices%0A%0A%20%20%20%20prices%20%3D%20load_prices(__file__)%0A%20%20%20%20prices_only%20%3D%20prices.drop(date_col)%0A%20%20%20%20assets%20%3D%20prices_only.columns%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20CTA%204.0%20-%20Optimization%201.0%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.function%0Adef%20f(price%3A%20%22pl.Expr%22%2C%20fast%3D32%2C%20slow%3D96%2C%20vola%3D32%2C%20clip%3D4.2)%20-%3E%20%22pl.Expr%22%3A%0A%20%20%20%20%22%22%22Return%20the%20tanh%20oscillator%20of%20vol-adjusted%20cumulative%20price.%22%22%22%0A%20%20%20%20return%20osc(vol_adj(price%2C%20vola%3Dvola%2C%20clip%3Dclip%2C%20min_samples%3D300).cum_sum()%2C%20fast%3Dfast%2C%20slow%3Dslow).tanh()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20fast%20%3D%20mo.ui.slider(4%2C%20192%2C%20step%3D4%2C%20value%3D32%2C%20label%3D%22Fast%20Moving%20Average%22)%0A%20%20%20%20slow%20%3D%20mo.ui.slider(4%2C%20192%2C%20step%3D4%2C%20value%3D96%2C%20label%3D%22Slow%20Moving%20Average%22)%0A%20%20%20%20vola%20%3D%20mo.ui.slider(4%2C%20192%2C%20step%3D4%2C%20value%3D32%2C%20label%3D%22Volatility%22)%0A%20%20%20%20winsor%20%3D%20mo.ui.slider(1.0%2C%206.0%2C%20step%3D0.1%2C%20value%3D4.2%2C%20label%3D%22Winsorizing%22)%0A%0A%20%20%20%20mo.vstack(%5Bfast%2C%20slow%2C%20vola%2C%20winsor%5D)%0A%20%20%20%20return%20fast%2C%20slow%2C%20vola%2C%20winsor%0A%0A%0A%40app.cell%0Adef%20_(fast%2C%20slow%2C%20vola%2C%20winsor)%3A%0A%20%20%20%20mu_np%20%3D%20prices_only.select(%0A%20%20%20%20%20%20%20%20f(pl.all()%2C%20fast%3Dfast.value%2C%20slow%3Dslow.value%2C%20vola%3Dvola.value%2C%20clip%3Dwinsor.value)%0A%20%20%20%20).to_numpy()%0A%20%20%20%20volax_np%20%3D%20prices_only.select(%0A%20%20%20%20%20%20%20%20pl.all().fill_nan(None).pct_change().ewm_std(com%3Dvola.value%2C%20min_samples%3Dvola.value)%0A%20%20%20%20).to_numpy()%0A%20%20%20%20euclid_norm%20%3D%20np.sqrt(np.nansum(mu_np**2%2C%20axis%3D1%2C%20keepdims%3DTrue))%0A%20%20%20%20euclid_norm%5Beuclid_norm%20%3D%3D%200%5D%20%3D%20np.nan%0A%20%20%20%20risk_scaled_np%20%3D%20mu_np%20%2F%20euclid_norm%0A%0A%20%20%20%20pos_np%20%3D%20np.nan_to_num(5e5%20*%20risk_scaled_np%20%2F%20volax_np%2C%20nan%3D0.0)%0A%20%20%20%20portfolio%20%3D%20Portfolio.from_cash_position(%0A%20%20%20%20%20%20%20%20prices%3Dprices%2C%0A%20%20%20%20%20%20%20%20cash_position%3Dpl.concat(%0A%20%20%20%20%20%20%20%20%20%20%20%20%5Bprices.select(date_col)%2C%20pl.from_numpy(pos_np%2C%20schema%3Ddict.fromkeys(assets%2C%20pl.Float64))%5D%2C%20how%3D%22horizontal%22%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20aum%3D1e8%2C%0A%20%20%20%20)%0A%20%20%20%20return%20(portfolio%2C)%0A%0A%0A%40app.cell%0Adef%20_(portfolio)%3A%0A%20%20%20%20print(portfolio.stats.sharpe())%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(portfolio)%3A%0A%20%20%20%20fig%20%3D%20portfolio.plots.snapshot()%0A%20%20%20%20fig%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
09f550325c9fed7e23653719476e4b8f