Indicator · Pine Script v6 · On the chart

Crypto Trading Strategy

by AmjadSaidam· code credited to Amjad_S

Crypto Trading Strategy identifies breakout setups on the price chart by combining Bollinger Bands with daily cumulative volume delta.

View on GitHub

GitHub stars2on the repository
Pine versionv6current
Lines of code124
Settings7inputs
LicenceMIT
Last update4 weeks ago24 Sep 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 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

124 lines of Pine Script v6 from pine/bollinger_band_cv_pine.txt, published under MIT. Keep the author's credit and licence lines when you reuse it.

bollinger_band_cv_pine.txt
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Amjad_S

//@version=6
//+------------------------------------------------------------------+
//                                                         INDICATOR |
//<<+----------------------------------------------------------------+{
indicator("CRYPTO TRADING STRATEGY",
    overlay = true)

//>>+----------------------------------------------------------------+}
//                                                            INPUTS |
//<<+----------------------------------------------------------------+{
int bb_window = input(20, title = 'Bollinger Band Window')
float bb_mult = input(2.0, title = 'Bollinger Bands Multiplier')
int z_score_window = input(20, title = 'Z Score Window')
float high_cv_thresh = input(2.0, title = 'Cumulative Volume Higher Threshold')
float low_cv_thresh = input(2.0, title = 'Cumulative Volume Lower Threshold')

// sl and tp 
atr = ta.atr(14)
float atr_mult = input(3.0, title = 'ATR SL MULTIPLIER')
float rr = input(1.0, title = 'RISK REWARD')

//>>+----------------------------------------------------------------+}
//                                                        INDICATORS |
//<<+----------------------------------------------------------------+{
// bollinger bands ---------------------------------------------------
[bb_m, bb_h, bb_l] = ta.bb(close, bb_window, bb_mult)

// z-score -----------------------------------------------------------
z_score(data) =>
    (data - ta.sma(data, z_score_window)) / ta.stdev(data, z_score_window, biased = false)

// cumulative volume -------------------------------------------------
var cum_vol = float(na)

var is_new_session = bool(na)
session_change = timeframe.change('1D')

if session_change == true
    cum_vol := 0.0

cum_vol += math.sign(close - open) * volume
stan_cvol = z_score(cum_vol)
z_cum_vol = na(stan_cvol) ? 0 : stan_cvol

//>>+----------------------------------------------------------------+}
//                                                        CONFLUENCE |
//<<+----------------------------------------------------------------+{

//>>+----------------------------------------------------------------+}
//                                                           SIGNALS |
//<<+----------------------------------------------------------------+{
long_signal = (close > bb_h) and (z_cum_vol > high_cv_thresh)
long_signal_conf = long_signal
long_valid = long_signal_conf[1]

short_signal = (close < bb_l) and (z_cum_vol < -1 * low_cv_thresh)
short_signal_conf = short_signal
short_valid = short_signal_conf[1]

//>>+----------------------------------------------------------------+}
//                                                           SL & TP |
//<<+----------------------------------------------------------------+{
rd(val) =>
    math.round(val, 5)

sl_tp(order) =>
    side = order == 'long' ? 1 : order == 'short' ? -1 : na 
    sl_dist = atr * atr_mult 
    sl = rd(open - sl_dist * side)
    tp = rd(open + sl_dist * side * rr)
    [sl, tp]

//>>+----------------------------------------------------------------+}
//                                                  VALIDATE SIGNALS |
//<<+----------------------------------------------------------------+{
long_trigger = long_valid and not long_valid[1]
short_trigger = short_valid and not short_valid[1] 

var FirstTrade = bool(na) 

if session_change
    FirstTrade := false 
else
    if long_trigger or short_trigger
        FirstTrade := true

FirstTradeValid = FirstTrade and not FirstTrade[1]

//>>+----------------------------------------------------------------+}
//                                                      SIGNAL PLOTS |
//<<+----------------------------------------------------------------+{
if long_trigger
    [sl, tp] = sl_tp('long')

    label.new(x = bar_index, y = low, 
        text = 'long' + '\n' + 'sl: @' + str.tostring(sl) + '\n' + 'tp: @' + str.tostring(tp), 
        color = FirstTradeValid ? color.green : color.gray,
        style = label.style_label_up)

    if FirstTradeValid
        alert(message = "LONG " + syminfo.ticker + " " + timeframe.period + " ent: @" + str.tostring(close, format.mintick) + 'sl: @' + str.tostring(sl) + 'tp: @' + str.tostring(tp),
             freq = alert.freq_once_per_bar)

