ProBacktest/probacktest · proorder

COUNTOFSHORTSHARES

COUNTOFSHORTSHARES returns the number of shares or lots held short by the current ProBacktest or ProOrder strategy. Syntax, worked examples and common gotchas.

Syntax

probuilder
COUNTOFSHORTSHARES

The keyword takes no parameters and is read like a variable inside conditions and expressions.

How it works

Each time the strategy code runs, COUNTOFSHORTSHARES reports the filled short quantity at that moment. Unlike COUNTOFPOSITION, which is signed, this keyword is always zero or positive, so it can be compared against a cap directly without an ABS() wrapper. When the strategy is flat or long, it returns 0.

The typical pattern combines three pieces: DEFPARAM CumulateOrders = true so that repeated SELLSHORT orders stack instead of being ignored, an entry condition that can fire more than once, and a guard such as COUNTOFSHORTSHARES < 5 that stops the position from growing without limit. The value updates as fills occur, so partial exits through EXITSHORT x SHARES reduce the count accordingly.

Pending orders are not included. A resting SELLSHORT ... LIMIT order that has not executed leaves the count unchanged until it fills. The long-side mirror of this keyword is COUNTOFLONGSHARES.

Examples

Example 1, Limiting stacked short entries to five lots (ProBacktest)

probuilder
// MACD used as the short trigger
myMACD = MACD[12,26,9](close)

// Short signal, MACD line falls through zero
short = myMACD crosses under 0

// First short entry only when no short is open
IF NOT ShortOnMarket AND short THEN
  SELLSHORT 1 CONTRACTS AT MARKET
ENDIF

// Guard, allow re-entry only below five short contracts
MAXSHARES = COUNTOFSHORTSHARES < 5

// Add to the short after a pullback in the strategy's favor
IF TRADEINDEX(1) > 5 AND TRADEPRICE(1) - Close > 10 AND ShortOnMarket AND MAXSHARES THEN
  SELLSHORT 1 CONTRACTS AT MARKET
ENDIF

// Trail the whole position
SET STOP TRAILING 50

The guard variable MAXSHARES blocks new entries once five contracts are short, keeping exposure bounded while the trend-following add-on logic stays active.

Example 2, Scaling out of a short in halves (ProOrder)

probuilder
DEFPARAM CumulateOrders = true

// Take half the short off after 30 points of profit
IF ShortOnMarket AND TRADEPRICE - close >= 30 * pointsize AND COUNTOFSHORTSHARES >= 2 THEN
  EXITSHORT COUNTOFSHORTSHARES / 2 SHARES AT MARKET
ENDIF

Reading the live short size means the partial exit always removes half of what is actually held, regardless of how many entries filled.

Example 3, Blocking hedged re-entries (ProOrder)

probuilder
DEFPARAM CumulateOrders = true

rsiVal = RSI[14](close)

// Only open or add to a short when RSI is overbought
// and the short book holds fewer than 3 lots
IF rsiVal > 70 AND COUNTOFSHORTSHARES < 3 THEN
  SELLSHORT 1 LOT AT MARKET
ENDIF

// Flatten the short when RSI normalises
IF ShortOnMarket AND rsiVal < 50 THEN
  EXITSHORT AT MARKET
ENDIF

The count acts as both the initial-entry check and the pyramiding cap, since 0 is less than 3 when the strategy is flat.

Common errors and gotchas

  • No stacking without CumulateOrders. With the default DEFPARAM CumulateOrders = false, a second SELLSHORT while already short is ignored, so COUNTOFSHORTSHARES stays at the first entry size and add-on logic never triggers.
  • Confusing shares with entries. The keyword counts shares or lots, not the number of trades. One SELLSHORT 5 CONTRACTS order makes the count 5, the same as five separate one-contract entries.
  • Pending orders are invisible. Unfilled limit or stop entry orders do not raise the count, so a cap written only against COUNTOFSHORTSHARES can still queue more pending size than intended within one bar.
  • Signed versus unsigned mix-ups. COUNTOFSHORTSHARES is positive while COUNTOFPOSITION is negative for the same short position. Mixing the two conventions in one condition is a frequent source of guards that never fire.