What it does
An inside bar is a candle whose whole range sits inside the previous candle, the "mother bar". It shows a pause where neither side pushed price beyond the prior candle. This indicator finds those setups, boxes the mother bar's range and signals when price closes beyond it. Setups that do not break out within a set number of bars expire.
How it works
- On each closed candle the script checks whether its high is below the previous high and its low is above the previous low.
- The mother bar must have a range of at least the set multiple of ATR (14), so tiny candles do not create setups.
- The mother bar's high and low become the setup levels, and a box is drawn across them. With "keep the first mother bar" on, further inside bars do not reset the setup.
- Bullish breakout: a closed candle finishes above the mother high (or trades above it, in wick mode). Bearish breakout: a close below the mother low. The box turns green or red and the setup ends.
- If neither happens within the expiry window, the box turns grey and the setup is cancelled.
The mother high and low are also plotted as lines while a setup is active.
How to use it
- Inside bars on H4 and daily charts tend to be more meaningful than on low timeframes, where they appear constantly.
- Breakouts in the direction of the higher-timeframe trend are the classic approach. A trend filter such as a 50 or 200 EMA, explained in our moving averages lesson, can help.
- A common reference stop is the opposite side of the mother bar. Because the mother bar defines the risk, check the size with the Position Size Calculator before you act.
- Wick mode signals earlier but is more prone to false breaks. Close mode waits for confirmation.
Alerts: new inside-bar setup, breakout up, breakout down.
Settings
| Input | Default | What it changes |
|---|---|---|
| Mother bar: min range (x ATR) | 0.8 | Minimum size of the mother candle |
| ATR length | 14 | ATR used by the filter |
| Keep the first mother bar when inside bars stack | On | Nested inside-bar handling |
| Setup expires after (bars) | 5 | Lifetime of a setup |
| Breakout confirmed by | Close | Close or wick |
| Box the mother-bar range | On | Setup boxes |
| Max boxes kept | 50 | Number of boxes on the chart |
Limitations
Inside-bar breakouts often fail: price closes beyond the mother bar and then reverses. Around news, a single candle can trade through both sides of the mother bar; in wick mode only the bullish break is then reported. The setup ignores where on the chart it forms, so an inside bar in the middle of a range is treated the same as one at a key level. Signals appear only after the breaking candle closes.
Pine Script source
In TradingView open Pine Editor, paste the code, click Save and then Add to chart.
FXP_InsideBarBreakout.pine
94 lines
// © FXPIPS ONLINE — https://fxpips.online/tradingview-indicators/inside-bar-breakout/
// License: MIT. Educational tool — not financial advice. Trading involves substantial risk.
//@version=6
// Marks inside-bar setups (a candle completely inside the previous "mother" candle),
// boxes the mother-bar range and signals the first close beyond it. Setups expire after
// a set number of bars. Everything is evaluated on closed candles.
indicator("FXP Inside Bar Breakout", shorttitle = "FXP Inside Bar", overlay = true, max_boxes_count = 500)
// ── Inputs ─────────────────────────────────────────────────────────────
grpS = "Setup"
minMother = input.float(0.8, "Mother bar: min range (x ATR)", minval = 0.0, step = 0.1, group = grpS, tooltip = "Skip setups whose mother candle is small relative to ATR. 0 = off.")
atrLen = input.int(14, "ATR length", minval = 1, group = grpS)
keepMother = input.bool(true, "Keep the first mother bar when inside bars stack", group = grpS)
expiryBars = input.int(5, "Setup expires after (bars)", minval = 1, maxval = 50, group = grpS)
breakSrc = input.string("Close", "Breakout confirmed by", options = ["Close", "Wick"], group = grpS)
grpD = "Display"
showBox = input.bool(true, "Box the mother-bar range", group = grpD)
maxBoxes = input.int(50, "Max boxes kept", minval = 1, maxval = 400, group = grpD)
colSetup = input.color(color.new(#2962ff, 85), "Active setup", group = grpD)
colDone = input.color(color.new(color.gray, 90), "Finished setup", group = grpD)
colBull = input.color(#26a69a, "Bullish breakout", group = grpD)
colBear = input.color(#ef5350, "Bearish breakout", group = grpD)
// ── State ──────────────────────────────────────────────────────────────
float atr = ta.atr(atrLen)
var bool active = false
var float motherHi = na
var float motherLo = na
var int setupBar = na
var box setupBox = na
var array<box> boxes = array.new<box>()
bool conf = barstate.isconfirmed
finishBox(color c) =>
if not na(setupBox)
setupBox.set_right(bar_index)
setupBox.set_bgcolor(c)
true
// ── Breakout of an active setup ────────────────────────────────────────
float upSrc = breakSrc == "Wick" ? high : close
float dnSrc = breakSrc == "Wick" ? low : close
bool bullBreak = conf and active and upSrc > motherHi
bool bearBreak = conf and active and not bullBreak and dnSrc < motherLo
bool expired = conf and active and not bullBreak and not bearBreak and bar_index - setupBar >= expiryBars
if bullBreak
finishBox(color.new(colBull, 85))
active := false
else if bearBreak
finishBox(color.new(colBear, 85))
active := false
else if expired
finishBox(colDone)
active := false
else if active and not na(setupBox)
setupBox.set_right(bar_index)
// ── New inside bar ─────────────────────────────────────────────────────
bool isInside = high < high[1] and low > low[1]
bool motherOk = (high[1] - low[1]) >= minMother * nz(atr[1])
bool newSetup = conf and isInside and motherOk and not (active and keepMother)
if newSetup
if active
finishBox(colDone)
active := true
motherHi := high[1]
motherLo := low[1]
setupBar := bar_index
if showBox
setupBox := box.new(bar_index - 1, high[1], bar_index, low[1], border_color = color.new(#2962ff, 50), bgcolor = colSetup)
boxes.push(setupBox)
while boxes.size() > maxBoxes
box.delete(boxes.shift())
else
setupBox := na
// ── Markers ────────────────────────────────────────────────────────────
plotshape(newSetup, "Inside bar setup", shape.circle, location.abovebar, color.new(#2962ff, 0), size = size.tiny)
plotshape(bullBreak, "Bullish breakout", shape.triangleup, location.belowbar, colBull, size = size.small)
plotshape(bearBreak, "Bearish breakout", shape.triangledown, location.abovebar, colBear, size = size.small)
plot(active ? motherHi : na, "Mother high", color = color.new(colBull, 40), style = plot.style_linebr)
plot(active ? motherLo : na, "Mother low", color = color.new(colBear, 40), style = plot.style_linebr)
// ── Alerts ─────────────────────────────────────────────────────────────
alertcondition(newSetup, "Inside bar setup", "{{ticker}} {{interval}}: new inside bar setup")
alertcondition(bullBreak, "Inside bar breakout up", "{{ticker}} {{interval}}: broke above the mother bar at {{close}}")
alertcondition(bearBreak, "Inside bar breakout down", "{{ticker}} {{interval}}: broke below the mother bar at {{close}}")

