Skip to content

Positions API

Position models for spot, perpetual, and futures instruments.

SpotPosition

SpotPosition dataclass

Bases: BasePositionImpl

Spot positions reuse the generic BasePositionImpl behavior.

from_trades classmethod

from_trades(
    trades: Sequence[Fill],
    *,
    cost_basis_method: CostBasisMethod = CostBasisMethod.FIFO
) -> "SpotPosition"

Build a SpotPosition from a sequence of fills.

PerpetualPosition

PerpetualPosition dataclass

Bases: BasePositionImpl

Perpetual swap position with funding tracking.

Extends BasePositionImpl with funding-specific fields to track cumulative funding payments received or paid over the position's lifetime.

Attributes:

Name Type Description
accumulated_funding Money

Total funding P&L accumulated (positive = received, negative = paid)

last_funding_timestamp_ms TimestampMs

Timestamp of the last applied funding event

Example

pos = PerpetualPosition.flat("BTC-PERP") pos = pos.apply_fill(fill) pos = pos.apply_funding(funding_event) print(pos.funding_pnl)

funding_pnl property

funding_pnl: Money

Cumulative funding P&L (positive = received, negative = paid).

total_realized_pnl property

total_realized_pnl: Money

Total realized P&L including trading and funding.

flat staticmethod

flat(instrument_id: str) -> 'PerpetualPosition'

Create an empty perpetual position.

apply_fill

apply_fill(fill: Fill) -> 'PerpetualPosition'

Apply fill and preserve perpetual-specific fields.

apply_funding

apply_funding(
    event: FundingEvent, fills: Sequence[Fill] | None = None
) -> "PerpetualPosition"

Apply funding event and accumulate funding P&L.

Parameters:

Name Type Description Default
event FundingEvent

Funding event to apply

required
fills Sequence[Fill] | None

Optional fills during funding period for time segmentation

None

Returns:

Type Description
'PerpetualPosition'

New PerpetualPosition with updated funding accumulator

Note

Unlike BasePositionImpl.apply_funding which adds funding to realized_pnl, this tracks funding separately in accumulated_funding for clearer attribution.

from_base classmethod

from_base(
    base: BasePositionImpl,
    *,
    accumulated_funding: Money = Decimal(0),
    last_funding_timestamp_ms: TimestampMs = TimestampMs(0)
) -> "PerpetualPosition"

Convert a BasePositionImpl to PerpetualPosition.

Parameters:

Name Type Description Default
base BasePositionImpl

Base position to convert

required
accumulated_funding Money

Initial funding accumulator value

Decimal(0)
last_funding_timestamp_ms TimestampMs

Initial last funding timestamp

TimestampMs(0)

Returns:

Type Description
'PerpetualPosition'

New PerpetualPosition with all base position data preserved

FuturesPosition

FuturesPosition dataclass

Bases: BasePositionImpl

Futures position with expiration and settlement support.

Extends BasePositionImpl with futures-specific fields for tracking contract expiration and handling settlement at expiry.

Attributes:

Name Type Description
expiry_ms TimestampMs | None

Contract expiration timestamp in milliseconds (None if not set)

settlement_price Price | None

Price at which position was settled (None if not yet settled)

is_settled bool

Whether the position has been settled

Example

pos = FuturesPosition.flat("BTC-DEC24", expiry_ms=1725289600000) pos = pos.apply_fill(fill) if pos.is_expired(current_time_ms): ... pos = pos.settle(settlement_event)

flat staticmethod

flat(
    instrument_id: str, expiry_ms: TimestampMs | None = None
) -> "FuturesPosition"

Create an empty futures position.

Parameters:

Name Type Description Default
instrument_id str

Instrument identifier

required
expiry_ms TimestampMs | None

Optional contract expiration timestamp

None

is_expired

is_expired(current_time_ms: TimestampMs) -> bool

Check if contract has expired.

Parameters:

Name Type Description Default
current_time_ms TimestampMs

Current timestamp in milliseconds

required

Returns:

Type Description
bool

