"""DCA Explorer tab — strategy comparison + subscription DCA.""" import streamlit as st from src.composed.simulator import scenario_dca_comparison from src.composed.subscription_dca import ( SubscriptionDCAConfig, simulate_subscription_dca, ) from src.composed.myco_surface import MycoSystemConfig from src.commitments.subscription import SubscriptionTier from dashboard.charts import fig_dca_comparison import plotly.graph_objects as go from plotly.subplots import make_subplots def render(): st.header("DCA Explorer") tab_compare, tab_subscription = st.tabs(["Strategy Comparison", "Subscription DCA"]) with tab_compare: _render_comparison() with tab_subscription: _render_subscription() def _render_comparison(): config = st.session_state.get("myco_config") n_assets = config.n_reserve_assets if config else 3 col1, col2, col3 = st.columns(3) with col1: total = st.number_input("Total amount ($)", 1000, 100_000, 10_000, step=1000, key="dca_total") with col2: chunks = st.slider("Chunks", 5, 50, 20, key="dca_chunks") with col3: interval = st.number_input("Interval", 0.5, 10.0, 1.0, step=0.5, key="dca_interval") if st.button("Compare Strategies", key="dca_compare_run"): with st.spinner("Running DCA comparison..."): results = scenario_dca_comparison( n_assets=n_assets, total_amount=float(total), n_chunks=chunks, interval=float(interval), ) st.session_state["dca_results"] = results if "dca_results" in st.session_state: results = st.session_state["dca_results"] cols = st.columns(len(results)) for i, (name, r) in enumerate(results.items()): with cols[i]: st.subheader(name) st.metric("Tokens", f"{r.order.total_tokens_received:.2f}") st.metric("Avg Price", f"{r.order.avg_price:.6f}") st.metric("DCA Advantage", f"{r.dca_advantage:+.4f}") st.plotly_chart(fig_dca_comparison(results), use_container_width=True) def _render_subscription(): config = st.session_state.get("myco_config", MycoSystemConfig()) col1, col2, col3 = st.columns(3) with col1: tier_payment = st.number_input("Payment/period ($)", 50, 5000, 100, step=50, key="sub_payment") with col2: n_chunks = st.slider("DCA chunks", 2, 20, 5, key="sub_chunks") with col3: duration = st.slider("Duration (days)", 90, 730, 365, key="sub_duration") if st.button("Simulate Subscription DCA", key="sub_run"): tiers = { "custom": SubscriptionTier( name="custom", payment_per_period=float(tier_payment), period_length=30.0, loyalty_multiplier_max=2.0, loyalty_halflife=90.0, ), } dca_config = SubscriptionDCAConfig(n_chunks=n_chunks, spread_fraction=0.8) subscribers = [("subscriber_1", "custom", 0.0)] with st.spinner("Running subscription DCA..."): sim = simulate_subscription_dca( tiers=tiers, config=dca_config, system_config=config, subscribers=subscribers, duration=float(duration), dt=1.0, ) st.session_state["sub_dca_result"] = sim if "sub_dca_result" in st.session_state: sim = st.session_state["sub_dca_result"] t = sim["times"].tolist() fig = make_subplots( rows=1, cols=2, subplot_titles=("Token Accumulation", "Total Supply"), ) fig.add_trace(go.Scatter( x=t, y=sim["total_curve_tokens"].tolist(), name="Curve Tokens", line=dict(color="#2196F3"), ), row=1, col=1) fig.add_trace(go.Scatter( x=t, y=sim["total_loyalty_bonus"].tolist(), name="Loyalty Bonus", line=dict(color="#FF9800", dash="dash"), ), row=1, col=1) fig.add_trace(go.Scatter( x=t, y=sim["total_supply"].tolist(), name="Supply", line=dict(color="#4CAF50"), ), row=1, col=2) fig.update_layout(height=400, template="plotly_white") st.plotly_chart(fig, use_container_width=True)