//@version=6
// © SeerQuant
indicator(
title = "Quartile For Loop [SeerQuant]",
shorttitle = "QFL [SeerQuant]",
overlay = false
)
// ----------------- INPUTS ----------------- //
// @param: Moving Average Settings
qLength = input.int(14, title = "Quartile Length", inline = "First", group = " > INDICATOR INPUTS <")
src = input.source(close, title = "Calculation Source", inline = "First", group = " > INDICATOR INPUTS <")
typeSig = input.bool(false, title = "Use Alternate Signal?", group = " > INDICATOR INPUTS <", tooltip = "Alternative way of scoring. Uses past quartile values instead of price source for iterative scoring.")
// @param: Global Settings
sl = input.int(5, title = "Loop Start", inline = "Global", group = " > FOR LOOP SETTINGS <")
el = input.int(55, title = "Loop End", inline = "Global", group = " > FOR LOOP SETTINGS <")
thrUp = input.float(35, title = "Threshold Uptrend", inline = "Global", group = " > FOR LOOP SETTINGS <")
thrDown = input.float(-5, title = "Threshold Downtrend", inline = "Global", group = " > FOR LOOP SETTINGS <")
// @param: Style Settings
paint = input.bool(false, title = "Colour Candles?", group = " > STYLE SETTINGS <")
// @param: Colour Scheme
colScheme = input.string("Default", "Color Scheme",
options = ["Default", "Modern", "Cool",
"Alternate", "Bright"], group = " > STYLE SETTINGS <")
[bull, bear, neutral] = switch colScheme
"Default" => [#00ff73, #ff0040, #606060]
"Modern" => [#23d7e4, #e11179, #707070]
"Cool" => [#00ffcc, #4e4f75, #505050]
"Alternate" => [#00ff80, #ff6600, #505050]
"Bright" => [#e8ec00, #f200fa, #505050]
// ----------------- FUNCTIONS ----------------- //
// @function: Weighted quartile function
f_quartile(src, len) =>
// Find Q1, Median and Q3
q1 = ta.percentile_nearest_rank(src, len, 25)
median = ta.percentile_nearest_rank(src, len, 50)
q3 = ta.percentile_nearest_rank(src, len, 75)
// Weighted average of each quartile, double weighted median.
(q1 + 2 * median + q3) / 4
// @function: For Loop scoring system, which optional scoring method.
calcScore(start, end, val, alt) =>
sum = 0.0
for i = start to end by 1
sum += (alt == false ? (src > val[i] ? 1 : -1) : (val > val[i] ? 1 : -1))
sum
// ----------------- CALCULATIONS ----------------- //
// @description: Call the functions
adaptive_quartile = f_quartile(src, qLength)
score = calcScore(sl, el, adaptive_quartile, typeSig)
// @description: Long and short conditions
goLong = score > thrUp
goShort = score < thrDown
var signal = 0
if goLong and not goShort
signal := 1
if goShort
signal := -1
// ----------------- PLOTTING ----------------- //
// @description: Color logic for plotting.
hist_color = signal == 1 ? bull : signal == -1 ? bear : neutral
// @description: Plotting the oscillator.
one = plot(score, color = color.new(hist_color, 0), style = plot.style_line, linewidth=3)
two = plot(thrUp, color = color.new(bull, 50), style = plot.style_line, linewidth=2)
three = plot(thrDown, color = color.new(bear, 50), style = plot.style_line, linewidth=2)
// @description: Optional input to color the candles with the selected color palette.
barcolor(paint ? hist_color : na)
// @description: Colored SMA for easy trend detection.
sma = ta.sma(close, 14)
a = plot(sma, color = hist_color, linewidth = 4, force_overlay = true)
// @description: State tracking for accurate plotting of signals.
var int prevTrendState = 0
var int currentTrendState = 0
if score > thrUp
currentTrendState := 1
else if score < thrDown
currentTrendState := -1
else
currentTrendState := 0
bullishTransition = (prevTrendState != 1 and currentTrendState == 1)
bearishTransition = (prevTrendState != -1 and currentTrendState == -1)
if bullishTransition or bearishTransition
prevTrendState := currentTrendState
// @description: Plot the bullish signal.
plotshape(bullishTransition ? adaptive_quartile - (adaptive_quartile * 0.075) : na,
title = "Bullish Transition",
style = shape.labelup,
location = location.absolute,
color = bull,
text = "▲",
textcolor = #000000,
size = size.small,
force_overlay = true)
// @description: Plot the bearish signal.
plotshape(bearishTransition ? adaptive_quartile + (adaptive_quartile * 0.075) : na,
title = "Bearish Transition",
style = shape.labeldown,
location = location.absolute,
color = bear,
text = "▼",
textcolor = #000000,
size = size.small,
force_overlay = true)
// ----------------- ALERTS ----------------- //
// Long (Bullish) Condition Alert.
alertcondition(signal == 1, title = "Quartile For-Loop Postive Trend", message = "Quartile For-Loop Bullish Signal on: {{exchange}}:{{ticker}}")
// Short/Cash (Bearish) Condition Alert.
alertcondition(signal == -1, title = "Quartile For-Loop Negative Trend", message = "Quartile For-Loop Bearish Signal on: {{exchange}}:{{ticker}}")
// ---------------------------------------------------------------------------------------------------------------- //