Camovia Tray™

Blog · Q&A

How to Code Stop Loss and Take Profit in Pine Script: A Complete Guide

Camovia Tray Team · 2026-09-17

You've built a strategy in TradingView. The entry signals are solid—maybe a crossover, maybe a breakout—and the backtest curve looks promising. You hit "Add to Chart," watch a few trades appear, and then you notice something: the trades just stay open. Or worse, they close at the wrong time. You didn't code the exits properly.

This is one of the most common stumbling blocks in Pine Script. Knowing how to enter a trade is only half the battle; managing the exit—specifically, coding stop loss and take profit—is what separates a strategy that looks good in theory from one that can actually be traded. Let's walk through exactly how to do it, and why it's trickier than it first appears.

The Core: Using strategy.exit()

The fundamental tool for exiting a trade with a stop loss or take profit is the strategy.exit() function. Its basic signature looks like this:

strategy.exit(id, from_entry, stop, limit)
  • id: A unique string identifier for this exit order.
  • from_entry: The id of the entry order you want to exit.
  • stop: The price at which the stop-loss order triggers.
  • limit: The price at which the take-profit order triggers.

The most intuitive approach is to place this immediately after your entry condition . For example:

if longCondition
    strategy.entry("Long", strategy.long)
    strategy.exit("Long Exit", from_entry="Long", stop=close * 0.99, limit=close * 1.02)

This works, but it's a bit naive. The stop and limit prices are calculated from close at the moment the entry order is placed. If the market gaps or moves quickly, those prices might be too close—or worse, already breached before the exit order is even active.

The Three Methods (and Which One to Use)

Over time, Pine Script developers have converged on a few patterns. Each has its place, but one is clearly superior for complex strategies.

Method 1: One strategy.exit() Per Entry This is the classic approach. You place one entry order and one exit order that handles both the stop and the take profit. It's clean, simple, and works perfectly for basic strategies. The limitation is that you can only have one take-profit level and one stop-loss level per trade.

Method 2: Multiple strategy.exit() Calls Some developers try to use multiple strategy.exit() calls—one for the stop and one for the take profit . The idea is to manage them independently. In practice, this often fails or produces unexpected behavior. Why? Because in Pine Script, each strategy.exit() call reserves a portion of your position. If you have two exit orders, each one gets a slice of your trade . The backtest might look like partial exits happened, but that's not what you intended.

Method 3: The Consolidated Exit Manager This is the most robust method, especially if you want to incorporate trailing stops, break-even stops, or dynamic calculations. Instead of placing an exit immediately on entry, you manage the exit state with var variables and call a single strategy.exit() on each bar while a position is open .

Here's a working template:

//@version=6
strategy("Exit Manager Example", overlay=true, initial_capital=10000)

// --- Inputs ---
slPct = input.float(1.0, "Stop Loss %", step=0.1) / 100
tpPct = input.float(2.0, "Take Profit %", step=0.1) / 100

// --- State Variables ---
var float trailPeak = na
var float trailTrough = na

// --- Entry Condition (Example: Crossover of SMAs) ---
fastSMA = ta.sma(close, 9)
slowSMA = ta.sma(close, 21)
longCondition = ta.crossover(fastSMA, slowSMA)
shortCondition = ta.crossunder(fastSMA, slowSMA)

if longCondition
    strategy.entry("Long", strategy.long)

if shortCondition
    strategy.entry("Short", strategy.short)

// --- Exit Management (Runs every bar) ---
if strategy.position_size > 0
    avgPrice = strategy.position_avg_price
    
    // Fixed Stop and TP levels
    float fixedSL = avgPrice * (1.0 - slPct)  // For long
    float fixedTP = avgPrice * (1.0 + tpPct)  // For long
    
    // --- Dynamic Adjustments (Example: Trail) ---
    // If long, track the highest high since entry
    trailPeak := math.max(nz(trailPeak), high)
    float trailSL = trailPeak * (1.0 - slPct)  // Trail from peak
    
    // Choose the most protective (higher) stop
    float finalStop = na
    if not na(fixedSL)
        finalStop := fixedSL
    if not na(trailSL) and (na(finalStop) or trailSL > finalStop)
        finalStop := trailSL
    
    // Single exit call with both levels
    strategy.exit("Long Exit", from_entry="Long", 
                  stop=finalStop, limit=fixedTP)
    
else
    // Reset trail when no position is open
    trailPeak := na

// --- Short side logic follows the same pattern with min() for stops ---

This approach ensures:

  • One exit order controls the entire position.
  • The stop can dynamically tighten (trail) without creating multiple partial exits.
  • The same logic works for both stop loss and take profit, updating each bar if needed.

