Conversation
- Updates to make sure exit_reason appears in the round-trips report
- Add report module with templated analysis report created after each run
- Improve exception handling on auth failures to clean up sessions
- Commit 84eb3cc broke IG env vars by moving a lazy import to the top of the file session_runners.py, causing settings to be instantiated before credentials are ever loaded. - Drop @DataClass and __post_init__ so env vars are no longer captured at import time - Make each credential a @Property that calls os.getenv(...) on every access
- Guard broker response that can have `null` return values in that are translated to `None` where a dict is expected. Propagation up the stack to something calling `.get()` on the None
- Commit 03ac1ab fixed _request (null body → {}) but missed _handle_retry_logic which has the same resp.json() call with body.get(...) — and AttributeError isn't in its except (ValueError, KeyError) clause - `_handle_retry_logic` adds `isinstance(body, dict)` guard
Fires after all SessionStartedEvent handlers complete (warmup + reconciliation). Used to gate post_warmup_check in ReconciliationManager.
Remove run(), _run_streaming(), _run_polling(), _has_streamer() — streaming lifecycle moves to BasePortfolio. Strategy now self-registers a _on_session_started handler that calls warmup() when the portfolio fires SessionStartedEvent.
BasePortfolio is the new top-level container for trading sessions. It owns the streaming lifecycle (run, _handle_event) and fires the session lifecycle events: SessionStartedEvent → SessionReadyEvent → [streaming] → SessionEndedEvent.
Wraps a single BaseStrategy with no risk allocation. Strategy warmup is handled automatically via SessionStartedEvent. Candle events are forwarded to the strategy's on_candle_close.
Subscribe to SessionStartedEvent for reconcile_on_startup() and SessionReadyEvent for post_warmup_check(). These no longer need to be called imperatively from user code — the portfolio's run() fires the events in the correct order.
The new entry point takes a portfolio_factory instead of a list of strategy specs. The factory receives a started Client and returns an initialised BasePortfolio. Lifecycle management (events, streaming, shutdown) is now owned by BasePortfolio.run().
Replace strategy_factory with portfolio_factory. The portfolio's run() now owns lifecycle events (SessionStartedEvent, SessionEndedEvent) and order handler wiring, so those are removed from the runner.
…runner Promotes Portfolio to the primary top-level container. Clients now extend BasePortfolio (or use SimplePortfolio for single-strategy use cases) instead of subclassing BaseStrategy. Key changes: - SessionReadyEvent fires after SessionStartedEvent handlers complete - BaseStrategy self-subscribes to SessionStartedEvent for warmup - BasePortfolio manages full session lifecycle (startup events, streaming, shutdown) and is the StreamConsumer (holds _handle_event, on_price_update, on_candle_close) - SimplePortfolio wraps one strategy, delegating both price and candle events - ReconciliationManager subscribes to SessionStartedEvent/SessionReadyEvent instead of being called imperatively - run_portfolio(portfolio_factory, client_factory) replaces run_strategies() - Backtest runner parameter renamed strategy_factory → portfolio_factory - Exports updated: run_portfolio, BasePortfolio, SimplePortfolio, SessionReadyEvent added to tradedesk public API - All tests updated to the new API; no backward-compat shims
Replace all run_strategies/strategy_specs references with the new run_portfolio(portfolio_factory, client_factory) pattern. Rewrite backtesting_guide.md from scratch to match the current API.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
major features, refactors and breakages. But it's better