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: Theidof 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 TrayFrequently 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:
Related Articles
MT5 Toolbar Missing for Beginners? Don’t Panic – Here’s What’s Actually Going On
Discover why your MT5 toolbar feels "missing" as a beginner and how Camovia Tray turns MT5 into a tray tool for quick quotes, positions, and one-click closes—all local.
MT5 Indicators Traders Try (And Why Most Give Up on Them)
Discover why most traders abandon MT5 indicators and how Camovia Tray helps you check quotes and manage positions from the system tray—without opening the terminal.
Why Hide MT5 PnL on Windows 10? A Better Way to Monitor Trades
Transform your MT5 trading on Windows 10: discreetly hide PnL and monitor positions from the system tray. Camovia Tray keeps your data local and your screen clean.
What Is a Stop Loss Fix? Why Your Stop-Loss Strategy Might Be Broken (and How to Actually Manage It)
Turn your MetaTrader stop-loss strategy into a practical workflow with Camovia Tray—monitor open positions and manage trades right from the system tray without keeping the terminal open.
What Is Leverage in Forex? A Trader’s Guide to Understanding and Managing Risk
Learn what leverage in forex is, how it amplifies both profits and losses, and key risk management strategies. Camovia Tray helps you monitor open positions and margin from your system tray for safer trading.