Back to Community
Do I need slippage on limit orders?

To try and replicate real world slippage - Do I need to add slippage on limit orders?

I get market orders, but limit orders should fill for what your limit is... right?

13 responses

I also have questions here - is it even possible to put slippage in live trading orders?

@Tyler

Yes, you should probably add (or just keep the default) 'slippage' model for limit orders. Slippage not only refers to the calculation of a realistic price but also a realistic volume. Check out the documentation https://www.quantopian.com/help#ide-slippage.

The slippage method also evaluates if your order is simply too big:
you can't trade more than market's volume, and generally you can't
expect to trade more than a fraction of the volume. All of these
concepts are wrapped into the slippage method.

It's true that a limit order won't fill for anything worse than the limit price. However, they may fill BETTER than the limit price. That price is based upon the slippage model.

@ QQQ
'Slippage' is purely a backtesting construct. In live trading, any slippage functions are disregarded. In live trading, the algorithm doesn't calculate the expected price and volume (ie the slippage). In live trading, the actual broker trade data is used. You can 'put' code in for slippage in a live traded algorithm (or more likely simply leave it in from your backtests) but it will have no effect.

@Dan - I've found where my $5,000 XIV order was spread out on default slippage. There is no way this would happen in live trading as this ETF is super liquid, especially with only a 5,000 order.

