Strategy · Pine Script v6 · On the chart

NQ NY Session OPR Breakout Strategy

by jcornierfra· code credited to Breizhoo

This strategy identifies an Opening Price Range during a specified time window and trades breakouts above or below the established range during the New York trading session.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code425
Settings22inputs
LicenceNone statedfile: MPL-2.0
Last update11 days ago17 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

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

Strategy_OPR_Breakout.pine
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Breizhoo
// Version: 1.0.0
// GitHub: https://github.com/jcornierfra/TradingView_Strategy_JCO_OPR_Breakout

//@version=6
strategy("Breakout NQ, NY Session with RSI extreme, EMA optionnelle, Swing SL, R:R commun/séparé, with parameters", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=10, max_lines_count=500, max_boxes_count=500)

// ============================
// 🔧 Paramètres horaires & fuseau (HH:MM) avec info-bulles
// ============================
groupSess = "Paramètres horaires & fuseau"

// Range Start
rsH = input.int(15, "Range Start HH", minval=0, maxval=23, group=groupSess, inline="rs", tooltip="Heure (HH) de la bougie de référence pour définir le range. Interprétée dans le fuseau sélectionné ci-dessous.")
rsM = input.int(30, "MM",             minval=0, maxval=59, group=groupSess, inline="rs", tooltip="Minutes (MM) de la bougie de référence pour définir le range.")

// ⏱️ Durée du range (en minutes) — même valeur pour High & Low
rangeMinutes = input.int(5, "Range Duration (min)", minval=1, maxval=240, group=groupSess, tooltip="Durée du range en minutes à partir de Range Start. Le plus haut et le plus bas sont accumulés pendant cette fenêtre.")

// Trade Open / Stop / Close
tradeOH = input.int(15, "Trade Open HH", minval=0, maxval=23, group=groupSess, inline="to", tooltip="Heure (HH) d'ouverture de la fenêtre d'entrées.")
tradeOM = input.int(35, "MM",            minval=0, maxval=59, group=groupSess, inline="to", tooltip="Minutes (MM) d'ouverture de la fenêtre d'entrées.")
tradeSH = input.int(16, "Trade Stop HH", minval=0, maxval=23, group=groupSess, inline="ts", tooltip="Heure (HH) de fin de la fenêtre d'entrées.")
tradeSM = input.int(30, "MM",            minval=0, maxval=59, group=groupSess, inline="ts", tooltip="Minutes (MM) de fin de la fenêtre d'entrées.")
tradeCH = input.int(19, "Trade Close HH", minval=0, maxval=23, group=groupSess, inline="tc", tooltip="Heure (HH) de clôture forcée des positions.")
tradeCM = input.int(30, "MM",             minval=0, maxval=59, group=groupSess, inline="tc", tooltip="Minutes (MM) de la clôture forcée.")

// Fuseau horaire (au choix)
tzInput = input.string(defval="Europe/Paris", title="Fuseau horaire", options=["Europe/Paris", "Exchange (syminfo.timezone)", "UTC", "America/New_York", "America/Chicago", "Europe/London", "Asia/Tokyo", "Asia/Hong_Kong", "Australia/Sydney"], group=groupSess, tooltip="Sélectionne le fuseau pour interpréter toutes les heures ci-dessus. Europe/Paris : 15:30 = ouverture NY (été). Exchange (syminfo.timezone) : fuseau de l'instrument (ex: CME = America/Chicago).")
tz = tzInput == "Exchange (syminfo.timezone)" ? syminfo.timezone : tzInput

// ============================
// 🎛️ Paramètres d'affichage / rétention
// ============================
groupVis = "Affichage"
showRangeBox = input.bool(true, "Afficher la box du range", group=groupVis, tooltip="Affiche une box grise semi-transparente couvrant la fenêtre du range (du début jusqu'à la fin).")
maxSessions = input.int(60, "Nombre de sessions à conserver", minval=1, maxval=1000, group=groupVis, tooltip="Garde uniquement les N dernières sessions (lignes & boxes). Les plus anciennes sont supprimées automatiquement.")

