Strategy · Pine Script v6 · On the chart

Breakout Follow Trend

by jzd101

Breakout Follow Trend is a quantitative trend-following strategy designed to capture volatility expansion.

View on GitHub

GitHub stars4on the repository
Pine versionv6current
Lines of code428
Settings25inputs
LicenceNone statedfile: MPL-2.0
Last update3 weeks ago2 Oct 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

428 lines of Pine Script v6 from src/pine/BreakoutFollowTrend_Strategy.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

BreakoutFollowTrend_Strategy.pine
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © jzd101

//@version=6
strategy("Breakout Follow Trend [Strategy]", overlay=true, initial_capital=10000, currency=currency.USD, commission_type=strategy.commission.cash_per_contract, commission_value=0.0, pyramiding=100, margin_long=0, margin_short=0)

// ==========================================
// Inputs
// ==========================================
// Risk Management
grp_risk = "Risk Management"
inpRiskPct    = input.float(1.0, "Risk % per Trade", minval=0.1, step=0.1, group=grp_risk, tooltip="Percentage of base balance to risk based on SL distance")
inpRR         = input.float(2.0, "Risk:Reward Ratio", minval=0.1, step=0.1, group=grp_risk)
inpATRMult    = input.float(2.0, "ATR Multiplier (SL)", minval=0.1, step=0.1, group=grp_risk)
inpMaxTrades  = input.int(1, "Max Concurrent Trades", minval=1, group=grp_risk)
inpCompound   = input.bool(true, "Use Compounding Risk", group=grp_risk, tooltip="If true, risk = current equity * risk%. If false, risk = fixed balance * risk%.")
inpFixedBal   = input.float(10000.0, "Fixed Balance (when compounding off)", minval=0.0, group=grp_risk)
inpDailyLoss  = input.float(1.0, "Daily Loss Limit %", minval=0.0, step=0.1, group=grp_risk, tooltip="0 = disabled. Blocks new entries once realized daily P&L drops below this % of base balance.")

// Partial Take Profit
grp_partial_tp = "Partial Take Profit"
inpUsePartialTP  = input.bool(true, "Enable Partial TP", group=grp_partial_tp, tooltip="When price reaches Partial TP at RR, close a percentage of the order.")
inpPartialTPAtRR = input.float(1.6, "Partial TP at RR", minval=0.1, step=0.1, group=grp_partial_tp, tooltip="Trigger partial close when price reaches this RR level.")
inpPartialTPPct  = input.float(50.0, "Close % at Partial TP", minval=1.0, maxval=99.0, step=1.0, group=grp_partial_tp, tooltip="Percentage of the position to close.")

// Indicators
grp_ind = "Indicators"
inpUseEMA          = input.bool(true, "Use EMA Trend Filter", group=grp_ind)
inpEMAPeriod       = input.int(200, "EMA Period", minval=1, group=grp_ind)
inpUseEMABodyFilter= input.bool(false, "Block Entry if Candle Overlaps EMA", group=grp_ind, tooltip="If the signal bar's High/Low range straddles the EMA (EMA is between High and Low), block the entry. Direction is ambiguous when price is crossing the EMA.")
inpBBPeriod        = input.int(15, "Bollinger Bands Period", minval=1, group=grp_ind)
inpBBDev           = input.float(1.5, "Bollinger Bands Deviation", minval=0.1, step=0.1, group=grp_ind)
inpATRPeriod       = input.int(18, "ATR Period", minval=1, group=grp_ind)

// Volume Filter
grp_vol = "Volume Filter"
inpUseVol     = input.bool(true, "Use Volume Filter", group=grp_vol)
inpVolPeriod  = input.int(15, "Volume MA Period", minval=1, group=grp_vol)

// Cooldown Bars After Close/SL/TP
grp_cooldown     = "Cooldown After Close/SL/TP"
inpUseCooldown   = input.bool(true, "Enable Cooldown Bars", group=grp_cooldown, tooltip="Block new entries for X bars after any position is closed (SL/TP/Manual close).")
inpCooldownBars  = input.int(6, "Cooldown Bars", minval=1, group=grp_cooldown, tooltip="Number of completed bars to wait after a close/SL/TP before allowing new entries. E.g. 1 = skip the next 1 bar.")