True if expiry_ms is set and current time is at or past expiry

time_to_expiry

time_to_expiry(current_time_ms: TimestampMs) -> int | None

Calculate time until expiration in milliseconds.

Parameters:

Name Type Description Default
current_time_ms TimestampMs

Current timestamp in milliseconds

required

Returns:

Type Description
int | None

Milliseconds until expiration, 0 if expired, None if no expiry set

time_to_expiry_hours

time_to_expiry_hours(
    current_time_ms: TimestampMs,
) -> float | None

Calculate time until expiration in hours.

Parameters:

Name Type Description Default
current_time_ms TimestampMs

Current timestamp in milliseconds

required

Returns:

Type Description
float | None

Hours until expiration, 0 if expired, None if no expiry set

apply_fill

apply_fill(fill: Fill) -> 'FuturesPosition'

Apply fill and preserve futures-specific fields.

settle

settle(event: SettlementEvent) -> 'FuturesPosition'

Settle the position at the settlement price.

This closes the position and realizes P&L based on the settlement price. After settlement, the position size becomes 0 and is_settled becomes True.

Parameters:

Name Type Description Default
event SettlementEvent

Settlement event with price and timestamp

required

Returns:

Type Description
'FuturesPosition'

New FuturesPosition with position closed and P&L realized

Raises:

Type Description
ValueError

If position is already settled or size is 0

from_base classmethod

from_base(
    base: BasePositionImpl,
    *,
    expiry_ms: TimestampMs | None = None
) -> "FuturesPosition"

Convert a BasePositionImpl to FuturesPosition.

Parameters:

Name Type Description Default
base BasePositionImpl

Base position to convert

required
expiry_ms TimestampMs | None

Contract expiration timestamp

None

Returns:

Type Description
'FuturesPosition'

New FuturesPosition with all base position data preserved

Position Metrics

mark_to_market

mark_to_market

mark_to_market(
    position: BasePosition, mark_price: Price
) -> Money

Return mark-to-market value (signed).

unrealized_pnl

unrealized_pnl

unrealized_pnl(
    position: BasePosition, mark_price: Price
) -> Money

Compute unrealized PnL using average entry price.

leverage

leverage

leverage(
    position: BasePosition, equity: Money
) -> Decimal | None

Return position leverage given portfolio equity.

Builders

PositionBuilder

PositionBuilder

Fluent builder for creating positions.

Example

pos = ( ... PositionBuilder("BTC-PERP") ... .long() ... .with_size("2.5") ... .with_entry_price("10000") ... .as_perpetual() ... .build() ... )

long

long() -> 'PositionBuilder'

Set position side to LONG.

short

short() -> 'PositionBuilder'

Set position side to SHORT.

with_side

with_side(side: PositionSide | str) -> 'PositionBuilder'

Set position side.

with_size

with_size(size: Decimal | str | float) -> 'PositionBuilder'

Set position size.

with_entry_price

with_entry_price(
    price: Decimal | str | float,
) -> "PositionBuilder"

Set average entry price.

with_realized_pnl

with_realized_pnl(
    pnl: Decimal | str | float,
) -> "PositionBuilder"

Set realized P&L.

with_unrealized_pnl

with_unrealized_pnl(
    pnl: Decimal | str | float,
) -> "PositionBuilder"

Set unrealized P&L.

with_fees

with_fees(fees: Decimal | str | float) -> 'PositionBuilder'

Set accumulated fees.

with_cost_basis

with_cost_basis(
    method: CostBasisMethod | str,
) -> "PositionBuilder"

Set cost basis method.

as_perpetual

as_perpetual() -> 'PositionBuilder'

Build as PerpetualPosition.

as_futures

as_futures(
    expiry_ms: int | None = None,
) -> "PositionBuilder"

Build as FuturesPosition.

with_accumulated_funding

with_accumulated_funding(
    funding: Decimal | str | float,
) -> "PositionBuilder"

Set accumulated funding (for perpetuals).

build

build() -> BasePositionImpl

Build the position.