Skip to main content
Orders and trades live on two services:
  • STXOrderService — place, cancel, and query orders
  • STXTradeService — query fills (trades)

Place an order

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

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

var order = await orders.ConfirmOrderAsync(
    price:     10,                   // cents
    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}");

Parameters

priceInteger cents. 50 = 50¢. Ignored for market orders.
quantityNumber of contracts.
marketIdFrom STXMarketService.GetMarketInfosAsync.
actionSTXOrderAction.buy / STXOrderAction.sell
orderTypeSTXOrderType.limit / STXOrderType.market
clientOrderIdYour idempotency key. If the call retries you won’t get a double-fill.
cancelOnDisconnectIf true, the exchange cancels this order when the websocket drops. Requires STXActiveOrdersChannel to be joined — see below.

Cancel-on-disconnect requires the active orders channel

If you pass cancelOnDisconnect: true but haven’t joined STXActiveOrdersChannel, the call throws STXCancelOnDisconnectNotEnabledException. For the market-maker workflow, always join the channel first (it costs nothing):
var activeOrders = serviceProvider.GetRequiredService<STXActiveOrdersChannel>();
await activeOrders.ConnectAsync();
If you only want a simple place-and-leave-it order, pass cancelOnDisconnect: false.

Batch orders

Placing many orders at once is one round-trip instead of N:
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);                           // one
await orders.CancelOrdersAsync(new[] { orderId1, orderId2 });     // several
await orders.CancelAllOrdersAsync();                              // everything open on this account
CancelAllOrdersAsync returns the list of every cancelled order, which is handy to reconcile against your own state.

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}");
}

Trades (fills)

Each fill is a trade:
var trades = serviceProvider.GetRequiredService<STXTradeService>();

// Everything
var hist = await trades.GetMyTradesAsync(
    limit:     50,
    sortBy:    STXTradesSortByField.time,
    sortOrder: STXSortOrder.desc);

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

Real-time: fills + order status

Polling the REST endpoints works but adds latency. The websocket channels push updates as they happen:
  • STXActiveOrdersChannel — every state change on an open order (openpartially_filledfilled / cancelled)
  • STXActiveTradesChannel — every new trade (fill)
See WebSockets → Orders & trades.

A canonical market-maker loop

Pulled straight from cssdk-console’s STXWorker.cs:
// 1. Login and connect channels
await _login.LoginAsync(email, password, keepSessionAlive: true);
await _ordersChannel.ConnectAsync();
await _tradesChannel.ConnectAsync();
await _portfolioChannel.ConnectAsync();

// 2. Subscribe to market updates
_marketChannel.OnPriceUpdate += OnPriceTick;
await _marketChannel.ConnectAsync();

// 3. On each tick, quote
void OnPriceTick(STXMarketInfoChannelData tick) {
    // Cancel stale orders and place fresh ones
    await _orderService.CancelAllOrdersAsync();
    await _orderService.ConfirmOrdersAsync(BuildQuotes(tick));
}
Cancel-on-disconnect, automatic session refresh, and portfolio-balance tracking are all handled by registered services — the loop above is the whole app.

See also