ProBacktest/probacktest · proorder

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

probuilder
ONMARKET

How 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)

probuilder
// Open a position only when nothing is currently held
IF NOT ONMARKET THEN
    BUY 1 CONTRACT AT MARKET
ENDIF

The 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)

probuilder
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
ENDIF

One 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)

probuilder
// 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
ENDIF

ONMARKET 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 CumulateOrders enabled, 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.
  • 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.