
If your Pine Script v5 strategy uses strategy.exit() with both relative and absolute exit parameters, your backtest results will change after migrating to v61. This is one of the most consequential and least obvious breaking changes in the Pine Script v6 migration. The code still compiles. The strategy still runs. But your trades exit at different prices, and your equity curve looks different.
This guide explains exactly what changed, shows you how to audit your strategy.exit() calls, and walks through the before-and-after behavior so you can fix your strategies with confidence.
The strategy.exit() function accepts three pairs of parameters that define exit price levels2. Each pair has a relative parameter that specifies a tick distance from the entry price, and an absolute parameter that specifies a fixed price level directly.
The three parameter pairs are:
In v5, when a strategy.exit() call included both the relative and absolute parameter from the same pair, the absolute parameter always took priority and the relative parameter was silently ignored1. In v6, both parameters are evaluated, and the strategy uses whichever exit level the market price is expected to reach first1.
In Pine Script v5, the rule was simple but hidden. If you specified both profit and limit in the same strategy.exit() call, the profit value was thrown away1. The strategy only used the limit price for take-profit exits. The same applied to loss versus stop, and trail_points versus trail_price.
Consider this v5 strategy that enters long and sets both a relative and absolute take-profit and stop-loss:
//@version=5
strategy("v5 Exit Behavior", overlay = true)
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if longCondition
strategy.entry("Long", strategy.long)
strategy.exit("Exit Long", "Long",
profit = 50,
limit = close + 200 * syminfo.mintick,
loss = 50,
stop = close - 200 * syminfo.mintick)
In v5, the profit = 50 and loss = 50 parameters are completely ignored. The strategy only uses the limit and stop prices. Exits happen at 200 ticks from the entry, not 50 ticks, because the absolute parameters override the relative ones.
Many traders never noticed this behavior. They added both parameters thinking they provided a backup or additional safety net. In reality, one set of values was silently discarded.
Pine Script v6 changes this completely. Both the relative and absolute parameters in each pair are now evaluated1. The strategy creates exit orders at the level the market price is expected to activate first.
Here is how the same strategy behaves after converting to v6:
//@version=6
strategy("v6 Exit Behavior", overlay = true)
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if longCondition
strategy.entry("Long", strategy.long)
strategy.exit("Exit Long", "Long",
profit = 50,
limit = close + 200 * syminfo.mintick,
loss = 50,
stop = close - 200 * syminfo.mintick)
In v6, the strategy evaluates both profit = 50 and limit = close + 200 * syminfo.mintick. The profit parameter translates to a take-profit level 50 ticks above the entry price. The limit parameter sets a take-profit at 200 ticks above entry. Since the profit level at 50 ticks is closer to the entry price, the market will reach it first for a long position. The strategy creates the take-profit order at the profit level.
The same logic applies to the stop-loss side. The loss = 50 level at 50 ticks below entry is closer than the stop at 200 ticks below entry. The strategy uses the loss level because the price reaches it first.
The result is dramatically different. Trades that exited at 200 ticks in v5 now exit at 50 ticks in v6. Your profit per trade, win rate, and overall equity curve all change.
The decision rule in v6 is straightforward. For take-profit orders on a long position, the strategy picks whichever level is lower (closer to the entry) between the profit-based price and the limit price1. For stop-loss orders on a long position, it picks whichever level is higher (closer to the entry) between the loss-based price and the stop price. The logic reverses for short positions.
In practical terms, the strategy always uses the tighter exit. The level the price will reach first wins.
All three pairs follow the same v6 evaluation logic. Here is a summary of each pair and what to watch for.
These define take-profit exit levels. In v5, if both were present, limit won1. In v6, the strategy uses whichever creates the tighter take-profit1. If your profit value translates to a price closer to entry than limit, your trades will now exit sooner with smaller profits.
These define stop-loss exit levels. In v5, if both were present, stop won1. In v6, the tighter stop is used. If your loss value translates to a price closer to entry than stop, your stops are now tighter and trades may stop out more frequently.
These define the activation level for a trailing stop. In v5, trail_price overrode trail_points when both were specified1. In v6, the trailing stop activates at whichever level the price reaches first. A trail_points value that translates to a closer activation level than trail_price will cause earlier trailing stop activation.
Not every strategy.exit() call is affected. You only need to fix calls that specify both the relative and absolute parameter from the same pair. Here is a systematic audit process.
Find every strategy.exit() call in your script. Most strategies have one to three exit calls. Some complex systems have more.
For each strategy.exit() call, check whether it uses both parameters from any of the three pairs:
If the answer is no for all three pairs, the call behaves identically in v5 and v6. No changes needed.
For each affected call, decide which exit level you actually want. In most cases, the v5 behavior was unintentional. Traders added both parameters without realizing one was ignored. Ask yourself which exit level your strategy should use, and remove the other parameter.
The cleanest fix is to keep only the parameter you want. If you intended to use a fixed price for your take-profit, keep limit and remove profit. If you intended a tick-based distance, keep profit and remove limit.
Here is an example of a cleaned-up v6 exit call using only absolute parameters:
//@version=6
strategy("Clean v6 Exit", overlay = true)
float entryPrice = strategy.opentrades.entry_price(0)
float tpPrice = entryPrice + 200 * syminfo.mintick
float slPrice = entryPrice - 100 * syminfo.mintick
if ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
strategy.entry("Long", strategy.long)
strategy.exit("Exit Long", "Long", limit = tpPrice, stop = slPrice)
And here is the same strategy using only relative parameters:
//@version=6
strategy("Clean v6 Exit Relative", overlay = true)
if ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
strategy.entry("Long", strategy.long)
strategy.exit("Exit Long", "Long", profit = 200, loss = 100)
Both approaches are clear and produce predictable results in v6.
In some strategies, you may genuinely want both a relative and absolute exit. For example, you might want a dynamic limit price based on a resistance level, with a minimum profit of 50 ticks as a safety net. In v6, this works exactly as intended. The strategy exits at whichever level is reached first.
//@version=6
strategy("Intentional Dual Exit", overlay = true)
float resistanceLevel = ta.highest(high, 20)
if ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
strategy.entry("Long", strategy.long)
strategy.exit("Exit Long", "Long",
profit = 50,
limit = resistanceLevel,
loss = 100)
In this case, if the resistance level is more than 50 ticks above the entry, the strategy exits at the profit level (50 ticks). If the resistance level is within 50 ticks, the strategy exits at the limit price (the resistance). This dual-parameter approach is now a valid and useful technique in v6.
After editing your strategy.exit() calls, compare the v5 and v6 backtest results side by side. Here is a structured testing approach.
Keep a copy of your v5 script and run both versions on the same symbol and timeframe. Compare total trades, net profit, win rate, and maximum drawdown. Differences in any of these metrics indicate that the strategy.exit() changes are affecting trade outcomes.
Use the Strategy Tester's trade list to compare individual trade exits. Look for trades that exit at different prices or different times between v5 and v6. These are the trades affected by the parameter evaluation change.
Plot your intended exit levels on the chart to visually confirm they match your expectations. You can use plot() with plot.style_linebr to see take-profit and stop-loss levels only while a position is open.
//@version=6
strategy("Exit Level Verification", overlay = true)
var float takeProfit = na
var float stopLoss = na
if ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
strategy.entry("Long", strategy.long)
strategy.exit("Exit Long", "Long", profit = 100, loss = 50)
if ta.change(strategy.opentrades) == 1
float entryPrice = strategy.opentrades.entry_price(0)
takeProfit := entryPrice + 100 * syminfo.mintick
stopLoss := entryPrice - 50 * syminfo.mintick
if ta.change(strategy.closedtrades) == 1
takeProfit := na
stopLoss := na
plot(takeProfit, "Take Profit", color.green, 2, plot.style_linebr)
plot(stopLoss, "Stop Loss", color.red, 2, plot.style_linebr)
Run your strategy across several symbols and timeframes. The strategy.exit() change can produce different magnitudes of impact depending on the instrument's tick size and volatility. A strategy that appears unchanged on ES futures might show significant differences on a stock with a different price scale.
Watch out for these pitfalls when fixing strategy.exit() calls.
Assuming the code is unchanged: The Pine Editor converter handles many v5-to-v6 changes automatically, but it does not remove redundant strategy.exit() parameters3. You must audit these manually.
Removing the wrong parameter: Before deleting a parameter, check which exit level your v5 strategy actually used. Remember that v5 always used the absolute parameter1. If your strategy was tuned and profitable in v5, keep the absolute parameter to preserve the same behavior.
Forgetting trail_points and trail_price: Traders often focus on profit/limit and loss/stop but forget to check the trailing stop pair. If your strategy uses trailing stops with both trail_points and trail_price, the activation level may change in v6.
Not retesting after changes: Any modification to exit logic changes your backtest results. Always rerun your backtest after migration to verify the strategy still meets your performance expectations.
Once your strategy.exit() calls are updated and verified in v6, you can automate execution with TradersPost. TradersPost connects your TradingView strategies to live broker accounts through webhook-based automation, supporting brokers including Tradovate, Alpaca, Interactive Brokers, and Robinhood4.
The combination of v6's more predictable exit behavior and TradersPost's automated execution gives you tighter control over how your strategies perform in live markets. When strategy.exit() evaluates both relative and absolute parameters correctly, the alerts sent to TradersPost reflect the exact exit logic you designed and tested.
To connect your v6 strategy to a broker, set up a TradingView alert with a webhook URL from TradersPost4. The alert fires when your strategy generates an entry or exit signal, and TradersPost routes the order to your connected broker account. Paper trading mode lets you verify the full pipeline before risking real capital.
Use this checklist to ensure your strategy.exit() migration is complete:
The strategy.exit() parameter evaluation change is one of the few v6 updates that can silently alter your backtest results without producing any compilation error1. Taking the time to audit and test your exit calls now prevents surprises when you move to live trading.
1 Pine Script v5 to v6 Migration Guide
2 Pine Script v6 Language Reference
3 Pine Script User Manual
4 TradersPost - Automated Trading Platform