Back to Community
Limit Order execution at varying prices

I'll admit I haven't done any rigorous verification but at a quick glance I suspect that orders specified with a limit_price, as in below example, are being executed at different prices:

order(sid, amount, limit_price=price)  

Perhaps the observed behavior is as designed or there is another way to achieve fills at a specified price. If one has some insight or can point me to it I'd appreciate it.

12 responses

Hello David,

I took a look and you're correct - the limit order execution isn't quite right. Thank you for pointing that out! We always appreciate the feedback. Here's a short description of what we've found:

  • When we check the order triggers for stop and limit orders, we use the data bar's current close price.
  • If the bar price triggers the order, the order goes into the execution engine.
  • The execution engine then applies the slippage model.
  • The order is filled using the slippage-adjusted price.

We need to take the slippage model out of it for limit orders - that will be a better model.

We're also thinking about modifying the slippage model instead of removing it in these cases. What do you think about looking at the high and low prices of the bar, and then filling the order depending on availability? For instance, imagine you have a limit order to buy 100 shares if the price dips to 10.00. In a one-minute bar, the high is 10.05, the low is 9.95, and the volume is 100. That order shouldn't completely fill - it should only fill for the parts of the bar that are under 10. Do you think we should head in that direction?

Thank you again for bringing it to our attention.


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 Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian 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.

Presumably creating a generic model for lightly quoted high volume instruments or highly liquid low volume instruments could prove challenging--different instruments are will have rather different behaviors wrt to filling a resting order despite possibly having similar volume and liquidity averages over a bar.

Either way what you are describing sounds reasonable. I would expect the possibility of a full, partial or no fill from your backtest engine if the market trades at/through the resting limit order price depending on factors such as average volume and average liquidity over the bar and would always expect to get filled at the specified limit price or better.


Thank you for the feedback! We will work on providing the fix, and possible improvements, to the limit order execution.

How do limit orders function currently in the live beta?

Hello Alisa & David,

As Rich Frank helped clarify in, under live trading with Interactive Brokers (IB), all orders (regardless of type) are sent immediately to IB as they are encountered in the algorithm, with IB managing any limit triggers (although I haven't yet seen a detailed mapping between Quantopian order types and the IB order types that will result). The implication is that the order fulfillment engine for the backtester needs to be modified to better model live trading. Currently, for a market order submission during bar 0, the order will be filled at bar 1, using the closing price of bar 0 (assuming no slippage). However, a better model for live trading might be to fill closer to the open price of bar 0 (although this is still dicey, since under live trading, the order could be submitted up to ~ 50 seconds into the bar). Additionally, as Alisa suggests, using the high/low levels for the bar might be a better way to determine the trigger levels for limit, stop & stop-limit orders, combined with an appropriate slippage model.

A note to Quantopian is that the validity of the backtester model can be benchmarked using paper trading at IB, so whatever route you go, do a study (or hire someone to do a study) and publish the results publicly. Also, it seems that IB would be the best consultant on how to modify the backtester to match live trading. Have you talked with them?


Has there been any work on the limit order model? I placed a short vwap order in the "Quantopian Open" that was filled 70 bps below it's limit.

Bump. Still a problem? Re: the limit order partial fill suggestion from two years ago, if the low of the bar was even one cent below the limit price, the limit order should be completely filled. Markets are generally not allowed to trade through a price without clearing all resting liquidity at that price. E.g. If my limit bid is at 10, I must be completely filled before the inside ask price can drop to 10.

Bump. It seems like this is still a problem. Is this being worked on? My backtesting is essentially useless! My algorithm relies on limit orders being executed properly.

Bump. This MAJOR bug needs to be fixed, my algo is also using limit orders.

This bug makes my algo noticeably more profitable (in back tests). Live trading seems to be always necessary to verify behavior as well as results. Please fix this bug.

Assuming that any limit order would be completely filled if price traded a tick beyond it is not a valid assumption. In real life, if you have a decent sized bid sitting there visible on the book, the HFTs will happily provide liquidity a penny above you.

In practice, using limit orders, all of your losing trades will get complete fills, but some of your winners (ones where your limit price was near the low of the day) will get zero or partial fills. This is why I prefer to use other order types such as "market if touched" or "limit if touched" with extra room.

These order types can be backtested in Quantopian by checking the low (buys) or high (sells) of the last minute and simulating a normal market order with slippage assumptions. A minute can be a long time, but the deviations average out over a number of trades.

Was there any work done on this? I noticed that limit orders are still only triggered according to the close price of the following bar, so are market orders, which leads to inaccurate filled prices, and cases in which limit orders aren't filled at all (although according to the values they should've).
This occurs especially on daily frequency, I presume it's because the probability of a higher difference in price as oppose to minute frequency)