Skip to main content

Overview

This page documents 6 operators (role: ORDER, POSITION).

Quick Reference


TargetPositionIntention

Build TradingIntention from normalized weights OR target_notional (delta trading). Supports TWO input modes:
  1. Weight-based (legacy): weights + book_size → target_notional computed internally
  2. Target-based (new): target_notional provided directly for maximum flexibility
Precedence: If target_notional is provided, weights and book_size are IGNORED. Flow:
  1. Get target_notional (from input OR weights * book_size)
  2. Apply safety guards (max_exposure, delta_capping)
  3. Compute target_qty = target_notional / price
  4. Compute delta = target_qty - current_qty
  5. Apply lot size rounding
  6. Create TradingIntention(entity_id=symbol, order_amount=delta)
Input Modes: Mode 1 (Weight-based):
  • weights: Normalized signal (Input from signal node)
  • book_size: Total tradeable capital (Input from BookSize)
Mode 2 (Target-based):
  • target_notional: Pre-computed target notional per symbol (Input) Allows upstream SizingOperator to handle complex allocation logic
Common Required Inputs:
  • positions: Current positions (Input from STATE:pos_quantity)
  • prices: Execution prices (Input from FIELD:close or similar)
Safety Guards:
  • max_exposure_ratio: Max total exposure as ratio of equity (requires equity input)
  • max_delta_notional: Max order value per tick (prevents slippage in illiquid markets)
Paired TP/SL (for arbitrage):
  • pair_id: External Input to link orders across different Intentions
  • static_pair_id: Static string for simple cases
Usage (Weight-based - legacy): intention = TargetPositionIntention( weights=Input(“signal_weights”, …), book_size=Input(“book_size”, …), positions=Input(“STATE:alpaca:equity:pos_quantity”, …), prices=Input(“FIELD:close”, …), axis_keys=symbol_source_map.axis_keys_for(“alpaca:equity”), execution_routing=symbol_source_map.execution_routing, ) Usage (Target-based - recommended for multi-venue):

First, create EquityCalculator for the venue

