ONMARKET
ONMARKET in ProBacktest and ProOrder returns true while any position is open, long or short. Used to prevent duplicate entries and guard position management.
Syntax
ONMARKETHow it works
ONMARKET takes no arguments and returns true when the strategy holds at least one open position, long or short, and false when it is flat. It is the direction-agnostic sibling of LONGONMARKET and SHORTONMARKET, which test one side each.
The value reflects filled orders only. A pending limit or stop order that has not executed leaves ONMARKET false, and the flag flips back to false on the bar after the position is fully closed. With CumulateOrders enabled, a stack of entries still reads as a single true value; COUNTOFPOSITION reports the actual size.
Typical uses fall into two groups. Entry code is wrapped in IF NOT OnMarket THEN ... ENDIF so a new trade only starts from flat. Management code, such as trailing logic or state resets, is wrapped in IF OnMarket THEN ... ENDIF, or its inverse is used to reinitialize variables between trades.
Examples
Example 1, Entry guard from flat (ProBacktest)
// Open a position only when nothing is currently held
IF NOT ONMARKET THEN
BUY 1 CONTRACT AT MARKET
ENDIFThe strategy buys one contract only when flat, so positions never accumulate. This is the example from the official reference.
Example 2, Symmetric long and short entries (ProOrder)
DEFPARAM CumulateOrders = false
fastMA = Average[20](close)
slowMA = Average[50](close)
// Take either direction, but only from flat
IF NOT onmarket THEN
IF fastMA CROSSES OVER slowMA THEN
BUY 1 CONTRACT AT MARKET
ELSIF fastMA CROSSES UNDER slowMA THEN
SELLSHORT 1 CONTRACT AT MARKET
ENDIF
ENDIFOne ONMARKET guard covers both directions, which is simpler than pairing separate LONGONMARKET and SHORTONMARKET checks around each entry.
Example 3, Resetting trade-state variables between positions (ProOrder)
// Clear the breakeven flag whenever the strategy is flat
IF NOT onmarket THEN
beArmed = 0
ENDIF
// Arm breakeven once the long shows 10 points of profit
IF longonmarket AND close - tradeprice >= 10 * pointsize THEN
beArmed = 1
ENDIF
IF beArmed = 1 THEN
SET STOP BREAKEVEN
ENDIFONMARKET is the natural reset trigger for per-trade state. The flag is cleared while flat, so each new position starts with a clean slate.
Common errors and gotchas
- Direction-blind by design. ONMARKET cannot distinguish long from short. Exit or stop code that only makes sense on one side must use LONGONMARKET or SHORTONMARKET, otherwise a short position can trigger long-side management.
- Pending orders do not count. Between placing a limit or stop entry and its fill, ONMARKET stays false, so an unguarded block can queue multiple orders that all fill later. Cancel or count pending orders in the entry logic.
- No size information. With
CumulateOrdersenabled, ONMARKET stays true whether the position holds one contract or twenty. Cap pyramiding with COUNTOFPOSITION rather than the boolean. - Wrong scope. ONMARKET inside a ProBuilder indicator or ProScreener does not compile. Position state exists only in ProBacktest and ProOrder code.
Related instructions
LONGONMARKET, true while a long position is open.SHORTONMARKET, true while a short position is open.MARKET, executes orders at the current market price.BUY, opens a long position.SELLSHORT, opens a short position.COUNTOFPOSITION, the size of the open position.POSITIONPERF, the performance of the open position.TRADEPRICE, the execution price of a past trade.
