diff --git a/app/pages/backtests.py b/app/pages/backtests.py index ec804da..cb3e6bc 100644 --- a/app/pages/backtests.py +++ b/app/pages/backtests.py @@ -803,21 +803,13 @@ def _render_backtests_page(workspace_id: str | None = None) -> None: mark_results_stale() def on_form_change() -> None: + """Handle form changes with minimal API calls.""" validation_label.set_text("") - entry_spot, entry_error = derive_entry_spot() + # Only update cost estimate, don't derive entry spot on every change + # Entry spot derivation is expensive (Databento API call) update_cost_estimate() - render_seeded_summary(entry_spot=entry_spot, entry_spot_error=entry_error) - if entry_error: - entry_spot_hint.set_text("Entry spot unavailable until the scenario dates are valid.") - validation_label.set_text(entry_error) - render_result_state("Scenario validation failed", entry_error, tone="warning") - return - validation_error = validate_current_scenario(entry_spot=entry_spot) - if validation_error: - validation_label.set_text(validation_error) - render_result_state("Scenario validation failed", validation_error, tone="warning") - else: - mark_results_stale() + # Keep existing entry spot, don't re-derive + mark_results_stale() def run_backtest() -> None: validation_label.set_text("") @@ -924,17 +916,19 @@ def _render_backtests_page(workspace_id: str | None = None) -> None: render_result(result) # Wire up event handlers + # Only call expensive derive_entry_spot on date changes data_source_select.on_value_change(lambda e: on_form_change()) - dataset_select.on_value_change(lambda e: on_form_change()) + dataset_select.on_value_change(lambda e: (update_date_range_hint(), on_form_change())) schema_select.on_value_change(lambda e: on_form_change()) - symbol_select.on_value_change(lambda e: (update_date_range_hint(), on_form_change())) + symbol_select.on_value_change(lambda e: update_date_range_hint()) start_input.on_value_change(lambda e: refresh_workspace_seeded_units()) end_input.on_value_change(lambda e: refresh_workspace_seeded_units()) - start_price_input.on_value_change(lambda e: on_form_change()) - template_select.on_value_change(lambda e: on_form_change()) - units_input.on_value_change(lambda e: on_form_change()) - loan_input.on_value_change(lambda e: on_form_change()) - ltv_input.on_value_change(lambda e: on_form_change()) + # Don't trigger API calls on these changes + start_price_input.on_value_change(lambda e: mark_results_stale()) + template_select.on_value_change(lambda e: mark_results_stale()) + units_input.on_value_change(lambda e: mark_results_stale()) + loan_input.on_value_change(lambda e: mark_results_stale()) + ltv_input.on_value_change(lambda e: mark_results_stale()) run_button.on_click(lambda: run_backtest()) # Initial render