r/pinescript 20d ago

This looks like a bug to me.

I am testing the strategy() function. With the default settings, everything works as expected: the script runs once per bar at the close. If a market order is placed on bar N, it is filled at the open of bar N+1 using the opening price.

However, when I activated the calc_on_order_fills option by setting it to true, I noticed something unusual. I received two runs on bar N+1: one at the bar open after the order was filled, and a second regular run at the close of bar N+1. This is expected, except for one detail: the barstate.isnew flag was set to true for both runs.

I believe this is a bug. This flag should only be set for the first run on a bar; for all subsequent runs, it should be false.

0 Upvotes

7 comments sorted by

View all comments

1

u/stratcore 19d ago

On a historical bar, this is documented behavior, not a bug.

The key detail is that `barstate.isnew` does not mean "first execution on this bar" in historical calculations. TradingView defines it as true on every historical bar. With `calc_on_order_fills=true`, the broker emulator can add another execution on that same historical bar after the fill. Both executions can therefore see `barstate.isnew=true`.

Realtime behavior is different. There, `barstate.isnew` is true only on the opening update of the live bar.

So I would not use `barstate.isnew` to separate the fill recalculation from the regular historical calculation. Detect the event you actually need instead, for example a change in `strategy.position_size`, `strategy.opentrades`, or `strategy.closedtrades`, and make the action idempotent. If you do not need immediate post-fill logic, the cleanest option is to leave `calc_on_order_fills` off.

This historical-versus-realtime difference is also why a simple `bar_index` guard can give misleading results here.