spot_equity = EquityCalculator( cash=Input(“STATE:gateio:spot:cash”, timeframe=“1m”, lookback=0), positions=Input(“STATE:gateio:spot:pos_quantity”, timeframe=“1m”, lookback=0), prices=Input(“FIELD:gateio:spot:ohlcv:close”, timeframe=“1m”, lookback=0), entry_prices=Input(“STATE:gateio:spot:pos_entry_price”, timeframe=“1m”, lookback=0), axis_keys=symbol_source_map.axis_keys_for(“gateio:spot”),

market_type auto-detected from cash Input source (“spot” from “STATE:gateio:spot:cash”)

) intention = TargetPositionIntention( target_notional=Input(“sizing_operator”, field=“spot_target”), positions=Input(“STATE:gateio:spot:pos_quantity”, timeframe=“1m”, lookback=0), prices=Input(“FIELD:gateio:spot:ohlcv:close”, timeframe=“1m”, lookback=1), axis_keys=symbol_source_map.axis_keys_for(“gateio:spot”), execution_routing=symbol_source_map.execution_routing, equity=Input(“spot_equity”, timeframe=“1m”, lookback=1), # From EquityCalculator max_exposure_ratio=1.5, max_delta_notional=50000, # Max $50k per tick pair_id=Input(“pair_id_gen”), # For paired TP/SL ) Output: Returns intention data as numpy array that TradingDriver extracts. Format: [{entity_id, order_amount, venue, pair_id, …}, …] order_amount is the delta: positive=BUY, negative=SELL (spot only allows BUY) Role: ORDER | Ephemeral: No

Parameters

Source Code

Full compute() implementation — no hidden logic.
Source: apps/trading/operators/order/intention.py

FuturesTargetPositionIntention

Build FuturesIntention from target_notional OR weights+book_size (delta trading). Same as TargetPositionIntention but with futures-specific parameters: leverage, margin_type, position_side, reduce_only, take_profit, stop_loss. Supports TWO input modes (same as TargetPositionIntention):
  1. Weight-based (legacy): weights + book_size → target_notional computed internally
  2. Target-based (new): target_notional provided directly for maximum flexibility
Precedence: If target_notional is provided, weights and book_size are IGNORED. Output contains order_amount (delta already computed):
  • order_amount above 0: BUY order (LONG)
  • order_amount below 0: SELL order (SHORT)
Input Modes: Mode 1 (Weight-based):
  • weights: Normalized signal (Input from signal node)
  • book_size: Total tradeable capital (Input from BookSize)
Mode 2 (Target-based):
  • target_notional: Pre-computed target notional per symbol (Input) Allows upstream SizingOperator to handle complex allocation logic
Futures-specific Parameters:
  • leverage: Static float or dynamic Input (per-symbol array)
  • margin_type: CROSS or ISOLATED
  • position_side: LONG, SHORT, or BOTH
  • reduce_only: If True, only reduces existing position
Safety Guards (same as TargetPositionIntention):
  • max_exposure_ratio: Max total exposure as ratio of equity
  • max_delta_notional: Max order value per tick
Usage (Weight-based - legacy): intention = FuturesTargetPositionIntention( weights=Input(“signal_weights”, …), book_size=Input(“book_size”, …), positions=Input(“STATE:gateio:futures:pos_quantity”, …), prices=Input(“FIELD:close”, …), axis_keys=symbol_source_map.axis_keys_for(“gateio:futures”), execution_routing=symbol_source_map.execution_routing, leverage=5.0, margin_type=MarginType.CROSS, ) Usage (Target-based - recommended for multi-venue):

First, create EquityCalculator for the venue

NOTE: For futures, equity = cash + unrealized_pnl (NOT cash + position_value)

futures_equity = EquityCalculator( cash=Input(“STATE:binance:futures:cash”, timeframe=“1m”, lookback=0), positions=Input(“STATE:binance:futures:pos_quantity”, timeframe=“1m”, lookback=0), prices=Input(“FIELD:binance:futures:ohlcv:close”, timeframe=“1m”, lookback=0), entry_prices=Input(“STATE:binance:futures:pos_entry_price”, timeframe=“1m”, lookback=0), axis_keys=symbol_source_map.axis_keys_for(“binance:futures”),

market_type auto-detected from cash Input source (“futures” from “STATE:binance:futures:cash”)

) intention = FuturesTargetPositionIntention( target_notional=Input(“sizing_operator”, field=“futures_target”), positions=Input(“STATE:binance:futures:pos_quantity”, timeframe=“1m”, lookback=0), prices=Input(“FIELD:binance:futures:ohlcv:close”, timeframe=“1m”, lookback=1), axis_keys=symbol_source_map.axis_keys_for(“binance:futures”), execution_routing=symbol_source_map.execution_routing, leverage=3.0, equity=Input(“futures_equity”, timeframe=“1m”, lookback=1), # From EquityCalculator max_exposure_ratio=1.5, max_delta_notional=50000, pair_id=Input(“pair_id_gen”), # For paired TP/SL take_profit_pct=0.5, stop_loss_pct=0.1, ) Role: ORDER | Ephemeral: No

Parameters

Source Code

Full compute() implementation — no hidden logic.
Source: apps/trading/operators/order/intention.py

DynamicUniverseIntention

Dynamic universe intention builder with symbol warmup and exit handling. Unlike FuturesTargetPositionIntention which requires a fixed axis_keys list, this operator:
  1. Reads axis_keys dynamically from Graph’s primary axis
  2. Tracks per-axis_key warmup (tick count since first seen)
  3. Auto-closes positions when axis_keys exit universe (exists=False)
Symbol States (managed via exists/valid + internal warmup counter):
  • WARMING_UP: exists=True, valid=True, but warmup_ticks < required → Skip trading, accumulate data
  • ACTIVE: exists=True, valid=True, warmup complete → Normal delta trading
  • EXITED: exists=False (filtered out or delisted) → Generate close order if position exists
Inputs (4 required, 1 optional):
  1. weights: Normalized signal from upstream (e.g., L1Norm output)
  2. book_size: Total capital from BookSize operator
  3. positions: Current positions from STATE:venue:pos_quantity
  4. prices: Execution prices from FIELD:close
  5. leverage (optional): Dynamic per-symbol leverage (Input from node)
Leverage:
  • Static: leverage=3.0 (same for all symbols)
  • Dynamic: leverage=Input(“leverage_node”, …) (per-symbol array)
Role: ORDER | Ephemeral: No

Parameters

Usage

Source Code

Full compute() implementation — no hidden logic.
Source: apps/trading/operators/order/intention.py

ArbitrageIntention

Arbitrage intention builder for cross-venue or cross-market trades. Generates paired orders: LONG on one venue, SHORT on another. Supports:
  • Cross-exchange arbitrage: Buy on Binance, Sell on Gateio
  • Basis trade: Buy spot, Sell futures (or vice versa)
  • Multi-symbol arbitrage: Process multiple symbols in parallel
The spread signal determines position sizing:
  • spread above 0: Go long on long_venue, short on short_venue
  • spread below 0: Go short on long_venue, long on short_venue
  • spread ≈ 0: Close positions (or no action)
Inputs (6 required):
  1. spread: Spread signal (array, one per symbol)
  2. book_size: Total capital for the trade (scalar)
  3. long_positions: Current positions on long_venue (STATE:venue:pos_quantity)
  4. short_positions: Current positions on short_venue (STATE:venue:pos_quantity)
  5. long_prices: Prices on long_venue (FIELD:close)
  6. short_prices: Prices on short_venue (FIELD:close)
Role: ORDER | Ephemeral: No

Parameters

Usage

Source Code

Full compute() implementation — no hidden logic.
Source: apps/trading/operators/order/intention.py

VenueAwareSizing

Compute target_notional for multi-venue strategies. Takes signal weights (per-symbol) and allocates capital across multiple venues based on configurable allocation rules. Outputs a single target_notional array aligned to all_axis_keys that can be fed to TargetPositionIntention and FuturesTargetPositionIntention. Key Design:
  • Outputs a single numpy array aligned to all_axis_keys
  • Each venue’s Intention extracts its portion using axis_indices (automatic)
  • For “inverse_hedge” mode: long venues get positive, short venues get negative
Allocation Modes:
  1. “equal”: Equal split across venues (default)
  2. “proportional”: Based on venue_weights dict
  3. “inverse_hedge”: Spot long, Futures short (or vice versa) for arbitrage
Example (Cross-venue arbitrage: Spot Long, Futures Short): sizing = VenueAwareSizing( signal=Input(“arb_signal”, timeframe=“1m”, lookback=1), total_equity=Input(“total_equity”, timeframe=“1m”, lookback=1), venue_configs={ “binance:spot”: {“role”: “long”, “allocation_ratio”: 0.5}, “binance:futures”: {“role”: “short”, “allocation_ratio”: 0.5}, }, axis_keys=all_axis_keys, execution_routing=execution_routing, allocation_mode=“inverse_hedge”, ) Connecting to Intention Operators:

Sizing outputs array aligned to all_axis_keys

Each Intention automatically extracts its venue’s portion

spot_intention = TargetPositionIntention( target_notional=Input(“sizing”, timeframe=“1m”, lookback=1), positions=Input(“STATE:binance:spot:pos_quantity”, …), prices=Input(“FIELD:binance:spot:close”, …), axis_keys=spot_axis_keys, # Only spot axis_keys execution_routing=execution_routing, ) futures_intention = FuturesTargetPositionIntention( target_notional=Input(“sizing”, timeframe=“1m”, lookback=1), positions=Input(“STATE:binance:futures:pos_quantity”, …), prices=Input(“FIELD:binance:futures:close”, …), axis_keys=futures_axis_keys, # Only futures axis_keys execution_routing=execution_routing, leverage=3.0, ) Role: POSITION | Ephemeral: No

Parameters

Source Code

Full compute() implementation — no hidden logic.
Source: apps/trading/operators/order/sizing.py

PairIdGenerator

Generate pair_id for linking orders across Intentions. Creates unique pair_ids for each symbol that has active signal across multiple venues. This allows Intention operators to link orders for atomic execution (e.g., Spot buy + Futures sell). Output: TaggedArray with pair_id strings per axis_key.
  • None for symbols with no signal (below threshold)
  • Unique string for symbols with active signal in multiple venues
Role: POSITION | Ephemeral: No

Parameters

Usage

Source Code

Full compute() implementation — no hidden logic.
Source: apps/trading/operators/order/sizing.py

Operator Protocol

How operators implement the compute() interface

StatefulGraph

How operators compose into a DAG