Back to Community
Why is the fill price greater than the limit price?

Hi Everyone
I am trying to create an order with a limit price but some fills are higher than the limit price.
Please let me know what I should be doing to ensure that the fill price is better or equal to the limit price.
Much appreciate
Savio

Clone Algorithm
1
Loading...
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
import pytz  

# Initialize the timezone:  
EST = pytz.timezone('US/Eastern')

def initialize(context):  
  # In this example, I'm looking at TSC   
  context.stock = sid(44690)  #TSC
  context.init_notional = 3500 

def handle_data(context, data):

    # timestamp of current event  
    ESTdate = get_datetime().astimezone(EST)  

    # test for market open by timestamp  
    if ESTdate.hour == 9 and ESTdate.minute == 31:  
        # Placing initial order for day  
        context.init_order_id = order(context.stock, context.init_notional, style=LimitOrder(23.95))
There was a runtime error.
5 responses

Seems to be an issue with the recently enacted default slippage model not playing well with limit orders. The default slippage model uses slippage.FixedBasisPointsSlippage(basis_points=5, volume_limit=0.1). This is explained in the documentation (https://www.quantopian.com/help#ide-commission)

The slippage is calculated by converting the basis_points constant to
a percentage (5 basis points = 0.05%), and multiplying that percentage
by the order price. Buys will fill at a price that is 0.05% higher
than the close of the next minute, while sells will fill at a price
that is 0.05% lower.

This appears to be a bug. As a workaround set the slippage model to use 'VolumeShareSlippage'

  set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.0))

Attached is your algorithm with this line added. It seems to buy at expected prices. One word of caution with thinly traded stocks like this is that the backtest doesn't really model these well. Real world would probably be different.

Clone Algorithm
0
Loading...
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
import pytz  

# Initialize the timezone:  
EST = pytz.timezone('US/Eastern')

def initialize(context):  
  set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.0))
  # In this example, I'm looking at TSC   
  context.stock = sid(44690)  #TSC
  context.init_notional = 3500 

def handle_data(context, data):

    # timestamp of current event  
    ESTdate = get_datetime().astimezone(EST)  

    # test for market open by timestamp  
    if ESTdate.hour == 9 and ESTdate.minute == 31:  
        # Placing initial order for day  
        context.init_order_id = order(context.stock, context.init_notional, style=LimitOrder(23.95))
There was a runtime error.

Hello Dan
I do very much appreciate you taking the time out of your weekend to help me.
Thanks very much.
Kind regards
Savio

Joakim asked whether this issue could be involved in my results with limit orders, here, so in case anyone might find this data of interest, default vs the workaround suggested above, and an extra that JA had asked about before (since that was handy). PvR is merely what the return would have been had the amount actually put into play been the initial capital setting.

Various slippage models, comparison, at 5 months

                  Default           .025             Luca  
  Q Return             77             41 (53%)         27 (35%)  
PvR Return            298            264 (88%)        151 (50%)  
Buys               290296         288350           287785  
Sells              222984         191468           293040  
Buy partial          5728          15454 (270%)     27768 (485%)  
Sell partial        19129          58303 (305%)     93122 (487%)  
Commissions          1621            867             1206  
Max Lvrg              .18            .12              .16  
Max stock PnL          56             28               38

==============================================================================================
Default, 5bps  
==============================================================================================
2017-06-02 13:00 _ti:1780 INFO  105 trading days     2 hr 41.1 min   2018-05-14 22:29 US/Pacific  
    Portfolio:   17708               2017-01-03 to 2017-12-28                  Alpha:  
 Initial Cash:   10000                      Buys: 290296 (5728 partial)         Beta:  0.06  
  Unused Cash:    8813                     Sells: 222984 (19129 partial)      Sharpe:  
   Max Margin:       0               Commissions:   1621                    Drawdown:   0.2  
     Max Risk:    2578 (26%)          Shares Now:    870                   Stability: 0.997  
  Cash Profit:    5988                Shares Val:   1720                     Sortino:  
 Total Profit:    7708                  Cash Now:  15988                    Shrt/Lng Now:  0.00  
     Q Return:  77.08% Profit/Init      Max Lvrg:   0.18  2017-03-21          Max Shorts:  -71  
   PvR Return: 298.97% Profit/Risk     PvR %/day:   2.85                      Max  Longs:  2578  