// Time & Filters
grp_time = "Time Filters"
inpUseTimeFilter = input.bool(true, "Enable Time Filter", group=grp_time, tooltip="When disabled, the EA trades all day without any hourly restriction.")
inpStartHour  = input.int(12, "Start Hour (0-23)", minval=0, maxval=23, group=grp_time)
inpEndHour    = input.int(18, "End Hour (0-23)", minval=0, maxval=23, group=grp_time)
inpWeekendCl  = input.bool(false, "Weekend Close (Friday)", group=grp_time)
inpFridayTime = input.string("2345", "Friday Close Time (HHMM)", group=grp_time)

// ==========================================
// Calculations
// ==========================================
// Moving Average (EMA)
emaVal = ta.ema(close, inpEMAPeriod)

// Bollinger Bands
[basis, upperBB, lowerBB] = ta.bb(close, inpBBPeriod, inpBBDev)

// ATR (Wilder's / RMA) — ta.atr uses same RMA formula as MQL5 CalculateRMA_ATR
atrVal = ta.atr(inpATRPeriod)

// Volume MA
volMA = ta.sma(volume, inpVolPeriod)

// Time Filter (disabled = trade all day)
isInTimeWindow = not inpUseTimeFilter or (inpStartHour < inpEndHour ? (hour >= inpStartHour and hour < inpEndHour) : (hour >= inpStartHour or hour < inpEndHour))

// Weekend Block (matches MQL5 CheckWeekendClose: Friday past time, full Sat/Sun, Monday before StartHour)
cleanTimeVal = str.tonumber(str.replace_all(inpFridayTime, ":", ""))
fHour = na(cleanTimeVal) ? 23 : int(math.floor(cleanTimeVal / 100))
fMin  = na(cleanTimeVal) ? 45 : int(math.floor(cleanTimeVal % 100))
fridayMin      = fHour * 60 + fMin
nowMin         = hour * 60 + minute
isFridayPast   = dayofweek == dayofweek.friday and nowMin >= fridayMin
isWeekend      = dayofweek == dayofweek.saturday or dayofweek == dayofweek.sunday
// isMondayBefore only applies when time filter is on (StartHour is meaningful)
isMondayBefore = inpUseTimeFilter and dayofweek == dayofweek.monday and hour < inpStartHour
isWeekendBlock = inpWeekendCl and (isFridayPast or isWeekend or isMondayBefore)

// ==========================================
// Risk Calculations
// ==========================================
// Matches MQL5: compound uses live equity, otherwise fixed balance input
baseBal    = inpCompound ? strategy.equity : inpFixedBal
slDist     = atrVal * inpATRMult
riskAmount = baseBal * (inpRiskPct / 100)
// Divide by syminfo.pointvalue to scale properly on Futures or CFDs
float pVal = nz(syminfo.pointvalue, 1.0)
bool isValidSize = not na(slDist) and slDist > 0 and pVal > 0
float posSize    = isValidSize ? (riskAmount / slDist) / pVal : 0.0

// ==========================================
// Daily Loss Limit & Cooldown Bars tracking (realized P&L)
// ==========================================
var float dailyPnL     = 0.0
var int   currentDay   = 0
var float dailyLossMax = 0.0
var int   lastClosedBar = -1000  // safe default
var int   prev_closed_trades = 0

int d = time("D")
if not na(d) and d != currentDay
    currentDay   := d
    dailyPnL     := 0.0
    // Recalculate daily loss max with current equity/balance (matches MQL5 daily reset)
    dailyLossMax := baseBal * (inpDailyLoss / 100)

// Sum ALL trades closed this bar (MQL5 OnTradeTransaction fires per-deal; loop covers simultaneous exits)
if strategy.closedtrades > prev_closed_trades
    for i = prev_closed_trades to strategy.closedtrades - 1
        dailyPnL := dailyPnL + strategy.closedtrades.profit(i) - nz(strategy.closedtrades.commission(i))
    lastClosedBar := bar_index
    prev_closed_trades := strategy.closedtrades

