Strategy · Pine Script v4 · On the chart

ABC and Parabolic SAR Strategy

by geraked

The ABC and Parabolic SAR Strategy calculates ABC chart patterns using a ZigZag structure alongside Fibonacci retracement levels and a trend cloud formed by six moving averages.

View on GitHub

Repaints

GitHub stars104on the repository
Pine versionv4older, still runs
Lines of code271
Settings21inputs
LicenceMIT
Last update3 years ago29 Oct 2023

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 strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

271 lines of Pine Script v4 from strategies/ABSAR.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

ABSAR.pine
// A strategy using ABC and Parabolic SAR indicators
// The strategy has been explained in this video: https://youtu.be/4H9bmo8IjY0
// © 2023 Geraked, Rabist
// Licensed under MIT

// Backtesting result:
//      Symbol:             EURUSD
//      Timeframe:          2 HOUR
//      Range:              2022-01-02 22:00 — 2023-09-01 19:00
//      Percent Profitable: 64.5%
//      Total Trades:       31
//      Profit Factor:      2.004

//@version=4
strategy("ABC and Parabolic SAR Strategy", "ABSAR", overlay = true)

tpCoef = input(defval = 2.0, title="TP Coefficient", group = "Strategy")
reverse = input(defval = false, title="Reverse", group = "Strategy")

prd = input(defval = 8, title="ZigZag Period", minval = 2, maxval = 50, group = "Setup")
fiboup = input(defval = 0.618, title = "Fibonacci Max", group = "Setup")
fibodn = input(defval = 0.382, title = "Fibonacci Min", group = "Setup")
errorrate = input(defval = 5.0, title = "Error Rate", minval = 0, maxval = 30, group = "Setup") / 100
showabc = input(defval = true, title = "Show ABC", group = "Extras")
keepabc = input(defval = true, title = "Keep Old ABCs", group = "Extras")
showcloud = input(defval = true, title = "Show Cloud", group = "Extras", inline = "cloud")
c_upcol = input(defval = color.new(color.lime, 75), title = "", group = "Extras", inline = "cloud")
c_dncol = input(defval = color.new(color.red, 75), title = "", group = "Extras", inline = "cloud")
showzigzag = input(defval = true, title = "Show Zig Zag & Fibo", group = "Extras", inline = "zigzag")
upcol = input(defval = color.lime, title = "", group = "Extras", inline = "zigzag")
dncol = input(defval = color.red, title = "", group = "Extras", inline = "zigzag")
srcma = input(defval = close, title = "Source for Moving Averages", group = "Trend Cloud")
malen1 = input(defval = 50, title = "SMA 1 Length", minval = 1, group = "Trend Cloud")
malen2 = input(defval = 100, title = "SMA 2 Length", minval = 1, group = "Trend Cloud")
malen3 = input(defval = 150, title = "SMA 3 Length", minval = 1, group = "Trend Cloud")
malen4 = input(defval = 200, title = "SMA 4 Length", minval = 1, group = "Trend Cloud")
malen5 = input(defval = 20, title = "EMA 1 Length", minval = 1, group = "Trend Cloud")
malen6 = input(defval = 40, title = "EMA 2 Length", minval = 1, group = "Trend Cloud")

ma_array = array.new_float(6)
array.set(ma_array, 0, sma(srcma, malen1))
array.set(ma_array, 1, sma(srcma, malen2))
array.set(ma_array, 2, sma(srcma, malen3))
array.set(ma_array, 3, sma(srcma, malen4))
array.set(ma_array, 4, ema(srcma, malen5))
array.set(ma_array, 5, ema(srcma, malen6))

float umax = na
float umin = na
float lmax = na
float lmin = na
int upper = 0
int lower = 0
for x = 1 to 6
    ma = array.get(ma_array, x -1)
    if ma >= max(open, close)
        upper := upper + 1
        if na(umax)
            umax := ma
            umin := ma
        else
            umax := max(umax, ma)
            umin := min(umin, ma)
    else if ma <= min(open, close)
        lower := lower + 1
        if na(lmax)
            lmax := ma
            lmin := ma
        else
            lmax := max(lmax, ma)
            lmin := min(lmin, ma)

var int trend = 0
trend := lower > 0 and upper == 0 and lower[1] > 0 and upper[1] == 0 ? 1 :
         lower == 0 and upper > 0 and lower[1] == 0 and upper[1] > 0 ? -1 :
         trend
         
