Zipline execution price inconsistencies

Hi Brian,

I’m finding some inconsistencies/questions as I analyze the profits of my zipline live trades. These may seem like small details, but I’m trying to do a pretty straightforward thing (getting the exact return of each trade) without much success.

  1. The last_sale_price and last_sale_date fields of the zipline Position object are different from the price/date data revealed when executions are queried with quantrocket.blotter.download_executions(). This is easy to reproduce if you place a couple trades in a live algorithm, print out the entire context.portfolio object, and then compare with the executions query. The difference is small for some trades, and larger for others (e.g. stop orders that trigger later).

Additionally, the last_sale_price does not exactly match the cost_basis field, even when there’s only been a single opening transaction (as opposed to piecemeal executions).

  1. The OrderId of a stop order execution will sometimes be different than the one originally placed (and returned by zipline.api.order()). I think this is because IBKR will hold the stop order as ‘pre-submitted’ and then create a separate order when it’s actually given to an exchange to execute. How do you handle this internally in zipline - are the two orderIds linked in a way readable by user?

The reason I ask is because querying executions is the only way I can find to accurately access the execution price of an order. If I want to access the execution price of a stop order, I need to query executions and filter with the orderId that was actually executed (not the one that IBKR discarded).

  1. I have also tried using context.blotter.get_transactions(data) to access execution prices from within the algo, but this returns empty lists when the algorithm is live. Is this working as intended?

If there’s an easier way to get the exact return of a trade that was exited via stop order, please do share!


Apologies, I may be mistaken on point (2) above, believing that IBKR cancelled certain stop orders instead of zipline (as we discussed in my previous thread). My recently filled stop orders have had the same orderId as when initially submitted (and marked ‘pre-submitted’ before becoming ‘filled’).

At least now I have a reliable way to get execution price of a stop order if I go outside of zipline. The other two points (1 & 3) remain open questions - they are relevant when download_executions() isn’t available (e.g. in backtest).

last_sale_price is based on the minute data and reflects all trades, not your last sale price. cost_basis reflects your average price.

Transactions are available in the backtest output but not from within the backtest.