Strategy - Relative Volume Gainers
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Arun_K_Bhaskar

//@version=5

// Acknowledgement: This strategy is developed based on the idea shared by "Vikram Prabhu" of "Pivot Call",
//                  through his video "Volume gainers Strategy".
//                  Note that there are additional rules for this strategy for that necessary data is not available. 

// Source Code Reference for Cumulative Volume:
//// Trader Profile: https://www.tradingview.com/u/danilogalisteu/
//// Indicator Name: "Cumulative Volume" by danilogalisteu
//// Indicator Link: https://www.tradingview.com/script/GV4I6F7M-Cumulative-Volume/
//// Acknowledgement: "danilogalisteu"

// Strategy Rules:
//// The indicator is only for Long Entry
//// Day Volume > or = Previous Day Volume
//// % Change > or = 2.5%
//// LTP > or = EMA 200
//// Relative Volume (30) > or = SMA (30) of Relative Volume
//// Current candle is Green or Bullish

// Strategy Requirement:
//// Add EMA 200 to the chart.
//// The indicator works in every timeframe.
//// For intraday use 1min timeframe.

indicator(title='Strategy - Relative Volume Gainers', shorttitle='Strategy - Relative Volume Gainers')//, format=format.volume)

////////////////////////////////////////////////////////////// Menu Start

i_timeframe = input.timeframe(defval='D', title='Timeframe')