tucolor = trend ==  1 ? c_upcol: na
tdcolor = trend == -1 ? c_dncol : na
fill(plot(umax, color = na), plot(umin, color = na), color = showcloud ? tdcolor : na)
fill(plot(lmax, color = na), plot(lmin, color = na), color = showcloud ? tucolor : na)

//===================================================================

// zigzag part
get_ph_pl_dir(len)=>
    float ph = highestbars(high, len) == 0 ? high : na
    float pl = lowestbars(low, len) == 0 ? low : na
    var dir = 0
    dir := iff(ph and na(pl), 1, iff(pl and na(ph), -1, dir))
    [ph, pl, dir]

[ph, pl, dir] = get_ph_pl_dir(prd)

var max_array_size = 10
var zigzag = array.new_float(0)

add_to_zigzag(value, bindex)=>
    array.unshift(zigzag, bindex)
    array.unshift(zigzag, value)
    if array.size(zigzag) > max_array_size
        array.pop(zigzag)
        array.pop(zigzag)
    
update_zigzag(value, bindex)=>
    if array.size(zigzag) == 0
        add_to_zigzag(value, bindex)
    else
        if (dir == 1 and value > array.get(zigzag, 0)) or (dir == -1 and value < array.get(zigzag, 0))
            array.set(zigzag, 0, value)
            array.set(zigzag, 1, bindex)
        0.

dir_changed = change(dir)
if ph or pl
    if dir_changed
        add_to_zigzag(dir == 1 ? ph : pl, bar_index)
    else
        update_zigzag(dir == 1 ? ph : pl, bar_index)

if showzigzag and array.size(zigzag) > 5
    var line zzline1 = na
    var line zzline2 = na
    line.delete(zzline1)
    line.delete(zzline2)
    zzline1 := line.new(x1 = round(array.get(zigzag, 1)) , y1 = array.get(zigzag, 0), x2 = round(array.get(zigzag, 3)), y2 = array.get(zigzag, 2), color = dir == 1 ? upcol : dncol, width = 2, style = line.style_dashed)
    zzline2 := line.new(x1 = round(array.get(zigzag, 3)) , y1 = array.get(zigzag, 2), x2 = round(array.get(zigzag, 5)), y2 = array.get(zigzag, 4), color = dir == -1 ? upcol : dncol, width = 2, style = line.style_dashed)
    // min/max fibo levels
    zzlen = abs(array.get(zigzag, 2) - array.get(zigzag, 4))
    fmin = dir == 1 ? array.get(zigzag, 2) + zzlen * (fibodn - errorrate) : array.get(zigzag, 4) + zzlen * ((1 - fibodn) + errorrate)
    fmax = dir == 1 ? array.get(zigzag, 2) + zzlen * (fiboup + errorrate) : array.get(zigzag, 4) + zzlen * ((1 - fiboup) - errorrate)
    var line fibo1 = na
    var line fibo2 = na
    line.delete(fibo1)
    line.delete(fibo2)
    fibo1 := line.new(x1 = round(array.get(zigzag, 3)), y1 = fmin, x2 = round(array.get(zigzag, 3)) + 1, y2 = fmin, color = color.blue, style = line.style_dashed, extend = extend.right)
    fibo2 := line.new(x1 = round(array.get(zigzag, 3)), y1 = fmax, x2 = round(array.get(zigzag, 3)) + 1, y2 = fmax, color = color.blue, style = line.style_dashed, extend = extend.right)

zchange = array.size(zigzag) > 0 ? array.get(zigzag, 0) :  0.0
abc = array.new_float(0)
if change(zchange) and array.size(zigzag) > 5 and ((pl and trend == 1  and dir == -1 and low < array.max(ma_array)) or (ph and trend == -1 and dir == 1 and high > array.min(ma_array)))
    a = array.get(zigzag, 0)
    b = array.get(zigzag, 2)
    b_loc = array.get(zigzag, 3)
    c = array.get(zigzag, 4)
    c_loc = array.get(zigzag, 5)
    rate = (a - b) / (c - b)
    if rate >= (fibodn - fibodn * errorrate) and rate <= (fiboup + fiboup * errorrate)
        array.push(abc, b)
        array.push(abc, b_loc)
        array.push(abc, c)
        array.push(abc, c_loc)

draw_line(dir, x1_,y1_, x2_, y2_, x3_, y3_)=>
    l1 = line.new(x1 = x1_, y1 = y1_, x2 = x2_, y2 = y2_, color = dir == 1 ? upcol : dncol, width = 2)
    l2 = line.new(x1 = x2_, y1 = y2_, x2 = x3_, y2 = y3_, color = dir == 1 ? dncol : upcol, width = 2)
    [l1, l2]

