Skip to content

Topstep rule reference (for the rule engine)

Researched July 2026. These numbers drive rules/params.py and the rule kernel. Treat them as cited config, not constants — parameterize by account size and creation date and re-verify medium/low-confidence rows against Topstep's live help center before trusting a pass verdict. Confidence and sources are noted per item.

Timezone: the project's canonical timezone is ET (America/New_York), so all times below are ET, with Topstep's native CT in parentheses for cross-referencing their help center. ET = CT + 1h always (CT and ET share the identical US DST schedule — no DST edge case between them). Internally the engine stores int-ns UTC; ET governs only where the day/session boundaries land and how times display.

⚠️ The single biggest correctness item: the Maximum Loss Limit is a two-state trailing drawdown — the floor ratchets on END-OF-DAY closed balance, but a breach is checked in REAL TIME on realized+unrealized equity. Modeling it as an intraday-trailing peak silently emulates Apex, not Topstep. See §2.


1. Trading Combine — parameters per account size

Account Profit Target Max Loss Limit (trailing) Daily Loss Limit (optional) Max position
$50K (Small) $3,000 $2,000 $1,000 5 minis / 50 micros
$100K (Medium) $6,000 $3,000 $2,000 10 minis / 100 micros
$150K (Large) $9,000 $4,500 $3,000 15 minis / 150 micros

