ProBacktest/probacktest · proorder

POSITIONPRICE

POSITIONPRICE returns the average entry price of the whole open position in ProBacktest and ProOrder, unlike TRADEPRICE which reads individual entry orders.

Syntax

probuilder
POSITIONPRICE

Past values are available with an index offset, so PositionPrice[1] reads the average position price as it was on the previous bar.

How it works

POSITIONPRICE reports the average price at which the open position was built. While the position consists of a single entry order, it equals that order's fill price. As soon as the strategy adds contracts, through pyramiding or averaging down, the value becomes the average of all open entries weighted by their sizes, and every later addition moves it again.

The distinction from TRADEPRICE matters and is a frequent source of bugs. TRADEPRICE is order-level: TRADEPRICE(1) returns the entry price of the most recent individual order, TRADEPRICE(2) the one before it. POSITIONPRICE is position-level: one number summarizing the whole open position. The two agree only while exactly one entry order is open. Exit logic that should react to the position's overall breakeven point belongs with POSITIONPRICE; logic that reacts to the latest fill, such as spacing rules between averaging entries, belongs with TRADEPRICE.

Instructions that measure distances from the entry, such as SET STOP PLOSS, are anchored to this average as well, so understanding how the average shifts when contracts are added is part of predicting where those levels end up.

Examples

Example 1, Averaging down and exiting above the average (ProOrder)

probuilder
// Unrealized profit of the whole position
floatingprofit = (((close - positionprice) * pointvalue) * countofposition) / pipsize

myMACD = MACD[12,26,9](close)

// Initial entry on a MACD zero-line cross
long = myMACD CROSSES OVER 0
IF NOT LongOnMarket AND long THEN
  BUY 1 CONTRACT AT MARKET
ENDIF

// Add a contract if the last order is aged and price fell 20 points below it
IF TRADEINDEX(1) > 5 AND TRADEPRICE(1) - Close > 20 AND LongOnMarket THEN
  BUY 1 CONTRACT AT MARKET
ENDIF

// Exit the averaged position once price recovers above its average entry
IF COUNTOFPOSITION >= 2 AND Close > POSITIONPRICE THEN
  SELL AT MARKET
ENDIF

SET TARGET PROFIT 20

The averaging rule spaces new entries using the order-level TRADEPRICE, while the exit compares the market with the position-level POSITIONPRICE, closing everything as soon as the averaged trade is back above water. This is the reference example from the source documentation with rewritten comments.

Example 2, Position average versus latest order price (ProBacktest)

probuilder
// Plot the two entry price references side by side
IF onmarket THEN
  GRAPH positionprice AS "Average position price"
  GRAPH tradeprice AS "Latest order entry price"
ENDIF

While only one order is open the two lines overlap. After each additional entry TRADEPRICE jumps to the newest fill while POSITIONPRICE moves only partway, showing the weighted average at work.

Example 3, Breakeven stop measured from the position average (ProOrder)

probuilder
// Promote the stop to the average entry after a 15 point gain
IF longonmarket AND (close - positionprice) >= 15 * pointsize THEN
  SET STOP BREAKEVEN
ENDIF

The profit condition is measured from POSITIONPRICE, so after averaging in, the 15-point requirement applies to the whole position rather than to the first fill.

Common errors and gotchas

  • Confusing it with TRADEPRICE. POSITIONPRICE is the average of the whole position, TRADEPRICE the price of one order. Exit rules written against TRADEPRICE behave unexpectedly once the position holds more than one entry, and vice versa.
  • Reading it while flat. With no open position the value carries no meaningful entry price. Guard any arithmetic on POSITIONPRICE with ONMARKET, LONGONMARKET, or SHORTONMARKET to avoid comparing against a stale or zero value.
  • The average moves. Every added order shifts POSITIONPRICE toward the new fill. Stops and profit conditions anchored to it move too, which can silently widen or tighten risk after pyramiding.
  • Index offsets read history, not orders. PositionPrice[1] is the previous bar's snapshot of the average, not the previous order's price. Order-by-order access requires TRADEPRICE(N).
  • TRADEPRICE, entry price of an individual order, the order-level counterpart.
  • TRADEINDEX, the bar index at which an order executed.
  • COUNTOFPOSITION, the signed size of the open position.
  • POSITIONPERF, performance of a position as a gain-to-cost ratio.
  • POINTVALUE, the cash value of a one-point move.
  • PIPSIZE, the size of one pip in price units.
  • ONMARKET, true while any position is open.
  • BREAKEVEN, moves the stop or target to the entry price.