Submit Order
Submit a new order to the exchange.
public async Task<OrderId> SubmitOrder(string account, Order order)
Parameters
Account identifier to submit the order from (e.g., Api.DemoAccount = “REM2046”)
Order object containing all order parameters
Order Properties
Order side: Side.Buy or Side.Sell
Order type: Type.Market or Type.Limit
Limit price (required for limit orders, null for market orders)
Time in force: Day, ImmediateOrCancel, FillOrKill, or GoodTillDate
Expiration date (required when Expiration is GoodTillDate)
Cancel previous orders for this instrument before submitting
Submit as iceberg order (hidden quantity)
Visible quantity for iceberg orders (required when Iceberg is true)
Response
Returns an OrderId object:
Client-side order identifier
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
The order identifier returned from SubmitOrder
Response
Returns an OrderStatus object with all order details:
Exchange order identifier
Current order status: New, PendingNew, Rejected, Cancelled, PendingCancel, PartiallyFilled, or Filled
Additional status information/description
Quantity filled in last execution
Total quantity filled so far
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
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.