Skip to content

Fix stop-limit fills after trigger bar - #9778

Open
matvt-cell wants to merge 1 commit into
QuantConnect:masterfrom
matvt-cell:bug-9773-stop-limit-fill
Open

Fix stop-limit fills after trigger bar#9778
matvt-cell wants to merge 1 commit into
QuantConnect:masterfrom
matvt-cell:bug-9773-stop-limit-fill

Conversation

@matvt-cell

Copy link
Copy Markdown

Description

Updates stop-limit fill handling so that bars after the stop has already triggered use resting limit-order semantics.

The trigger bar retains the existing conservative close-based check because OHLC data does not reveal whether the bar's high/low occurred before or after the stop trigger. On subsequent bars, the entire bar is post-trigger, so:

  • Buy stop-limit orders fill when the bar low penetrates the limit price.
  • Sell stop-limit orders fill when the bar high penetrates the limit price.
  • Favorable gaps fill at the opening price.
  • The existing trigger-bar behavior remains unchanged.

The change is applied to both EquityFillModel.StopLimitFill and the base FillModel.StopLimitFill.

Related Issue

Fixes #9773

Motivation and Context

After a stop-limit order triggered, LEAN continued to apply the close-based limit test on every subsequent bar.

This could leave an already-triggered stop-limit order unfilled even when a later bar traded through its limit price, as long as that bar did not also close through the limit.

The close-based rule is appropriate on the trigger bar because the ordering of OHLC values is unknown. It is unnecessarily conservative on later bars, where the entire price range necessarily occurred after the stop had already triggered.

This change distinguishes those two cases and applies the existing resting limit-order behavior to subsequent bars.

Requires Documentation Change

No.

How Has This Been Tested?

Added regression coverage for both EquityFillModel and the base FillModel, including:

  • Buy stop-limit filling on a later-bar limit penetration while the close remains above the limit.
  • Buy stop-limit filling at the open on a favorable gap.
  • Trigger-bar low penetration not causing a fill when the close remains above the limit.
  • Sell-side mirror of the later-bar penetration case.

Local test results:

  • Targeted stop-limit regression corridor: 24/24 passed
  • EquityFillModelTests and ImmediateFillModelTests: 236/236 passed

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • Refactor (non-breaking change which improves implementation)
  • Performance (non-breaking change which improves performance. Please add associated performance test and results)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Non-functional change (xml comments/documentation/etc)

Checklist:

  • My code follows the code style of this project.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and relevant existing tests passed.
  • My branch follows the naming convention bug-<issue#>-<description> or feature-<issue#>-<description>

@matvt-cell
matvt-cell force-pushed the bug-9773-stop-limit-fill branch from cc41ace to a79601f Compare September 7, 2026 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant