Skip to main content

Submit Order

Submit a new order to the exchange.
public async Task<OrderId> SubmitOrder(string account, Order order)

Parameters

account
string
required
Account identifier to submit the order from (e.g., Api.DemoAccount = “REM2046”)
order
Order
required
Order object containing all order parameters

Order Properties

Instrument
Instrument
required
The instrument to trade
Side
Side
required
Order side: Side.Buy or Side.Sell
Quantity
int
required
Order quantity/size
Type
Type
required
Order type: Type.Market or Type.Limit
Price
decimal?
Limit price (required for limit orders, null for market orders)
Expiration
Expiration
required
Time in force: Day, ImmediateOrCancel, FillOrKill, or GoodTillDate
ExpirationDate
DateTime
Expiration date (required when Expiration is GoodTillDate)
CancelPrevious
bool
default:"false"
Cancel previous orders for this instrument before submitting
Iceberg
bool
default:"false"
Submit as iceberg order (hidden quantity)
DisplayQuantity
uint
Visible quantity for iceberg orders (required when Iceberg is true)

Response

Returns an OrderId object:
ClientOrderId
string
Client-side order identifier
Proprietary
string
Exchange-assigned proprietary order identifier

Example: Simple Limit Order

using Primary;
using Primary.Data;
using Primary.Data.Orders;

var api = new Api(Api.DemoEndpoint);
await api.Login(Api.DemoUsername, Api.DemoPassword);

// Get instrument
var instruments = await api.GetAllInstruments();
var instrument = instruments.First();

// Create limit order
var order = new Order
{
    Instrument = instrument,
    Side = Side.Buy,
    Quantity = 100,
    Price = 150.50m,
    Type = Type.Limit,
    Expiration = Expiration.Day
};

try
{
    var orderId = await api.SubmitOrder(Api.DemoAccount, order);
    Console.WriteLine($"Order submitted successfully!");
    Console.WriteLine($"Client Order ID: {orderId.ClientOrderId}");
    Console.WriteLine($"Proprietary ID: {orderId.Proprietary}");
}
catch (Exception ex)
{
    Console.WriteLine($"Order failed: {ex.Message}");
}

Example: Market Order

var order = new Order
{
    Instrument = instrument,
    Side = Side.Sell,
    Quantity = 50,
    Price = null, // No price for market orders
    Type = Type.Market,
    Expiration = Expiration.ImmediateOrCancel
};

var orderId = await api.SubmitOrder(Api.DemoAccount, order);

Example: Iceberg Order

var order = new Order
{
    Instrument = instrument,
    Side = Side.Buy,
    Quantity = 1000,
    Price = 148.25m,
    Type = Type.Limit,
    Expiration = Expiration.Day,
    Iceberg = true,
    DisplayQuantity = 100 // Only show 100, hide remaining 900
};

var orderId = await api.SubmitOrder(Api.DemoAccount, order);

Example: Good Till Date Order

var order = new Order
{
    Instrument = instrument,
    Side = Side.Buy,
    Quantity = 200,
    Price = 145.00m,
    Type = Type.Limit,
    Expiration = Expiration.GoodTillDate,
    ExpirationDate = DateTime.Today.AddDays(7) // Expires in 7 days
};

var orderId = await api.SubmitOrder(Api.DemoAccount, order);

Get Order Status

Retrieve the current status and details of an order.
public async Task<OrderStatus> GetOrderStatus(OrderId orderId)

Parameters

orderId
OrderId
required
The order identifier returned from SubmitOrder

Response

Returns an OrderStatus object with all order details:
Id
string
Exchange order identifier
Status
Status
Current order status: New, PendingNew, Rejected, Cancelled, PendingCancel, PartiallyFilled, or Filled
StatusText
string
Additional status information/description
Account
AccountId
Account information
ExecutionId
string
Execution identifier
TransactionTime
DateTime
Transaction timestamp
AveragePrice
decimal
Average fill price
LastPrice
decimal
Last fill price
LastQuantity
uint
Quantity filled in last execution
CumulativeQuantity
uint
Total quantity filled so far
LeavesQuantity
uint
Remaining unfilled quantity

Example

// Submit order
var orderId = await api.SubmitOrder(Api.DemoAccount, order);

// Wait a moment
await Task.Delay(1000);

// Get order status
var status = await api.GetOrderStatus(orderId);

Console.WriteLine($"Order Status: {status.Status}");
Console.WriteLine($"Filled: {status.CumulativeQuantity}/{order.Quantity}");
Console.WriteLine($"Average Price: {status.AveragePrice}");
Console.WriteLine($"Remaining: {status.LeavesQuantity}");
Console.WriteLine($"Details: {status.StatusText}");

Monitor Order Until Filled

var orderId = await api.SubmitOrder(Api.DemoAccount, order);

while (true)
{
    var status = await api.GetOrderStatus(orderId);
    
    Console.WriteLine($"Status: {status.Status}, Filled: {status.CumulativeQuantity}/{order.Quantity}");
    
    if (status.Status == Status.Filled || 
        status.Status == Status.Cancelled || 
        status.Status == Status.Rejected)
    {
        break;
    }
    
    await Task.Delay(500);
}

Cancel Order

Cancel an existing order.
public async Task CancelOrder(OrderId orderId)

Parameters

orderId
OrderId
required
The order identifier to cancel

Example

// Submit order
var orderId = await api.SubmitOrder(Api.DemoAccount, order);

Console.WriteLine("Order submitted. Press Enter to cancel...");
Console.ReadLine();

// Cancel the order
try
{
    await api.CancelOrder(orderId);
    Console.WriteLine("Order cancelled successfully");
    
    // Verify cancellation
    var status = await api.GetOrderStatus(orderId);
    Console.WriteLine($"Final status: {status.Status}");
}
catch (Exception ex)
{
    Console.WriteLine($"Cancel failed: {ex.Message}");
}

Order Enums

Order Type

public enum Type
{
    Market,  // Execute at current market price
    Limit    // Execute at specified price or better
}

Order Side

public enum Side
{
    Buy,   // Buy order
    Sell   // Sell order
}

Order Expiration (Time in Force)

public enum Expiration
{
    Day,                 // Valid until market close
    ImmediateOrCancel,   // Fill immediately or cancel
    FillOrKill,          // Fill completely or cancel
    GoodTillDate         // Valid until specified date
}

Order Status

public enum Status
{
    New,              // Successfully submitted
    PendingNew,       // Being processed
    Rejected,         // Rejected by exchange
    Cancelled,        // Cancelled
    PendingCancel,    // Cancellation being processed
    PartiallyFilled,  // Partially executed
    Filled            // Completely executed
}

Complete Trading Example

using Primary;
using Primary.Data;
using Primary.Data.Orders;
using System;
using System.Linq;
using System.Threading.Tasks;

class TradingBot
{
    static async Task Main()
    {
        var api = new Api(Api.DemoEndpoint);
        await api.Login(Api.DemoUsername, Api.DemoPassword);
        
        // Get instrument
        var instruments = await api.GetAllInstruments();
        var instrument = instruments.First();
        
        // Get current market data
        var marketData = await api.GetMarketData(instrument);
        
        if (marketData.Data.HasOffers())
        {
            decimal offerPrice = marketData.Data.GetTopOfferPrice();
            
            // Submit order at 1% below offer
            var order = new Order
            {
                Instrument = instrument,
                Side = Side.Buy,
                Quantity = 10,
                Price = offerPrice * 0.99m,
                Type = Type.Limit,
                Expiration = Expiration.Day
            };
            
            Console.WriteLine($"Submitting buy order @ {order.Price}");
            var orderId = await api.SubmitOrder(Api.DemoAccount, order);
            
            // Monitor for 10 seconds
            for (int i = 0; i < 20; i++)
            {
                var status = await api.GetOrderStatus(orderId);
                Console.WriteLine($"[{i}] {status.Status}: {status.CumulativeQuantity}/{order.Quantity} @ {status.AveragePrice}");
                
                if (status.Status == Status.Filled)
                {
                    Console.WriteLine("Order filled!");
                    break;
                }
                
                await Task.Delay(500);
            }
            
            // Cancel if not filled
            var finalStatus = await api.GetOrderStatus(orderId);
            if (finalStatus.Status != Status.Filled)
            {
                Console.WriteLine("Cancelling unfilled order...");
                await api.CancelOrder(orderId);
            }
        }
    }
}

API Endpoints

GET {BaseUri}/rest/order/newSingleOrder
GET {BaseUri}/rest/order/id
GET {BaseUri}/rest/order/cancelById
All order operations use the ROFX market identifier internally.

Build docs developers (and LLMs) love