//
═══════════════════════════════════════════════════════════════════════════════════
════
// Precision Trend Signals - Advanced Moving Average Signal System
// © 2024 SPTrading - Professional Trading Indicators
// Version: 1.0
//
═══════════════════════════════════════════════════════════════════════════════════
════
//@version=6
indicator(title='Precision Trend Signals', shorttitle='PTS', overlay=true)
//
═══════════════════════════════════════════════════════════════════════════════════
════
// INPUT PARAMETERS
//
═══════════════════════════════════════════════════════════════════════════════════
════
// Essential Settings
source = close
useCurrentTimeframe = input(true, title='Use Current Chart Timeframe')
customTimeframe = input.timeframe(title='Custom Timeframe', defval='D')
// Filters
use200EMAFilter = input(true, title='Enable 200 EMA Trend Filter')
// Linear Regression Channel Settings
group1 = "Linear Regression Channel"
lengthInput = input.int(100, title="Length", minval = 1, maxval = 5000, group =
group1)
sourceInput = input.source(close, title="Source", group = group1)
group2 = "Channel Settings"
useUpperDevInput = input.bool(true, title="Upper Deviation", inline = "Upper
Deviation", group = group2)
upperMultInput = input.float(2.0, title="", inline = "Upper Deviation", group =
group2)
useLowerDevInput = input.bool(true, title="Lower Deviation", inline = "Lower
Deviation", group = group2)
lowerMultInput = input.float(2.0, title="", inline = "Lower Deviation", group =
group2)
group3 = "Display Settings"
showPearsonInput = input.bool(true, "Show Pearson's R", group = group3)
extendLeftInput = input.bool(false, "Extend Lines Left", group = group3)
extendRightInput = input.bool(true, "Extend Lines Right", group = group3)
extendStyle = switch
extendLeftInput and extendRightInput => extend.both
extendLeftInput => extend.left
extendRightInput => extend.right
=> extend.none
group4 = "Color Settings"
colorUpper = input.color(color.new(color.blue, 85), "", inline = group4, group =
group4)
colorLower = input.color(color.new(color.red, 85), "", inline = group4, group =
group4)
// Fixed Parameters (not user inputs)
primaryLength = 20
primaryType = 1
secondaryLength = 50
secondaryType = 1
trendSmoothness = 4
t3Factor = 7
secondaryT3Factor = 7
showPriceCross = false
showSecondaryPriceCross = false
enableTrendColors = true
enableSecondaryColors = true
showCrossSignals = false
showSecondaryMA = false
//
═══════════════════════════════════════════════════════════════════════════════════
════
// CORE CALCULATION ENGINE
//
═══════════════════════════════════════════════════════════════════════════════════
════
timeframeToUse = useCurrentTimeframe ? timeframe.period : customTimeframe
// Advanced Moving Average Calculations
calculateHullMA(source, length) =>
ta.wma(2 * ta.wma(source, length / 2) - ta.wma(source, length),
math.round(math.sqrt(length)))
calculateTEMA(source, length) =>
ema1 = ta.ema(source, length)
ema2 = ta.ema(ema1, length)
ema3 = ta.ema(ema2, length)
3 * (ema1 - ema2) + ema3
// Tilson T3 Algorithm
calculateT3(source, length, factor) =>
f = factor * 0.1
gd1 = ta.ema(source, length) * (1 + f) - ta.ema(ta.ema(source, length), length)
* f
gd2 = ta.ema(gd1, length) * (1 + f) - ta.ema(ta.ema(gd1, length), length) * f
gd3 = ta.ema(gd2, length) * (1 + f) - ta.ema(ta.ema(gd2, length), length) * f
gd3
// Linear Regression Channel Calculations
calcSlope(source, length) =>
max_bars_back(source, 5000)
if not barstate.islast or length <= 1
[float(na), float(na), float(na)]
else
sumX = 0.0
sumY = 0.0
sumXSqr = 0.0
sumXY = 0.0
for i = 0 to length - 1 by 1
val = source[i]
per = i + 1.0
sumX += per
sumY += val
sumXSqr += per * per
sumXY += val * per
slope = (length * sumXY - sumX * sumY) / (length * sumXSqr - sumX * sumX)
average = sumY / length
intercept = average - slope * sumX / length + slope
[slope, average, intercept]
calcDev(source, length, slope, average, intercept) =>
upDev = 0.0
dnDev = 0.0
stdDevAcc = 0.0
dsxx = 0.0
dsyy = 0.0
dsxy = 0.0
periods = length - 1
daY = intercept + slope * periods / 2
val = intercept
for j = 0 to periods by 1
price = high[j] - val
if price > upDev
upDev := price
price := val - low[j]
if price > dnDev
dnDev := price
price := source[j]
dxt = price - average
dyt = val - daY
price -= val
stdDevAcc += price * price
dsxx += dxt * dxt
dsyy += dyt * dyt
dsxy += dxt * dyt
val += slope
stdDev = math.sqrt(stdDevAcc / (periods == 0 ? 1 : periods))
pearsonR = dsxx == 0 or dsyy == 0 ? 0 : dsxy / math.sqrt(dsxx * dsyy)
[stdDev, pearsonR, upDev, dnDev]
// Primary Trend Calculator
getPrimaryMA(source, length, maType, t3Factor) =>
switch maType
1 => ta.sma(source, length)
2 => ta.ema(source, length)
3 => ta.wma(source, length)
4 => calculateHullMA(source, length)
5 => ta.vwma(source, length)
6 => ta.rma(source, length)
7 => calculateTEMA(source, length)
8 => calculateT3(source, length, t3Factor)
=> ta.ema(source, length)
primaryTrend = getPrimaryMA(source, primaryLength, primaryType, t3Factor)
// Secondary Filter Calculator
getSecondaryMA(source, length, maType, t3Factor) =>
switch maType
1 => ta.sma(source, length)
2 => ta.ema(source, length)
3 => ta.wma(source, length)
4 => calculateHullMA(source, length)
5 => ta.vwma(source, length)
6 => ta.rma(source, length)
7 => calculateTEMA(source, length)
8 => calculateT3(source, length, t3Factor)
=> ta.ema(source, length)
secondaryFilter = getSecondaryMA(source, secondaryLength, secondaryType,
secondaryT3Factor)
// Multi-Timeframe Processing
primaryMA = request.security(syminfo.tickerid, timeframeToUse, primaryTrend,
lookahead=barmerge.lookahead_off)
secondaryMA = request.security(syminfo.tickerid, timeframeToUse, secondaryFilter,
lookahead=barmerge.lookahead_off)
//
═══════════════════════════════════════════════════════════════════════════════════
════
// SIGNAL PROCESSING ENGINE
//
═══════════════════════════════════════════════════════════════════════════════════
════
// Price Crossing Detection
primaryCrossUp = open < primaryMA and close > primaryMA
primaryCrossDown = open > primaryMA and close < primaryMA
secondaryCrossUp = open < secondaryMA and close > secondaryMA
secondaryCrossDown = open > secondaryMA and close < secondaryMA
// Trend Direction Analysis
trendBullish = primaryMA >= primaryMA[trendSmoothness]
trendBearish = primaryMA < primaryMA[trendSmoothness]
// Color System
primaryColor = enableTrendColors ? (trendBullish ? color.lime : trendBearish ?
color.red : color.gray) : color.gray
secondaryColor = enableSecondaryColors ? (trendBullish ? color.lime :
trendBearish ? color.red : color.gray) : color.white
// Cross Signal Position
crossPosition = secondaryMA
// Visual Elements (Hidden for Clean Chart)
// Primary and Secondary MA plots are commented out for clean signal-only display
plot(showCrossSignals and ta.cross(primaryMA, secondaryMA) ? crossPosition : na,
style=plot.style_cross, linewidth=15, color=color.new(color.aqua, 0), title="MA
Cross Signals")
// Price Crossing Highlights
barcolor(showPriceCross and primaryCrossUp ? color.yellow : showPriceCross and
primaryCrossDown ? color.yellow : na, title="Primary Price Cross")
barcolor(showSecondaryPriceCross and secondaryCrossUp ? color.orange :
showSecondaryPriceCross and secondaryCrossDown ? color.orange : na,
title="Secondary Price Cross")
//
═══════════════════════════════════════════════════════════════════════════════════
════
// LINEAR REGRESSION CHANNEL DISPLAY
//
═══════════════════════════════════════════════════════════════════════════════════
════
// Calculate Linear Regression Channel
[s, a, i] = calcSlope(sourceInput, lengthInput)
startPrice = i + s * (lengthInput - 1)
endPrice = i
// Base Line
var line baseLine = na
if na(baseLine) and not na(startPrice)
baseLine := line.new(bar_index - lengthInput + 1, startPrice, bar_index,
endPrice, width=1, extend=extendStyle, color=color.new(colorLower, 0))
else
line.set_xy1(baseLine, bar_index - lengthInput + 1, startPrice)
line.set_xy2(baseLine, bar_index, endPrice)
na
// Calculate Deviations
[stdDev, pearsonR, upDev, dnDev] = calcDev(sourceInput, lengthInput, s, a, i)
// Upper and Lower Channel Lines
upperStartPrice = startPrice + (useUpperDevInput ? upperMultInput * stdDev : upDev)
upperEndPrice = endPrice + (useUpperDevInput ? upperMultInput * stdDev : upDev)
var line upper = na
lowerStartPrice = startPrice + (useLowerDevInput ? -lowerMultInput * stdDev : -
dnDev)
lowerEndPrice = endPrice + (useLowerDevInput ? -lowerMultInput * stdDev : -dnDev)
var line lower = na
if na(upper) and not na(upperStartPrice)
upper := line.new(bar_index - lengthInput + 1, upperStartPrice, bar_index,
upperEndPrice, width=1, extend=extendStyle, color=color.new(colorUpper, 0))
else
line.set_xy1(upper, bar_index - lengthInput + 1, upperStartPrice)
line.set_xy2(upper, bar_index, upperEndPrice)
na
if na(lower) and not na(lowerStartPrice)
lower := line.new(bar_index - lengthInput + 1, lowerStartPrice, bar_index,
lowerEndPrice, width=1, extend=extendStyle, color=color.new(colorUpper, 0))
else
line.set_xy1(lower, bar_index - lengthInput + 1, lowerStartPrice)
line.set_xy2(lower, bar_index, lowerEndPrice)
na
// Channel Fill
linefill.new(upper, baseLine, color = colorUpper)
linefill.new(baseLine, lower, color = colorLower)
// Trend Detection
float trend = math.sign(startPrice - endPrice)
// Pearson's R Label
var label r = na
label.delete(r[1])
if showPearsonInput and not na(pearsonR)
r := label.new(bar_index - lengthInput + 1, lowerStartPrice,
str.tostring(pearsonR, "#.################"), color = color.new(color.white, 100),
textcolor=color.new(colorUpper, 0), size=size.normal, style=label.style_label_up)
//
═══════════════════════════════════════════════════════════════════════════════════
════
// SMART TREND ARROWS - SIGNAL GENERATION
//
═══════════════════════════════════════════════════════════════════════════════════
════
// 200 EMA Filter for Market Context
ema200 = ta.ema(close, 200)
// Advanced Trend Change Detection
previousTrendBullish = primaryMA[1] >= primaryMA[1 + trendSmoothness]
previousTrendBearish = primaryMA[1] < primaryMA[1 + trendSmoothness]
// Current Trend State
currentTrendBullish = trendBullish
currentTrendBearish = trendBearish
// Smart Signal Logic with Multi-MA Filter + Optional 200 EMA Context
// Bearish Signal: Trend shifts from bullish to bearish + Secondary MA confirms
weakness + Optional 200 EMA filter
bearishSignal = currentTrendBearish and previousTrendBullish and secondaryMA <
primaryMA and (not use200EMAFilter or close < ema200)
// Bullish Signal: Trend shifts from bearish to bullish + Secondary MA confirms
strength + Optional 200 EMA filter
bullishSignal = currentTrendBullish and previousTrendBearish and secondaryMA >
primaryMA and (not use200EMAFilter or close > ema200)
// Professional Arrow Display
plotshape(bearishSignal, title="🔻 Bearish Signal", location=location.abovebar,
style=shape.arrowdown, size=size.normal, color=color.new(color.red, 0),
textcolor=color.white, text="SELL")
plotshape(bullishSignal, title="🔺 Bullish Signal", location=location.belowbar,
style=shape.arrowup, size=size.normal, color=color.new(color.lime, 0),
textcolor=color.white, text="BUY")
// Smart Alert System
alertcondition(bearishSignal, title="🔻 Precision Trend: Bearish Signal",
message="Precision Trend Signals: Bearish trend confirmed - Consider SELL
position")
alertcondition(bullishSignal, title="🔺 Precision Trend: Bullish Signal",
message="Precision Trend Signals: Bullish trend confirmed - Consider BUY position")
// Linear Regression Channel Alerts
alertcondition(sourceInput > line.get_price(upper, bar_index) or sourceInput <
line.get_price(lower, bar_index), title='Regression Channel Exited', message="The
price movement has exited Regression Channel's bounds")
alertcondition(trend[1] >= 0 and trend < 0, title='Switched to Uptrend',
message='The Regression Channel trend switched from Downtrend to Uptrend')
alertcondition(trend[1] <= 0 and trend > 0, title='Switched to Downtrend',
message='The Regression Channel trend switched from Uptrend to Downtrend')
//
═══════════════════════════════════════════════════════════════════════════════════
════
// END OF PRECISION TREND SIGNALS by SPTrading
//
═══════════════════════════════════════════════════════════════════════════════════
════