Convert daily resolution market orders to MarketOnClose/MarketOnOpen#9534
Merged
Martin-Molinero merged 5 commits intoJun 16, 2026
Conversation
A market order placed intraday (e.g. through a scheduled event) on an asset subscribed only at daily resolution has no fresh intraday price to fill against, so it was filling at the stale previous daily close. This is common when mixing daily resolution assets with minute resolution assets or intraday scheduled events. QCAlgorithm.MarketOrder now converts these orders so they fill at a real daily open/close instead of the stale previous close: - market closed (any resolution): MarketOnOpen, as before - market open, daily-only subscription: MarketOnClose (today's close), or MarketOnOpen (next open) when already within the MarketOnClose submission buffer near the close Assets with intraday data are left untouched, and the conversion is only applied in backtesting; in live trading an open-market market order fills at the real current price. Adds DailyResolutionMarketOrderConversionRegressionAlgorithm covering the MarketOnClose and MarketOnOpen conversion paths plus a minute resolution asset that is correctly left as a regular market order. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rrent price" Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Daily-resolution market orders placed intraday are now converted to
MarketOnClose/MarketOnOpen so they fill at a real daily open/close
instead of the stale previous close. This shifts the affected fills:
- IndexOptionCall{ITM,OTM}ExpiryDaily: the SPX option entry, placed one
minute after the open, now fills at the daily close. Same economics,
one extra data point and a new order list hash.
- AllShortableSymbols (C# + Python): an intraday order's type changed
from Market to a converted order; identical End Equity, new hash.
- ResolutionSwitchingAlgorithm sampling test: the RemoveSecurity
liquidation (fired at 15:50) previously filled at the stale previous
close; it now converts, shifting the equity/performance samples.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Closed
4 tasks
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
A market order placed intraday — for example through a scheduled event — on an asset subscribed only at daily resolution has no fresh intraday price to fill against, so it was filling at the stale previous daily close. This is a common footgun when mixing daily resolution assets with minute resolution assets or intraday scheduled events.
QCAlgorithm.MarketOrdernow converts these orders so they fill at a real daily open/close instead of the stale previous close:MarketOnOpen(unchanged)MarketOnClose(today's close)MarketOnOpen(next open)Market(unchanged)Notes:
Related Issue
Daily/Hour resolution market orders (and orders placed from intraday scheduled events) filling at a stale previous close.
Motivation and Context
Filling at a stale previous close silently mis-prices fills for daily resolution strategies, especially when combined with intraday scheduling or mixed-resolution universes. Routing these to
MarketOnClose/MarketOnOpenproduces a realistic daily open/close fill.Requires Documentation Change
No public API change. New behavior is described via the algorithm warnings.
How Has This Been Tested?
Added
DailyResolutionMarketOrderConversionRegressionAlgorithm(daily SPY + minute IBM) asserting:MarketOnClose; minute order is not converted and fills immediately.MarketOnOpen, filling next session.Ran locally end-to-end (3 orders, both conversion warnings observed, all assertions pass).
Types of changes
Checklist
Regression statistics updated
The conversion changes the fills of a few existing daily-resolution algorithms that place market orders intraday. All are legitimate improvements (orders no longer fill at the stale previous close), the in-algorithm assertions still pass, and only the affected fills/statistics changed:
MarketOrderone minute after the open. On daily resolution this previously filled at the stale previous close; it now converts toMarketOnCloseand fills at the daily close. Same economics (End Equityunchanged), one extra data point, newOrderListHash.MarketOrders on daily-resolution coarse-selected symbols. An intraday order's type changes (Market → converted);End Equityand all other statistics are identical, only theOrderListHashchanged.Tests/Engine/Results/BacktestingResultHandlerTests.cs) — a sampling change-detector. The algorithm'sRemoveSecurityliquidation fires at 15:50 while the market is open; on daily resolution it previously filled at the stale previous close and now converts, shifting the equity/performance samples (benchmark samples unchanged). Expected sample values were updated accordingly.Markets that never close (crypto/forex) and futures are excluded from the conversion, and the conversion is not applied in live trading.
🤖 Generated with Claude Code