// ============================
// 🕒 Horaires de trading (pour la fenêtre d'entrées)
// ============================
tradeOpen  = timestamp(tz, year, month, dayofmonth, tradeOH, tradeOM)
tradeStop  = timestamp(tz, year, month, dayofmonth, tradeSH, tradeSM)
tradeClose = timestamp(tz, year, month, dayofmonth, tradeCH, tradeCM)

// ============================
// 🧭 Fenêtre de RANGE avec session (robuste fuseau)
// ============================
pad2(x) => x < 10 ? "0" + str.tostring(x) : str.tostring(x)
_endTotal = rsH * 60 + rsM + rangeMinutes
endH = math.floor(_endTotal / 60) % 24
endM = _endTotal % 60
startStr = pad2(rsH) + pad2(rsM)
endStr   = pad2(endH) + pad2(endM)
rangeSess = startStr + "-" + endStr + ":1234567"

tRange = time(timeframe.period, rangeSess, tz)
inRangeWindow     = not na(tRange)
isFirstBarInRange = inRangeWindow and not inRangeWindow[1]
justAfterRange    = (not inRangeWindow) and inRangeWindow[1]

// ============================
// 📈 Accumulation du range pendant la fenêtre
// ============================
var float rangeHighRef = na
var float rangeLowRef  = na
var bool  rangeReady   = false

if isFirstBarInRange
    rangeHighRef := na
    rangeLowRef  := na
    rangeReady   := false
    // ⚑ Conserver l'étiquette de début de range (couleur actuelle)
    label.new(x=bar_index, y=high, text="📍 Début Range", style=label.style_label_down, color=color.yellow, textcolor=color.black)

if inRangeWindow
    rangeHighRef := na(rangeHighRef) ? high : math.max(rangeHighRef, high)
    rangeLowRef  := na(rangeLowRef)  ? low  : math.min(rangeLowRef,  low)

if justAfterRange
    rangeReady := true
// ============================
// 🧱 Box visuelle du range (historique, 1 par jour)
// ============================
var array<box> rangeBoxes = array.new_box()
var box curRangeBox = na

// Masquage
if not showRangeBox
    if not na(curRangeBox)
        box.delete(curRangeBox)
        curRangeBox := na
    sz = array.size(rangeBoxes)
    if sz > 0
        for i = 0 to sz - 1
            bx = array.get(rangeBoxes, i)
            if not na(bx)
                box.delete(bx)
        array.clear(rangeBoxes)

// Création au premier bar de la fenêtre de range
if showRangeBox and isFirstBarInRange
    if not na(curRangeBox)
        box.delete(curRangeBox)
    _top = na(rangeHighRef) ? high : rangeHighRef
    _bot = na(rangeLowRef)  ? low  : rangeLowRef
    curRangeBox := box.new(left = bar_index, top = _top, right = bar_index, bottom = _bot, border_color = color.new(color.gray, 20), bgcolor = color.new(color.gray, 85), xloc = xloc.bar_index)

// Pendant la fenêtre de range
if showRangeBox and not na(curRangeBox) and inRangeWindow
    _top = na(rangeHighRef) ? high : rangeHighRef
    _bot = na(rangeLowRef)  ? low  : rangeLowRef
    box.set_right(curRangeBox, bar_index)
    box.set_top(curRangeBox, _top)
    box.set_bottom(curRangeBox, _bot)

// Fin du range : fige, archive, purge
if showRangeBox and not na(curRangeBox) and justAfterRange
    box.set_right(curRangeBox, bar_index)
    box.set_top(curRangeBox, rangeHighRef)
    box.set_bottom(curRangeBox, rangeLowRef)
    array.push(rangeBoxes, curRangeBox)
    while array.size(rangeBoxes) > maxSessions
        oldBx = array.shift(rangeBoxes)
        if not na(oldBx)
            box.delete(oldBx)
    curRangeBox := na