if short_trigger
    [sl, tp] = sl_tp('short')

    label.new(x = bar_index, y = high, 
        text = 'short' + '\n' + 'sl: @' + str.tostring(sl) + '\n' + 'tp: @' + str.tostring(tp), 
        color = FirstTradeValid ? color.red : color.gray,
        style = label.style_label_down)

    if FirstTradeValid
        alert(message = "SHORT " + syminfo.ticker + " " + timeframe.period + " ent: @" + str.tostring(close, format.mintick) + 'sl: @' + str.tostring(sl) + 'tp: @' + str.tostring(tp),
             freq = alert.freq_once_per_bar)
         
//>>+----------------------------------------------------------------+}
//                                                   INDICATOR PLOTS |
//<<+----------------------------------------------------------------+{
plot(bb_m, title = 'Moving Average', color = color.blue)
plot(bb_h, title = 'Upper Bollinger Band', color = color.green)
plot(bb_l, title = 'Lower Bollinger Band', color = color.red)

Overview

Crypto Trading Strategy computes a standard Bollinger Band envelope alongside a daily resetting cumulative volume series normalised into z-scores. A long trigger generates when price closes above the upper band while volume momentum surpasses the positive threshold, verified on the following bar. Short triggers require price below the lower band and negative volume z-scores. The script also calculates ATR-based stop-loss and take-profit levels using configurable risk-reward multipliers.

Details

Published by

AmjadSaidam on GitHub

Code credit

Amjad_S, as written in the script's header

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

Breakout, Volume, Volatility & bands

Markets

Crypto

Timeframes

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

cryptocurrencyforexmetatrader5stockstrading-bot

Settings

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

SettingTypeDefaultVariable
Bollinger Band Windowint20bb_window
Bollinger Bands Multiplierfloat2.0bb_mult
Z Score Windowint20z_score_window
Cumulative Volume Higher Thresholdfloat2.0high_cv_thresh
Cumulative Volume Lower Thresholdfloat2.0low_cv_thresh
ATR SL MULTIPLIERfloat3.0atr_mult
RISK REWARDfloat1.0rr
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 indicator identifies and plots price compression zones directly on the price chart using multi-module scoring. It measures ATR compression, ADX chop levels, boundary touches, volume dry-up, and historical pivot levels to identify consolidation areas and s

Indicator v6 BreakoutSupport & resistance
Updated yesterday · MIT GitHub repository of CoilForge Zones [WavesUnchained]
3 stars

Greeffer's Long Study calculates Donchian Channels alongside a volume moving average filter to generate trade signals. When price touches the lower or upper channel boundaries combined with volume exceeding a custom moving average multiplier, the indicator tri

Indicator v4 TrendVolatility & bands
Updated 4 years ago · CC0-1.0 GitHub repository of Greeffer's Long Study
2 stars

Calculates 20-day Average Daily Range percentage, multi-month performance metrics, opening gap size, and relative volume to identify Kristjan Kullamägi style Breakout and Episodic Pivot setups. When conditions are satisfied on the price chart, it flags candles

Indicator v6 BreakoutVolume
Updated 4 months ago · Custom licence GitHub repository of Qullamaggie Breakout / EP Flags

KLSE VCP Stage v2

by kevinesk
1 stars

This indicator classifies market structure into volatility contraction pattern (VCP) stages on the main price chart. It evaluates a Mark Minervini Trend Template score alongside Bollinger Band width percentiles and volume metrics to determine stages such as Co

Indicator v5 TrendVolatility & bands
Updated 4 months ago · None stated GitHub repository of KLSE VCP Stage v2

This indicator evaluates and scores trade signal quality using a four-layer filtering process drawn directly on the main chart. It evaluates volume spikes against a moving average, higher-timeframe EMA trend alignment, price breaches beyond ATR volatility band

Indicator v6 Volatility & bandsVolume Repaints
Updated 2 months ago · None stated GitHub repository of TeleNexus Fakeout Signal Quality

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