Skip to content

Trading

Submit orders, cancel positions, react to fills.


The Connection object

All trading goes through a Connection obtained from Platform:

from fastboxex import Platform, load_config
import os

cfg = load_config()
p   = Platform.login(cfg, "alice", os.environ["FASTBOXEX_PASSWORD"])
asset_id = p.asset_by_symbol("JTW")["asset_id"]

conn = p.connection()
conn.activate(asset_id)

Submit and cancel orders

# Limit buy at 99.95 display (= 999_500 raw ticks)
conn.submit_limit(asset_id, side=0, price=999_500, qty=100, client_tag=42)

# Limit sell at 100.05
conn.submit_limit(asset_id, side=1, price=1_000_500, qty=100, client_tag=43)

# Cancel all resting orders for this asset
conn.cancel_all(asset_id)

# Cancel by tag
conn.cancel_by_tag(42, asset_id, side=0)

# Cancel orders worse than a reference price
conn.cancel_worse_than(asset_id, side=0, ref_price=999_000)

submit_limit(asset_id, side, price, qty, *, client_tag=0) parameters:

Parameter Type Description
asset_id int Asset to trade
side 0 or 1 0 = BUY, 1 = SELL
price int Price in raw ticks
qty int Quantity in lots
client_tag int Optional identifier echoed in acks/fills

Draining events

Both methods are non-blocking and return all pending events since the last call.

for fill in conn.drain_fills():
    side = "BUY" if fill["side"] == 0 else "SELL"
    print(f"FILL {side} {fill['volume']} @ {fill['price'] / 10_000:.4f}")

for ack in conn.drain_acks():
    print(f"ACK status={ack['status']} tag={ack['client_tag']}")

Market and delta orders

Market order — sweep the book

conn.submit_market(asset_id, side=0, qty=100)   # BUY at any price
conn.submit_market(asset_id, side=1, qty=100)   # SELL at any price

Sweeps all available liquidity on the opposite side. Returns a BookEmpty rejection if the book is empty — no silent failures.

Delta order — BBO-relative with optional IOC

Place at p_eff = best_ask + delta_ticks × tick_size (buy) or p_eff = best_bid + delta_ticks × tick_size (sell).

# Touch buy — executes at current best ask, rests if partially filled
conn.submit_delta(asset_id, side=0, delta_ticks=0, qty=100)

# IOC — execute what's available, cancel the rest immediately
conn.submit_ioc(asset_id, side=0, delta_ticks=0, qty=100)

delta_ticks=0 is a touch order — the most common pattern for aggressive strategies. delta_ticks=1 makes the order one tick more aggressive (pays up by 1 tick).

Full mathematical treatment

See Order Types — Mathematical Framework for the complete derivation, comparison with conventional exchanges, the cube taxonomy, and the passive-peg pattern.


Quoting both sides: complete example

from fastboxex import Platform, load_config
from fastboxex.price import to_display
import os, random

cfg      = load_config()
p        = Platform.login(cfg, cfg.username, os.environ["FASTBOXEX_PASSWORD"])
asset_id = p.asset_by_symbol("JTW")["asset_id"]

conn = p.connection()
conn.activate(asset_id)

SPREAD = 400  # raw ticks

for _ in range(100):
    market = p.market()
    md = market.get_latest(asset_id)
    if md is None:
        continue

    bid, ask = md["bid"], md["ask"]
    mid = (bid + ask) // 2 + random.randint(-2, 2) * 100

    conn.cancel_all(asset_id)
    conn.submit_limit(asset_id, side=0, price=mid - SPREAD // 2, qty=200, client_tag=1)
    conn.submit_limit(asset_id, side=1, price=mid + SPREAD // 2, qty=200, client_tag=2)

    for fill in conn.drain_fills():
        side = "BUY" if fill["side"] == 0 else "SELL"
        print(f"FILL {side} {fill['volume']} @ {to_display(fill['price']):.4f}")

    import time
    time.sleep(0.3)

Observer — monitor all connections

Observer gives you a read-only view of all fills and portfolio events across all connections for your user:

obs = p.observer()

for fill in obs.drain_fills():
    print(f"OBS FILL user_id={fill['user_id']} price={fill['price']}")

portfolio_events = obs.drain_portfolio()

Useful for monitoring arena participants or multiple trading connections from a single point.