This strategy identifies breakouts above or below a higher-timeframe reference level (daily by default) and executes trades with automated position sizing based on risk percentage.
// Calculation
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// @version=5
strategy(title="Breakout Strategy", overlay=true, currency="USD")
// Import ZenLibrary
import ZenAndTheArtOfTrading/ZenLibrary/3 as zen
// Get user input
res = input.timeframe(title="Timeframe", defval="D")
rr = input.float(title="Risk:Reward", defval=1.0)
stopMultiplier = input.float(title="Stop Multiplier", defval=1.0)
lookback = input.int(title="Stop Lookback", defval=1)
riskPerTrade = input.float(title="Risk Per Trade %", defval=1.0)
// Get highs and lows
dailyHigh = request.security(syminfo.tickerid, res, high[barstate.isrealtime ? 1 : 0])
dailyLow = request.security(syminfo.tickerid, res, low[barstate.isrealtime ? 1 : 0])
// Detect unique breakout for today
var bullishBreakoutToday = false
var bearishBreakoutToday = false
newDay = ta.change(time("D"))
if newDay
bullishBreakoutToday := false
bearishBreakoutToday := false
// Get ATR
atr = ta.atr(14)
// Check for breakouts
bullishBO = close > dailyHigh and close[1] <= dailyHigh and not bullishBreakoutToday and not na(atr) and strategy.position_size == 0
bearishBO = close < dailyLow and close[1] >= dailyLow and not bearishBreakoutToday and not na(atr) and strategy.position_size == 0
// Get stops & targets
longStop = ta.lowest(low, lookback) - (atr * stopMultiplier)
shortStop = ta.highest(high, lookback) + (atr * stopMultiplier)
longStopDist = close - longStop
shortStopDist = shortStop - close
longTarget = close + (longStopDist * rr)
shortTarget = close - (shortStopDist * rr)
//------------- DETERMINE CURRENCY CONVERSION RATE -------------//
// Check if our account currency is the same as the base or quote currency or neither (for risk $ conversion purposes)
accountSameAsCounterCurrency = strategy.account_currency == syminfo.currency
accountSameAsBaseCurrency = strategy.account_currency == syminfo.basecurrency
accountNeitherCurrency = not accountSameAsCounterCurrency and not accountSameAsBaseCurrency
// Get currency conversion rates if applicable
conversionCurrencyPair = accountSameAsCounterCurrency ? syminfo.tickerid : strategy.account_currency + syminfo.currency
conversionCurrencyRate = accountSameAsBaseCurrency or accountNeitherCurrency ? request.security(conversionCurrencyPair, "D", close, ignore_invalid_symbol=true) : 1.0
// Display the current conversion currency ticker (for debug purposes)
if barstate.islastconfirmedhistory
table t = table.new(position.top_right, 1, 1, color.black)
table.cell(t, 0, 0, "Conversion: " + conversionCurrencyPair + " (" + str.tostring(conversionCurrencyRate) + ")", text_color=color.white, text_size=size.small)
//------------- END CURRENCY CONVERSION RATE CODE -------------//
// Save stop & target
var float t_stop = na
var float t_target = na
// If bullish breakout detected today, disable any future signals for today
if bullishBO
bullishBreakoutToday := true
t_stop := longStop
t_target := longTarget
positionSize = zen.av_getPositionSize(strategy.equity, riskPerTrade, zen.toWhole(longStopDist) * 10, conversionCurrencyRate)
stopLabelText = str.tostring(longStopDist / syminfo.mintick / 10, "#.#")
strategy.entry(id="Long", direction=strategy.long, qty=positionSize, comment="Long (SL=" + stopLabelText + " pips)")
// If bearish breakout detected today, disable any future signals for today
if bearishBO
bearishBreakoutToday := true
t_stop := shortStop
t_target := shortTarget
positionSize = zen.av_getPositionSize(strategy.equity, riskPerTrade, zen.toWhole(shortStopDist) * 10, conversionCurrencyRate)
stopLabelText = str.tostring(shortStopDist / syminfo.mintick / 10, "#.#")
strategy.entry(id="Short", direction=strategy.short, qty=positionSize, comment="Short (SL=" + stopLabelText + " pips)")
// Check long stops & targets being hit
strategy.exit(id="Long Exit",
from_entry="Long",
limit=t_target,
stop=t_stop,
when=strategy.position_size > 0,
comment="Long Exit (Equity: " + str.tostring(strategy.equity, "###,###,###") + ")")
// Check short stops & targets being hit
strategy.exit(id="Short Exit",
from_entry="Short",
limit=t_target,
stop=t_stop,
when=strategy.position_size < 0,
comment="Short Exit (Equity: " + str.tostring(strategy.equity, "###,###,###") + ")")
// Draw highs and lows to the chart
plot(dailyHigh, color=color.red, linewidth=2)
plot(dailyLow, color=color.green, linewidth=2)
// Draw signals
plotshape(bearishBO, title="Bearish Breakout", style=shape.triangledown, location=location.abovebar, color=color.red)
plotshape(bullishBO, title="Bullish Breakout", style=shape.triangleup, location=location.belowbar, color=color.green)
// Draw stops & targets
plot(strategy.position_size != 0 ? t_stop : na, color=color.red, style=plot.style_linebr, title="Trade Stop")
plot(strategy.position_size != 0 ? t_target : na, color=color.green, style=plot.style_linebr, title="Trade Target")
Overview
Entries occur when the close crosses the reference high or low for the first time in a session. Stop losses are calculated using ATR and recent swing lookbacks, while take-profit targets use a fixed risk-to-reward ratio. Note that the higher-timeframe data request behaves differently between historical and real-time bars, which causes historical discrepancies.
Higher-timeframe breakout detection
Account currency conversion calculation
Dynamic position sizing based on percentage risk
ATR-adjusted swing stop loss and risk-reward targets
The inputs you can change from the gear icon on the chart. Defaults are the author's.
Setting
Type
Default
Variable
Timeframe
timeframe
D
res
Risk:Reward
float
1.0
rr
Stop Multiplier
float
1.0
stopMultiplier
Stop Lookback
int
1
lookback
Risk Per Trade %
float
1.0
riskPerTrade
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.
This trend-following strategy executes a classic Donchian channel breakout system designed to cross-validate backtest results against external framework benchmarks. It triggers a long entry when the closing price breaks above the highest high of the prior entr
This strategy plots running pivot highs as red R circles and pivot lows as blue S circles directly on the price chart. It computes an EMA 3 and a Cto trend line from close prices, then generates long signals on upward EMA-Cto crossovers combined with price pos
The Chained Linear Regression Reversal Strategy plots linear regression channels with upper and lower standard deviation bands directly on the price chart across a user-defined time window. When price breaks out of the static channel for a confirmed number of
STRG-HOLP is a trading strategy that identifies High of Low Period (HOLP) and Low of High Period (LOHP) breakout setups. It tracks the lowest low or highest high over a user-defined lookback window. A long trade opens when the close breaks above the high of th
This script monitors opening gap conditions and breakout behavior relative to the first candle's range across up to twenty configurable stock tickers. It detects whether following bars remain inside the opening range before breaking out, displaying the status
This trend breakout strategy plots Donchian Channels consisting of upper, lower, and middle bands directly on the main price chart. Long positions enter when price touches the upper channel and pulls back to or below the middle band, placing a stop loss at the