-
Notifications
You must be signed in to change notification settings - Fork 284
Description
Summary
Several correctness bugs in the simulation layer can produce incorrect backtest results:
1. execute_daily_cancel_policy only cancels first order per asset
In SimulationBlotter.execute_daily_cancel_policy, when an asset has multiple open orders, only the first order is cancelled. Additionally, assets with exactly one open order are skipped entirely because the len(orders) > 1 guard excludes them. The fix replaces the inline logic with cancel_all_orders_for_asset(), consistent with execute_cancel_policy.
File: src/zipline/finance/blotter/simulation_blotter.py
2. NoSlippage and FixedSlippage use order.amount instead of order.open_amount
Both models return order.amount (the original order size) instead of order.open_amount (the remaining unfilled portion), causing partially filled orders to be overfilled.
File: src/zipline/finance/slippage.py
3. VolumeShareSlippage returns bare None on null price
When price is NaN, process_order returns None instead of the expected (None, None) tuple, causing a TypeError during tuple unpacking in the blotter's fill loop.
File: src/zipline/finance/slippage.py
4. before_trading_start flag not reset on exception
If the user's before_trading_start callback raises an exception, _in_before_trading_start is never reset to False, permanently blocking all subsequent order calls for the rest of the simulation.
File: src/zipline/algorithm.py
5. limit_price and stop_price validated with truthiness instead of is not None
validate_order_params and __convert_order_params_for_blotter use if limit_price: and if stop_price:, which treats a valid price of 0.0 as falsy. This silently converts what should be a LimitOrder(0.0) into a MarketOrder.
File: src/zipline/algorithm.py