Indicator · Pine Script v5 · On the chart

Barbwire v2.0.0

by itmakesyousick· code credited to boitoki

Finds barbwire zones, runs of bars with small bodies or ranges, and draws boxes around them on the price chart.

View on GitHub

GitHub stars1on the repository
Pine versionv5runs as is
Lines of code419
Settings18inputs
LicenceNone statedfile: MPL-2.0
Last update4 years ago9 Jul 2022

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 indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

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

2.0.0.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © boitoki

//@version=5
indicator("Barbwire", overlay=true, precision=2, max_boxes_count=300, max_lines_count=500)

import boitoki/AwesomeColor/5 as ac
import boitoki/ma_function/3 as ma
import boitoki/RCI/4 as rci_func

[hopen, hclose] = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, [open, close])

////////////
// DEFINE //

GP3                 = 'MOMENTUM'
option_source1      = 'Open-Close Heikin-Ashi'
option_source4      = 'Open-Close'
option_source2      = 'High-Low'
option_source3      = 'Hybrid'

//////////////
// FUNCTION //

//
oc2 (_open, _close) => math.avg(math.max(_open, _close), math.min(_open, _close))

//
hoc2 () => math.avg(math.max(hopen, hclose), math.min(hopen, hclose))

//
f_HR (_open, _close) =>  math.abs(_open - _close)

//
f_get_data (_source, _len) =>
    data = array.new<float>()

    for i = 1 to _len
        array.push(data, _source[i])
    
    data

f_remove_boxes (_arr, _max) =>
    if array.size(_arr) > _max
        for i = _max to array.size(_arr)
            box.delete(array.shift(_arr))

//
f_renderBox (_start, _processing, _end, _min, _border_width, _border_color, _bgcolor, _drawing_max, _show) =>
    if _show
        var box barb_box    = na
        var label txt       = na
        var line top        = na
        var line bot        = na
        var float y1        = na
        var float y2        = na
        var int x1          = na
        line_style = line.style_dotted
        var boxes = array.new<box>()
    
        if _start
            x1 := bar_index
            y1 := high
            y2 := low
            barb_box := box.new(x1, y1, x1, y2, _border_color, _border_width, line.style_solid, bgcolor=_bgcolor)
            txt := label.new(x1, y1, '•', color=color.new(_border_color, 5), textcolor=ac.panda('verydarkgray'), size=size.tiny)
    
        if _processing
            y1 := math.max(y1, high)
            y2 := math.min(y2, low)
            box.set_top(barb_box, y1)
            box.set_bottom(barb_box, y2)
            box.set_right(barb_box, bar_index)
            label.set_y(txt, y1)
            label.set_text(txt, '•••')
        
        if _end
            box.set_right(barb_box, bar_index-1)
            label.delete(txt)
    
            width = math.abs(box.get_right(barb_box) - box.get_left(barb_box))
    
            if width < _min
                box.delete(barb_box)
            else
                array.push(boxes, barb_box)
                
                f_remove_boxes(boxes, _drawing_max)
    
            y1 := na, y2 := na

//
//
f_dir_by_roc (_src, _len) =>
    roc_arr     = array.new<float>(_len)
    roc         = ta.roc(_src, 2)
    roc_moved   = math.abs(roc - roc[3])
    
    for i = 1 to _len
        array.push(roc_arr, roc_moved[i])

    min_roc_value   = array.min(roc_arr)
    min_roc_value  := array.stdev(roc_arr) * 3.0
    
    roc_moved <= min_roc_value

// 
f_barb_roc (_len) =>
    height = math.max(hopen, hclose) - math.min(hopen, hclose)
    roc = ta.roc(height, _len)
    
    roc <= 0

//
f_barb_stoch (_source, _len, _lv) =>
    v = ta.sma(ta.stoch(_source, _source, _source, _len), 1)
    v <= _lv

//
f_barb_rank (_source, _len, _sens) =>
    arr = array.new<float>(_len)
    new_arr = array.new<float>()

    for i = 1 to _len
        array.push(arr, _source[i])

    min_value = array.min(arr)
    min_value := array.percentile_nearest_rank(arr, _sens)
    min_value := math.max(min_value, syminfo.mintick * 2)

    in_barb = _source <= (min_value)

    in_barb

