---
title: "Pine Script Error Reference: strategy.exit &amp; trail_offset"
slug: pine-script-error-reference-strategy-exit-trail_offset
date: 2026-07-17
modified: 2026-07-17
author: Bhavishya Goyal
excerpt: ""
meta_description: "A Pine Script error reference for strategy.exit(), trail_offset, and the most common compile errors, with the exact fix for each."
focus_keyword: pine script error reference
canonical_url: "https://blog.pickmytrade.trade/pine-script-error-reference-strategy-exit-trail_offset/"
og_title: "Pine Script Error Reference: strategy.exit &amp; trail_offset"
og_description: "A Pine Script error reference for strategy.exit(), trail_offset, and the most common compile errors, with the exact fix for each."
og_image: "https://blog.pickmytrade.trade/wp-content/uploads/2026/07/Gemini_Generated_Image_wahz2rwahz2rwahz-1024x572.avif"
schema_type: FAQPage
categories:
  - TradingView
  - Tradingview Strategy
tags: []
reading_time: 12
word_count: 2789
robots: "index, follow"
lang: en-US
---

# Pine Script Error Reference: strategy.exit &amp; trail_offset

If the Pine Editor just threw red text at you, you’re not alone. In my experience debugging strategies for traders moving toward automation, two errors show up more than any other: `strategy.exit` parameter conflicts and `trail_offset` misuse. Both stem from Pine Script’s strict pairing rules, not from bad trading logic. This Pine Script error reference exists for exactly that: the exact error text, why Pine throws it, and the fix, organized so you can jump straight to your error and get back to coding.

Table of Contents

