perf(backtest): reduce Databento API calls on input changes
- on_form_change: Only update cost estimate, skip expensive derive_entry_spot - Only call derive_entry_spot on date changes (start/end inputs) - Other inputs (template, units, loan, LTV) just mark results stale - This reduces lag from constant API polling
This commit is contained in:
@@ -803,21 +803,13 @@ def _render_backtests_page(workspace_id: str | None = None) -> None:
|
|||||||
mark_results_stale()
|
mark_results_stale()
|
||||||
|
|
||||||
def on_form_change() -> None:
|
def on_form_change() -> None:
|
||||||
|
"""Handle form changes with minimal API calls."""
|
||||||
validation_label.set_text("")
|
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()
|
update_cost_estimate()
|
||||||
render_seeded_summary(entry_spot=entry_spot, entry_spot_error=entry_error)
|
# Keep existing entry spot, don't re-derive
|
||||||
if entry_error:
|
mark_results_stale()
|
||||||
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()
|
|
||||||
|
|
||||||
def run_backtest() -> None:
|
def run_backtest() -> None:
|
||||||
validation_label.set_text("")
|
validation_label.set_text("")
|
||||||
@@ -924,17 +916,19 @@ def _render_backtests_page(workspace_id: str | None = None) -> None:
|
|||||||
render_result(result)
|
render_result(result)
|
||||||
|
|
||||||
# Wire up event handlers
|
# Wire up event handlers
|
||||||
|
# Only call expensive derive_entry_spot on date changes
|
||||||
data_source_select.on_value_change(lambda e: on_form_change())
|
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())
|
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())
|
start_input.on_value_change(lambda e: refresh_workspace_seeded_units())
|
||||||
end_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())
|
# Don't trigger API calls on these changes
|
||||||
template_select.on_value_change(lambda e: on_form_change())
|
start_price_input.on_value_change(lambda e: mark_results_stale())
|
||||||
units_input.on_value_change(lambda e: on_form_change())
|
template_select.on_value_change(lambda e: mark_results_stale())
|
||||||
loan_input.on_value_change(lambda e: on_form_change())
|
units_input.on_value_change(lambda e: mark_results_stale())
|
||||||
ltv_input.on_value_change(lambda e: on_form_change())
|
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())
|
run_button.on_click(lambda: run_backtest())
|
||||||
|
|
||||||
# Initial render
|
# Initial render
|
||||||
|
|||||||
Reference in New Issue
Block a user