// ============================
// 🕘 Session active (fenêtre d'entrées)
// ============================
isSession = (time >= tradeOpen and time <= tradeStop)
isSessionStart =  isSession and not isSession[1]
isSessionEnd   = (not isSession) and isSession[1]

// Indices & lignes pour alignement Trade Open → Trade Stop
var int  tradeStartIdx = na
var int  tradeStopIdx  = na
var line hiLine = na
var line loLine = na

// 🗃️ Arrays pour conserver les lignes par session (pour purge)
var array<line> hiLinesArr = array.new_line()
var array<line> loLinesArr = array.new_line()

// Début de session
if isSessionStart
    tradeStartIdx := bar_index
    tradeStopIdx  := na
    hiLine := na
    loLine := na

if isSessionEnd
    tradeStopIdx := bar_index
    if not na(hiLine) and not na(loLine)
        array.push(hiLinesArr, hiLine)
        array.push(loLinesArr, loLine)
        while array.size(hiLinesArr) > maxSessions
            oldHi = array.shift(hiLinesArr)
            if not na(oldHi)
                line.delete(oldHi)
        while array.size(loLinesArr) > maxSessions
            oldLo = array.shift(loLinesArr)
            if not na(oldLo)
                line.delete(oldLo)

// ============================
// 📊 RSI / EMA / Règle 1 trade par jour
// ============================
groupRSI = "Filtre RSI"

useRSIFilter = input.bool(true, "Activer le filtre RSI", group=groupRSI)
rsiOverbought = input.int(70, "Seuil surachat", minval=50, maxval=100, group=groupRSI)
rsiOversold = input.int(30, "Seuil survente", minval=0, maxval=50, group=groupRSI)

rsiMode = input.string("RSI en dehors du range", "Mode d'application", options=["Aucun filtre", "RSI en dehors du range", "RSI dans le range"], group=groupRSI)

rsi = ta.rsi(close, 14)

rsiOkBuy = switch rsiMode
    "Aucun filtre" => true
    "RSI en dehors du range" => rsi >= rsiOverbought
    "RSI dans le range" => rsi > rsiOversold and rsi < rsiOverbought
    => true

rsiOkSell = switch rsiMode
    "Aucun filtre" => true
    "RSI en dehors du range" => rsi <= rsiOversold
    "RSI dans le range" => rsi > rsiOversold and rsi < rsiOverbought
    => true

// ============================
// 🟠 ➕ Paramètres EMA (optionnels)
// ============================
groupEMA = "Filtre EMA"
useEMA  = input.bool(false, "Activer le filtre EMA ?", group=groupEMA, tooltip="Si désactivé, le filtre EMA est ignoré dans les entrées.")
emaLen  = input.int(50, "Période EMA", minval=1, group=groupEMA)

emaSeries = ta.ema(close, emaLen)

emaOkBuy  = useEMA ? (open > emaSeries and close > emaSeries and low > emaSeries)   : true
emaOkSell = useEMA ? (open < emaSeries and close < emaSeries and high < emaSeries) : true

plot(emaSeries, title="EMA", color=color.new(color.blue, useEMA ? 0 : 100), linewidth=1)

// ============================
// 🔁 Règle 1 trade par jour
// ============================
var bool tradedToday = false
if dayofmonth != dayofmonth[1]
    // ⚠️ filet de sécurité : si des SL/TP courants n'ont pas été archivés, on fige à la dernière barre d'hier
    // (implémenté plus bas via finalize si besoin)
    tradedToday  := false
    tradeStartIdx := na
    tradeStopIdx  := na

// ============================
// 🔎 Swings
// ============================
findLastSwingLow() =>
    var float swingLow = na
    for i = 1 to 20
        if low[i] < low[i-1] and low[i] < low[i+1]
            swingLow := low[i]
            break
    swingLow
findLastSwingHigh() =>
    var float swingHigh = na
    for i = 1 to 20
        if high[i] > high[i-1] and high[i] > high[i+1]
            swingHigh := high[i]
            break
    swingHigh

// ============================
// ⚙️ Paramètres du trade
// ============================
groupTrade = "Paramètres du trade"
tick = syminfo.mintick
pip = tick * 10
slBuffer = 1 * pip

// —— R:R commun ou séparé
rrSeparate = input.bool(false, "Utiliser R:R séparé (Long/Short) ?", group=groupTrade, tooltip="Active des R:R distincts pour les positions longues et courtes.")
rrCommon   = input.float(1.5, "R:R commun", minval=0.1, step=0.1, group=groupTrade, tooltip="Risk:Reward utilisé si l'option séparée est désactivée.")
rrLongInp  = input.float(1.5, "R:R Long",  minval=0.1, step=0.1, group=groupTrade, tooltip="Risk:Reward pour les positions longues (utilisé si option séparée activée).")
rrShortInp = input.float(1.5, "R:R Short", minval=0.1, step=0.1, group=groupTrade, tooltip="Risk:Reward pour les positions courtes (utilisé si option séparée activée).")

rrLong  = rrSeparate ? rrLongInp  : rrCommon
rrShort = rrSeparate ? rrShortInp : rrCommon

// ============================
// 🚀 Cassure du range (après rangeReady)
// ============================
breakHigh = rangeReady and isSession and (not useRSIFilter or rsiOkBuy)  and emaOkBuy  and not tradedToday and close > rangeHighRef
breakLow  = rangeReady and isSession and (not useRSIFilter or rsiOkSell) and emaOkSell and not tradedToday and close < rangeLowRef

// =====================================================================
// 🔴 SL/TP persistants — DÉBUT (entre entrée du trade et tradeClose + historique)
// =====================================================================
var line slLine = na
var line tpLine = na
var array<line> slHistory = array.new_line()
var array<line> tpHistory = array.new_line()
var int entryIdx = na
var int tradeCloseIdx = na

// Détection du passage à l'heure de tradeClose (barre exacte)
tradeCloseCross = (time >= tradeClose) and (time[1] < tradeClose)

// Quand l'heure tradeClose est atteinte : fige x2, archive et purge
if tradeCloseCross
    tradeCloseIdx := bar_index
    if not na(slLine)
        line.set_x2(slLine, tradeCloseIdx)
    if not na(tpLine)
        line.set_x2(tpLine, tradeCloseIdx)

    // Archive si les deux lignes existent
    if not na(slLine) and not na(tpLine)
        array.push(slHistory, slLine)
        array.push(tpHistory, tpLine)
        // Purge selon maxSessions
        while array.size(slHistory) > maxSessions
            oldSL = array.shift(slHistory)
            if not na(oldSL)
                line.delete(oldSL)
        while array.size(tpHistory) > maxSessions
            oldTP = array.shift(tpHistory)
            if not na(oldTP)
                line.delete(oldTP)

    // Réinitialisation pour la prochaine journée
    slLine := na
    tpLine := na
    entryIdx := na
    tradeCloseIdx := na

// Filet de sécurité : au premier bar d'un nouveau jour, si des lignes subsistent non archivées
newDay = dayofmonth != dayofmonth[1]
if newDay and (not na(slLine) or not na(tpLine))
    // fige sur la dernière barre d'hier
    tradeCloseIdx := bar_index[1]
    if not na(slLine)
        line.set_x2(slLine, tradeCloseIdx)
    if not na(tpLine)
        line.set_x2(tpLine, tradeCloseIdx)

    if not na(slLine) and not na(tpLine)
        array.push(slHistory, slLine)
        array.push(tpHistory, tpLine)
        while array.size(slHistory) > maxSessions
            oldSL = array.shift(slHistory)
            if not na(oldSL)
                line.delete(oldSL)
        while array.size(tpHistory) > maxSessions
            oldTP = array.shift(tpHistory)
            if not na(oldTP)
                line.delete(oldTP)

    slLine := na
    tpLine := na
    entryIdx := na
    tradeCloseIdx := na

// Pendant la vie du trade (avant tradeClose), prolonge x2 au fil des barres
if not na(slLine) and na(tradeCloseIdx)
    line.set_x2(slLine, bar_index)
if not na(tpLine) and na(tradeCloseIdx)
    line.set_x2(tpLine, bar_index)
// =====================================================================
// 🔴 SL/TP persistants — FIN
// =====================================================================

sl = 0.0
op = 0.0
// ============================
// 🟢 Achat
// ============================
if breakHigh and strategy.position_size == 0
    swingLow = findLastSwingLow()
    sl := swingLow - slBuffer
    sl := sl < rangeLowRef ? rangeLowRef : sl
    tp = close + rrLong * (close - sl)
    op := close-(10*tick)
    strategy.entry(id="Buy", direction=strategy.long, limit=op)
    strategy.exit("TP/SL Buy", from_entry="Buy", stop=sl, limit=tp)
    tradedToday := true

    // --- REMPLACE les anciennes lignes SL/TP (+50) par :
    entryIdx := bar_index
    // S'assure d'effacer d'éventuels restes (sécurité)
    if not na(slLine)
        line.delete(slLine)
    if not na(tpLine)
        line.delete(tpLine)
    tradeCloseIdx := na
    slLine := line.new(x1=entryIdx, y1=sl, x2=bar_index, y2=sl, color=color.red,   width=1, xloc=xloc.bar_index, extend=extend.none)
    tpLine := line.new(x1=entryIdx, y1=tp, x2=bar_index, y2=tp, color=color.green, width=1, xloc=xloc.bar_index, extend=extend.none)

// ============================
// 🔴 Vente
// ============================
if breakLow and strategy.position_size == 0
    swingHigh = findLastSwingHigh()
    sl := swingHigh + slBuffer
    sl := sl > rangeHighRef ? rangeHighRef : sl
    tp = close - rrShort * (sl - close)
    op := close+(10*tick)
    strategy.entry(id="Sell", direction=strategy.short, limit=op)
    strategy.exit("TP/SL Sell", from_entry="Sell", stop=sl, limit=tp)
    tradedToday := true

    // --- REMPLACE les anciennes lignes SL/TP (+50) par :
    entryIdx := bar_index
    if not na(slLine)
        line.delete(slLine)
    if not na(tpLine)
        line.delete(tpLine)
    tradeCloseIdx := na
    slLine := line.new(x1=entryIdx, y1=sl, x2=bar_index, y2=sl, color=color.red,   width=1, xloc=xloc.bar_index, extend=extend.none)
    tpLine := line.new(x1=entryIdx, y1=tp, x2=bar_index, y2=tp, color=color.green, width=1, xloc=xloc.bar_index, extend=extend.none)

// ============================
// ⏱️ Trailing SL
// ============================
//if strategy.position_size != 0
//    if strategy.position_size > 0 and close > close + (close - sl)
//        strategy.order(id="Buy", direction=strategy.long, stop=op + ((close - sl) * 0.5), comment=("SL update"))
//    if strategy.position_size < 0 and close < close - (sl - close)
//        strategy.order(id="Sell", direction=strategy.short, stop=op - ((sl - close) * 0.5), comment=("SL update"))

// ============================
// ⏱️ Clôture forcée
// ============================
if (time >= tradeClose) and strategy.position_size != 0
    strategy.close_all(comment="Clôture forcée")

// ============================
// 📏 Lignes alignées sur Trade Open → Trade Stop
// ============================
canCreateLines = rangeReady and not na(tradeStartIdx)
if canCreateLines and na(hiLine)
    hiLine := line.new(x1=tradeStartIdx, y1=rangeHighRef, x2=bar_index, y2=rangeHighRef, color=color.blue, width=1, xloc=xloc.bar_index, extend=extend.none)
if canCreateLines and na(loLine)
    loLine := line.new(x1=tradeStartIdx, y1=rangeLowRef,  x2=bar_index, y2=rangeLowRef,  color=color.blue,   width=1, xloc=xloc.bar_index, extend=extend.none)