f_le (_v, _std, _malt) => _v <= _std * _malt
f_ge (_v, _std, _malt) => _v >= _std * _malt
f_id (_v, _arr) => array.indexof(_arr, array.min(_arr)) < _v

////////////
// INPUTS //

i_source_type       = input.string(option_source1, 'Source', options=[option_source1, option_source2, option_source3, option_source4])
i_len               = input.int(50, 'Length')
i_min               = input.int(3, 'Num. of minimum bars', minval=0)

// LOGIC
i_barb_type         = input.string('Rank', 'Calculated by', options=['Rank', 'Stochastic', 'Stdev', 'ROC'])
i_sensitivity       = input.int(20, '• Nearest rank %', minval=1, maxval=100)
i_stoch_len         = input.int(14, '• Stochastic length', minval=1, maxval=100)
i_filter_roc        = input.bool(false, "Directional Exclusion by ROC", group='Filter')
i_filter_stdev5     = true // input.bool(true, 'Filtered ">5STDEV"', group='Filter')

// STYLE
i_show_barbwire     = input.bool(true, 'Show Barbwire', group='style')
i_border_width      = input.int(2, '', minval=0, group='style', inline='style', tooltip='Border width / color / bgcolor')
i_boxcolor          = input.color(color.new(#E6DB74, 20), '', group='style', inline='style')
i_bgcolor           = input.color(color.new(#E6DB74, 80), '', group='style', inline='style')

i_spot_minid        = input.bool(false, 'Min. ID', group='SPOT FLAGS')
i_spot_smnr         = input.bool(false, 'Sm. NR', group='SPOT FLAGS')
i_spot_lrwr         = input.bool(false, 'Lr. WR', group='SPOT FLAGS')
//i_spot_div          = input.bool(false, 'Divergence', group='SPOT FLAGS')

i_barcolor          = input.bool(true, "Bar colors", group='OPTIONS')
i_memory_cleaning   = input.bool(false, 'Memory cleaning', group='OPTIONS')
i_drawing_max       = i_memory_cleaning ? 5 : 200


emoji_light         = '⚡'
emoji_danger        = '⚠️'

HR                  = switch i_source_type
    option_source1  => f_HR(hopen, hclose)
    option_source2  => f_HR(high, low)
    option_source3  => math.avg(f_HR(hopen, hclose) * 0.5, f_HR(open, close) * 0.3, f_HR(high, low) * 0.2)
    option_source4  => f_HR(open, close)
    => f_HR(high, low)

//////////
// DATA //
data_len        = i_len //input.int(150, 'Data lookback', group='Data')

all_data        = f_get_data(HR, data_len)
all_stdev       = array.stdev(all_data)
a_data          = array.new<float>()

if i_filter_stdev5 and array.size(all_data) > 0
    for i = 0 to array.size(all_data) - 1
        my_value = array.get(all_data, i)
        if my_value < all_stdev * 5
            array.push(a_data, my_value)
else
    a_data     := array.copy(all_data)

v_std           = array.stdev(a_data)
v_avg           = array.avg(a_data)

i_stdev_xs      = 0.10
i_stdev_s       = 0.50
i_stdev_l       = 4.00
i_stdev_xl      = 5.00

is_le030        = f_le(HR, v_std, i_stdev_s)
is_le005        = f_le(HR, v_std, i_stdev_xs)
is_geL          = f_ge(HR, v_std, i_stdev_l)
is_geXL         = f_ge(HR, v_std, i_stdev_xl)


//////////
// CALC //
in_barb             = f_barb_rank(HR, i_len, i_sensitivity)
in_barb_by_roc      = f_barb_roc(16)
in_barb_by_stoch    = f_barb_stoch(HR, i_stoch_len, 20)
is_dir_by_roc       = f_dir_by_roc(hoc2(), i_len)

f_barb_type (_type) =>
    switch _type
        'rank'              => in_barb
        'stdev'             => is_le030
        'roc'               => in_barb_by_roc
        'stochastic'        => in_barb_by_stoch
        => false


///////////////////
// Conditions
///////////////////



////////////////
// CONDITIONS //

is_barb = f_barb_type(str.lower(i_barb_type))


if i_filter_roc
    is_barb := is_barb and is_dir_by_roc

barb_start  = is_barb and (not is_barb[1])
barb_end    = (not is_barb) and is_barb[1]

bar_type    = close  > open  ? 1 : -1
hbar_type   = hclose > hopen ? 1 : -1

is_flip     = bar_type != hbar_type and hbar_type != hbar_type[1]

///////////
// ALERT //

alertcondition(barb_start, "Barb wire start", "Barb wire start")
alertcondition(barb_end, "Barb wire end", "Barb wire end")

///////////////
// RENDERING //

//if barstate.isconfirmed
f_renderBox(barb_start, is_barb, barb_end, i_min, i_border_width, i_boxcolor, i_bgcolor, i_drawing_max, i_show_barbwire)

//////////////
// PLOTTING //

color bar_color = na

top = math.max(open, close)
bot = math.min(open, close)

od = high > high[1] and low < low[1]
up = top  > top[1]  and bot > low[1]
dn = top  < high[1] and bot < bot[1]

//if i_spot_lrwr
//    if is_geXL
//        bar_color := color.from_gradient(30, 0, 100, color.red, color.orange)
//    else if is_geL
//        bar_color := color.from_gradient(70, 0, 100, color.red, color.orange)
//
//

// color.rgb(8, 16, 48, 0)
// color.rgb(0, 32, 96, 0)
// color.rgb(0, 52, 146, 0)
// color.rgb(0, 90, 148, 0)
// color.rgb(0, 117, 146, 0)
// color.rgb(26, 140, 147, 0)
// color.rgb(103, 162, 155, 0)
// color.rgb(155, 183, 172, 0)
// color.rgb(182, 182, 182, 0) ---
// color.rgb(175, 174, 152, 0)
// color.rgb(167, 147, 107, 0)
// color.rgb(163, 116, 67, 0)
// color.rgb(159, 81, 44, 0)
// color.rgb(142, 47, 57, 0)
// color.rgb(111, 24, 64, 0)
// color.rgb(48, 8, 24, 0)

if i_barcolor
    if      HR <= v_std * 0.05
        bar_color := color.rgb(195, 63, 63, 0)
    else if HR < v_std * 0.08
        bar_color := color.rgb(227, 73, 19, 0)
    
    else if HR >= v_std * 5.00
        bar_color := color.rgb(0, 45, 253, 0)
    else if HR >= v_std * 4.00
        bar_color := color.rgb(164, 171, 255, 0)
    else 
        bar_color := color.rgb(182, 182, 182, 70)

    if is_flip
        bar_color := color.yellow

barcolor(i_barcolor ? bar_color : na)

color_1 = color.from_gradient(80, 0, 100, color.white, color.yellow)
color_2 = color.from_gradient(80, 0, 100, color.yellow, color.red)

plotshape(i_spot_smnr ? is_le005 ? hl2 : na : na, "Sm. NR", style=shape.circle, text="Sm. NR", color=color.new(color_1, 70), location=location.absolute, size=size.normal, textcolor=color.new(color.white, 100))
plotshape(i_spot_minid ? f_id(1, a_data) ? hl2[1] : na : na, 'Min. ID', style=shape.circle, text="Min. ID", color=color.new(color_2, 10)   , location=location.absolute, size=size.small , textcolor=color.new(color.white, 100), offset=-1)















//////////////
// ANALYSIS //

i_analysis_show = input.bool(false, 'Analysis', group='ANALYSIS')
i_analysis_asc  = input.bool(false, 'Order ascending', group='ANALYSIS')

verticalAdj     = 0.6
lookbackLength  = i_len//input.int(200, 'Length', group='ANALYSIS')
priceHighest    = ta.highest(high, lookbackLength)
priceLowest     = ta.lowest (low , lookbackLength)
priceChangeRate = (priceHighest - priceLowest) / priceHighest
oscTop          = priceLowest  * (1 - priceChangeRate * 0.2)
oscBottom       = priceLowest  * (1 - priceChangeRate * verticalAdj)
priceHighest   := priceHighest * (1 + priceChangeRate * verticalAdj)
barIndex        = 0

oscHeight        = oscTop - oscBottom
oscHighest      = array.max(a_data)

analysis_data_  = f_get_data(HR, lookbackLength)
analysis_data   = array.new<float>()
analysis_stdev  = array.stdev(analysis_data_)

if i_filter_stdev5 and array.size(analysis_data_) > 0
    for i = 0 to array.size(analysis_data_) - 1
        my_value = array.get(analysis_data_, i)
    
        if my_value < analysis_stdev * 5
            array.push(analysis_data, my_value)
else
    analysis_data := array.copy(analysis_data_)    

var a_line = array.new<line>()
var a_labels = array.new<label>()
var a_boxes = array.new<box>()

if barstate.islast and i_analysis_show and array.size(analysis_data) > 0

    if (array.size(a_line) > 0)
        for i = 0 to array.size(a_line) - 1
            line.delete(array.shift(a_line))

    if (array.size(a_boxes) > 0)
        for i = 0 to array.size(a_boxes) - 1
            box.delete(array.shift(a_boxes))
    
    if (array.size(a_labels) > 0)
        for i = 0 to array.size(a_labels) - 1
            label.delete(array.shift(a_labels))

    hightAdj = oscHeight / oscHighest

    rank        = array.percentile_nearest_rank(analysis_data, i_sensitivity)
    stdev       = array.stdev(analysis_data)

    stdev_xs    = stdev * i_stdev_xs
    stdev_s     = stdev * i_stdev_s
    stdev_l     = stdev * i_stdev_l

    // _y1 = oscBottom * (1 / oscHighest * hightAdj)
    // _y2 = oscBottom * (1 / oscHighest * hightAdj)
    
    if i_analysis_asc
        array.sort(analysis_data, order.ascending)

    array.push(a_line, line.new(bar_index, oscTop,  bar_index - lookbackLength, oscTop,  width=1, color=color.new(color.blue, 75)))
    array.push(a_line, line.new(bar_index, oscBottom,  bar_index - lookbackLength, oscBottom,  width=1))
    array.push(a_line, line.new(bar_index, oscBottom,  bar_index - lookbackLength, oscBottom,  width=1))
    array.push(a_line, line.new(bar_index, oscBottom + (rank     * hightAdj), bar_index - lookbackLength, oscBottom + (rank     * hightAdj), style=line.style_dotted, width=1, color=color.new(color.orange, 30)))
    array.push(a_line, line.new(bar_index, oscBottom + (stdev_xs * hightAdj), bar_index - lookbackLength, oscBottom + (stdev_xs * hightAdj), style=line.style_dotted, width=1, color=color.new(color.purple, 30)))
    array.push(a_line, line.new(bar_index, oscBottom + (stdev_l  * hightAdj), bar_index - lookbackLength, oscBottom + (stdev_l  * hightAdj), style=line.style_dotted, width=1))
    array.push(a_labels, label.new(bar_index + 1, oscBottom + (rank     * hightAdj), 'Rank',     color=color.new(color.orange, 30), style=label.style_label_left, textcolor=color.white, size=size.tiny))
    array.push(a_labels, label.new(bar_index + 1, oscBottom + (stdev_xs * hightAdj), 'Stdev XS', color=color.new(color.purple, 30), style=label.style_label_left, textcolor=color.white, size=size.tiny))
    array.push(a_labels, label.new(bar_index + 1, oscBottom + (stdev_l  * hightAdj), 'Stdev L' , color=color.new(color.blue  , 30), style=label.style_label_left, textcolor=color.white, size=size.tiny))

    xc = int(math.avg(bar_index, bar_index - lookbackLength))
    array.push(a_line, line.new(xc, oscBottom, xc, oscBottom + oscHeight, style=line.style_dotted))

    for i = 0 to array.size(analysis_data) - 1
        y2 = array.get(analysis_data, i)
        color_bar   = y2 < (rank)   ? color.orange : y2 < (stdev) ? color.blue : color.from_gradient(50, 0, 100, color.blue, color.black)
        color_bar  := y2 < stdev_xs ? color.purple : color_bar

        //array.push(a_boxes, box.new(bar_index - i, oscBottom, bar_index - i, oscBottom + (y2 * hightAdj), color.new(color_bar, 40), 2, bgcolor=color.new(color_bar, 50)) )
        array.push(a_line, line.new(bar_index - i, oscBottom, bar_index - i, oscBottom + (y2 * hightAdj), color=color.new(color_bar, 40), width=2) )

Overview

The bar size source can be Heikin-Ashi open to close, high to low, a hybrid or open to close. Detection can use rank, stochastic or rate of change methods, with a sensitivity and minimum bar count. It can also mark the minimum, small narrow-range and large wide-range bars, colour bars and show an analysis table.

Details

Published by

itmakesyousick on GitHub

Code credit

boitoki, as written in the script's header

Type

Indicator, Pine Script v5

Draws

On the price chart

Category

Candlestick patterns, Volatility & bands

Markets

Any symbol

Timeframes

Any timeframe

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

pinescript

Settings

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

SettingTypeDefaultVariable
Sourcestringoption_source1i_source_type
Lengthint50i_len
Num. of minimum barsint3i_min
Calculated bystringRanki_barb_type
• Nearest rank %int20i_sensitivity
• Stochastic lengthint14i_stoch_len
Directional Exclusion by ROCboolfalsei_filter_roc
Show Barbwirebooltruei_show_barbwire
i_border_widthint2i_border_width
i_boxcolorcolorcolor.new(#E6DB74, 20)i_boxcolor
i_bgcolorcolorcolor.new(#E6DB74, 80)i_bgcolor
Min. IDboolfalsei_spot_minid
Show all 18 settings
SettingTypeDefaultVariable
Sm. NRboolfalsei_spot_smnr
Lr. WRboolfalsei_spot_lrwr
Bar colorsbooltruei_barcolor
Memory cleaningboolfalsei_memory_cleaning
Analysisboolfalsei_analysis_show
Order ascendingboolfalsei_analysis_asc
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

Body Mass Indicator

by harryguiacorn
219 stars

The Body Mass Indicator highlights candles with exceptionally large body ranges relative to recent price movement. It calculates the absolute distance between open and close prices. When enabled, it identifies bars where the body range achieves a new high over

Indicator v5 Volatility & bandsCandlestick patterns
Updated 1 year ago · None stated GitHub repository of Body Mass Indicator

Raschke Patterns

by TradersPost
218 stars

This overlay indicator marks Linda Raschke short-term bar setups on the price chart. It flags Turtle Soup and Turtle Soup plus one false breakouts of a prior extreme, 80-20 bars, inside bars, failed inside-bar breakouts, outside up and down bars, NR4 and NR7 c

Indicator v6 Candlestick patternsBreakout Repaints
Updated 3 months ago · None stated GitHub repository of Raschke Patterns

Five-in-one Strategy

by capissimo
114 stars

Five-in-one Strategy combines five analytical tools into a single price chart overlay: the Dual Thrust Trading Algorithm (DTTA), Semafore, HalfTrend, Nick Rypock Trailing Reverse, and Tweezer or Kangaroo Tail candlestick patterns. It generates trade signals us

Indicator v4 TrendBreakout Repaints
Updated 1 year ago · None stated GitHub repository of Five-in-one Strategy

Force Bar

by milocaetano
48 stars

Force Bar highlights candlesticks directly on the price chart using three distinct body and range criteria: widest range (Biggest), extreme body relative to historical average (Exhaustion), and moderate body relative to historical average (Force). Colors apply

Indicator v5 Candlestick patternsVolatility & bands
Updated 2 days ago · MIT GitHub repository of Force Bar

Zen Z Bars V1

by Zen-Tim
29 stars

Zen Z Bars V1 analyzes bar-by-bar price action, candle range expansion, and internal bar strength (IBS). It identifies breakouts, inside and outside bars, climax candles based on range expansion factors, and tiered range multiple bars. The indicator draws brea

Indicator v5 Candlestick patternsBreakout
Updated 2 weeks ago · MIT GitHub repository of Zen Z Bars V1
15 stars

This indicator plots Bollinger Bands and smoothed HAMA candles on the price chart. It builds each candle from separate moving averages of open, high, low and close, using selectable EMA, SMA or WMA lengths. A simple moving average forms the band basis, and an

Indicator v5 Candlestick patternsMoving averages
Updated 4 months ago · Apache-2.0 GitHub repository of NSDT HAMA Candles with Bollinger Bands

More indicators

Trade Your Charts With a Regulated Broker

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

Compare brokers