The default slippage model has a lot of basis in real world results (see https://blog.quantopian.com/accurate-slippage-model-comparing-real-simulated-transaction-costs/ ) though it does have limitations. It's probably over aggressive in spreading out trades across multiple bars especially with liquid stocks. However, what that spreading out can do is determine a more realistic 'average actual price paid' even though in live trading that may have all traded in a single bar. Another result of spreading out (especially with limit orders) is to guesitmate when the order actually fills. If it takes 20 bars to fill an order in backtesting using the default slippage model, then in live trading one can be reasonably sure the order will have filled in 20 minutes (even though it may have filled in a single bar).

The 'spreading out' won't affect most algorithms unless one is buying and selling minutely quite a lot. If that's the case then one can always set a higher volume limit on the slippage model. Though, changing it would probably just rely on ones 'hunch' as to the best value. The only true test is by live trading the algorithm.

"There is no way this would happen in live trading as this ETF is super liquid, especially with only a 5,000 order"

XIV wasn't always 'super liquid'. If you are looking at backtests from 2011-2013 the volumes weren't nearly as high and an order could easily be spread out across multiple bars with the default model (see attached notebook). This is one of the dilemmas of backtesting. We are using past data to infer future performance. However, we all know that 'past performance does not predict future performance'. A big assumption in backtesting is that the future data will be like the past data. With new ETFs especially, the first year or so after inception, the volumes are typically very low (until the market begins to accept them). That past data will NOT represent future data very well.

Loading notebook preview...
Notebook previews are currently unavailable.

Hi Dan,

Regarding your comment about XIV liquidity, looking at the ETN's volume alone does not tell you the whole picture. The liquidity of ETF/ETNs are dependent on their underlyings' liquidity, in this case VIX futures. It is possible for thinly traded ETF/ETNs to have very high liquidity if their underlyings have sizable volume. VIX futures daily average volume is about $5 billion (for context, SPY's daily average volume is about $28-30 billion). As such, I do not believe the default slippage model is appropriate for all ETF/ETNs. It is most accurate only for individual stocks IMO.

You can read more here: https://am.jpmorgan.com/blob-gim/1383272223898/83456/1323416812894_Debunking-myths-about-ETF-liquidity.pdf

@Dan Whitnable

minutes_to_trade = 5000 / (day_pricing.mean_minute_dollar_vol * .025)  

I see you are taking the mean minute dollar volume.. and seeing how much volume there was to sustain an order of 5000 shares. the * 0.25... what does 0.25 represent?

@Joakim Arvidsson asked me to try Luca's class myVolumeShareSlippage over here and since my code involves limit orders I thought this might be a good place for those results. I noticed at Changes Coming to the Default Slippage Model the current default slippage took effect in January. On the right, partial fill numbers are higher and other than that, with any luck this might mean something to others with more market experience than myself. Some would wonder so the data is a tool I'm calling TradeInfo and side-by-side is in CompareIt.

I also wanted to see how Q's slippage model was applied to limit orders. I don't understand it. Here is a simple algo that buys a single share of Apple on a given day, On that day, Apple opened at 186.57. The algo creates a BUY Limit Order at 186.00. Later in the day, at around 11:00am, Apple goes down to 186.00 and the order is triggered. When I look in the backtest result, under Activity/Transaction, I see that the cost of purchase is 186.05. Even tough the commission is set to 0. This looks like a bug or bad implementation.

Any thoughts?

/Luc

Clone Algorithm
2
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 5b32c410c6b84b43c0525c93
There was a runtime error.

Maybe you've identified a bug in Activity/Transaction. Hats off for simplifying the example.
I also do not know the details on slippage with limit.

In track_orders at line 115 this logs the filled order at minute 62 and I made it more readable below, shows zero commission.

2018-06-20 06:31 _trac:63 INFO    1   Buy 1 AAPL _ at 186.55 limit 186.0                    1000  248d  
2018-06-20 07:32 _trac:63 INFO   62      Bot 1 AAPL (1) at 185.96 limit 186.0               813  248d

2018-06-20 07:32 track_orders:115 INFO Event(  
    {  
        'status'        : 1,  
        'amount'        : 1,  
        'filled'        : 1  
        'commission'    : 0,  
        'limit'         : 186.0,  
        'limit_reached' : True,  
        'stop'          : None,  
        'stop_reached'  : False,  
        'reason'        : None,  
        'sid'           : Equity(24 [AAPL]),  
        'created'       : Timestamp('2018-06-20 13:31:00+0000', tz='UTC'),  
        'dt'            : Timestamp('2018-06-20 14:32:00+0000', tz='UTC'),  
        'id'            : '23a78f6d73ce4e3ca677b21e2823248d',  
    }  
)
Clone Algorithm
1
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 5b32d3a262bb37447d3b3248
There was a runtime error.

@Blue, that is pretty cool code.

When I run with slippage at 0, then the order goes through at just below 186, something like 185.87, which makes a lot more sense.

/Luc

Clone Algorithm
2
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 5b32c5e443d4ae44a0ca5fac
There was a runtime error.

The default slippage model now uses FixedBasisPointsSlippage which doesn't handle limit orders correctly. One way around this is to specify VolumeShareSlippage which oddly does handle limit orders correctly. See this post and especially @Grant Kiehne's response at the end. https://www.quantopian.com/posts/limit-orders-not-backtesting-properly

As for the original question in this post "Do I need slippage on limit orders?". The answer is a definite maybe. To understand the definite part, assume that stock ABC is trading at $100. If one places a buy order with a limit of $200, then this order is very much like a market order. There could be the chance that this order doesn't fill at $100 but a little lower (ie slippage). The slippage isn't applied to the limit price but rather the fill price. As in real trading one would/should never pay more than the limit price.

It's a rather philosophical question if one actually would incur this slippage (which is the maybe part). One could argue that, in the backtest, the algo order being placed is mimicking one of the recorded historical orders and NOT an additional order. Therefore, the algo order doesn't introduce any additional new slippage.

My personal experience, using VolumeShareSlippage(volume_limit=0.1, price_impact=0.1), has seemed to match my real trades pretty well. This however, is VERY dependent upon individual stock liquidity. I typically trade in medium liquidity stocks where my trades are less than 10% of the minute volume averaged over the previous 10 minutes. And BTW, in live trading I ALWAYS place limit orders.

See attached backtest with 'VolumeShareSlippage' and note that the price paid is never more than the limit price (as it should be).

Clone Algorithm
1
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 5b32f3a5cbe85444618f22f0
There was a runtime error.

Thanks @Dan. Awesome answer. I appreciate the part about your personal live trading experience.

As suggested you have to use VolumeShareSlippage to handle limit orders properly, but don't forget that there is still this bug that makes your orders perform better than reality.