Force live results store once holdings changes settle#9624
Open
jhonabreul wants to merge 4 commits into
Open
Conversation
Monitor the securities holdings quantity changes in the live trading result handler and force a store of the full results once the changes have settled for a configurable period (holdings-changed-store-delay, defaults to 10 seconds), so stored results reflect fills quickly instead of waiting for the next scheduled store.
jhonabreul
marked this pull request as ready for review
July 16, 2026 20:03
The holdings change monitor now subscribes to the transaction handler's NewOrderEvent and tracks fills, instead of wiring into every security holding QuantityChanged event, which required monitoring the securities collection changes as well.
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.
Description
The live trading result handler now monitors the order events, subscribing to the transaction handler's
NewOrderEventand tracking events with a fill status (OrderStatus.FilledorOrderStatus.PartiallyFilled) as holdings changes. Once the changes have settled for a configurable period —holdings-changed-store-delay, defaulting to 10 seconds — the update loop forces a store of the full live results instead of waiting for the next scheduled store (every 1 minute). The monitoring is encapsulated in a private nestedHoldingsChangeMonitorclass.Repeated fills keep resetting the settle clock, and under continuous holdings churn the regular scheduled store still applies. Since the update loop runs on its own cadence, the effective worst-case latency is the settle delay plus one update pass. Holdings mutations that don't come from order fills (e.g. brokerage-side holdings syncs outside of orders) don't force stores and fall back to the scheduled store.
Related Issue
N/A
Motivation and Context
The full live results (including holdings) are only stored on a fixed 1-minute schedule, so consumers of the stored results can see holdings that are stale by up to a minute after fills. This change makes the stored results reflect the new holdings shortly after they settle.
Requires Documentation Change
The new
holdings-changed-store-delayconfiguration could be documented.How Has This Been Tested?
LiveTradingResultHandlerTests.HoldingsChangeForcesResultsStoreOnceSettledunit test running the real result handler thread and filling real orders through aBacktestingTransactionHandler/BacktestingBrokeragepair on a crypto security (market always open). It asserts that a store is forced only after the settle delay when a position is opened, increased, reduced and liquidated; that no store is forced without fills; and that order events without fills (a limit order submitted and canceled) don't force stores. FullLiveTradingResultHandlerTestsfixture passes.FakeDataQueue+PaperBrokerage) running an algorithm that trades a crypto basket in batches every 30 seconds: every batch was followed by exactly one forced store 10-13 seconds after the fills (the settle delay plus up to one update pass), with no stores in between batches.Types of changes
Checklist:
bug-<issue#>-<description>orfeature-<issue#>-<description>