Micros count 10:1 vs minis. Only these three sizes are offered. (Note: the commonly cited "target = 1.5 × MLL / DLL = 0.5 × MLL" ratios hold only for the $50K — at $100K/$150K the table's dollar figures give target = 2 × MLL and DLL = 2/3 × MLL. The dollar figures are canonical, not any ratio.) (high confidence — Topstep help center: trading-combine-parameters, what-is-the-maximum-loss-limit; profit-target dollar figures corroborated by third parties + the 1.5× ratio rather than a single official numeric page.)

Pass condition:

eod_balance ≥ start + profit_target        (reach AND MAINTAIN at end of day — not an intraday touch)
AND best_single_day ≤ 0.50 × total_profit  (consistency)
AND MLL never breached
(A Personal-DLL hit does not preclude passing — it only flattens and locks that day; the account "stays eligible to continue" per Topstep. See §3.) On satisfying these, Topstep advances the trader to an Express Funded Account. No maximum time limit on the Combine (monthly subscription). No separate minimum-days or winning-days objective — the ~2-day minimum is implied by the 50% consistency rule.


2. Maximum Loss Limit — the two-state trailing drawdown (critical)

State A — floor ratchet (end of day only): - The floor = min(starting_balance, peak_end_of_day_balance − MLL). - Updates only at end of day on realized/closed balance. Intraday spikes in open/unrealized profit do not move it. It never moves down. - Locks permanently at the starting balance once EOD balance reaches start + MLL. - $50K example: floor starts at $48,000; after a day closing +$500 → floor $48,500; a later −$500 day (back to $50,500 balance) leaves floor at $48,500 (never down); once EOD balance hits $52,000, floor locks at $50,000 (the starting balance) — note this lock happens before the $53,000 profit-target balance.

State B — breach check (real time): - Monitored every tick on live equity = realized closed balance + open unrealized P&L. - Touch the floor at any point intraday → account liquidated immediately via market order (so realized loss typically exceeds the floor due to liquidation slippage — model a distinct ForcedLiquidation path).

(high confidence — what-is-the-maximum-loss-limit.) Open: the exact clock instant of the EOD snapshot is not pinned to the minute (practically the daily settlement around 16:10 / 17:00 ET ≈ 15:10 / 16:00 CT).


3. Daily Loss Limit — optional

  • Amounts $1,000 / $2,000 / $3,000 (= 0.5 × MLL). OPTIONAL and off by default — Topstep removed the default DLL on TopstepX in Aug 2024; a trader may set a Personal DLL or Trailing Personal DLL.
  • Resets at 18:00 ET (17:00 CT); the trading day runs 18:00 ET → 16:10 ET next day.
  • Hitting the DLL is not a violation: positions flatten, pending orders cancel, no new trades until 18:00 ET next session; the account stays eligible.
  • Model as a configurable toggle (default OFF). When ON, treat as real-time daily net P&L incl. open positions (medium confidence — official page doesn't explicitly state realized-vs-unrealized; calibrate against a real account with a Personal DLL set).

(source: daily-loss-limit-in-the-trading-combine-and-express-funded-account.)


4. Consistency rule ("Consistency Target")

  • Single best day of profit must stay ≤ 50% of the Profit Target. If exceeded, the required target inflates — you must keep trading until best_day ≤ 0.50 × total_profit.
  • Formula Topstep gives: Best Day Profit / Total Profit = Best Day % (must be ≤ 50%).
  • Per-size best-day caps to avoid inflating the target: $1,500 / $3,000 / $4,500.
  • Implies a ~2-day minimum to pass. Losses don't reset the best day.

(high confidence — consistency-at-topstep.)

CALIBRATED 2026-08-03 — what counts as a "trading day" (confirmed by Tarric against a real account; previously the largest open question in this section):

Question Answer Where it lives
Activity or profit? Activity. A day counts if you traded, regardless of P&L. CombineKernel.on_trade_activity sets a flag; no P&L gate
Minimum profit for a day to count? None. A losing day and a +$5 day both count. same — it is a bool
Does a forced exit count? Yes. A 16:10 flatten or an MLL liquidation is activity. sim_broker.py::_close_position_at calls on_trade_activity
What is "activity"? A FILL. A submitted order that never trades is not a trading day. on_trade_activity is called only from the two fill paths, never at placement
When does the counter roll? 18:00 ET, same boundary as the DLL and EOD-MLL resets. core/time.py::trading_day_of

The engine already matched all five; nothing changed but the confidence. Pinned by test_a_forced_flatten_still_counts_the_trading_day and test_an_unfilled_order_does_not_count_the_trading_day.

Still open here: is a "day's profit" gross or net of fees? realized closed P&L or EOD-balance delta? Both still move the verdict.


5. Sessions, flatten, position cap

  • Flatten by 16:10 ET (15:10 CT) (or the product's earlier close). Risk managers begin auto-flatten ~16:08 ET; open positions & pending orders auto-cancel at 16:10 ET; daily break 16:10 → 18:00 ET. Trading day / all resets (DLL, EOD-MLL ratchet) key off 18:00 ET (17:00 CT).
  • Products with earlier closes: CBOT grains ~14:20 ET (13:20 CT), CME ag ~14:05 ET (13:05 CT) — exit before their own close.
  • Position cap is fixed at 5/10/15 minis (50/100/150 micros, 10:1) for the whole Combine — no scaling in the Combine (the balance-based Scaling Plan is Express-Funded-only).

  • Exchange holidays and holiday half-sessions are NOT modelled. There is no holiday calendar in the engine (the computed one was removed 2026-07-28 — it disagreed with CME on about five dates a year and silently dropped tradable sessions). A holiday bar is treated as an ordinary weekday bar: the daily 16:10 flatten and 18:00 reset still fire, the validator raises nothing, and only weekends are refused as closed. Filter holidays and early closes out of the input data upstream.

(high — when-and-what-products-can-i-trade, trading-combine-parameters.) Open: does the live cap count working orders toward the limit, or only net position? (model net + working, reject over-cap with APIError(AccountViolation=4); verify live.)


6. Express Funded Account (XFA) — the funded phase — ⏸️ DEFERRED / PARKED REFERENCE

Out of current scope. We are combine-focused for now; the funded phase is "another time." This section is a parked reference so the rules aren't lost — do not build against it yet. It drops in later as a new RuleSet behind the same seam, with zero changes to the combine path.

Structurally different from the Combine — its own RuleSet:

  • Starts at $0 balance (the "$50K/$100K/$150K" label is buying power only). No profit target — the objective is banking winning days and taking payouts.
  • Trailing MLL buffer = same $2,000 / $3,000 / $4,500. Starts at −buffer, trails on EOD balance, locks at $0 net once balance first reaches the buffer.
  • After the FIRST payout the MLL is permanently set to $0 → remaining balance is the hard floor with zero buffer (the single biggest "keep the account" trap; a distinct on_first_payout transition).
  • DLL same amounts, optional, fixed once set.
  • Scaling Plan gates max contracts by end-of-day balance; a step-up takes effect next session only (e.g. $50K: 2 lots <$1,500, 3 at $1,500+, 5 at $2,000+, topping at the combine max 5/10/15). (mid-tier 100K/150K counts: low confidence — official numbers are a chart image; third-party transcriptions conflict.)

Payout paths (choose one): | Path | Requirement | Consistency | Caps | |---|---|---|---| | Standard | 5 winning days each ≥ $150 net | none | lower (per size/path, date-dependent) | | Consistency | 3 trading days (≥1 trade/day) | largest day ≤ 40% of total net | higher |

  • 90/10 profit split (accounts created on/after Jan 12, 2026 are 90/10 from dollar one). $125 min payout; withdraw ≤ 50% of balance per payout, capped by a per-payout cap. First payout needs only the winning-days requirement; every subsequent payout also requires being net-positive since the last payout.
  • Per-payout caps changed Apr 28, 2026 → key them off account creation date.

(sources: express-funded-account-parameters, topstep-payout-policy, what-is-the-scaling-plan, what-is-the-maximum-loss-limit. XFA 40% consistency is separate from the Combine's 50%-of-target rule.)

A real Live Funded Account (LFA) is a rare later stage (~0.71% of XFA traders in 2025): no consistency target, no payout cap, "Dynamic Live Risk Expansion" instead of scaling. Out of scope initially.


7. Fees (calibrate before trusting micro-scalp verdicts)

Per-side, per-instrument, charged on entry AND exit — for micros the round-turn cost can rival the per-trade edge, so a small error flips pass↔fail.

  • Topstep commissions (2025): minis ~$0.50/side, micros ~$0.25/side; NFA ~$0.01–0.02/side; a $10/contract fee applies only to automatic liquidations.
  • CME exchange+clearing (non-member, per side, representative): ES/NQ/YM/RTY ~$1.38, micro equity (MES/MNQ/MYM/M2K) ~$0.35, CL ~$1.50, MCL ~$0.50, GC ~$1.65, MGC ~$1.10.
  • All-in round-turn: ES-class minis ~$3.6–3.8, MES ~$1.2–1.4.

(medium confidence — topstepbrokerage.com/commissions-and-fees, TradeStation/MetroTrade schedules; CME rates change — reconcile against the CME Fee Finder and a real account blotter.)


8. Instrument specs (reference; runtime source of truth is the SDK ContractModel.tick_size)

point_value = tick_value / tick_size. Store the {tick_size, tick_value, point_value} triple and assert consistency on load. Tick sizes are heterogeneous — never hardcode per class.

Sym Exch Tick Tick $ Point $ RTH (ET)
ES CME 0.25 12.50 50 09:30–16:15
MES CME 0.25 1.25 5 09:30–16:15
NQ CME 0.25 5.00 20 09:30–16:15
MNQ CME 0.25 0.50 2 09:30–16:15
YM CBOT 1.0 5.00 5 09:30–16:15
MYM CBOT 1.0 0.50 0.50 09:30–16:15
RTY CME 0.10 5.00 50 09:30–16:15
M2K CME 0.10 0.50 5 09:30–16:15
CL NYMEX 0.01 10.00 1,000 09:00–14:30
MCL NYMEX 0.01 1.00 100 09:00–14:30
NG NYMEX 0.001 10.00 10,000 09:00–14:30
GC COMEX 0.10 10.00 100 08:20–13:30
MGC COMEX 0.10 1.00 10 08:20–13:30
SI COMEX 0.005 25.00 5,000 08:25–13:25
SIL COMEX 0.005 5.00 1,000 08:25–13:25

Shared Globex session: Sun 18:00 ET → Fri 17:00 ET (17:00 CT → 16:00 CT), daily maintenance halt 17:00–18:00 ET (Mon–Thu). Equity/index cash-settled quarterly (H,M,U,Z, 3rd Friday); commodities monthly/ cycle-based → a continuous-contract builder must pick the front month by volume/OI, not a fixed quarterly assumption. (high confidence — CME contract-spec pages + NinjaTrader/Ironbeam.)


9. Verification checklist (do before a pass verdict is trustworthy)

  • [ ] Exact EOD-snapshot instant for the MLL ratchet.
  • [ ] DLL basis (realized-only vs incl. unrealized) — calibrate vs a real Personal-DLL account.
  • [ ] Consistency: gross vs net-of-fees day profit; target inflation. ("Trading day" definition is DONE — calibrated 2026-08-03, see §4. Activity not profit; no minimum; forced exits count; activity means filled; rolls 18:00 ET. The engine already matched on all five.)
  • [ ] Position cap: net-only vs net + working orders.
  • [ ] Gateway per-half-turn P&L method (FIFO vs weighted-average) — from real fills.
  • [ ] trail_price vs trail_distance population on the returned OrderModel.
  • [ ] XFA scaling-plan mid-tier contract counts (100K/150K).
  • [ ] Fee/exchange defaults + NFA $0.01 vs $0.02 — from a real account blotter. Apply the correction with Backtest(..., fee_model=TopstepFees(overrides={...})) (per-symbol FeeSchedule replacement); no hand-wiring of broker + fill model required.