bool dailyLossHit = inpDailyLoss > 0 and currentDay != 0 and dailyPnL <= -dailyLossMax
bool cooldownActive = inpUseCooldown and (bar_index - lastClosedBar) <= inpCooldownBars

// ==========================================
// Signal Conditions — plain comparison on closed bar (matches MQL5: close1 > upperBB / close1 < lowerBB)
// ==========================================
bool volCond           = (not inpUseVol) or na(volMA) or nz(volMA) == 0 or volume > nz(volMA)

// v6: explicit na-guards for all indicator values used in conditions
bool emaReady = not na(emaVal)
bool atrReady = not na(atrVal)
bool bbReady  = not na(upperBB) and not na(lowerBB)

// EMA Body Overlap filter: block if EMA is inside the candle's High-Low range (ambiguous direction)
bool emaOverlap = emaReady and (low <= nz(emaVal) and high >= nz(emaVal))
bool emaOverlapBlocked = inpUseEMABodyFilter and inpUseEMA and emaOverlap

bool isAboveEMA = emaReady and close > nz(emaVal)
bool isBelowEMA = emaReady and close < nz(emaVal)

bool isAboveBB = bbReady and close > nz(upperBB)
bool isBelowBB = bbReady and close < nz(lowerBB)

bool canLong  = (not inpUseEMA or isAboveEMA) and isAboveBB
bool canShort = (not inpUseEMA or isBelowEMA) and isBelowBB

bool isInTimeWindowVal = (not inpUseTimeFilter) or (inpStartHour < inpEndHour ? (hour >= inpStartHour and hour < inpEndHour) : (hour >= inpStartHour or hour < inpEndHour))

bool longCondition  = atrReady and canLong  and volCond and isInTimeWindowVal and not isWeekendBlock and not dailyLossHit and not cooldownActive and not emaOverlapBlocked
bool shortCondition = atrReady and canShort and volCond and isInTimeWindowVal and not isWeekendBlock and not dailyLossHit and not cooldownActive and not emaOverlapBlocked

// ==========================================
// Strategy Execution
// ==========================================
// Entry IDs are unique so each position carries its own SL/TP (matches MQL5 hedge-like per-position management)
var int entryCounter = 0

// Per-entry slDist queue: stores (entryCounter, slDist) so visual section can retrieve
// the exact ATR-based distance for the bar that generated each signal,
// even when MaxTrades > 1 and signals fire on consecutive bars.
var int[]   sl_entry_ids  = array.new_int()
var float[] sl_dist_queue = array.new_float()

// Push signal's slDist into queue BEFORE incrementing entryCounter
// so we store the counter value that will be assigned to this entry.
// Guard: only one direction per bar (matches MQL5 if/else-if structure)
bool didLongEntry = false

if longCondition and strategy.opentrades < inpMaxTrades and posSize > 0
    array.push(sl_entry_ids, entryCounter + 1)
    array.push(sl_dist_queue, slDist)

if (not didLongEntry) and shortCondition and strategy.opentrades < inpMaxTrades and posSize > 0
    array.push(sl_entry_ids, entryCounter + 1)
    array.push(sl_dist_queue, slDist)

// Matches MQL5: if(lotSize > 0) guard prevents zero-size entries when ATR is unavailable
if (longCondition and strategy.opentrades < inpMaxTrades and posSize > 0)
    entryCounter += 1
    string trade_id = "L" + str.tostring(entryCounter)
    strategy.entry(trade_id, strategy.long, qty=posSize, comment="Long")
    didLongEntry := true

if ((not didLongEntry) and shortCondition and strategy.opentrades < inpMaxTrades and posSize > 0)
    entryCounter += 1
    string trade_id = "S" + str.tostring(entryCounter)
    strategy.entry(trade_id, strategy.short, qty=posSize, comment="Short")

// Weekend Close — close all positions while inside the weekend block
if (isWeekendBlock)
    strategy.close_all(comment="Weekend Close")

