// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Piotr Kowalski "piecioshka"
// Docs (EN): https://github.com/piecioshka/tradingview-pine-scripts/blob/main/indicators/oscillators/roc/roc.md
// Docs (PL): https://github.com/piecioshka/tradingview-pine-scripts/blob/main/indicators/oscillators/roc/roc.pl.md
//@version=6
indicator('ROC = Rate of Change', overlay=false, max_labels_count=500)
aLen = input.int(9, 'Length')
src = input.source(close, 'Source')
showTrades = input.bool(true, 'Signal markers', tooltip='Markers on the price panel: below the candle (long) when the ROC crosses zero up (momentum turns positive), above the candle (sell) when it crosses zero down. Shape and size in the Appearance group.')
gA = 'Appearance'
shapeName = input.string('Triangle', 'Marker shape', options=['Triangle', 'Arrow', 'Label arrow', 'Circle', 'Diamond'], group=gA, tooltip='Triangle - solid triangle.\nArrow - small thin arrow.\nLabel arrow - arrow-shaped label bubble.\nCircle / Diamond - neutral dot markers.')
sizeName = input.string('Small', 'Marker size', options=['Tiny', 'Small', 'Normal', 'Large'], group=gA)
// Markers as labels - the shape is picked from an input, which plotshape() cannot do (its style must be a constant).
upStyle = shapeName == 'Arrow' ? label.style_arrowup : shapeName == 'Label arrow' ? label.style_label_up : shapeName == 'Circle' ? label.style_circle : shapeName == 'Diamond' ? label.style_diamond : label.style_triangleup
downStyle = shapeName == 'Arrow' ? label.style_arrowdown : shapeName == 'Label arrow' ? label.style_label_down : shapeName == 'Circle' ? label.style_circle : shapeName == 'Diamond' ? label.style_diamond : label.style_triangledown
markerSize = sizeName == 'Tiny' ? size.tiny : sizeName == 'Normal' ? size.normal : sizeName == 'Large' ? size.large : size.small
roc = (src - src[aLen]) / src[aLen] * 100
rocColor = roc >= 0 ? color.new(color.green, 50) : color.new(color.red, 50)
plot(roc, 'ROC', color=rocColor, linewidth=2, style=plot.style_columns)
hline(0, 'Zero', color=color.gray, linestyle=hline.style_solid)
// --- Signal markers on the price panel (zero cross) ---
longTrade = ta.crossover(roc, 0)
sellTrade = ta.crossunder(roc, 0)
if showTrades and longTrade
label.new(bar_index, na, '', yloc=yloc.belowbar, style=upStyle, color=color.green, size=markerSize, force_overlay=true)
if showTrades and sellTrade
label.new(bar_index, na, '', yloc=yloc.abovebar, style=downStyle, color=color.red, size=markerSize, force_overlay=true)
// --- Alerts ---
alertcondition(longTrade, 'ROC: cross up', 'ROC crossed zero up (momentum turned positive)')
alertcondition(sellTrade, 'ROC: cross down', 'ROC crossed zero down (momentum turned negative)')