draw_label(dir, x1_,y1_, x2_, y2_, x3_, y3_)=>
    alabel = label.new(  x = x1_, 
                         y = y1_, 
                         text = "C", 
                         style = dir == 1 ? label.style_label_down : label.style_label_up, 
                         color = color.new(color.white, 100),
                         textcolor = color.blue)
    blabel = label.new(  x = x2_, 
                         y = y2_, 
                         text = "B", 
                         style = dir == -1 ? label.style_label_down : label.style_label_up, 
                         color = color.new(color.white, 100),
                         textcolor = color.blue)
    clabel = label.new(  x = x3_, 
                         y = y3_, 
                         text = "A", 
                         style = dir == 1 ? label.style_label_down : label.style_label_up, 
                         color = color.new(color.white, 100),
                         textcolor = color.blue)
    [alabel, blabel, clabel]
    
var abclines = array.new_line(2)
var abclabels = array.new_label(3)

if showabc and array.size(abc) >= 4
    if not keepabc
        line.delete(array.pop(abclines))
        line.delete(array.pop(abclines))
        label.delete(array.pop(abclabels))
        label.delete(array.pop(abclabels))
        label.delete(array.pop(abclabels))
        
    [l1_, l2_] = draw_line(dir, bar_index, array.get(zigzag, 0), round(array.get(abc, 1)),  array.get(abc, 0), round(array.get(abc, 3)), array.get(abc, 2))
    array.unshift(abclines, l1_)
    array.unshift(abclines, l2_)
    
    [la1_, la2_, la3_] = draw_label(dir, bar_index, array.get(zigzag, 0), round(array.get(abc, 1)),  array.get(abc, 0), round(array.get(abc, 3)), array.get(abc, 2))
    array.unshift(abclabels, la1_)
    array.unshift(abclabels, la2_)
    array.unshift(abclabels, la3_)

// bounce?
lbounced = false
sbounced = false
for i = 0 to 5
    if min(low, low[1]) <= array.get(ma_array, i) and close > array.get(ma_array, i) and close > open
        lbounced := true
    if max(high, high[1]) >= array.get(ma_array, i) and close < array.get(ma_array, i) and close < open
        sbounced := true

// stoch give signal?
sto = sma(stoch(close, high, low, 5), 3)
sto_sig = sma(sto, 3)
lstoch = sto[1] <= sto_sig[1] and sto > sto_sig and sto[1] < 50 //and sto_sig > 20
sstoch = sto[1] >= sto_sig[1] and sto < sto_sig  and sto[1] > 50 //and sto_sig < 80

/// check if conditions met
there_is_abc = array.size(abc) != 0
var float last_zz_point = 0.
last_zz_point := array.size(zigzag) > 2 and there_is_abc ? array.get(zigzag, 0) : last_zz_point
var abc_bar_count = 0
abc_bar_count := there_is_abc ? 0 : abc_bar_count + 1
hhh_ = highest(abc_bar_count + 1)
lll_ = lowest(abc_bar_count + 1)

// long condition
abLong = trend == 1 and abc_bar_count <= 6 and lbounced and lll_ >= last_zz_point
abShort = trend == -1 and abc_bar_count <= 6 and sbounced and hhh_ <= last_zz_point
plotshape(abLong,  style = shape.triangleup, color = upcol, location =  location.belowbar, size = size.small)
plotshape(abShort,  style = shape.triangledown, color = dncol, location =  location.abovebar, size = size.small)