The Critical Rule: Exit Orders Are Not "Updates"

A common point of confusion is treating strategy.exit() like a function that "updates" an order. It doesn't. In Pine Script, if you call strategy.exit() again with the same id, it replaces the previous exit order entirely . More importantly, you cannot update just the stop loss or just the take profit. Every time you call strategy.exit(), you must specify both the stop and limit parameters, even if only one has changed.

This is why the consolidated manager pattern is so powerful. By recalculating both the stop and take profit levels every bar and calling a single strategy.exit() with the latest values, you ensure your exits are always current—whether you're adjusting a trailing stop, moving a take profit, or activating a break-even rule.

What About Percentage-Based Exits?

Pine Script also offers helper functions for expressing stop loss and take profit as percentages. The library function exitPercent() is a wrapper that lets you specify losses and profits as a percentage of the entry price . For example:

// Requires the Strategy library
// exitPercent("Exit", lossPercent=1.0, profitPercent=2.0)

However, this approach can be unreliable with pyramiding enabled, as it uses strategy.position_avg_price internally, which may not reflect the individual entry's price . For most cases, manually calculating prices from strategy.position_avg_price or a specific entry price is more transparent and predictable.

From Backtest to Reality: Where the Code Meets the Market

You've coded your stop loss and take profit. The backtest looks like a straight line up. But here's the reality check: Pine Script is a backtesting language. Its execution model is "once per bar," and orders are simulated based on high, low, open, and close. In a live market, things move continuously.

This is where the gap between coded logic and market execution becomes very real. You might spend hours perfecting your Pine Script exits, only to realize that executing those trades in MetaTrader requires manual intervention, copy-pasting alert messages, or juggling multiple windows to keep an eye on open positions.

If you're actively trading strategies built in TradingView, you've probably felt this friction. You're not just coding stop losses—you need to monitor them without cluttering your screen. You need to know your open positions' current profit and loss without clicking back and forth between platforms. And if you're running multiple strategies, you need a way to manage it all without getting buried in tabs.

This is a workflow problem that code alone doesn't solve. You can write the perfect Pine Script exit logic, but if you're still stuck checking your MT5 terminal every five minutes to see if your stop was hit, something is off.

Managing the Gap Between Logic and Execution

This is where tools that bridge the gap between TradingView and MetaTrader start to matter. But more than that, there's a simpler layer of the trading experience that often gets overlooked: how you actually watch the market.

Imagine you've coded your stops and profits in Pine Script. You've backtested, you're confident in the logic. Now you're running it live. You still want to keep an eye on your positions—the current P&L, whether a trailing stop is getting tighter, how your equity curve is moving in real time. But you don't want to keep the entire MT5 terminal open, taking up screen real estate, competing for your attention with charts and news feeds. And you definitely don't want it visible on your screen when you're sharing your desktop or walking away from your desk.

This is the exact use case that Camovia Tray addresses. It turns your MT5 or MT4 into a tray tool—you can check live quotes by simply hovering over the system tray icon, and view all your open positions in a compact floating window . From that same interface, you can see your current open trades, their entry price, current P&L, and close any position with a couple of clicks . The whole point is that your trading data stays on your machine, not floating around in the cloud or exposed on a screen you'd rather keep private .

So while your Pine Script is handling the automated logic of when to exit, Camovia Tray handles the human layer: making sure you can actually see and manage what's happening without interrupting your flow or your privacy.

Tying It All Together

Coding stop loss and take profit in Pine Script is a fundamental skill. The consolidated exit manager pattern gives you full control, handles dynamic adjustments like trailing stops, and respects the rule that you must specify both levels in a single strategy.exit() call. Avoid the trap of multiple exit orders that slice your position into pieces.

But remember: Pine Script is the theory. Execution is the practice. Once your strategy is live, you need a sane way to monitor it. If you've ever found yourself toggling between TradingView and MetaTrader, squinting at position details in a crowded terminal, you might find that the real productivity gain isn't in writing better code—it's in managing your workspace better.

After all, the best stop-loss logic in the world doesn't help if you can't see your positions clearly and act on them when the moment comes.

MT4/MT5 Tray Assistant

Silent tracking, one-click close - check quotes and manage positions right from the tray.

Download Camovia Tray

Frequently Asked Questions

What information can I monitor?

Quotes and open positions: symbol, direction, open time, current P&L, and more - all visible in the popup positions tab. Click an order to close it.

Which languages are supported?

Chinese and English, switchable on both the website and the client.

How do I download it?

Install from the Microsoft Store - the download page on this site has the link.

How do I report issues or contact you?

Send an email to [email protected].

Popular Symbols Trading Hours

Open/close times, weekend hours & live market status: