This post was inspired by question I recently saw on reddit on /r/Forex/. The user simply wanted to know:
What does the “Recalculate After Order Filled flag” actually do?
At first, I thought a quick look at Tradingview’s help pages would be enough to find the answer. It turns out that the documentation is not so clear:
You can set the strategy to perform additional calculation after an order is filled. For this you need to check off “Recalculate After Order filled” in settings or do it in script itself:
The question I found myself asking is what additional calculation are we talking about? Do I need to specify something to be calculated? Is it a special calculation that is documented elsewhere? The text itself is a little ambiguous.
Recalculate After Order Filled
Before I give my interpretation, the first thing I should point out is recalculate after order filled is the name of the setting you see in the strategy settings screen. In the code, it is actually referred to as “calc_on_order_fills” and it is set as a keyword argument in the strategy() function call.
So it turns out that the calculation in question is effectively your whole script. On each bar of historical data your script gets “calculated“. When recalculate after order filled is turned on and an order is filled, the script is calculated once again as soon as it is filled. With Tradingview’s broker emulator this happens before the next bar.
It can appear as if it does nothing (or it can massively increase your risk)
Depending on the contents of your script, setting “recalculate after order filled” (calc_on_order_fills) may not have any noticeable affect on the script. Simple strategies that di not allow “pyramiding” is one example.
On the other side of the table, it can over expose you by placing multiple entries on the same bar. If you allow pyramiding and your conditions for entry are still met after “recalculating”, it will place a second order on the same bar. This defeats the point of pyramiding in my opinion.
Below is a very, very simple strategy. Since it is so simple, I limited the backtest range to 100 days so the chart is not overrun with buy and sell orders. (you can do this by using the max_bars_back keyword)
strategy("calc_on_order_fills testing", default_qty_type=strategy.percent_of_equity, default_qty_value=2, overlay=true, calc_on_order_fills=false, pyramiding=2, max_bars_back=100)
ma = sma(close, 50)
plot(ma, color=orange, linewidth=2)
longCondition = (open > ma)
strategy.entry("MA Long Sig", strategy.long)
shortCondition = (open < ma)
strategy.entry("MA Short Sig", strategy.short)
After running the script with default settings and then tweaking the settings we can see the following:
calc_on_order_fills = false, pyramiding = 2
The key thing to note on this image is that each entry / exit is on a different bar. Below we have an example of the same script but with calc_on_order_fills set to true.
calc_on_order_fills = true, pyramiding = 2
Here we can see that the 2 entry orders are both executed on the same bar. This happens because the whole script is recalculated and the conditions to entry are still valid.
I think seeing the two images side by side makes it easy to see what the setting does. I also believe the second image highlights the dangers of pyramiding when recalculate after order filled is on. This setting could be more useful in forward testing where conditions are not identical after the order is filled or when Tradingview rolls out automated trading with real brokers.
PS. If you are new to pinescript be sure to check out some of my other Tradingview posts: