Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.sportsxapp.com/llms.txt

Use this file to discover all available pages before exploring further.

Trading in the SportsX SDK uses two services. STXOrderService handles order placement, cancellation, and order history. STXTradeService handles fills (trades). Both services support real-time counterparts via WebSocket channels for latency-sensitive workflows.

Place an order

using STX.Sdk.Enums;
using STX.Sdk.Services;

var orders = serviceProvider.GetRequiredService<STXOrderService>();

var order = await orders.ConfirmOrderAsync(
    price:              10,                  // integer cents; 10 = 10¢
    quantity:           1,
    marketId:           "mkt_abc",
    action:             STXOrderAction.buy,
    orderType:          STXOrderType.limit,
    clientOrderId:      "my-ref-1",          // optional idempotency key
    cancelOnDisconnect: true);

Console.WriteLine($"Order {order.Id} placed at {order.Price}c x {order.Quantity}");

Order parameters

ParameterNotes
priceInteger cents. 50 = 50¢. Ignored for market orders.
quantityNumber of contracts.
marketIdFrom STXMarketService.GetMarketInfosAsync.
actionSTXOrderAction.buy or STXOrderAction.sell.
orderTypeSTXOrderType.limit or STXOrderType.market.
clientOrderIdYour idempotency key. If the call retries, you won’t receive a duplicate fill.
cancelOnDisconnectWhen true, the exchange cancels this order if the WebSocket drops. Requires STXActiveOrdersChannel to be joined first.

Cancel-on-disconnect

If you pass cancelOnDisconnect: true without having joined STXActiveOrdersChannel, the call throws STXCancelOnDisconnectNotEnabledException. For a market-maker workflow, join the channel before placing any orders:
var activeOrders = serviceProvider.GetRequiredService<STXActiveOrdersChannel>();
await activeOrders.ConnectAsync();

// Now cancelOnDisconnect: true is safe to use
var order = await orders.ConfirmOrderAsync(
    price:              45,
    quantity:           5,
    marketId:           "mkt_abc",
    action:             STXOrderAction.sell,
    orderType:          STXOrderType.limit,
    cancelOnDisconnect: true);
If you only want a resting order that survives disconnects, pass cancelOnDisconnect: false.

Batch orders

Placing multiple orders in one call reduces round-trips and is the preferred approach for market makers quoting several markets simultaneously:
var batch = new[]
{
    new STXConfirmOrderParams
    {
        Price     = 10,
        Quantity  = 1,
        MarketId  = "mkt_a",
        Action    = STXOrderAction.buy,
        OrderType = STXOrderType.limit,
    },
    new STXConfirmOrderParams
    {
        Price     = 85,
        Quantity  = 2,
        MarketId  = "mkt_b",
        Action    = STXOrderAction.sell,
        OrderType = STXOrderType.limit,
    },
};

var placed = await orders.ConfirmOrdersAsync(batch);

Cancel orders

await orders.CancelOrderAsync(orderId);
CancelAllOrdersAsync returns every order it cancelled, which is useful for reconciling your local state after a strategy reset.

Query order history

var history = await orders.GetMyOrdersAsync(
    statusFilter: new[] { STXOrderStatus.filled, STXOrderStatus.cancelled },
    limit:        50,
    sortBy:       STXOrdersSortByField.insertedAt,
    sortOrder:    STXSortOrder.desc);

foreach (var o in history.Orders)
{
    Console.WriteLine($"{o.Id,-10} {o.Status,-10} {o.MarketId,-12} {o.Price}c x {o.Quantity}");
}

Query trades (fills)

Each matched order generates one or more trade records. Resolve STXTradeService to query them:
var trades = serviceProvider.GetRequiredService<STXTradeService>();

// All fills, most recent first
var allFills = await trades.GetMyTradesAsync(
    limit:     50,
    sortBy:    STXTradesSortByField.time,
    sortOrder: STXSortOrder.desc);

// Fills for a specific order
var orderFills = await trades.GetMyTradesForOrderAsync(orderId);

Real-time order and trade updates

Polling the HTTP endpoints works but adds unnecessary latency. The WebSocket channels push updates as they happen:
  • STXActiveOrdersChannel — every state transition on an open order (openpartially_filledfilled or cancelled).
  • STXActiveTradesChannel — each new fill as it lands.
See WebSockets for setup details.

A canonical market-maker loop

The pattern below is adapted from cssdk-console’s STXWorker.cs. It shows the full lifecycle: connect channels, subscribe to price ticks, and requote on each tick:
// 1. Authenticate and connect channels
await _login.LoginAsync(email, password, keepSessionAlive: true);
await _ordersChannel.ConnectAsync();
await _tradesChannel.ConnectAsync();
await _portfolioChannel.ConnectAsync();

// 2. Subscribe to market price ticks
_marketChannel.OnPriceUpdate += OnPriceTick;
await _marketChannel.ConnectAsync();
await _marketChannel.SubscribeAsync("mkt_abc");

// 3. Requote on each tick
async void OnPriceTick(STXMarketInfoChannelData tick)
{
    // Cancel stale quotes and place fresh ones in one batch
    await _orderService.CancelAllOrdersAsync();
    await _orderService.ConfirmOrdersAsync(BuildQuotes(tick));
}
Cancel-on-disconnect, automatic JWT refresh, and portfolio-balance tracking are all handled by the registered SDK services — the loop above is the core of the app.

See also