Pace a prop-firm evaluation or funded account - profit target, trailing max loss, daily loss limit, consistency - so the account survives long enough for the edge to show. Covers harness-tracked attempts (accounts/<name>/ACCOUNT.md; the harness tool combine_status, and the user's combine.js to start or stop one) and the policy strategies that trade them. Use at the start of each day, after big wins or losses, and whenever a policy strategy (signal policy) is trading.
Install
npx skillscat add johnamcruz/futures-trading-harness/prop-challenge-pacing Install via the SkillsCat registry.
Prop Challenge Pacing
When to Use
- Start of each trading day: set today's risk budget.
- After a large win (protect it) or a drawdown (de-risk).
How It Works
Harness-tracked attempts (a policy strategy)
A policy strategy (signal: policy, e.g. prop_portfolio) is the prop
challenge as a strategy: it trades the setups of the rules strategies it
lists on an account profile (accounts/<name>/ACCOUNT.md, e.g.topstep_100k: $6,000 target, $3,000 trailing max loss, $2,000 daily limit),
sized from the cushion in the selected contract (contracts: micro | mini | auto only when none is selected): each setup gets the largest size itssizing allows, or is skipped. A contract's risk is its stop plus the
stop's expected slippage (sizing.stop_slippage_ticks, a tick by default,
as the backtester fills stops) plus fees both ways, so a stop filled
within its expected slippage never reaches the floor or the daily limit; a
gap or fast market that fills it further past the stop still can. The harness tracks the attempt and enforces
it:
- In autonomous runs the cycle prompt carries each running attempt's state
(balance, floor, cushion, profit, the day, sessions left, the size budget,
any entry block) and the live verdicts, from the runner's latest snapshot. - The harness tool
combine_statusshows the balance, floor, cushion,
profit, sessions left, the size budget in dollars, whether entries are
blocked, and each policy strategy's live verdict. Read it before planning;
quote it in theplanentry. The size budget is per policy strategy (each
has its ownsizing); the gate checks the verdict's size against it. - At each setup the runner records a verdict: the strategy that fired, the
side,fullorskip, the contract (the selected one: MNQ or NQ, MES or ES, ...), the largest
size, and the stop in ticks. A verdict is a ceiling, never an order:
take it only when the priority order (the strategy-library skill) says so (it may
skip it or halve it), and then exactly as given: rationalesetup:<policy strategy> ..., that contract and side, at most that size,stopLossBracket.ticksequal to its stop ticks (order_planwith the
policy strategy's name, the bars file and itssymbol, the micro whose
bars the runner scans, gives exactly these arguments, or refuses with the
gate's reason). A verdict is for its own bar: the gate takes it only while
that bar is still the last one recorded for the policy strategy's
timeframe (the runner records each bar it scans). Once a newer bar is recorded
without a verdict for its setup (for example the component fired again and
no new verdict came), the old one is refused ([policy] ... the latest verdict is for the 3m bar opened X; the setup on the bar opened Y has no verdict yet), as is a verdict that names no bar: stand aside until the
next setup's verdict. A verdict permits one
entry: after a stop-out, wait for the next setup's verdict. Never exceed it
or route around it. Once in, the policy strategy's own exit (its trail)
manages the trade; nothing closes it early past the ratchet. - Before the first live entry (the user's steps, not an agent's): the
policy strategy must beactive(prop_portfoliois; its sizing rules
decide each verdict), and the user starts the attempt withcombine.js start. A policy strategy still atpaper(e.g.prop_flow_1m)
stays so until the user activates it, and every verdict entry is refused
([strategy] ... status "paper"): report it and stand aside. - A verdict for the mini (
NQwhile the bars are MNQ's): use the
contract nameNQas the contractId (the harness translates it to the
broker's id), and write the plan and the order with it; a plan forMNQdoesn't count for an NQ order. - The order gate refuses (
[combine],[policy],[prop-one-position];
none can be skipped): no started attempt
(node <root>/scripts/combine.js start --account <name>, the user's call); a
snapshot older than 10 minutes or dated in the future (a clock that
stepped back: tell the user); a missed close (the user records it withcombine.js record-day: tell them the exact command); a passed or finished attempt; the soft or firm
daily limit; a size over the budget; any entry that doesn't match the
verdict, or whose verdict is not for the last recorded bar; any position already open on the account, or any order working
on it (a resting entry on another market could fill next to it); any entry once another
went in since the latest account snapshot ("wait for the next bar's
snapshot"; one whose journal time is unreadable counts as since it: tell
the user); and, while an attempt runs, any entry from a strategy that
isn't its policy strategy. - Several markets, one account (a policy strategy over NQ, ES, YM, and
RTY trades one attempt): one position at a time across all of them. When
two markets have verdicts on the same bar, place one (the first listed in
the prompt, unless a verdict says skip) and stand aside on the other: the
gate refuses it until the account is flat again and a new verdict comes.
Never split the budget between markets; each verdict is sized from the
whole cushion.
Pacing by judgment (no account profile)
Ask the user for the account's current rules; don't assume them. Track these
numbers each morning (from get_account_snapshot and the user):
- Target remaining = profit target − profit so far.
- Cushion = balance − trailing loss floor. The floor trails the end-of-day
high-water mark on the bundled combine profiles; it stops trailing at the starting
balance once the passmark is reached (account-type dependent). - Days traded and the best day's share of total profit (consistency).
Rules of thumb (the PropEvolve objective: pass without blowing the account):
- Survival first. Daily risk budget ≤ 25–30% of the cushion; per-trade risk
≤ 10% of the cushion. A small cushion means smaller size, not "make it back". - Pace, don't sprint. Aim for the target remaining ÷ 10–15 days per day. Stop for the
day at +1.5× the daily pace; protecting a green day is worth more than
stretching it. - Consistency. If one day would exceed the firm's best-day share,
stop for the day. Past the target, the gate stops entries once today's
close would pass; while the best day is still too large a share, the
attempt keeps trading (at normal size) on days smaller than the best one,
and stops for the day once today is the best day (more can't help). - After a red day, the next day's budget is half until a green day.
- Near the target, cut size: the last 10% isn't worth risking the account.
- Funded accounts, scale only per the firm's scaling plan and the
journal's evidence.
Write the day's numbers into the plan entry so reviews can grade pacing.
Examples
combine_status {}
topstep_100k: active, balance $101250 (floor $98000, cushion $3250), profit $1250 of $6000,
day $250, 4 sessions done, 26 left; prop_portfolio size budget $975; entries allowed
prop_portfolio: long setup from supertrend: full, at most 4 NQ with a 40-tick stop
Yesterday closed at $101000, so the floor trails to $101000 - $3000 = $98000.
prop_portfolio's sizing: 0.3 x $3250 = $975 (under the $1,000 cap; no
drawdown from the peak). A 40-tick stop plus a tick of expected slippage
risks 41 x $0.50 = $20.50 + $0.74 fees = $21.24 a micro: 45 micros ($975 /
$21.24), traded as 4 NQ with NQ selected (NQ: 41 x $5 = $205 + $2.80 fees =
$207.80 each, $831.20 in all). Halved by the priority order: 22 micros, 2 NQ.
With MNQ selected the verdict is 45 MNQ ($955.80), halved 22 MNQ.Target $3,000, profit $1,150 → remaining $1,850. Cushion $1,400.
Daily budget = 25% × 1,400 = $350; per trade ≤ 10% × 1,400 = $140;
pace ≈ $1,850 ÷ 10 = $185/day; stop for the day at +1.5 × $185 ≈ $280.