ps = sar(0.02, 0.02, 0.2)
psLong = ps[1] > high[1] and ps < low
psShort = ps[1] < low[1] and ps > high
plot(ps, "ParabolicSAR", style=plot.style_cross, color=#2962FF)

long = false
short = false
for i = 0 to 5
    if abLong[i]
        long := true
    if abShort[i]
        short := true

long := long and psLong
short := short and psShort

longSl = lowest(low, 5)
shortSl = highest(high, 5)

if long
    if not reverse
        strategy.entry("long", strategy.long)
        inn = close
        longTp = inn + tpCoef * (inn - longSl)
        strategy.exit("exit", "long", stop=longSl, limit=longTp)
    else
        strategy.entry("short", strategy.short)
        inn = close
        longTp = inn + tpCoef * (inn - longSl)
        strategy.exit("exit", "short", stop=longTp, limit=longSl)   

if short
    if not reverse
        strategy.entry("short", strategy.short)
        inn = close
        shortTp = inn - tpCoef * (shortSl - inn)
        strategy.exit("exit", "short", stop=shortSl, limit=shortTp)
    else
        strategy.entry("long", strategy.long)
        inn = close
        shortTp = inn - tpCoef * (shortSl - inn)
        strategy.exit("exit", "long", stop=shortTp, limit=shortSl)

Overview

ABC and Parabolic SAR Strategy visualizes trend direction and pattern signals directly on the main price chart. Traders can adjust the ZigZag period, Fibonacci boundaries, Take Profit multiplier, reverse trade mode, and moving average lengths. Because ZigZag calculations rely on pivot points, historical pattern overlays and pivot legs repaint until the pivot bar is fully confirmed.

Details

Published by

geraked on GitHub

Type

Strategy, Pine Script v4

Draws

On the price chart

Category

Trend, Support & resistance, Moving averages

Markets

Forex

Timeframes

M15-H1, H4 and above

Risk Notes

  • Signals can change on the live bar or after it closes (repainting)

Topics

backtesting-trading-strategiesexpert-advisorexpert-advisorsforex-botgerakedmetatraderpinescriptrabiststock-markettrading-algorithms

Settings

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

SettingTypeDefaultVariable
TP Coefficientfloat2.0tpCoef
Reverseboolfalsereverse
ZigZag Periodint8prd
Fibonacci Maxfloat0.618fiboup
Fibonacci Minfloat0.382fibodn
Error Ratefloat5.0errorrate
Show ABCbooltrueshowabc
Keep Old ABCsbooltruekeepabc
Show Cloudbooltrueshowcloud
c_upcolcolorcolor.new(color.lime, 75)c_upcol
c_dncolcolorcolor.new(color.red, 75)c_dncol
Show Zig Zag & Fibobooltrueshowzigzag
Show all 21 settings
SettingTypeDefaultVariable
upcolcolorcolor.limeupcol
dncolcolorcolor.reddncol
Source for Moving Averagessourceclosesrcma
SMA 1 Lengthint50malen1
SMA 2 Lengthint100malen2
SMA 3 Lengthint150malen3
SMA 4 Lengthint200malen4
EMA 1 Lengthint20malen5
EMA 2 Lengthint40malen6
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

Omar Edited WF

by Alorse
330 stars

Omar Edited WF is a trading strategy overlay built around Williams Fractals and multiple Exponential Moving Averages. It detects high and low fractal pivot points over configurable lookback periods alongside three adjustable EMA trendlines. Long entries are ma

Strategy v5 TrendMoving averages
Updated 2 months ago · None stated GitHub repository of Omar Edited WF
257 stars

This strategy calculates dynamic support and resistance levels using pivot highs and lows alongside a custom smoothed trend filter and a 3-period EMA. It identifies entry opportunities when price breaks out relative to the trend filter and short-term EMA cross

Strategy v5 TrendSupport & resistance Repaints
Updated 6 weeks ago · None stated GitHub repository of 30s - ES 1m Strategy Candle Bar

This strategy overlays the price chart and looks for VWAP pullbacks. It goes long when a short SMA crosses above VWAP after RSI has been oversold within ten bars, and short on the opposite cross after RSI has been overbought. Optional Minervini-style moving-av

Strategy v5 TrendOscillators & momentum
Updated 2 years ago · GPL-3.0 GitHub repository of Advanced VWAP-Momentum Pullback Trend Qualifier

This strategy executes trades based on pivot levels, an exponential moving average, and a multi-stage smoothing trend line. It identifies support and resistance points from pivot highs and lows, combining them with price relationship rules against a custom smo

Strategy v5 TrendMoving averages Repaints
Updated 2 years ago · None stated GitHub repository of Binancash - Candle Strategy Futures on Binance
13 stars

This strategy generates entry signals using pivot points and uses custom Curie moving average closing lines for exiting positions. It features risk management components including percentage-based stop loss, take profit, trailing stops, and break-even levels,

Strategy v5 TrendMoving averages
Updated 1 year ago · None stated GitHub repository of BitLa PivotPoints A002

XXX

by MeridianAlgo
9 stars

This multi-timeframe scalping strategy plots moving averages alongside Smart Money Concepts elements on the price chart. It calculates trend signals using configurable moving average types like ALMA, Hull MA, or TEMA across alternate timeframes. It also plots

Strategy v5 TrendMoving averages Repaints
Updated 4 months ago · MIT GitHub repository of XXX

More strategys

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers