Skip to main content

Position Tracking

A position in AEX represents your net exposure in a contract for the current trading session. As your orders fill, the add-in accumulates fill data and updates your position in real time. Two custom functions let you read this data directly in Excel:

  • AEX.POSITION — reads a single property for one contract (streaming)
  • AEX.POSITIONS — returns all positions as a spill table (streaming)

Positions are scoped to the current trading session and reset at session close.


AEX.POSITION

Returns a single streaming property of a position for a specific contract.

=AEX.POSITION(contractCode, property)
ParameterTypeDescription
contractCodestring7-character contract code, e.g. BPK1AH6
propertystringProperty name (see below)

Returns: number (streaming). Returns #N/A if no position exists for the contract yet.

Available Properties

PropertyTypeDescription
netQtynumberNet position in MW. Positive = net long; negative = net short
longnumberTotal volume bought (filled buy orders) in MW
shortnumberTotal volume sold (filled sell orders) in MW
avgBuyPxnumberVolume-weighted average price of all buy fills in $/MWh
avgSellPxnumberVolume-weighted average price of all sell fills in $/MWh
avgOpenPxnumberAverage open price for the current net position in $/MWh
pnlnumberUnrealised profit and loss for the session

Examples

=AEX.POSITION("BPK1AH6","netQty")     ' Net position: +10 means long 10 MW
=AEX.POSITION("BPK1AH6","long") ' Total long volume filled
=AEX.POSITION("BPK1AH6","short") ' Total short volume filled
=AEX.POSITION("BPK1AH6","avgBuyPx") ' Average buy price
=AEX.POSITION("BPK1AH6","avgSellPx") ' Average sell price
=AEX.POSITION("BPK1AH6","avgOpenPx") ' Average open price
=AEX.POSITION("BPK1AH6","pnl") ' Unrealised P&L

AEX.POSITIONS

Returns all current positions as a streaming spill array. The first row is a header row.

=AEX.POSITIONS()

Parameters: none

Returns: matrix (streaming, spill array)

The spill array has the following columns:

ColumnDescription
ContractContract ID
Net QtyNet position in MW
LongTotal long volume in MW
ShortTotal short volume in MW
Avg BuyVolume-weighted average buy price in $/MWh
Avg SellVolume-weighted average sell price in $/MWh
Avg OpenAverage open price in $/MWh
PnLUnrealised P&L

The table updates in real time as fills arrive. It includes only contracts where at least one fill has occurred in the current session.

tip

Enter =AEX.POSITIONS() in a cell with at least 8 blank columns to the right and enough blank rows below for your expected number of positions. The spill range expands automatically as new contracts are filled.


How P&L Is Calculated

The pnl property reflects unrealised profit and loss based on fill activity within the current session. It is calculated from the fills accumulated in the order store — the difference between buy and sell activity weighted by volume.

note

AEX is a market for electricity CFDs. P&L shown in the add-in reflects intra-session fill activity. Settlement calculations follow the contract terms and are performed by the exchange separately.


Session Scope

Position data is scoped to the current trading session:

  • Positions initialise to zero at the start of each session.
  • The positionStore is updated as fill events arrive over the WebSocket connection.
  • When the session closes, positions freeze at their final values until the next session begins.
  • If the add-in reconnects mid-session, the server sends a snapshot of current positions to restore the store.

AEX.POSITION returns #N/A for a contract if no fills have occurred for that contract yet in the session.


Building a Position Blotter

The simplest blotter uses AEX.POSITIONS as a live table:

  1. Select an empty cell — for example, A1.
  2. Enter =AEX.POSITIONS().
  3. The table spills across 8 columns and grows downward as positions are filled.

For a more structured blotter, combine AEX.POSITION with a static list of contract codes:

' Column A: your contract codes (static list)
' Column B: net quantity
' Column C: P&L

B2: =AEX.POSITION(A2,"netQty")
C2: =AEX.POSITION(A2,"pnl")
D2: =AEX.POSITION(A2,"avgOpenPx")

This approach gives you control over the layout and lets you add your own calculated columns — for example, mark-to-market using AEX.LAST:

' Mark-to-market: net position × (last price − average open price)
=AEX.POSITION(A2,"netQty") * (AEX.LAST(A2) - AEX.POSITION(A2,"avgOpenPx"))
note

AEX.LAST and AEX.POSITION are both streaming. A cell that combines them updates automatically whenever either value changes.


Next Steps