import%20marimo%0A%0A__generated_with%20%3D%20%220.13.15%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%20%20%20%20from%20cvxsimulator%20import%20interpolate%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%20%20%20%20pd.options.plotting.backend%20%3D%20%22plotly%22%0A%0A%20%20%20%20path%20%3D%20Path(__file__).parent%20%2F%20%22public%22%20%2F%20%22Prices_hashed.csv%22%0A%0A%20%20%20%20date_col%20%3D%20%22date%22%0A%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).apply(interpolate)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%23%20CTA%201.0%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.function%0Adef%20f(price%2C%20fast%3D32%2C%20slow%3D96)%3A%0A%20%20%20%20%22%22%22Calculate%20trading%20signals%20based%20on%20the%20difference%20between%20fast%20and%20slow%20moving%20averages.%0A%0A%20%20%20%20Args%3A%0A%20%20%20%20%20%20%20%20price%3A%20Price%20series%20data%0A%20%20%20%20%20%20%20%20fast%3A%20Fast%20moving%20average%20period%20(default%3A%2032)%0A%20%20%20%20%20%20%20%20slow%3A%20Slow%20moving%20average%20period%20(default%3A%2096)%0A%0A%20%20%20%20Returns%3A%0A%20%20%20%20%20%20%20%20Series%20of%20trading%20signals%20(-1%2C%200%2C%20or%201)%20based%20on%20the%20sign%20of%20the%20difference%0A%20%20%20%20%20%20%20%20between%20fast%20and%20slow%20moving%20averages%0A%20%20%20%20%22%22%22%0A%20%20%20%20s%20%3D%20price.ewm(com%3Dslow%2C%20min_periods%3D100).mean()%0A%20%20%20%20f%20%3D%20price.ewm(com%3Dfast%2C%20min_periods%3D100).mean()%0A%20%20%20%20return%20np.sign(f%20-%20s)%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%0A%20%20%20%20mo.vstack(%5Bfast%2C%20slow%5D)%0A%0A%20%20%20%20return%20fast%2C%20slow%0A%0A%0A%40app.cell%0Adef%20_(fast%2C%20slow)%3A%0A%20%20%20%20pos%20%3D%205e6%20*%20prices.apply(f%2C%20fast%3Dfast.value%2C%20slow%3Dslow.value).fillna(0.0)%0A%20%20%20%20return%20(pos%2C)%0A%0A%0A%40app.cell%0Adef%20_(pos)%3A%0A%20%20%20%20from%20cvxsimulator%20import%20Portfolio%0A%20%20%20%20%23%20builder%20%3D%20Builder(prices%3Dprices%2C%20initial_aum%3D1e8)%0A%0A%20%20%20%20%23%20for%20t%2C%20state%20in%20builder%3A%0A%20%20%20%20%23%20%20%20%20%23%20update%20the%20position%0A%20%20%20%20%23%20%20%20%20position%20%3D%20pos.loc%5Bt%5B-1%5D%5D%0A%20%20%20%20%23%20%20%20%20builder.cashposition%20%3D%20position%5Bstate.assets%5D.values%0A%20%20%20%20%23%20%20%20%20%23%20Do%20not%20apply%20trading%20costs%0A%20%20%20%20%23%20%20%20%20builder.aum%20%3D%20state.aum%0A%0A%20%20%20%20%23%20portfolio%20%3D%20builder.build()%0A%0A%20%20%20%20%23%20interpolate%20the%20prices%20inside%20here...%0A%20%20%20%20portfolio%20%3D%20Portfolio.from_cashpos_prices(prices%3Dprices%2C%20cashposition%3Dpos%2C%20aum%3D1e8)%0A%20%20%20%20print(portfolio.sharpe())%0A%20%20%20%20return%20(portfolio%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%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%20Results%20do%20not%20look%20terrible%20but...%0A%20%20%20%20*%20No%20concept%20of%20risk%20integrated.%0A%20%20%20%20*%20The%20size%20of%20each%20bet%20is%20constant%20regardless%20of%20the%20underlying%20asset.%0A%20%20%20%20*%20The%20system%20lost%20its%20mojo%20in%202009%20and%20has%20never%20really%20recovered.%0A%20%20%20%20*%20The%20sign%20function%20is%20very%20expensive%20to%20trade%20as%20position%20changes%20are%20too%20extreme.%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%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%20Such%20fundamental%20flaws%20are%20not%20addressed%20by%20**parameter-hacking**%0A%20%20%20%20or%20**pimp-my-trading-system**%20steps%20(remove%20the%20worst%20performing%20assets%2C%0A%20%20%20%20insane%20quantity%20of%20stop-loss%20limits%2C%20...)%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_(portfolio)%3A%0A%20%20%20%20fig%20%3D%20portfolio.snapshot()%0A%20%20%20%20%23%20import%20urllib%0A%0A%20%20%20%20%23%23%20Convert%20figure%20to%20HTML%20and%20encode%20for%20URL%0A%20%20%20%20%23%20plot_html%20%3D%20fig.to_html()%0A%20%20%20%20%23%20urllib.parse.quote(plot_html)%0A%20%20%20%20fig%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%23%20Create%20HTML%20link%20to%20open%20in%20new%20tab%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20pd.set_option(%22display.precision%22%2C%202)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%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%20cvxSimulator%20can%20construct%20portfolio%20objects.%20Those%20objects%20will%0A%20%20%20%20expose%20functionality%20and%20attributes%20supporting%20all%20analytics.%0A%20%20%20%20There%20are%20two%20types%20of%20portfolio%20--%20EquityPortfolio%20and%20FuturesPortfolio.%0A%20%20%20%20We%20start%20with%20the%20FuturesPortfolio.%20The%20most%20simple%20use-case%0A%20%20%20%20is%20when%20we%20have%20computed%20all%20desirec%20cash-positions%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%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
d17279f2f7e963e98d3fd2d268174d603dbdf7fca02ed4161e08e28b2273df0d