2017-06-02 13:00 ti:1961 INFO .  
2017-06-02 13:00 _ti:1773 INFO   Sort column 1              Positions: 80 of 948 traded  
         Profit   Max    Return  Return   Buy    Price    Buy|Sell    Max     Shares  Shares  Partial  
 Symbol    PnL   Risked      %   %/day    Hold  Init|Now   Orders   Shrt|Lng   Now         %   Fills  
   RCKT    56      56    100.0    50.0    -0.0    2|2     393|524     0|23       0         0     55  
   VSLR    54      54    100.0    25.0     0.2    3|3     412|516     0|14       0         0     11

==============================================================================================
       set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1))  
==============================================================================================
2017-06-02 13:00 _ti:2445 INFO  105 trading days     2 hr 44.9 min   2018-05-15 21:08 US/Pacific  
    Portfolio:   14160               2017-01-03 to 2017-12-28                  Alpha:  
 Initial Cash:   10000                      Buys: 288350 (15454 partial)        Beta:  0.05  
  Unused Cash:    9189                     Sells: 191468 (58303 partial)      Sharpe:  
   Max Margin:       0               Commissions:    867                    Drawdown:   0.1  
     Max Risk:    1574 (16%)          Shares Now:    495                   Stability: 0.999  
  Cash Profit:    2971                Shares Val:   1189                     Sortino:  
 Total Profit:    4160                  Cash Now:  12971                    Shrt/Lng Now:  0.00  
     Q Return:  41.60% Profit/Init      Max Lvrg:   0.12  2017-01-30          Max Shorts:  -62  
   PvR Return: 264.23% Profit/Risk     PvR %/day:   2.52                      Max  Longs:  1561  
2017-06-02 13:00 ti:2626 INFO .  
2017-06-02 13:00 _ti:2438 INFO   Sort column 1              Positions: 78 of 948 traded  
         Profit   Max    Return  Return   Buy    Price    Buy|Sell    Max     Shares  Shares  Partial  
 Symbol    PnL   Risked      %   %/day    Hold  Init|Now   Orders   Shrt|Lng   Now         %   Fills  
   LBIX    28      57     48.7    2.43     0.3    2|2     421|398    -17|18      6    0.0008    115  
   TYHT    27      50     53.7    2.98    -0.1    4|4     364|374     -6|7       0         0     58

==============================================================================================
Luca slippage class  
==============================================================================================
2017-06-02 13:00 _ti:982 INFO  105 trading days     3 hr 19.6 min   2018-05-14 08:18 US/Pacific  
    Portfolio:   12788               2017-01-03 to 2017-12-28                  Alpha:  
 Initial Cash:   10000                      Buys: 287785 (27768 partial)        Beta:  0.07  
  Unused Cash:    8694                     Sells: 293040 (93122 partial)      Sharpe:  
   Max Margin:       0               Commissions:   1206                    Drawdown:   0.2  
     Max Risk:    1843 (18%)          Shares Now:    582                   Stability: 0.999  
  Cash Profit:    1632                Shares Val:   1156                     Sortino:  
 Total Profit:    2788                  Cash Now:  11632                    Shrt/Lng Now:  0.03  
     Q Return:  27.88% Profit/Init      Max Lvrg:   0.16  2017-03-21          Max Shorts:  -76  
   PvR Return: 151.30% Profit/Risk     PvR %/day:   1.44                      Max  Longs:  1833  
2017-06-02 13:00 ti:1163 INFO .  
2017-06-02 13:00 _ti:975 INFO   Sort column 1              Positions: 89 of 948 traded  
         Profit   Max    Return  Return   Buy    Price    Buy|Sell    Max     Shares   Shares  Partial  
 Symbol    PnL   Risked      %   %/day    Hold  Init|Now   Orders   Shrt|Lng   Now          %   Fills  
   RCKT    38      38    100.0    50.0    -0.0    2|2     388|666     0|17       0          0    181  
   VSLR    34      38     90.8    18.2     0.2    3|3     407|772     0|14       0          0    171  

@Blue,

Are you using default commission rates (set_commission(commission.PerShare(cost=0.001, min_trade_cost=0))? If so, then your results may be overstated as the default commission rates is for institutional investors. A more realistic commission rate for retail investing is IB rates (set_commission(commission.PerShare(cost=0.0075, min_trade_cost=1)) . If you're designing this for commission free RH, I doubt if they do take limit/stop orders commission free. Hopes this helps.

Thanks for mentioning that, it helps. I have two goals: 1) Adapt elements of my code to be viable for contest/fund and/or 2) Trade with a broker in some other way. Q's defaults would reflect their new fund broker. RH doesn't charge for stop, limit, I have experience with that. On IB with the dollar minimum my algo would need to have an increase in initial capital or fewer stocks (higher amounts each) to survive. Commissions were 10077 (622% vs the 1621 above) with the line you provided. Good to know.