gpRV = "Relative Volume"
i_avg_vol_length = input.int(defval=90, title='Length', minval=2, inline='1', group=gpRV)
i_rel_vol_pos_color = input.color(defval=#00FF00, title='', inline='1', group=gpRV)
i_rel_vol_neu_color = input.color(defval=#505050, title='', inline='1', group=gpRV)

i_show_avg_vol = input.bool(defval=false, title="Avg Vol Multiplier", inline='2', group=gpRV)
i_avg_vol_muli = input.float(defval=5, title='', minval=0, inline='2', group=gpRV)
i_avg_vol_color = input.color(defval=#0000FF, title='', inline='2', group=gpRV)

gpCV = 'Cumulative Volume'
i_show_cum_vol = input.bool(defval=true, title="Cumulative Volume", inline='1', group=gpCV)
i_cum_vol_pos_color = input.color(defval=#FFFF00, title='', inline='1', group=gpCV)
i_cum_vol_neu_color = input.color(defval=#505050, title='', inline='1', group=gpCV)

gpSi = "Signal"
i_show_bgcolor = input.bool(defval=true, title="Signal", inline='1', group=gpSi)
i_show_candle = input.bool(defval=true, title="Candle", inline='1', group=gpSi)
i_candle_color = input.color(defval=#0000FF, title='', inline='1', group=gpSi)
ttPC = "Consider only the stocks which are trading above the given % Change"
i_pchg_val = input.float(defval=2.5, title='%Chg Above', tooltip='', inline='2', group=gpSi)
i_vol_pchg_val = input.float(defval=250, title='Vol %Chg Above', tooltip='', inline='3', group=gpSi)

gpTb = 'Table'
i_show_table = input.bool(defval=true, title="Table", inline='1', group=gpTb)
i_table_text_size  = input.string(defval='small', title='Size', options=['tiny','small','normal','large','huge'], inline='1', group=gpTb)
i_pos_color = input.color(defval=#00FF00, title='', inline='1', group=gpTb)
i_neu_color = input.color(defval=#FFFFFF, title='', inline='1', group=gpTb)

i_show_note = input.bool(defval=false, title="Important Note", inline='', group='')

////////////////////////////////////////////////////////////// Menu End

////////////////////////////////////////////////////////////// Calculations Start

///////////////////////////////// Get Data
get_ohlcv(timeframe, value) => 
  request.security(symbol=syminfo.tickerid, timeframe=timeframe, expression=value, gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on)

prev_close = get_ohlcv(i_timeframe, close[1])
day_volume = get_ohlcv(i_timeframe, volume)
prev_volume = get_ohlcv(i_timeframe, volume[1])

///////////////////////////////// Calculate Percentage Change
percentage_change(current_value, previous_value) =>
    pchg = (current_value / previous_value - 1) * 100
    pchg

// Calculate % Change
day_pchg = percentage_change(close, prev_close)

// Calculate Volume % Change
volume_pchg = percentage_change(day_volume, prev_volume)

// Calculate EMA
price_ema = ta.ema(open, 200)

///////////////////////////////// Calculate Relative Volume
average_volume = ta.sma(volume, i_avg_vol_length)
relative_volume = volume / average_volume[1]

average_volume_sma = ta.sma(relative_volume, i_avg_vol_length) * i_avg_vol_muli

// Relative Volume Signal
var bool long_condition = na
var bool show_long = na

long_condition := day_volume >= prev_volume and 
                 day_pchg >= i_pchg_val and
                 volume_pchg >= i_vol_pchg_val and
                 close >= price_ema and 
                 relative_volume >= average_volume_sma and 
                 open < close and
                 barstate.isconfirmed

show_long :=  long_condition and not long_condition[1] ? long_condition : na

// Plot Relative Volume
rel_vol_color = long_condition ? i_rel_vol_pos_color : i_rel_vol_neu_color
plot(series=relative_volume, title='Relative Volume', color=rel_vol_color, style=plot.style_columns)
bgcolor(color=i_show_bgcolor and show_long ? color.new(rel_vol_color, 85) : na, title='Long Signal')
barcolor(color=i_show_candle and show_long ? i_candle_color : na, title='Long Signal Candle')

plot(series=i_show_avg_vol ? average_volume_sma : na, title='Average Volume SMA', color=i_avg_vol_color, style=plot.style_line)


///////////////////////////////// Calculate Cumulative Volume
cumulative_volume(timeframe) =>
    is_new_day = ta.change(time(timeframe)) != 0 ? 1 : 0
    cnt_new_day = ta.barssince(is_new_day)

    var float cum_vol = 0.0
    cum_vol := volume + (is_new_day ? 0 : cum_vol)

    cum_vol

cum_vol = cumulative_volume(i_timeframe)
cum_vol_percentage = cum_vol / prev_volume

// Plot Cumulative Volume
cum_vol_col = cum_vol > prev_volume ? i_cum_vol_pos_color : i_cum_vol_neu_color
plot(series=i_show_cum_vol ? cum_vol_percentage : na, title='Cumulative Volume', color=cum_vol_col, linewidth=2, style=plot.style_line)

////////////////////////////////////////////////////////////// Calculations End

////////////////////////////////////////////////////////////// Table Start

// To String
volume_pchg_str = str.tostring(volume_pchg,"#.##") + ' %'
day_volume_str = str.tostring(day_volume/100000,"#.##") + ' L'
prev_day_volume_str = str.tostring(prev_volume/100000,"#.##") + ' L'
day_pchg_str = str.tostring(day_pchg,"#.##") + ' %'

// Color
bgcolor_1 = color.new(i_neu_color, 85)
bgcolor_2 = color.new(i_neu_color, 95)
vol_pchg_col = day_volume > prev_volume ? i_pos_color : i_neu_color
pchg_col = day_pchg > i_pchg_val ? i_pos_color : i_neu_color

// Plot Table
var table plot_table = table.new(position=position.bottom_right, columns=2, rows=4, border_width=2)
if barstate.islast and i_show_table
    table.cell(plot_table, column=0, row=0, text=day_pchg_str, text_color=pchg_col, text_halign=text.align_right, bgcolor=bgcolor_2, text_size=i_table_text_size)
    table.cell(plot_table, column=1, row=0, text="Chg", text_color=i_neu_color, text_halign=text.align_left, bgcolor=bgcolor_2, text_size='small')

    table.cell(plot_table, column=0, row=1, text=volume_pchg_str, text_color=vol_pchg_col, text_halign=text.align_right, bgcolor=bgcolor_1, text_size=i_table_text_size)
    table.cell(plot_table, column=1, row=1, text="Vol Chg", text_color=i_neu_color, text_halign=text.align_left, bgcolor=bgcolor_1, text_size='small')

    table.cell(plot_table, column=0, row=2, text=day_volume_str, text_color=i_neu_color, text_halign=text.align_right, bgcolor=bgcolor_2, text_size=i_table_text_size)
    table.cell(plot_table, column=1, row=2, text="Vol", text_color=i_neu_color, text_halign=text.align_left, bgcolor=bgcolor_2, text_size='small')

    table.cell(plot_table, column=0, row=3, text=prev_day_volume_str, text_color=i_neu_color, text_halign=text.align_right, bgcolor=bgcolor_1, text_size=i_table_text_size)
    table.cell(plot_table, column=1, row=3, text="Prev Vol", text_color=i_neu_color, text_halign=text.align_left, bgcolor=bgcolor_1, text_size='small')

////////////////////////////////////////////////////////////// Table End

////////////////////////////////////////////////////////////// Note
note_text = "Note:\nThe indicator works in every timeframe.\n" + 
             "Add EMA 200 to the chart.\n" + 
             "For intraday use 1min timeframe.\n" + 
             "The indicator is only for Long Entry."

note_label = label(na)
if i_show_note
    note_label := label.new(x=bar_index - 75, y=20, text=note_text, color=#FF0000, style=label.style_label_center, textcolor=#FFFFFF, size=size.large)
    label.delete(note_label[1])

////////////////////////////////////////////////////////////// CODE END