Trading
Order execution simulation
Our test environment simulates multiple real life scenarios to facilitate debugging.
- Orders with a symbol that start with “AA” will be fully filled. Limit orders execute at the price specified on the order, market orders execute at $50.00
- Orders with a symbol not starting with the letters “AA” will remain open and would be available to cancel replace later.
- Orders with a symbol starting with “PAR” will be partially filled to half of the requested quantity.
- Orders with a symbol starting with the letters “BUST” will be filled and then the fill will be immediately busted.
- Orders with a symbol starting with “CORRECTP” in them will be filled and then corrected with the price of +$1.00 of the initial fill price.
- Orders with a symbol starting with “CORRECTQ” will be filled and then corrected with the filled quantity to -10 of the initially filled quantity.
Sending new equity orders
The method to send equity orders
public async Task IClient.PlaceAsync(
long orderId,
int quantity,
long price,
Side side,
string symbol,
string route,
OrderOptions options)
Relevant callback events
void ICallback.OnOrderAck(long eventId, long orderId, long limeOrderId,
AckOptions options);
void ICallback.OnOrderReject(long eventId, long orderId, string reason);
void ICallback.OnFill(long eventId, long orderId, Side side, int liquidity,
long fillPrice, int quantityFilled, int quantityLeft,
DateTime transactTime, string symbol, FillOptions options)
Use PlaceAsync
method to create a new equity order.
parameter | description |
---|---|
long orderId | a unique id generated by client. Uniqueness must be maintained within the trading day. An order with duplicate id will be rejected. |
int quantity | quantity of the order |
long price | order limit price scaled to 1/100 of a cent. For example, value of $40.52 should be represented as 405200 . The value of 0 indicates a Market order. |
Side side | Buy , Sell , SellShort or BuyToCover |
string symbol | security Symbol |
string route | route name known to Lime |
As soon as Lime Trading Server receives the order it assigns a lime order id and sends an acknowledge event back to the client. OnOrderAck
method on your ICallback
instance receives both orderId and limeOrderId. If the acknowledge has never been called the client can assume that the order has never been received by Lime. Otherwise, in case of any errors the client receives an OnOrderReject
. After the acknowledgement the order becomes active and can receive one or more OnFill
events.
Sending new option orders
// Generating a unique order id as unix timestamp.
// Note that this does not necessarily guarantee uniqueness if you send more than one order per millisecond
var orderId = (long)(DateTime.Now - new DateTime(1970, 1, 1)).TotalMilliseconds;
// Create an option Call on underlying symbol PAR, expiring tomorrow, strike price $170.00
// The strike price is scaled to 1/1000 of a dollar.
var option = USOptionsSymbol.Call("PAR", DateTime.Now.AddDays(1), 170000);
// Buy to open 50 contracts at $120.00
await client.PlaceUSOptionsAsync(orderId, 50, 1200000, Side.Buy, PositionEffect.Open,
option, "ARCP");
Relevant callback events
void ICallback.OnOrderAck(long eventId, long orderId, long limeOrderId,
AckOptions options);
void ICallback.OnOrderReject(long eventId, long orderId, string reason);
void ICallback.OnUSOptionsFill(long eventId, long orderId, Side side,
int liquidity, long fillPrice, int quantityFilled, int quantityLeft,
DateTime transactTime, USOptionsSymbol symbol, FillOptions options)
To create an option order, use PlaceUSOptionsAsync
. The general behaviour and parameters are essentially the same as for equity order
parameter | description |
---|---|
long orderId | a unique id generated by client. Uniqueness must be maintained within the trading day. An order with duplicate id will be rejected. |
int quantity | number of contracts |
long price | order limit price scaled to 1/100 of a cent. For example, value of $40.52 should be represented as 405200 . The value of 0 indicates a Market order. |
Side side | Buy , Sell . Note that SellShort and BuyToCover sides are not applicable to options. |
PositionEffect positionEffect | Open or Close . The client is expected to track the positions and send Open when buying or selling to open, or Close when selling or buying to close an existing position |
USOptionsSymbol symbol | a USOptionsSymbol structure describing an options contract.- string underlying - is the root symbol of the option - DateTime expiration - the contract expiration date - int strike - contract strike price. Unlike the limit price where the value is scaled to 1/10000 of a dollar, the strike price is scaled to 1/1000 of a dollar - USOptionType type - Put or Call |
string route | route name known to Lime |
Cancelling orders
await client.CancelAsync(id);
await client.CancelAllAsync(id);
Related callback events
void ICallback.OnCancelAck(long eventId, long orderId);
void ICallback.OnCancelReject(long eventId, long orderId, string reason);
There are multiple ways to cancel an order.
You need to call CancelAsync
method passing its id to cancel a specific order. On successul cancellation, callback receives an OnCancelAck
event. In case of an error the callback receives an OnCancelReject
including a human-readable message explaining he reason. The most common reason is that requested order is no longer active. It is either cancelled or filled by the time the cancellation is requested. Another common mistake is a wrong order id so that lime trading server can't find the requested order at all.
There is also CancelAllAsync
that allows cancel all active orders at once. The client receives cancellation acknowledgment events on each of the cancelled orders. In case if no orders have been active the client receives nothing.
Anoher common practice is to instruct Lime to cancel all orders in case of connectivity issue. To do that, the client has to specify cancelOnDisconnect
parameter on ConnectAsync
.
Replacing orders
You can cancel an order and replace it with a new order in one call. On most exchanges this is equivalent to actually cancelling the order and sending a new one. It gives the order a new position on the execution queue at exchanges's matching engine. The exception is when order quantity is decreased with same limit price, in this case exchanges amend the order without losing its place on the queue.
public async Task ReplaceAsync(
long originalOrderId, long orderId, int newQuantity, long newPrice, ReplaceOptions options);
Required. An existing open order to be replaced.
long orderIdRequired. The new order id.
int newQuantityRequired. The new quantity of the order.
long newPriceRequired. The new limit price of the order. Market orders can not be replaced.
ReplaceOptions optionsOptional information for a replace request
ReplaceOptions structure
Option | Description |
---|---|
int ShortSaleAffirmLongQuantity | This option is required for certain accounts and affirms that the client has the given long position in the security being traded. This option can only be set for orders which are short-sales. The value must be greater than zero. |
int MinQuantity | Minimum quantity of an order to be executed, only valid for specific destinations. |
int MinimumTriggerVol | Minimum Trigger Volume tag, valid for specific destinations and order types. |
On succesful replace, callback receives OnReplaceAck
with the new order id. The previous order is considered Cancelled. Otherwise, OnReplaceReject
is called with rejection reason and the previous order stays unaffected. One of the most common reasons of rejecting a replace request is when the original order has already been filled or cancelled.
void ICallback.OnReplaceAck(long eventId, long origOrderId, long orderId,
long limeOrderId, AckOptions options);
void ICallback.OnReplaceReject(long eventId, long origOrderId, long orderId,
string reason);
Busted and corrected orders
There is a rare case when an exchange would need to handle an error and correct a previously executed fill. They can either bust the fill and after that send a new execution event, or they can send a correction event amending executed price or quantity. The trade to bust or correct is identified by its FillOptions.ExecId
.
void ICallback.OnBust(long eventId, long orderId, Side reversedSide,
long bustedPrice, int quantityBusted, int quantityLeft,
DateTime transactTime, string symbol, FillOptions options);
void ICallback.OnUSOptionsBust(long eventId, long orderId, Side reversedSide,
long bustedPrice, int quantityBusted, int quantityLeft,
DateTime transactTime, USOptionsSymbol symbol, FillOptions options);
void ICallback.OnCorrect(long eventId, long orderId, Side side,
long newFillPrice, int newFilledQuantity, int quantityLeft,
DateTime transactTime, string symbol, FillOptions options);
void ICallback.OnUSOptionsCorrect(long eventId, long orderId, Side side,
long newFillPrice, int newFilledQuantity, int quantityLeft,
DateTime transactTime, USOptionsSymbol symbol, FillOptions options);