if isSession
    if not na(hiLine)
        line.set_x1(hiLine, tradeStartIdx)
        line.set_x2(hiLine, bar_index)
        line.set_y1(hiLine, rangeHighRef)
        line.set_y2(hiLine, rangeHighRef)
    if not na(loLine)
        line.set_x1(loLine, tradeStartIdx)
        line.set_x2(loLine, bar_index)
        line.set_y1(loLine, rangeLowRef)
        line.set_y2(loLine, rangeLowRef)

if isSessionEnd and not na(tradeStopIdx)
    if not na(hiLine)
        line.set_x2(hiLine, tradeStopIdx)
    if not na(loLine)
        line.set_x2(loLine, tradeStopIdx)

Overview

Entries can be filtered using optional RSI extremes and EMA trend direction, restricted to a maximum of one trade per session. Stop losses are placed dynamically using recent swing high or low levels, with profit targets set by a configurable risk-to-reward ratio. All open positions are automatically closed at a defined end time. Range boxes and levels are plotted directly on the price chart.

Details

Published by

jcornierfra on GitHub

Code credit

Breizhoo, as written in the script's header

Type

Strategy, Pine Script v6

Draws

On the price chart

Category

Breakout, Sessions & time, Support & resistance, Trend

Markets

Indices

Timeframes

M1-M5, M15-H1

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Topics

algorithmic-tradingnasdaqpine-scripttrading-strategytradingview

Settings

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

SettingTypeDefaultVariable
Range Start HHint15rsH
MMint30rsM
Range Duration (min)int5rangeMinutes
Trade Open HHint15tradeOH
MMint35tradeOM
Trade Stop HHint16tradeSH
MMint30tradeSM
Trade Close HHint19tradeCH
MMint30tradeCM
Fuseau horairestringEurope/ParistzInput
Afficher la box du rangebooltrueshowRangeBox
Nombre de sessions à conserverint60maxSessions
Show all 22 settings
SettingTypeDefaultVariable
Activer le filtre RSIbooltrueuseRSIFilter
Seuil surachatint70rsiOverbought
Seuil surventeint30rsiOversold
Mode d'applicationstringRSI en dehors du rangersiMode
Activer le filtre EMA ?boolfalseuseEMA
Période EMAint50emaLen
Utiliser R:R séparé (Long/Short) ?boolfalserrSeparate
R:R communfloat1.5rrCommon
R:R Longfloat1.5rrLongInp
R:R Shortfloat1.5rrShortInp
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

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

Strategy v6 BreakoutTrend
Updated today · AGPL-3.0 GitHub repository of Forven S01509 - Simple Donchian 20/10 Breakout
257 stars

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

Strategy v6 TrendMoving averages Repaints
Updated 6 weeks ago · None stated GitHub repository of Best Chart 1m Strategy Candle Bar
106 stars

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

Strategy v4 Screeners & dashboardsBreakout Repaints
Updated 2 years ago · GPL-3.0 GitHub repository of 1St Bar GAP+BkOut Screener v2 by RM
53 stars

This strategy enters long or short on the price chart when price is on the correct side of a 200-period EMA, MACD agrees, RSI is not at the opposing extreme, ADX exceeds a threshold, volume beats a 20-bar average, and close breaks the recent high or low. A tim

Strategy v6 TrendOscillators & momentum
Updated 2 months ago · MPL-2.0 GitHub repository of BTCUSD 5M Optimized Strategy

ATOM 1m scalp HK

by dearvn
43 stars

This overlay strategy targets one-minute ATOM scalps. It tracks pivot highs and lows as resistance and support, compares a three-period EMA with a multi-stage smoothed close, and flags long or short when price crosses that curve in the matching direction. Dail

Strategy v5 ScalpingSupport & resistance Repaints
Updated 2 years ago · None stated GitHub repository of ATOM 1m scalp HK

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