You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
calc_on_order_fills = true: strategy.close + reversing strategy.entry opens a second lot past pyramiding = 1 #708
With calc_on_order_fills = true and pyramiding = 1, a script that closes a long with strategy.close("L") and opens a short with strategy.entry("S", ...) on the same bar ends up with two short lots filled at the same tick when the reversal condition is still true on the fill bar. The second lot comes from the recalculation after the fill. Without calc_on_order_fills, or without the strategy.close call, only one short opens.
Script
Trades on PineForge
calc_on_order_fills = true, close + entry
Long 11→21, Short 21→31 qty 2, Short 21→31 qty 3
calc_on_order_fills = false, close + entry
Long 11→21, Short 21→31 qty 2
calc_on_order_fills = true, entry only (no strategy.close)
Long 11→21, Short 21→31 qty 2
(bar indexes; all entries of bar 21 fill at that bar's open, 43687.85)
Versions
pineforge-engine v1.9.1 (fc0a2df), pineforge-codegen 1.9.1, Apple clang 17.0.0, macOS 15 arm64. BTCUSDT 1h bars from 2024-01-01 to 2024-03-01, initial capital 1000000, no commission or slippage, input timeframe = script timeframe = 1h.
Reproduction
//@version=6
strategy("repro", overlay = true, pyramiding = 1, calc_on_order_fills = true, default_qty_type = strategy.fixed, default_qty_value = 1, initial_capital = 1000000)
// The reversal signal stays true on two consecutive bars.
signal = bar_index == 20 or bar_index == 21
if bar_index == 10
strategy.entry("L", strategy.long, qty = 1)
if signal and barstate.isconfirmed
strategy.close("L")
strategy.entry("S", strategy.short, qty = bar_index == 20 ? 2 : 3)
if bar_index == 30
strategy.close_all()
The second short has qty 3, so it was created by a script execution on bar 21, yet it fills at bar 21's open together with the qty 2 short ordered on bar 20. Controls: the same script with calc_on_order_fills = false, and the same script without the strategy.close("L") line.
Expected
One short position (qty 2), as in both controls. pyramiding = 1 allows one entry per direction, and a repeated strategy.entry with the same id should not add a lot to a position in that direction. With barstate.isconfirmed in the condition, a recalculation after an intrabar fill should also not place the order at all.
TradingView check (2026-11-02, BINANCE:BTCUSDT 5m, chart range): the script above gives Long 11→21 and one Short 21→31 with qty 2; there is no qty 3 lot. With TradingView's default initial capital (100,000) the qty 2 short is not opened at all for lack of margin, hence initial_capital = 1000000 in the script.
Workaround
Drop the redundant strategy.close of the old side (the reversing strategy.entry closes it), or set calc_on_order_fills = false when the script does not need it.
Thank you for the clear report and the minimal script. We are reproducing it now: your script against TradingView's own result, on v1.9.1 and on the current development build. You will get the triage result here by 2026-11-03 18:00 (Taipei), including whether the position size differs and, if so, how it will be fixed.
Confirmed. With your script on v1.9.1 (and on the current development build, identical result), the engine opens two short lots at the same bar (2024-01-01 21:00, qty 2 and qty 3) where TradingView opens one (qty 2), so the position size is wrong. Both of your controls (calc_on_order_fills = false, or no strategy.close) match TradingView. This is a silent wrong result in a released version; a fix is in progress and the next release will not ship without it. We will post the fix here.
The reproduction above, without barstate.isconfirmed and otherwise the same calls (strategy.close("L") then strategy.entry("S", strategy.short, qty = bar_index == 20 ? 2 : 3) on bars 20 and 21, pyramiding = 1, calc_on_order_fills = true, process_orders_on_close = false), on a BINANCE:BTCUSDT 60-minute chart from 2024-01-01 to 2024-03-01, compared with TradingView's exported list of trades:
Trades
TradingView
Long qty 1, Short qty 2
PineForge 1.9.1
Long qty 1, Short qty 2, Short qty 3 (entering at the same bar open as the qty 2 short)
PineForge development line
the same as 1.9.1
A fix is in progress; a candidate version gives TradingView's two trades on this script.
Activity
luisleo526 commentedon Nov 2, 2026
Thank you for the clear report and the minimal script. We are reproducing it now: your script against TradingView's own result, on v1.9.1 and on the current development build. You will get the triage result here by 2026-11-03 18:00 (Taipei), including whether the position size differs and, if so, how it will be fixed.
luisleo526 commentedon Nov 2, 2026
Confirmed. With your script on v1.9.1 (and on the current development build, identical result), the engine opens two short lots at the same bar (2024-01-01 21:00, qty 2 and qty 3) where TradingView opens one (qty 2), so the position size is wrong. Both of your controls (
calc_on_order_fills = false, or nostrategy.close) match TradingView. This is a silent wrong result in a released version; a fix is in progress and the next release will not ship without it. We will post the fix here.luisleo526 commentedon Nov 3, 2026
Measured again (2026-11-03)
The reproduction above, without
barstate.isconfirmedand otherwise the same calls (strategy.close("L")thenstrategy.entry("S", strategy.short, qty = bar_index == 20 ? 2 : 3)on bars 20 and 21,pyramiding = 1,calc_on_order_fills = true,process_orders_on_close = false), on a BINANCE:BTCUSDT 60-minute chart from 2024-01-01 to 2024-03-01, compared with TradingView's exported list of trades:A fix is in progress; a candidate version gives TradingView's two trades on this script.
luisleo526 commentedon Nov 3, 2026
Fixed by #727 (9fa1ac5). The order-fill recalculation and pyramiding-cap fix will be included in v1.10.0.
luisleo526 commentedon Nov 3, 2026
This fix is released in v1.10.0: https://github.com/pineforge-4pass/pineforge-engine/releases/tag/v1.10.0
Fix fill recalculation, declared quantity steps, and intraday request…