QuantJourney Backtester

QuantJourney Backtester

Share product feedback

✓

Thank you.

Your note is now in the QuantJourney inbox.

docs/engine/positions.mdx

Positions

How QuantJourney records realized share or unit exposure in weight mode and order mode.

Positions are realized units held through time. In weight mode they are derived from actual weights, NAV and prices. In order mode they are updated from fills.

Sourcebacktester/core.py + backtester/portfolio/portf_data.py
LayerRealized portfolio state
ModeWeights and orders
Inputactual weights or fills, prices, cash and NAV
Outputportfolio_data.positions DataFrame
Primary APIportfolio_data.positions
Main caveatPositions are not strategy intent. They are accounting output after execution assumptions.

Engine Contract

Signals answer "what do I like?" Weights answer "how much exposure do I want?" Positions answer "how many units does the portfolio hold after the engine has applied timing, costs, rebalancing or fills?"

WEIGHT MODE actual_weights + NAV + close price -> positions ORDER MODE fills -> cash update + position update -> positions

Data Contract

Contract itemMeaning
Shapedates x instruments DataFrame
Unitshares, contracts or instrument units depending on instrument model
Signpositive long, negative short, zero flat
Weight mode sourceactual_weights * NAV / price
Order mode sourceaccumulated buy/sell fills
Storageportfolio_data.positions

Level 1: Inspect Positions After A Run

Read realized positions
python
await strategy.run_strategy()

positions = strategy.portfolio_data.positions
latest_positions = positions.iloc[-1]

print(latest_positions[latest_positions != 0])

Level 2: Compare Weights And Positions

Positions are not always intuitive when NAV changes. Inspect values and weights together.

Position audit table
python
close = strategy.instruments_data.get_feature("adj_close")
nav = strategy.portfolio_data.net_asset_value
positions = strategy.portfolio_data.positions
weights = strategy.portfolio_data.weights

date = positions.index[-1]

audit = pd.DataFrame({
    "price": close.loc[date],
    "units": positions.loc[date],
    "market_value": positions.loc[date] * close.loc[date],
    "weight": weights.loc[date],
})

print(audit.sort_values("weight", ascending=False))

Level 3: Order Mode State In A Strategy

In order mode, current_positions is passed into

_compute_orders(...). Use it to prevent duplicate entries and to size exits correctly.

Use current_positions inside order mode
python
class PositionAwareOrders(Backtester):
    def _compute_orders(self, date, bars, current_positions, nav):
        inst = "AAPL"
        bar = bars[inst]
        pos = current_positions.get(inst, 0.0)

        if pos == 0 and self._entry_signal(date, inst):
            qty = int(nav * 0.15 / bar.close)
            self.fill_engine.submit(Order(
                instrument=inst,
                side=OrderSide.BUY,
                quantity=qty,
                order_type=OrderType.MARKET,
            ))

        elif pos > 0 and self._exit_signal(date, inst):
            self.fill_engine.cancel_all(instrument=inst)
            self.fill_engine.submit(Order(
                instrument=inst,
                side=OrderSide.SELL,
                quantity=pos,
                order_type=OrderType.MARKET,
            ))

Weight Mode Positions

In weight mode positions are a derived accounting frame:

text
positions = actual_weights * nav / close

This means weight mode does not model order queues, pending orders or partial fills. It records the share/unit exposure required to represent the realized weight path.

Order Mode Positions

In order mode positions change only when fills occur. A pending stop or limit does not change the position until the fill engine emits a fill and the portfolio accounting path applies it.

Failure Modes

  • Using raw target weights when you meant realized positions.
  • Assuming a pending order has already changed the position.
  • Forgetting that a signal exit and a stop-loss exit are different paths.
  • Interpreting position units without checking instrument contract specs.
  • Comparing position counts across assets without converting to market value.

Audit Checklist

  • In weight mode, compare weights, positions, NAV and close.
  • In order mode, compare fills to changes in current_positions.
  • Check whether the strategy is flat because no orders filled or because no entry was submitted.
  • Inspect stale pending orders when positions do not change as expected.