Back

Canceling an order?

Curious how I could go about canceling an order? Say I place a limit or stop order, how would I later retrieve and/or cancel it?
Update Backtest








This question is a bit trickier than I first imagined, mostly because of the async nature of the ordering process. My first try was to use the Transactions collection in SecurityTransactionManager in my OnData.

var actualSubmittedTicket = Transactions.GetOrderTickets(
t => t.Symbol == symbol
&& t.OrderType == OrderType.Limit
&& t.Status == OrderStatus.Submitted);



Then tried iterating the returned IEnumerable collection to cancel the order. There should be only one order in the collection, but you still need to iterate it or do something like:

var actualTicket = actualSubmittedTicket.Single();
actualTicket.Cancel();

However, this approach broke down because of latency between the algorithm and the broker. By the time my code got the next 1 minute bar the order might have filled or, even worse, partially filled and then I cancelled it. Bad result: Invalid Order.

Finally I realized I need to save the state from the OnOrderEvent which I do in a variable called TradeAttempts for each symbol I am following. I keep track of TradeAttempts in a structure called SignalInfo which is something like this:

public class SignalInfo
{
public int Id { get; set; }
public Symbol Symbol { get; set; }
public OrderSignal Value { get; set; }
public OrderStatus Status { get; set; }
public int TradeAttempts { get; set; }
public string Name { get; set; }
}

I create a SignalInfo for each Symbol I am following and put them in a List. the currentSignalInfo is the member of the list for the Symbol I am working on. I retrieve it as follows:

var currentSignalInfo = signalInfos.FirstOrDefault(s => s.Symbol == orderEvent.Symbol);


I use a switch statement in OrOrderEvent to check orderEvent.Status.

switch (orderEvent.Status)
{
case OrderStatus.New:
case OrderStatus.None:
case OrderStatus.Submitted:
break;
case OrderStatus.PartiallyFilled:
currentSignalInfo.TradeAttempts++;
break;
case OrderStatus.Canceled:
currentSignalInfo.TradeAttempts = 0;
break;
case OrderStatus.Filled:
currentSignalInfo.TradeAttempts = 0;
break;
}

Then, back in OnData for the symbol, I check the collection.

IEnumerable livetickets =
Transactions.GetOrderTickets(t => t.Symbol == data.Key && t.Status == OrderStatus.Submitted);

foreach (OrderTicket liveticket in livetickets)
{
if (currentSignalInfo.TradeAttempts > 3)
{
liveticket.Cancel();
Log(string.Format("Order {0} cancellation sent. Trade attempts > 3.", liveticket.OrderId));
}
}


That way if the order fills in the OnOrderEvent before the next OnData fires, I have the most current status in currentSignalInfo.TradeAttempts. BTW, that happens more frequently than you might realize. Market orders almost always fill before the next bar happens. It can take a few bars for partials to complete the order. That is why I use a 3 bar wait time before I cancel the order.

I am sure Jared and Michael will have a more elegant way to handle this scenario.

Nick
2

Hi,

I've also investigated the problem of cancelling orders.
My idea was to cancel all orders inside OnOrderEvent when number of positions reaches 2.
public override void OnOrderEvent(OrderEvent fill)
{
if (fill.Status.IsClosed() && fill.FillQuantity > 0)
{
var openedPositions = Securities.Values.Where(sec => sec.HoldStock).ToList();
Console.WriteLine(Time + ": Bought " + fill.FillQuantity + " " + fill.Symbol + " for " + fill.FillPrice + " Open Positions=" + openedPositions.Count);

if (openedPositions.Count >= 2)
{
foreach (var ticket in Transactions.GetOrderTickets(x => x.Status.IsOpen()))
{
ticket.Cancel();
}
var openedTickets = Transactions.GetOrderTickets(x => x.Status.IsOpen()).ToList();
Console.WriteLine(Time + ": Opened tickets: " + openedTickets.Count);
}
}
}

But it doesn't work at all. I have still opened tickets after loop to cancel each of them.
Has anybody working solution to cancel opened orders?
1

When you cancel it generates a "Cancellation Request" - this is processed on a different thread after the OnData loop has passed. By the next iteration of OnData you should have cancelled all of them.

In reality when you submit a Cancel to the brokerages it can take up to 100ms-1s -- you should design around this behavior in your algorithm.
1

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


FYI on ETrade recently, out of curiosity, I placed and then cancelled an after hours limit order.   Placing the order took 1 minute, and cancelling it took several minutes.  

Not sure how other brokerages work.

For other brokerages, has anyone experienced more than 5 seconds to cancel a limit order during normal trading hours?

0

Hey Keith; you placed it through the eTrade website? Or do you have an eTrade adaptor for LEAN?

Even for afterhours trading no broker should take more than 1sec to place an order. If thats true (and not just a UX glitch) then eTrade seems fairly slow.

0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


I was just doing a manual order, not using LEAN.

I was placing an after hours order on ETrade.  It was a very thinly traded stock, and I was placing a Bid, but there was no Ask.  Maybe it took so long because there was no Ask?

With regards to an adaptor for ETrade... its very low on my priority list of things to do.  Its going to be a while before my code is safe enough for automatic trading.  I'll stick with SMS messages and email until then.

 

0

If you're placing a limit order then there's no limit to how long it can take to fill. But placing the order should be instantaneous. 

0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


on ETrade using manual trading, it took 2 minutes to update an existing after hours limit order by changing my bid.  I eventually cancelled the order after increasing the bid 5 times over a 10 minute period.  Inevitably, the next morning the stock had popped up ~2%.

Now, you're probably correct that when I submitted the limit order initially, it was instantaneous.

 

0

Jared does this 100ms~1s also apply to backtesting data (which is moving very fast)?

 

0

No. That response span range only applies to live trading when Lean is connected to a real brokerages. It depends on how fast/slow the brokerage server respond to our resquest (order placing, cancelling, etc).
In backtesting mode, order cancelling should be, like placing, instantaneous.

0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Thanks for the reply Alex. Does this also apply to orders placed from within the OnOrder event? Ignoring functions like MarketOrderOnClose, is there some kind of restriction regarding the resolution of the algorithm? IE:

Resolution is hourly.
- 17:00 OnData makes some StopOrder()
- 17:16 OnOrderEvent gets a Filled event (Could this theoretically happen any time? not restricted to the "hourly pulse"?
- 18:00 OnData is fired again.

 

Is this the standard flow?
 

 

 

0

I just did a small test to see what is happening with OrderEvents. It seems that events are actually happening by the minute. This mean's that OnOrderEvent is tied to the "Resolution" set by the algorithm. Now, either I am misunderstanding the usage, or this makes it completely useless at emulating a live situation, where an algorithm may be subscribed to "minute" data, but may want to perform actions within that minute if something should happen which fires the OnOrderEvent. 

0

In backtesting mode, when our algorithm subscribes to a ticker with given resolution, no event will be fired at a higher frequency, because there is no higher resolution data to trigger an event. E.g.:
Resolution is hourly.
- 17:00 OnData makes some StopOrder()
- 18:00 OnOrderEvent gets a Filled event (not possible to be fired at 17:16)
- 18:00 OnData is fired again.

I wouldn't say it is useless at emulating a live situation, because it is not really the point. We use low resolution data to test a theory quickly. Once we have validated it, we should increase resolution to catch intraday nuances if we want our algorithm to trade during the day. 

0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Update Backtest





0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Loading...

This discussion is closed