1. [What Does strategy.exit() Actually Require?](https://blog.pickmytrade.trade/#what-does-strategy-exit-actually-require)
2. [Why Does trail_offset Throw “Must Have At Least One Parameter”?](https://blog.pickmytrade.trade/#why-does-trail_offset-throw-must-have-at-least-one-parameter)
3. [How Do trail_price and trail_points Actually Differ?](https://blog.pickmytrade.trade/#how-do-trail_price-and-trail_points-actually-differ)
4. [Why Did My strategy.exit() Behave Differently After Upgrading to Pine v6?](https://blog.pickmytrade.trade/#why-did-my-strategy-exit-behave-differently-after-upgrading-to-pine-v6)
5. [What Does “Undeclared Identifier” Mean and How Do I Fix It?](https://blog.pickmytrade.trade/#what-does-undeclared-identifier-mean-and-how-do-i-fix-it)
6. [How Do I Fix “Mismatched Input” and “No Viable Alternative” Errors?](https://blog.pickmytrade.trade/#how-do-i-fix-mismatched-input-and-no-viable-alternative-errors)
7. [Why Doesn’t My when Parameter Work Anymore?](https://blog.pickmytrade.trade/#why-doesnt-my-when-parameter-work-anymore)
8. [How Do I Combine a Stop-Loss and Trailing Stop in One strategy.exit() Call?](https://blog.pickmytrade.trade/#how-do-i-combine-a-stop-loss-and-trailing-stop-in-one-strategy-exit-call)
9. [What Are oca_name and oca_type For?](https://blog.pickmytrade.trade/#what-are-oca_name-and-oca_type-for)
10. [Do Built-In Trailing Stops Repaint on Historical Bars?](https://blog.pickmytrade.trade/#do-built-in-trailing-stops-repaint-on-historical-bars)
11. [Frequently Asked Questions](https://blog.pickmytrade.trade/#frequently-asked-questions)
12. [Why does Pine Script say "strategy.exit must have at least one of the following parameters"?](https://blog.pickmytrade.trade/#why-does-pine-script-say-strategy-exit-must-have-at-least-one-of-the-following-parameters)
13. [Can I use trail_price and trail_points together?](https://blog.pickmytrade.trade/#can-i-use-trail_price-and-trail_points-together)
14. [What changed in strategy.exit() between Pine Script v5 and v6?](https://blog.pickmytrade.trade/#what-changed-in-strategy-exit-between-pine-script-v5-and-v6)
15. [How do I fix "no viable alternative at character" in Pine Script?](https://blog.pickmytrade.trade/#how-do-i-fix-no-viable-alternative-at-character-in-pine-script)
16. [Why did my Pine v5 script stop compiling after switching to v6?](https://blog.pickmytrade.trade/#why-did-my-pine-v5-script-stop-compiling-after-switching-to-v6)
17. [Related Resources](https://blog.pickmytrade.trade/#related-resources)
18. [Still Have Questions?](https://blog.pickmytrade.trade/#still-have-questions)

&gt; **Key Takeaways**
&gt; 
&gt; 
&gt; 
&gt; 
&gt; 
&gt; 
&gt; 
&gt; - `trail_offset` cannot be used alone. It must be paired with `trail_price` or `trail_points`, or Pine throws `strategy.exit must have at least one of the following parameters`.
&gt; - Pine Script v6 changed how `strategy.exit()` evaluates `stop`/`loss` and `limit`/`profit` together. It now picks whichever level the market hits first, instead of always favoring the absolute price.
&gt; - Most “mismatched input” and “no viable alternative” compile errors trace back to indentation, a missing comma, or a stray character, not logic bugs.
&gt; - The `when` parameter was removed from all order functions in v6. Wrap the call in an `if` statement instead.

## What Does strategy.exit() Actually Require? {#what-does-strategy-exit-actually-require}

`strategy.exit()` needs at least one of `profit`, `limit`, `loss`, or `stop`, or a valid trailing-stop pair, or Pine won’t compile the call at all. Skip all of them and you’ll see `strategy.exit must have at least one of the following parameters: profit, limit, loss, stop, trail_price, trail_points`, which is Pine’s way of saying the exit has nothing to actually trigger on.

The function closes an open position created by `strategy.entry()`, and it separates **absolute price levels** from **relative distances**:

| Parameter | Type | What it means |
| --- | --- | --- |
| limit | absolute price | Take-profit price level |
| stop | absolute price | Stop-loss price level |
| profit | ticks | Take-profit distance from entry |
| loss | ticks | Stop-loss distance from entry |
| trail_price | absolute price | Price at which the trailing stop activates |
| trail_points | ticks | Distance from entry at which the trailing stop activates |
| trail_offset | ticks | How far behind price the trailing stop follows once active |

In practice, most beginner errors come from mixing an absolute-price parameter with a relative-distance one and assuming Pine will “figure it out.” It won’t. Each pair has its own rule, covered below.

![Programming code displayed on a dark computer screen, representing a Pine Script strategy being edited in the Pine Editor](https://images.pexels.com/photos/6424584/pexels-photo-6424584.jpeg?auto=compress&amp;cs=tinysrgb&amp;w=1200&amp;fm=webp)

## Why Does trail_offset Throw “Must Have At Least One Parameter”? {#why-does-trail_offset-throw-must-have-at-least-one-parameter}

`trail_offset` on its own does nothing, because Pine needs a second value telling it _when_ the trailing stop should activate. Set `trail_offset` without `trail_price` or `trail_points` and Pine can’t build a valid trailing-stop order. It falls back to the generic “must have at least one of the following parameters” error, even though you clearly passed an argument.

The rule is simple once you see it stated plainly. `trail_price` defines the activation _price_. `trail_points` defines the activation _distance_ in ticks. `trail_offset` defines how far the stop trails behind price once triggered. You need one activation parameter plus `trail_offset`. Never use `trail_offset` by itself, and never use `trail_price` or `trail_points` without it.

```
//@version=6
strategy("Trail Offset Example", overlay=true)

longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if longCondition
    strategy.entry("Long", strategy.long)

// Wrong: trail_offset with nothing to activate it
// strategy.exit("Exit Long", "Long", trail_offset=10)

// Correct: trail_points sets activation distance, trail_offset sets trail distance
strategy.exit("Exit Long", "Long", trail_points=50, trail_offset=10)
```

**What just happened:** the trailing stop arms once price moves 50 ticks in your favor (`trail_points`), then follows price at a fixed 10-tick distance (`trail_offset`). Swap `trail_points` for `trail_price=high*1.01` if you’d rather arm the trail at a specific price instead of a tick distance.

Trailing Stop Parameter Pairing
  trail_price or trail_points sets the activation point. Either one must be paired with trail_offset to define the trail distance, producing a valid trailing stop. trail_offset used alone produces the “must have at least one parameter” error.
  

  
  trail_price
  activation price

  
  trail_points
  activation distance

  
  

  
  + trail_offset
  trail distance (required)

  

  
  Valid trailing
  stop compiles

  
  trail_offset
  used alone

  

  
  Error: must have
  at least one
  parameter

  
    
      
    
  

How trail_offset pairs with trail_price or trail_points to compile a valid trailing stop
*How trail_offset pairs with trail_price or trail_points to compile a valid trailing stop*

&gt; **Watch out:** `trail_price` and `trail_points` are mutually exclusive activation methods. Pick one, not both, and always pair whichever you choose with `trail_offset`.

## How Do trail_price and trail_points Actually Differ? {#how-do-trail_price-and-trail_points-actually-differ}

`trail_points` measures the activation distance in ticks from your entry price. `trail_price` sets an exact price level at which trailing begins instead. Pick `trail_points` for distance-based logic that scales across instruments, and `trail_price` when your strategy reasons in specific price levels, like a prior swing high.

|  | trail_points | trail_price |
| --- | --- | --- |
| Unit | Ticks from entry | Absolute price |
| Best for | Percentage/ATR-based systems | Level-based systems (swing highs/lows) |
| Example | trail_points=100 | trail_price=high[1] |
| Still needs | trail_offset | trail_offset |

## Why Did My strategy.exit() Behave Differently After Upgrading to Pine v6? {#why-did-my-strategy-exit-behave-differently-after-upgrading-to-pine-v6}

Pine Script v6 changed how `strategy.exit()` resolves combined absolute and relative parameters. It now evaluates both specified levels and closes the position at whichever one the market is expected to reach first. That’s different from v5, which always gave priority to the absolute price (`stop` or `limit`) over the relative one (`loss` or `profit`). If your v5 strategy relied on `stop` silently overriding `loss`, backtest results on v6 can shift.

```
//@version=6
strategy("v6 Exit Priority Example", overlay=true)

if ta.crossover(close, ta.sma(close, 50))
    strategy.entry("Long", strategy.long)

// v6 evaluates both stop and loss, exits at whichever triggers first
strategy.exit("Exit Long", "Long", stop=close * 0.97, loss=200)
```

This same first-to-trigger logic applies to `limit` vs. `profit`. If you maintain strategies written for v5 and haven’t re-tested them on v6, this is the first place to look when live results diverge from your backtest.

strategy.exit() Priority: Pine v5 vs v6
  In Pine v5, the absolute stop parameter always wins over the relative loss parameter when both are set. In Pine v6, both stop and loss are evaluated together and whichever level the market reaches first triggers the exit.
  

  Pine v5
  
  stop (absolute)
  always wins if both set

  
  loss (relative)
  ignored if stop is set

  

  Pine v6
  
  stop (absolute)
  evaluated together

  
  loss (relative)
  evaluated together

  
  

  
  whichever level
  triggers first wins

  
    
      
    
  

Pine v5 always favored the absolute stop/limit level; Pine v6 evaluates both and exits at whichever triggers first
*Pine v5 always favored the absolute stop/limit level; Pine v6 evaluates both and exits at whichever triggers first*

Here’s a pattern worth flagging. Strategies that pass a loose `stop` (a wide absolute price meant as a catastrophic backstop) alongside a tight `loss` (the real risk parameter) behaved identically in v5 and v6, because the tighter level always triggers first no matter which evaluation rule is active. Behavior actually diverges when the two levels sit close together and volatility decides which one gets hit first. That’s the scenario worth backtesting on both versions before you trust the numbers.

## What Does “Undeclared Identifier” Mean and How Do I Fix It? {#what-does-undeclared-identifier-mean-and-how-do-i-fix-it}

“Undeclared identifier” means Pine Script doesn’t recognize a name you’ve used, almost always because it’s missing its namespace prefix or because the standalone function it replaced was removed in v6. If the identifier is a built-in you’re sure exists, add the correct prefix (`ta.` for indicators like `ta.sma`, `request.` for `request.security`, `color.` for named colors like `color.green`).

The most common v6-specific trigger is the old `input()` function with a `type=` argument. v6 splits it into dedicated functions per type (`input.int()`, `input.float()`, `input.bool()`, `input.string()`, and so on), each with its own parameter names.

```
// v5 style: throws "undeclared identifier" style errors when ported carelessly
// length = input(14, title="Length", type=input.integer)

// v6: dedicated typed input function
length = input.int(14, title="Length")
```

## How Do I Fix “Mismatched Input” and “No Viable Alternative” Errors? {#how-do-i-fix-mismatched-input-and-no-viable-alternative-errors}

“Mismatched input ‘’ expecting ‘'” almost always points to an indentation or line-placement problem. “No viable alternative at character ‘'” points to an invalid character that doesn’t belong at that spot in the syntax. Both are structural problems, not logical ones, so the fix lives in formatting, not strategy logic.

| Error | Typical Cause | Fix |
| --- | --- | --- |
| mismatched input 'plot' expecting 'end of line' | Statement indented when it should start a new line | Remove the leading whitespace before the statement |
| no viable alternative at character '$' | Invalid character inside a string/argument, often from copy-pasting | Replace with a plain string literal, e.g. "title" |
| syntax error at input 'end of line without line continuation' | A trailing // comment placed after a wrapped line | Move the comment above the line instead of at the end |
| syntax error at input '' | Missing closing parenthesis or bracket | Count your ( against your ) for that statement |

Across the strategies I’ve debugged for other traders migrating to PickMyTrade automation, the single most repeated fix has been the same one. A `plot()`, `strategy.exit()`, or `alert()` call gets left indented under an `if` block it was never meant to belong to. Pine treats indentation as structural, so one accidental extra space turns a top-level statement into a conditional one. The compiler reports it as a mismatched-input error rather than “wrong indentation,” which is why it trips up experienced coders too.

![A computer screen showing a pink and green candlestick chart, representing a Pine Script strategy plotting entries and exits](https://images.pexels.com/photos/5834240/pexels-photo-5834240.jpeg?auto=compress&amp;cs=tinysrgb&amp;w=1200&amp;fm=webp)

## Why Doesn’t My when Parameter Work Anymore? {#why-doesnt-my-when-parameter-work-anymore}

The `when` parameter was removed from every order function, including `strategy.entry()`, `strategy.exit()`, and `strategy.order()`, in Pine Script v6. Any v5 script still passing `when=` will fail to compile. Replace it with an `if` statement wrapping the order call instead.

```
// v5: no longer valid in v6
// strategy.exit("Exit Long", "Long", stop=close * 0.97, when=barstate.isconfirmed)

//@version=6
if barstate.isconfirmed
    strategy.exit("Exit Long", "Long", stop=close * 0.97)
```

This is one of the most common breaks when you pull in an older strategy written for v5, since `when=` was a common pattern for gating orders to confirmed bars.

## How Do I Combine a Stop-Loss and Trailing Stop in One strategy.exit() Call? {#how-do-i-combine-a-stop-loss-and-trailing-stop-in-one-strategy-exit-call}

Yes, a single `strategy.exit()` call can carry a hard stop, a take-profit, and a trailing stop simultaneously. Pine evaluates all specified exit conditions on the same order and executes whichever triggers first. This is the standard “bracket + trail” pattern for prop-firm strategies that need a hard daily-loss backstop alongside adaptive profit protection.

```
//@version=6
strategy("Combined Exit Example", overlay=true, margin_long=100, margin_short=100)

if ta.crossover(ta.ema(close, 9), ta.ema(close, 21))
    strategy.entry("Long", strategy.long)

strategy.exit(
     "Bracket + Trail",
     "Long",
     stop=strategy.position_avg_price * 0.98,
     limit=strategy.position_avg_price * 1.04,
     trail_points=60,
     trail_offset=15,
     comment_trailing="Trailing",
     alert_message="exit_long")
```

**What just happened:** the hard `stop`/`limit` bracket protects against a runaway move while `trail_points`/`trail_offset` locks in gains once price runs 60 ticks in your favor. The `alert_message` argument is what lets a webhook, including the one PickMyTrade listens on, fire the moment this exact exit condition executes. That’s what keeps your broker or prop-firm account closing the position in sync with the chart instead of a few seconds behind it.

## What Are oca_name and oca_type For? {#what-are-oca_name-and-oca_type-for}

`oca_name` and `oca_type` group multiple exit orders so that filling one automatically cancels or reduces the others, which matters when a single `strategy.exit()` call isn’t enough to express a partial take-profit plus stop-loss structure. Set `oca_type=strategy.oca.reduce` when you want each fill to reduce the remaining group’s quantity instead of canceling it outright. That’s the correct setting for scaled exits.

```
strategy.exit("TP1", "Long", qty_percent=50, limit=strategy.position_avg_price * 1.02,
     oca_name="ExitGroup", oca_type=strategy.oca.reduce)
strategy.exit("TP2", "Long", qty_percent=50, limit=strategy.position_avg_price * 1.05,
     oca_name="ExitGroup", oca_type=strategy.oca.reduce)
```

## Do Built-In Trailing Stops Repaint on Historical Bars? {#do-built-in-trailing-stops-repaint-on-historical-bars}

Yes. Pine’s built-in `trail_points`/`trail_offset` trailing stop can repaint on historical bars because it models trailing behavior against assumed intrabar price movement rather than actual tick data. A backtest’s trailing exits may not fill at the exact same point a live chart would. This is a known limitation, not a bug in your code.

If exact bar-by-bar consistency between backtest and live matters more than convenience, code the trailing logic manually instead. That usually matters most for strategies you plan to run live through [TradingView-to-broker automation](https://blog.pickmytrade.trade/tradovate-automation-futures-bots-guide-2026/), where a repainted backtest can overstate how well the exit actually performs. Recalculate `strategy.exit()`‘s `stop` and `limit` parameters on each `barstate.isconfirmed` bar. You trade a small amount of responsiveness for a stop level that can’t repaint.

## Frequently Asked Questions {#frequently-asked-questions}

		

				

## Why does Pine Script say "strategy.exit must have at least one of the following parameters"? {#why-does-pine-script-say-strategy-exit-must-have-at-least-one-of-the-following-parameters}

				

						

				

This fires when a `strategy.exit()` call has no valid exit condition: either none of `profit`/`limit`/`loss`/`stop` are set, or `trail_offset` is set without a matching `trail_price` or `trail_points`. Add at least one activation parameter alongside `trail_offset`, or one of the four basic exit parameters.

			

		

		

				

				

## Can I use trail_price and trail_points together? {#can-i-use-trail_price-and-trail_points-together}

				

						

				

No. `trail_price` and `trail_points` are two different ways of defining the same thing: the trailing stop’s activation point. Pine only needs one. Pick whichever matches your logic: `trail_points` for tick-distance-based systems, `trail_price` for level-based systems, and pair either with `trail_offset`.

			

		

		

				

				

## What changed in strategy.exit() between Pine Script v5 and v6? {#what-changed-in-strategy-exit-between-pine-script-v5-and-v6}

				

						

				

The biggest behavioral change is that v6 evaluates combined absolute/relative parameter pairs (`stop`+`loss`, `limit`+`profit`) together and exits at whichever level the market reaches first, where v5 always gave priority to the absolute price. The `when` parameter was also removed entirely. Replace it with an `if` statement around the order call.

			

		

		

				

				

## How do I fix "no viable alternative at character" in Pine Script? {#how-do-i-fix-no-viable-alternative-at-character-in-pine-script}

				

						

				

This error means Pine hit a character it can’t parse at that position in the syntax, usually a stray symbol from copy-pasting code or a typo like `$` where a string was expected. Check the exact character named in the error message and the line it points to. The fix is almost always replacing or removing that one character.

			

		

		

				

				

## Why did my Pine v5 script stop compiling after switching to v6? {#why-did-my-pine-v5-script-stop-compiling-after-switching-to-v6}

				

						

				

The most common causes are the removed `when` parameter, the retired generic `input()` function (now split into `input.int()`, `input.float()`, etc.), and stricter boolean typing that no longer implicitly casts `int`/`float` to `bool`. Compare each compile error against the specific v6 breaking change it maps to, rather than guessing.

			

		

		

		

## Related Resources {#related-resources}

- [Debugging TradingView Strategies: 10 Common Pine Script Mistakes](https://blog.pickmytrade.io/debugging-tradingview-strategies-10-common-pine-script-mistakes/): broader troubleshooting beyond `strategy.exit()` specifically, including repainting and loop-timeout issues.
- [Tradovate Automation &amp; Futures Bots Guide](https://blog.pickmytrade.trade/tradovate-automation-futures-bots-guide-2026/): what happens after your `strategy.exit()` fires a clean `alert_message`, from webhook to filled order.
- [PickMyTrade automation setup](https://pickmytrade.trade/pages/pricing/): once your `strategy.exit()` calls compile cleanly, this is what turns the resulting alert into a real order on Tradovate, Rithmic, IBKR, or a funded prop-firm account.

## Still Have Questions? {#still-have-questions}

I update this reference whenever a Pine Script version bump changes `strategy.exit()` behavior or introduces a new class of compile error. If you hit an error not listed here, drop the exact error text in the comments. That’s usually enough to trace it back to the parameter or syntax rule causing it.

---

_**Disclaimer:**  
This content is for informational purposes only and does not constitute financial, investment, or trading advice. Trading and investing in financial markets involve risk, and it is possible to lose some or all of your capital. Always perform your own research and consult with a licensed financial advisor before making any trading decisions. The mention of any proprietary trading firms, brokers, does not constitute an endorsement or partnership. Ensure you understand all terms, conditions, and compliance requirements of the firms and platforms you use._

---

Also Checkout: [Automate TradingView Indicators with Tradovate Using PickMyTrade](https://blog.pickmytrade.trade/automate-tradingview-indicators-with-tradovate-using-pickmytrade/)

For AI tools &amp; developers:[View Markdown →](https://blog.pickmytrade.trade/pine-script-error-reference-strategy-exit-trail_offset.md)