// ==========================================
// Visuals & Position Tools
// ==========================================
plot(inpUseEMA ? emaVal : na, color=color.new(color.blue, 0), title="EMA Trend")
p1 = plot(upperBB, color=color.new(color.gray, 50), title="Upper BB")
p2 = plot(lowerBB, color=color.new(color.gray, 50), title="Lower BB")
fill(p1, p2, color=color.new(color.gray, 90), title="BB Background")

// ── Trade Box Color Palette (TradingView Style) ──────────────────────────────
color_tp_fill      = color.new(#089981, 85)
color_sl_fill      = color.new(#f23645, 85)
color_tp_border    = color.new(#089981,  0)
color_sl_border    = color.new(#f23645,  0)
color_tp_label     = color.new(#089981,  0)
color_sl_label     = color.new(#f23645,  0)
color_entry_line   = color.new(#b2b5be,  0)
color_entry_lbl    = color.new(#b2b5be,  0)
// ── Partial TP Label Color ───────────────────────────────────────────────────
color_ptp_label = color.new(#089981, 0)

// ── Persistent Arrays for Active Visual Objects ───────────────────────────────
var float[]  active_sl_prices    = array.new_float()
var float[]  active_tp_prices    = array.new_float()
var string[] active_trade_ids    = array.new_string()
var bool[]   active_trade_dirs   = array.new_bool()      // true = long
var box[]    active_tp_boxes     = array.new_box()
var box[]    active_sl_boxes     = array.new_box()
var line[]   active_entry_lines  = array.new_line()
var label[]  active_tp_labels    = array.new_label()
var label[]  active_sl_labels    = array.new_label()
var label[]  active_en_labels    = array.new_label()
var float[]  active_entry_prices = array.new_float()     // Entry price per trade (for SL move calc)
var float[]  active_sl_dists     = array.new_float()     // Original SL distance per trade
var bool[]   active_partial_tp_done = array.new_bool()   // Whether Partial TP has executed

// ── Helper: format price to 5 sig-figs ───────────────────────────────────────
f_fmt(float p) => str.tostring(p, format.mintick)

// ── 1. Extend all active boxes & lines to the current bar ─────────────────────
if array.size(active_tp_boxes) > 0
    for i = 0 to array.size(active_tp_boxes) - 1
        box.set_right(array.get(active_tp_boxes, i),    bar_index)
        box.set_right(array.get(active_sl_boxes, i),    bar_index)
        line.set_x2(array.get(active_entry_lines, i),   bar_index)
        // Slide labels to the right edge
        label.set_x(array.get(active_tp_labels, i),     bar_index)
        label.set_x(array.get(active_sl_labels, i),     bar_index)
        label.set_x(array.get(active_en_labels, i),     bar_index)

// ── Helper: look up slDist from queue by entry-ID number ─────────────────────
f_pop_sl_dist(string entry_id) =>
    float result = na
    int num = int(str.tonumber(str.substring(entry_id, 1, str.length(entry_id))))
    if not na(num) and array.size(sl_entry_ids) > 0
        for k = 0 to array.size(sl_entry_ids) - 1
            if array.get(sl_entry_ids, k) == num
                result := array.get(sl_dist_queue, k)
                array.remove(sl_entry_ids, k)
                array.remove(sl_dist_queue, k)
                break
    result

// ── 2. New entry detection ────────────────────────────────────────────────────
int total_trades      = strategy.closedtrades + strategy.opentrades
var int prev_total_trades = 0
if total_trades > prev_total_trades
    int num_opened       = total_trades - prev_total_trades
    int trades_to_process = math.min(num_opened, strategy.opentrades)
    if trades_to_process > 0
        for i = 0 to trades_to_process - 1
            int    trade_idx = strategy.opentrades - trades_to_process + i
            string eid       = strategy.opentrades.entry_id(trade_idx)
            float  sd        = f_pop_sl_dist(eid)
            if na(sd)
                sd := slDist
            bool  is_long = strategy.opentrades.size(trade_idx) > 0
            float en      = strategy.opentrades.entry_price(trade_idx)

            // Round to mintick (MQL5 parity)
            float sd_rounded = math.round(sd             / syminfo.mintick) * syminfo.mintick
            float tp_rounded = math.round((sd * inpRR)   / syminfo.mintick) * syminfo.mintick

            float tp = is_long ? en + tp_rounded : en - tp_rounded
            float sl = is_long ? en - sd_rounded : en + sd_rounded

            // ── Box y-coordinates: top > bottom always ────────────────────────
            float tp_top    = is_long ? tp : en
            float tp_bottom = is_long ? en : tp
            float sl_top    = is_long ? en : sl
            float sl_bottom = is_long ? sl : en

            // ── Draw boxes ────────────────────────────────────────────────────
            box b_tp = box.new(
                 bar_index - 1, tp_top, bar_index, tp_bottom,
                 bgcolor=color_tp_fill, border_color=color_tp_border,
                 border_width=1, border_style=line.style_solid,
                 text="", text_size=size.tiny)

            box b_sl = box.new(
                 bar_index - 1, sl_top, bar_index, sl_bottom,
                 bgcolor=color_sl_fill, border_color=color_sl_border,
                 border_width=1, border_style=line.style_solid,
                 text="", text_size=size.tiny)

            // ── Entry dashed line ─────────────────────────────────────────────
            line l_en = line.new(
                 bar_index - 1, en, bar_index, en,
                 color=color_entry_line, width=1, style=line.style_dashed)

            // ── TP label (positioned at TP price level, right edge) ───────────
            string tp_txt   = "TP  " + f_fmt(tp)
            label lbl_tp = label.new(
                 bar_index, tp,
                 text=tp_txt,
                 style=is_long ? label.style_label_left : label.style_label_left,
                 color=color.new(#089981, 100),
                 textcolor=color_tp_label,
                 size=size.small)

            // ── SL label ─────────────────────────────────────────────────────
            string sl_txt   = "SL  " + f_fmt(sl)
            label lbl_sl = label.new(
                 bar_index, sl,
                 text=sl_txt,
                 style=label.style_label_left,
                 color=color.new(#f23645, 100),
                 textcolor=color_sl_label,
                 size=size.small)

            // ── Entry label ───────────────────────────────────────────────────
            string dir_txt  = is_long ? "▲ LONG" : "▼ SHORT"
            string en_txt   = dir_txt + "  " + f_fmt(en)
            label lbl_en = label.new(
                 bar_index, en,
                 text=en_txt,
                 style=label.style_label_left,
                 color=color.new(#b2b5be, 100),
                 textcolor=color_entry_lbl,
                 size=size.small)

            array.push(active_tp_boxes,    b_tp)
            array.push(active_sl_boxes,    b_sl)
            array.push(active_entry_lines, l_en)
            array.push(active_tp_labels,   lbl_tp)
            array.push(active_sl_labels,   lbl_sl)
            array.push(active_en_labels,   lbl_en)
            array.push(active_sl_prices,   sl)
            array.push(active_tp_prices,   tp)
            array.push(active_trade_ids,   eid)
            array.push(active_trade_dirs,  is_long)
            array.push(active_entry_prices, en)
            array.push(active_sl_dists,    sd_rounded)
            array.push(active_partial_tp_done, false)
    prev_total_trades := total_trades

// ── 3. Prune closed trades ────────────────────────────────────────────────────
if array.size(active_trade_ids) > 0
    box[]    temp_tp_boxes    = array.new_box()
    box[]    temp_sl_boxes    = array.new_box()
    line[]   temp_entry_lines = array.new_line()
    label[]  temp_tp_labels   = array.new_label()
    label[]  temp_sl_labels   = array.new_label()
    label[]  temp_en_labels   = array.new_label()
    float[]  temp_sl_prices   = array.new_float()
    float[]  temp_tp_prices   = array.new_float()
    string[] temp_trade_ids   = array.new_string()
    bool[]   temp_trade_dirs  = array.new_bool()
    float[]  temp_entry_prices = array.new_float()
    float[]  temp_sl_dists    = array.new_float()
    bool[]   temp_partial_tp_done = array.new_bool()

    for i = 0 to array.size(active_trade_ids) - 1
        string tid = array.get(active_trade_ids, i)
        bool is_still_open = false
        if strategy.opentrades > 0
            for j = 0 to strategy.opentrades - 1
                if strategy.opentrades.entry_id(j) == tid
                    is_still_open := true
                    break

        if is_still_open
            // Keep active trades to slide them on next bars
            array.push(temp_tp_boxes,    array.get(active_tp_boxes,    i))
            array.push(temp_sl_boxes,    array.get(active_sl_boxes,    i))
            array.push(temp_entry_lines, array.get(active_entry_lines, i))
            array.push(temp_tp_labels,   array.get(active_tp_labels,   i))
            array.push(temp_sl_labels,   array.get(active_sl_labels,   i))
            array.push(temp_en_labels,   array.get(active_en_labels,   i))
            array.push(temp_sl_prices,   array.get(active_sl_prices,   i))
            array.push(temp_tp_prices,   array.get(active_tp_prices,   i))
            array.push(temp_trade_ids,   tid)
            array.push(temp_trade_dirs,  array.get(active_trade_dirs,  i))
            array.push(temp_entry_prices, array.get(active_entry_prices, i))
            array.push(temp_sl_dists,    array.get(active_sl_dists,    i))
            array.push(temp_partial_tp_done, array.get(active_partial_tp_done, i))

    active_tp_boxes    := temp_tp_boxes
    active_sl_boxes    := temp_sl_boxes
    active_entry_lines := temp_entry_lines
    active_tp_labels   := temp_tp_labels
    active_sl_labels   := temp_sl_labels
    active_en_labels   := temp_en_labels
    active_sl_prices   := temp_sl_prices
    active_tp_prices   := temp_tp_prices
    active_trade_ids   := temp_trade_ids
    active_trade_dirs  := temp_trade_dirs
    active_entry_prices := temp_entry_prices
    active_sl_dists    := temp_sl_dists
    active_partial_tp_done := temp_partial_tp_done

// ── 4. Emergency Reset (Omitted to preserve historical boxes) ─────────────────

// ── 5. Partial TP executed natively via strategy.exit ───────────────────────

// ── 6. Re-submit exit orders every bar using stored prices ────────────────────
if array.size(active_trade_ids) > 0
    for i = 0 to array.size(active_trade_ids) - 1
        string tid   = array.get(active_trade_ids, i)
        float sl_val = array.get(active_sl_prices,  i)
        float tp_val = array.get(active_tp_prices,  i)
        
        if inpUsePartialTP
            float sd_t = array.get(active_sl_dists, i)
            float en_t = array.get(active_entry_prices, i)
            bool is_long_t = array.get(active_trade_dirs, i)
            
            float partial_tp_raw = is_long_t ? en_t + sd_t * inpPartialTPAtRR : en_t - sd_t * inpPartialTPAtRR
            float partial_tp_val = math.round(partial_tp_raw / syminfo.mintick) * syminfo.mintick
            bool ptp_done = array.get(active_partial_tp_done, i)
            
            if not ptp_done
                strategy.exit("XP" + tid, tid, qty_percent=inpPartialTPPct, stop=sl_val, limit=partial_tp_val, comment_loss="SL", comment_profit="P-TP")
                bool hit = is_long_t ? high >= partial_tp_val : low <= partial_tp_val
                if hit
                    array.set(active_partial_tp_done, i, true)
                    
            strategy.exit("X" + tid, tid, stop=sl_val, limit=tp_val, comment_loss="SL", comment_profit="TP")
        else
            strategy.exit("X" + tid, tid, stop=sl_val, limit=tp_val, comment_loss="SL", comment_profit="TP")

Overview

Breakout Follow Trend triggers entries when price breaks out of Bollinger Bands, filtered by an EMA trend filter, optional candle overlap rules, and a volume moving average. Stop loss is derived from ATR multipliers with target exits set via fixed risk-to-reward ratios. Features include partial take-profit scaling, post-trade bar cooldowns, session time windows, compounding account risk, and daily drawdown protection. The strategy draws directly on the price chart.

Details

Published by

jzd101 on GitHub

Type

Strategy, Pine Script v6

Draws

On the price chart

Category

Trend, Volatility & bands, Breakout

Markets

Gold

Timeframes

M15-H1

Risk Notes

  • The strategy can add several entries in the same direction

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Risk % per Tradefloat1.0inpRiskPct
Risk:Reward Ratiofloat2.0inpRR
ATR Multiplier (SL)float2.0inpATRMult
Max Concurrent Tradesint1inpMaxTrades
Use Compounding RiskbooltrueinpCompound
Fixed Balance (when compounding off)float10000.0inpFixedBal
Daily Loss Limit %float1.0inpDailyLoss
Enable Partial TPbooltrueinpUsePartialTP
Partial TP at RRfloat1.6inpPartialTPAtRR
Close % at Partial TPfloat50.0inpPartialTPPct
Use EMA Trend FilterbooltrueinpUseEMA
EMA Periodint200inpEMAPeriod
Show all 25 settings
SettingTypeDefaultVariable
Block Entry if Candle Overlaps EMAboolfalseinpUseEMABodyFilter
Bollinger Bands Periodint15inpBBPeriod
Bollinger Bands Deviationfloat1.5inpBBDev
ATR Periodint18inpATRPeriod
Use Volume FilterbooltrueinpUseVol
Volume MA Periodint15inpVolPeriod
Enable Cooldown BarsbooltrueinpUseCooldown
Cooldown Barsint6inpCooldownBars
Enable Time FilterbooltrueinpUseTimeFilter
Start Hour (0-23)int12inpStartHour
End Hour (0-23)int18inpEndHour
Weekend Close (Friday)boolfalseinpWeekendCl
Friday Close Time (HHMM)string2345inpFridayTime
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.

Similar Pine Scripts

257 stars

This strategy plots VWMA-based Bollinger bands on the 1-minute ES futures price chart for volatility analysis and potential breakout identification. It calculates dynamic long and short stop loss and take profit levels using percentage inputs relative to entry

Strategy v6 Volatility & bandsSupport & resistance
Updated 6 weeks ago · None stated GitHub repository of V1.6 ES - Futures 1M No Repaint
106 stars

This strategy runs on the price chart and enters long when a fast simple moving average crosses above a slow one, and short on the opposite cross, while closing the other side. Entries also need ATR above a filter, a pullback check, a minimum candle-body chang

Strategy v5 TrendMoving averages
Updated 2 years ago · GPL-3.0 GitHub repository of 9:22 5 MIN 15 MIN BANKNIFTY

均线突破交易系统

by tangly1024
76 stars

This strategy trades long breakouts of a fast and a slow moving average on the price chart. It opens a long position when price crosses above either average, using a percentage of equity as size. It reduces the position by a set share when the high reaches the

Strategy v5 TrendMoving averages
Updated 4 months ago · None stated GitHub repository of 均线突破交易系统
16 stars

This trend-following strategy adapts classic Donchian breakout channels according to market volatility regimes. It calculates an ATR percentile rank across a rolling lookback period, shifting dynamically between tighter breakout channels with smaller stops dur

Strategy v6 TrendBreakout
Updated 11 months ago · None stated GitHub repository of Seykota Alt 1: Adaptive Volatility

This strategy executes breakout trades using two Donchian Channels alongside an optional 200-period EMA trend filter. Entries trigger when the price sets a new highest high or lowest low over the primary Donchian Channel period. Exits are managed via a shorter

Strategy v5 BreakoutTrend
Updated 1 year ago · None stated GitHub repository of Ruckard Walcrypto DoubleDonchian B002

Breakout Strategy

by JoelPasapera
11 stars

This strategy implements a channel breakout system directly on the main price chart. It calculates highest highs and lowest lows over configurable entry and exit periods using historical candles. A long entry triggers when the close breaks above the entry chan

Strategy v6 BreakoutTrend
Updated 5 months ago · Apache-2.0 GitHub repository of Breakout Strategy

More strategys

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers