fastboxex.connection¶
Connection is the trading channel for one sub-user. Obtained from
p.connection(), arena.connect_generator(), or arena.connect_trader(i).
Activation¶
Must be called once per asset before any fills are routed to this connection. Required for both live trading and arena connections.
Order submission¶
submit_limit(asset_id, side, price, qty, *, client_tag=0) → None¶
Post a passive limit order at the given price.
| Parameter | Type | Description |
|---|---|---|
side |
int |
0 = BUY, 1 = SELL |
price |
int |
Raw ticks |
qty |
int |
Quantity (multiple of lot_size) |
client_tag |
int |
Optional identifier echoed in acks/fills |
submit_market(asset_id, side, qty) → None¶
Sweep the book at any price. Rejected if the opposite side is empty.
submit_delta(asset_id, side, delta_ticks, qty, *, client_tag=0) → None¶
Price-relative order. Effective price = BBO ± delta_ticks × tick_size.
Rests if only partially filled.
conn.submit_delta(asset_id, side=0, delta_ticks=2, qty=100) # 2 ticks inside BBO
conn.submit_delta(asset_id, side=0, delta_ticks=0, qty=100) # touch (at best bid)
submit_ioc(asset_id, side, delta_ticks, qty, *, client_tag=0) → None¶
Same as submit_delta but cancels any unfilled remainder immediately.
Cancellation¶
conn.cancel_all(asset_id) # both sides
conn.cancel_all(asset_id, side=0) # bids only
conn.cancel_by_tag(client_tag, asset_id, side=0) # by tag
conn.cancel_worse_than(asset_id, side=0, ref_price=999_000) # clear inferior quotes
Draining events¶
Both methods are non-blocking and return all pending events since the last call.
drain_fills() → list[dict]¶
Returns fill events. Key fields:
| Key | Type | Description |
|---|---|---|
ts |
int |
Nanosecond timestamp |
price |
int |
Fill price (raw ticks) |
volume |
int |
Filled quantity |
side |
int |
0=BUY fill, 1=SELL fill |
is_maker |
bool |
True if this order was passive |
client_tag |
int |
Tag from the original submission |
asset_id |
int |
Asset |
drain_acks() → list[dict]¶
Returns order acknowledgements. Key fields:
| Key | Type | Description |
|---|---|---|
status |
int |
1=New/OK, 6=PendingNew, other=rejected |
client_tag |
int |
Tag from submission |
reject_reason |
int \| None |
Non-zero if rejected |
Properties¶
| Property | Type | Description |
|---|---|---|
conn.user_id |
int |
Sub-user ID |
conn.label |
str |
Human-readable label |
conn.role |
str |
"Generator", "Trader", or "Joiner" |
Polars export¶
fills_df = conn.fills_to_polars(asset_id) # → Polars DataFrame or None
acks_df = conn.acks_to_polars(asset_id)
Columns: ts, price, volume, side, is_maker, client_tag, asset_id.
Zero-copy tensor path¶
import numpy as np
mv = conn.fills_as_tensor() # PyMemoryView — zero-copy
arr = np.frombuffer(mv, dtype=np.uint8) # no allocation
LOB access (live exchange only)¶
Arena context
conn.lob() is only populated in live exchange connections, not in arena connections.
In arena scripts, use p.arena_market().get_latest(asset_id) instead.
# Live exchange:
lob = conn.lob(asset_id=1)
print(lob.best_bid, lob.best_ask, lob.spread)
# Arena:
md = arena_market.get_latest(arena.asset_id)
mid = (md["bid"] + md["ask"]) // 2
UserLOB¶
Returned by conn.lob() and conn.rebuild_lob().
| Property | Type | Description |
|---|---|---|
lob.best_bid |
int \| None |
Best bid price (raw ticks) |
lob.best_ask |
int \| None |
Best ask price (raw ticks) |
lob.spread |
int \| None |
best_ask - best_bid |
lob.is_crossed |
bool |
True if bid ≥ ask |
lob.is_empty |
bool |
True if both sides are empty |