PINE LIBRARY

ZigZag

TradingViewの投稿
アップデート済
█  OVERVIEW


This library is a Pine Script™ programmer’s tool containing custom user-defined types and functions to calculate ​Zig Zag indicators within their scripts. It is not a stand-alone indicator.

Pine Script™ libraries are publications that contain reusable code for importing into Pine Script™ indicators, strategies, and other libraries. For more information on libraries and incorporating them into your scripts, see the Libraries section of the Pine Script™ User Manual.



█  CONCEPTS


​Zig Zag​

​Zig ​Zag​ is a popular indicator that filters out minor price fluctuations to denoise data and emphasize trends. Traders commonly use ​​Zig Zag​ for trend confirmation, identifying potential ​support and ​resistance​, and pattern detection​. It is formed by identifying significant local high and low points in alternating order and connecting them with straight lines, omitting all other data points from their output. There are several ways to calculate the ​Zig Zag​'s data points and the conditions by which its direction changes. This script uses ​pivots as the data points, which are the highest or lowest values over a defined number of bars before and after them. The direction only reverses when a newly formed ​​pivot​ deviates from the last ​​Zig Zag​ point in the opposite direction by an amount greater than or equal to a specified percentage.

To learn more about ​Zig Zag​ and how to calculate it, see this entry from the Help Center.



█ FOR Pine Script™ CODERS


Notes

This script's architecture utilizes user-defined types (UDTs) to create custom objects which are the equivalent of variables containing multiple parts, each able to hold independent values of different types. UDTs are the newest addition to Pine Script™ and the most advanced feature the language has seen to date. The feature's introduction creates a new runway for experienced coders to push the boundaries of Pine. We recommend that newcomers to the language explore the basics first before diving into UDTs and objects.


Demonstration Code

Our example code shows a simple use case by displaying a ​​Zig Zag​ with user-defined settings. A new ​ZigZag object is instantiated on the first bar using a Settings object to control its attributes. The fields for the Settings object are declared using variables assigned to input.* functions, allowing control of the field values from the script's settings. The `update()` function is invoked on each bar to update the ​​ZigZag object's fields and create new lines and labels when required.



Look first. Then leap.



█ TYPES


This library contains the following types:


Settings
  Provides calculation and display attributes to ​ZigZag objects.
  Fields:
    devThreshold: The minimum percentage deviation from a point before the ​ZigZag will change direction.
    depth: The number of bars required for ​pivot detection.
    lineColor: Line color.
    extendLast: Condition allowing a line to connect the most recent ​pivot with the current ​close.
    displayReversalPrice: Condition to display the ​pivot ​price in the ​pivot label.
    displayCumulativeVolume: Condition to display the cumulative ​volume for the ​pivot segment in the ​pivot label.
    displayReversalPriceChange: Condition to display the change in price or percent from the previous ​pivot in the ​pivot label.
    differencePriceMode: Reversal change display mode. Options are "Absolute" or "Percent".
    draw: Condition to display lines and labels.

​Point
  A coordinate containing time and price information.
  Fields:
    tm: A value in UNIX time.
    price: A value on the Y axis (price).

​Pivot
  A level of significance used to determine directional​ movement or potential support​ and resistance.
  Fields:
    ln: A line object connecting the `start` and `end` ​Point objects.
    lb: A label object to display ​pivot values.
    isHigh: A condition to determine if the ​pivot is a ​​pivot high.
    vol: ​​Volume for the ​pivot segment.
    start: The coordinate of the previous ​Point.
    end: The coordinate of the current ​Point.

​ZigZag
  An object to maintain ​Zig Zag​ settings, ​pivots, and ​volume.
  Fields:
    settings: Settings object to provide calculation and display attributes.
    pivots: An array of ​​​Pivot objects.
    sumVol: The ​​volume sum for the ​​​pivot segment.
    extend: ​​Pivot object used to project a line from the last ​​​pivot to the last bar.



█ FUNCTIONS


This library contains the following functions:


last​Pivot(this)
  Returns the last ​​​Pivot of `this` ​​ZigZag if there is at least one ​​Pivot to return, and `na` otherwise.
  Parameters:
    this: (series ​​ZigZag) A ​​ZigZag object.
  Returns: (​Pivot) The last ​​Pivot in the ​​ZigZag.

update(this)
  Updates `this` ​​​ZigZag object with new ​pivots, ​volume, ​lines, labels.
  Parameters:
    this: (series ​​ZigZag) a ​​ZigZag object.
  Returns: (bool) true if a new ​Zig​ Zag​ line is found or the last Zig​ Zag​​ line has changed.

newInstance(settings)
  Instantiates a new ​ZigZag​ object with `settings`. If no settings are provided, a default ​ZigZag​​ object is created.
  Parameters:
    settings: (series Settings) A Settings object.
  Returns: (​ZigZag) A new ​ZigZag​ instance.
リリースノート
v2

Minor update to function comments.
リリースノート
v3

A `barIndex` field was added to the `Point` type to allow tracking the bar_index where a ​​pivot occurs:

​Point
  A coordinate containing bar, price, and time information.
  Fields:
    tm: A value in UNIX time.
    price: A value on the Y axis (price).
    barIndex: A `bar_index`.

リリースノート
v4

This version release comes with the following changes:

 • When the ​Zig​ Zag depth was less than 2, the ​Zig​ Zag calculation would fail. The new logic prevents setting a depth of less than 2.
 • The script now has the option to detect ​​pivot​ highs and ​pivot​ lows in a single bar. This option enhances the ​Zig​ Zag functionality, enabling it to capture double ​pivots​.
 • The library has been modified to utilize user-defined methods​. Pine Script™ methods are special functions associated with instances of specific types that offer a simpler, more convenient syntax.

This update includes the following type and methods:

Settings
  Provides calculation and display attributes to ​ZigZag objects.
  Fields:
    devThreshold: The minimum percentage deviation from a point before the ​Z​igZag will change direction.
    depth: The number of bars required for ​​pivot detection.
    lineColor: Line color.
    extendLast: Condition allowing a line to connect the most recent​​ ​pivot with the current close.
    displayReversalPrice: Condition to display the ​pivot ​price in the ​pivot label.
    displayCumulativeVolume: Condition to display the cumulative ​volume for the ​pivot segment in the ​​pivot label.
    displayReversalPriceChange: Condition to display the change in price or percent from the previous ​​pivot in the ​​pivot label.
    differencePriceMode: Reversal change display mode. Options are "Absolute" or "Percent".
    draw: Condition to display lines and labels.
    allowZigZagOnOneBar: Condition to allow double ​pivots to occur ​ie. when a large bar makes both a ​​pivot high and a ​pivot low.

lastPivot(this)
  Returns the last ​Pivot of `this` ​ZigZag if there is at least one ​Pivot to return, and `na` otherwise.
  Can be used as a method.
  Parameters:
    this: (series ​ZigZag) A ​ZigZag object.
  Returns: (​Pivot) The last ​Pivot in the ​ZigZag.

update(this)
  Updates `this` ​ZigZag object with new ​pivots, ​volume, lines, labels. NOTE: The function must be called on every bar for accurate calculations.
  Can be used as a method.
  Parameters:
    this: (series ​ZigZag) a ​ZigZag object.
  Returns: (bool) true if a new ​Zig Zag line is found or the last ​Zig Zag line has changed.
リリースノート
v5

Fixed a minor bug that would occasionally cause the Zig Zag to register incorrect pivot points.
リリースノート
v6

Fixed a minor bug that would occasionally cause the Zig Zag to register incorrect pivot points on symbols with negative prices.
リリースノート
v7

This version's release includes the following changes:

 • We've eliminated the `Point` user-defined type from the library, as it's now unnecessary. The UDTs and functions in this library version utilize Pine's new chart.point built-in type. Additionally, all parts of the code that handle creation and modification of lines and labels now use chart.point objects to determine their coordinates. The transition to utilizing this type does not affect the functional output of the library in any way.
 • We've refined the library's code comments, annotations, and variable names for clarity and readability.

Removed:

Point
  A coordinate containing bar, price, and time information.


techindicator
TradingView
Get $15 worth of TradingView Coins for you and a friend: tradingview.com/share-your-love/

Read more about the new tools and features we're building for you: tradingview.com/blog/en/

Pineライブラリ

TradingViewの精神に則り、作者はPineコードをオープンソースライブラリとして公開し、コミュニティの他のPineプログラマーが再利用できるようにしました。作者に敬意を表します!このライブラリを個人的に、または他のオープンソースの投稿で使用することができますが、このコードを投稿で再利用するには、ハウスルールに準拠する必要があります。

Pineスクリプト™ ライブラリ

ZigZag

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © TradingView

//@version=5
library("ZigZag", overlay = true)

// ZigZag Library
// v7, 2023.10.26

// This code was written using the recommendations from the Pine Script™ User Manual's Style Guide:
//   https://www.tradingview.com/pine-script-docs/en/v5/writing/Style_guide.html



//#region ———————————————————— Library types and functions


// @type                                Provides calculation and display properties to `ZigZag` objects. 
// @field devThreshold                  The minimum percentage deviation from a point before the `ZigZag` changes direction. 
// @field depth                         The number of bars required for pivot detection. 
// @field lineColor                     The color of each line drawn by the `ZigZag`.
// @field extendLast                    A condition allowing a line to connect the most recent pivot with the current close. 
// @field displayReversalPrice          A condition to display the pivot price in the pivot label. 
// @field displayCumulativeVolume       A condition to display the cumulative volume for the pivot segment in the pivot label. 
// @field displayReversalPriceChange    A condition to display the change in price or percent from the previous pivot in each pivot label. 
// @field differencePriceMode           The reversal change display mode. Options are "Absolute" or "Percent"
// @field draw                          A condition to determine whether the `ZigZag` displays lines and labels. 
// @field allowZigZagOnOneBar           A condition to allow double pivots i.e., when a large bar makes both a pivot high and a pivot low.
export type Settings
    float  devThreshold = 5.0
    int    depth = 10
    color  lineColor = #2962FF
    bool   extendLast = true
    bool   displayReversalPrice = true
    bool   displayCumulativeVolume = true
    bool   displayReversalPriceChange = true
    string differencePriceMode = "Absolute"
    bool   draw = true
    bool   allowZigZagOnOneBar = true


// @type                                Represents a significant level that indicates directional movement or potential support and resistance.
// @field ln                            A `line` object connecting the `start` and `end` chart points. 
// @field lb                            A `label` object to display pivot values. 
// @field isHigh                        A condition to determine whether the pivot is a pivot high. 
// @field vol                           The cumulative volume for the pivot segment. 
// @field start                         A `chart.point` object representing the coordinates of the previous point.
// @field end                           A `chart.point` object representing the coordinate of the current point.
export type Pivot
    line        ln
    label       lb
    bool        isHigh 
    float       vol
    chart.point start
    chart.point end


// @type                                An object to maintain a Zig Zag's settings, pivots, and cumulative volume. 
// @field settings                      A `Settings` object to provide calculation and display properties.
// @field pivots                        An array of `Pivot` objects. 
// @field sumVol                        The volume sum for the current `Pivot` object's line segment. 
// @field extend                        A `Pivot` object used to project a line from the last pivot point to the current bar. 
export type ZigZag
    Settings     settings
    array<Pivot> pivots
    float        sumVol = 0
    Pivot        extend = na



// @function                            Identifies a pivot point when the `src` has not reached beyond its value 
//                                      from `length` bars ago. Finds pivot highs when `isHigh` is `true`, and 
//                                      finds pivot lows otherwise.
// @param src                           (series float) The data series to calculate the pivot value from. 
// @param length                        (series float) The length in bars required for pivot confirmation. 
// @param isHigh                        (simple bool) Determines whether the pivot is a pivot high or pivot low. 
// @returns                             (chart.point) A `chart.point` object when a pivot is found, `na` otherwise.
findPivotPoint(series float src, series float length, simple bool isHigh) =>
    float pivotPrice = nz(src[length])
    if length == 0
        chart.point.new(time, bar_index, pivotPrice)
    else if length * 2 <= bar_index
        bool isFound = true
        for i = 0 to math.abs(length - 1)
            if (isHigh and src[i] > pivotPrice) or (not isHigh and src[i] < pivotPrice)
                isFound := false
                break
        for i = length + 1 to 2 * length
            if (isHigh and src[i] >= pivotPrice) or (not isHigh and src[i] <= pivotPrice)
                isFound := false
                break
        if isFound
            chart.point.new(time[length], bar_index[length], pivotPrice)


// @function                            Calculates the deviation percentage between the `price` and the `basePrice`. 
// @param basePrice                     (series float) The start price. 
// @param price                         (series float) The end price. 
// @returns                             (float) The signed deviation percentage. 
calcDev(series float basePrice, series float price) =>
    float result = 100 * (price - basePrice) / math.abs(basePrice)


// @function                            Calculates the difference between the `start` and `end` point as a price or 
//                                      percentage difference and converts its value to a "string". 
// @param start                         (series float) The start price. 
// @param end                           (series float) The end price. 
// @param settings                      (series Settings) A `Settings` object. 
// @returns                             (string) A "string" representation of the difference between points. 
priceRotationDiff(series float start, series float end, Settings settings) =>
    float  diff    = end - start
    string sign    = math.sign(diff) > 0 ? "+" : ""
    string diffStr = switch settings.differencePriceMode 
        "Absolute" => str.tostring(diff, format.mintick)  
        =>            str.tostring(diff * 100 / start, format.percent)
    string result  = str.format("({0}{1})", sign, diffStr) 


// @function                            Creates a "string" containing the price, cumulative volume, and change in price 
//                                      for the pivot.  
// @param start                         (series float) The start price. 
// @param end                           (series float) The end price. 
// @param vol                           (series float) The pivot's cumulative volume.
// @param settings                      (series Settings) A `Settings` object.
// @returns                             (string) A "string" to display in pivot labels. 
priceRotationAggregate(series float start, series float end, series float vol, Settings settings) =>
    string str = ""
    if settings.displayReversalPrice
        str += str.tostring(end, format.mintick) + " "
    if settings.displayReversalPriceChange
        str += priceRotationDiff(start, end, settings) + " "
    if settings.displayCumulativeVolume
        str += "\n" + str.tostring(vol, format.volume)
    str


// @function                            Creates a label with coordinates from the `point` if the `settings` display 
//                                      properties allow it. 
// @param isHigh                        (series bool) The condition to determine the label's color and location. 
// @param point                         (series chart.point) A `chart.point` object. 
// @param settings                      (series Settings) A `Settings` object. 
// @returns                             (void) The function does not return a value. 
makePivotLabel(series bool isHigh, chart.point point, Settings settings) =>
    if settings.displayReversalPrice or settings.displayReversalPriceChange or settings.displayCumulativeVolume
        [yloc, txtColor] = switch 
            isHigh => [yloc.abovebar, color.green]
            =>        [yloc.belowbar, color.red]
        label.new(point, style = label.style_none, xloc = xloc.bar_time, yloc = yloc, textcolor = txtColor)


// @function                            Updates a `Pivot` object's properties, including its `end` point, 
//                                      cumulative volume, label text, and label and line drawing locations. 
//                                      Can be used as a function or method.
// @param this                          (series Pivot) The `Pivot` object to update. 
// @param end                           (series chart.point) A new `chart.point` for the `end` field of the `Pivot`. 
// @param vol                           (series float) The cumulative volume of the `Pivot`.
// @param settings                      (series Settings) A `Settings` object. 
// @returns                             (void) The function does not return a value.
method updatePivot(Pivot this, chart.point end, float vol, Settings settings) =>
    this.end := end
    this.vol := vol
    if not na(this.lb)
        this.lb.set_point(this.end)
        this.lb.set_text(priceRotationAggregate(this.start.price, this.end.price, this.vol, settings))
    this.ln.set_second_point(this.end)


// @function                            Creates a new `Pivot` object, and assigns a line and label if the `draw` field 
//                                      of the `settings` allows it.
// @param start                         (series chart.point) A `chart.point` for the `start` of the `Pivot`. 
// @param end                           (series chart.point) A `chart.point` for the `end` of the `Pivot`. 
// @param vol                           (series float) The cumulative volume of the `Pivot`. 
// @param isHigh                        (series bool) Specifies whether the `Pivot` represents a pivot high or pivot low. 
// @param settings                      (series settings) A `Settings` object. 
// @returns                             (Pivot) The new `Pivot` object. 
newPivot(
     series chart.point start, series chart.point end, series float vol, series bool isHigh, series Settings settings
 ) =>
    Pivot p = Pivot.new(na, na, isHigh, vol, start, end)
    if settings.draw 
        p.ln := line.new(start, end, xloc = xloc.bar_time, color = settings.lineColor, width = 2)
        p.lb := makePivotLabel(isHigh, end, settings) 
    p.updatePivot(end, vol, settings)
    p


// @function                            Deletes the `line` and `label` objects assigned to the `ln` and `lb` fields in 
//                                      a `Pivot` object. 
//                                      Can be used as a function or method.
// @param this                          (series Pivot) The `Pivot` object to modify. 
// @returns                             (void) The function does not return a value.
method delete(series Pivot this) =>
    if not na(this.ln)
        this.ln.delete()
    if not na(this.lb)
        this.lb.delete()


// @function                            Determines whether the `price` of the `point` reaches past the `price` of the 
//                                      `end` chart point of a `Pivot` object. 
//                                      Can be used as a function or method.
// @param this                          (series Pivot) A `Pivot` object. 
// @param point                         (series chart.point) A `chart.point` object.
// @returns                             (bool) `true` if the `price` of the `point` reaches past that of the `end` 
//                                      in the `Pivot` object, `false` otherwise.
method isMorePrice(series Pivot this, series chart.point point) => 
    int m = this.isHigh ? 1 : -1
    bool result = point.price * m > this.end.price * m


// @function                            Returns the last `Pivot` object from a `ZigZag` instance if it contains at 
//                                      least one `Pivot`, and `na` otherwise.
//                                      Can be used as a function or method.
// @param this                          (series ZigZag) A `ZigZag` object. 
// @returns                             (Pivot) The last `Pivot` object in the `ZigZag`. 
export method lastPivot(series ZigZag this) =>
    int numberOfPivots = this.pivots.size()
    Pivot result = numberOfPivots > 0 ? this.pivots.get(numberOfPivots - 1) : na


// @function                            Updates the fields of the last `Pivot` in a `ZigZag` object and sets the 
//                                      `sumVol` of the `ZigZag` to 0. 
//                                      Can be used as a function or method.
// @param this                          (series ZigZag) A `ZigZag` object. 
// @param point                         (series chart.point) The `chart.point` for the `start` of the last `Pivot`.
// @returns                             (void) The function does not return a value. 
method updateLastPivot(series ZigZag this, series chart.point point) =>
    Pivot lastPivot = this.lastPivot()
    if this.pivots.size() == 1
        lastPivot.start := point
        if this.settings.draw
            lastPivot.ln.set_first_point(point)
    lastPivot.updatePivot(point, lastPivot.vol + this.sumVol, this.settings)
    this.sumVol := 0


// @function                            Pushes a new `Pivot` object into the `pivots` array of a `ZigZag` instance. 
//                                      Can be used as a function or method.
// @param this                          (series ZigZag) A `ZigZag` object.
// @param new                           (series Pivot) The new `Pivot` to add to the ZigZag. 
// @returns                             (void) The function does not return a value. 
method newPivotFound(series ZigZag this, series Pivot new) =>
    this.pivots.push(new)
    this.sumVol := 0


// @function                            Determines if a new pivot point is detected or if the properties of the 
//                                      last `Pivot` in the `ZigZag` need to be updated by comparing the `end` of the 
//                                      last `Pivot` to a new `point`. Updates the `ZigZag` and returns `true` if 
//                                      either condition occurs. 
//                                      Can be used as a function or method.
// @param this                          (series ZigZag) A `ZigZag` object. 
// @param isHigh                        (series bool) Determines whether it checks for a pivot high or pivot low.
// @param point                         (chart.point) A `chart.point` to compare to the `end` of the last 
//                                      `Pivot` in the `ZigZag`. 
// @returns                             (bool) `true` if it updates the last `Pivot` or adds a new `Pivot` to 
//                                      the `ZigZag`, `false` otherwise.
method newPivotPointFound(series ZigZag this, simple bool isHigh, series chart.point point) =>
    bool result = false
    Pivot lastPivot = this.lastPivot()
    if not na(lastPivot)
        if lastPivot.isHigh == isHigh 
            if lastPivot.isMorePrice(point)
                this.updateLastPivot(point)
                result := true
        else
            float dev = calcDev(lastPivot.end.price, point.price)
            if (not lastPivot.isHigh and dev >= this.settings.devThreshold) or 
                 (lastPivot.isHigh and dev <= -1 * this.settings.devThreshold)
                newPivotFound(this, newPivot(lastPivot.end, point, this.sumVol, isHigh, this.settings))
                result := true
    else
        this.newPivotFound(newPivot(point, point, this.sumVol, isHigh, this.settings))
        result := true
    result


// @function                            Tries to find a new pivot point for the `ZigZag` instance. Updates the
//                                      `ZigZag` and returns `true` when it registers a detected pivot.
//                                      Can be used as a function or method.
// @param this                          (series ZigZag) A `ZigZag` object.
// @param src                           (series float) The data series to calculate the pivot value from.  
// @param isHigh                        (simple bool) Determines whether it checks for a pivot high or pivot low. 
// @param depth                         (series int) The number of bars to search for new pivots. 
// @param registerPivot                 (series bool) A condition that determines whether or not to register a pivot. 
// @returns                             (bool) `true` when a new pivot point is registered and the `ZigZag` is updated, 
//                                      `false` otherwise.
method tryFindPivot(
     series ZigZag this, series float src, simple bool isHigh, series int depth, series bool registerPivot = true
 ) =>
    chart.point point = findPivotPoint(src, depth, isHigh)
    bool result = not na(point) and registerPivot ? this.newPivotPointFound(isHigh, point) : false


// @function                            Updates a `ZigZag` objects with new pivots, volume, lines, and labels.
//                                      NOTE: This function must be called on every bar for accurate calculations.
//                                      Can be used as a function or method.
// @param this                          (series ZigZag) A `ZigZag` object.         
// @returns                             (bool) `true` when a new pivot point is registered and the `ZigZag` is updated, 
//                                      `false` otherwise.
export method update(series ZigZag this) =>
    int depth = math.max(2, math.floor(this.settings.depth / 2))
    this.sumVol += nz(volume[depth])
    bool somethingChanged = this.tryFindPivot(high, true, depth)
    somethingChanged := this.tryFindPivot(
         low, false, depth, this.settings.allowZigZagOnOneBar or not somethingChanged
     ) or somethingChanged
    Pivot lastPivot = this.lastPivot()
    float remVol = math.sum(volume, math.max(depth, 1))
    if this.settings.extendLast and barstate.islast and not na(lastPivot)
        bool isHigh = not lastPivot.isHigh
        float curSeries = isHigh ? high : low
        chart.point end = chart.point.new(time, bar_index, curSeries)
        if na(this.extend) or somethingChanged
            if not na(this.extend)
                this.extend.delete()
            this.extend := newPivot(lastPivot.end, end, this.sumVol, isHigh, this.settings)
        this.extend.updatePivot(end, this.sumVol + remVol, this.settings)
    somethingChanged


// @function                            Instantiates a new `ZigZag` object with optional `settings`. 
//                                      If no `settings` are provided, creates a `ZigZag` object with default settings. 
// @param settings                      (series Settings) A `Settings` object. 
// @returns                             (ZigZag) A new `ZigZag` instance. 
export newInstance(series Settings settings = na) =>
    ZigZag result = ZigZag.new(na(settings) ? Settings.new() : settings, array.new<Pivot>())
//#endregion



//#region ———————————————————— Example Code

// @variable The deviation percentage from the last local high or low required to form a new Zig Zag point.
float deviationInput = input.float(5.0, "Deviation (%)", minval = 0.00001, maxval = 100.0)
// @variable The number of bars in the pivot calculation.
int depthInput = input.int(10, "Depth", minval = 1)
// @variable The color of the Zig Zag's lines.
color lineColorInput = input.color(#2962FF, "Line Color")
// @variable If `true`, the Zig Zag will also display a line connecting the last known pivot to the current `close`.
bool extendInput = input.bool(true, "Extend to Last Bar")
// @variable If `true`, the pivot labels will display their price values.
bool showPriceInput = input.bool(true, "Display Reversal Price")
// @variable If `true`, each pivot label will display the volume accumulated since the previous pivot.
bool showVolInput = input.bool(true, "Display Cumulative Volume")
// @variable If `true`, each pivot label will display the change in price from the previous pivot.
bool showChgInput = input.bool(true, "Display Reversal Price Change", inline = "Price Rev")
// @variable Controls whether the labels show price changes as raw values or percentages when `showChgInput` is `true`.
string priceDiffInput = input.string("Absolute", "", options = ["Absolute", "Percent"], inline = "Price Rev")

// @variable A `Settings` instance for `ZigZag` creation.
var Settings settings = 
 Settings.new(
     deviationInput, depthInput, 
     lineColorInput, extendInput, 
     showPriceInput, showVolInput, 
     showChgInput,   priceDiffInput
 )

// @variable A `ZigZag` object created using the `settings`.
var ZigZag zigZag = newInstance(settings)

// Update the `zigZag` on every bar.
zigZag.update()
//#endregion

82件のコメント

    2022 12月 12
    Thank you very much.
    I never though that library can be written in this way.
    2022 12月 13
    RozaniGhani-RG, We are happy you like it and appreciate your support! Happy coding 💚
    2023 1月 12
    How to return extremum x and y ? want to plot vertical lines from extremum .
    cant manage to do this .
    what code after
    import TradingView/ZigZag/3 as zz
    .......
    var zz.ZigZag zigZag = zz.newInstance(settings)
    zz.update(zigZag)
    try bifferent options , not work for me
    zz.Point pp = zz.Point.new()
    hiLine := line.new(pp.barIndex[1], pp.price[1],pp.barIndex, pp.price[1], color = color.rgb(224, 116, 116), width = 1)
    2023 2月 23
    Somehow, ZigZagLib.lastPivot(zzBig) always gives me a na. No matter what.
    ```
    var lastPivot = ZigZagLib.lastPivot(zzBig)
    if not na(lastPivot)
    line.set_color(lastPivot.ln, lastPivot.start.price > lastPivot.end.price ? color.green : lastPivot.start.price < lastPivot.end.price ? color.red : color.gray)
    ```
    2023 2月 24
    2023 2月 24
    moonypto, It was a mistake on my end.
    2023 2月 24
    niquedegraaff, I see :) hows trading so far?
    2023 3月 29
    niquedegraaff, okay what was the mistake? I keep getting "na" as well.
    2023 6月 1
    Please help.

    I have been struggling to extract the last zig zag pivot price in a plottable data format for quite some time. The following (in quotation marks) is a minimal code example of my attempt that feels the closest:

    "
    //version=5
    indicator("Zig Zag Pivot Data Extractor", overlay = true, max_lines_count = 500, max_labels_count = 500)

    import TradingView/ZigZag/6 as ZigZagLib

    // Create Zig Zag instance from user settings.
    var zigZag = ZigZagLib.newInstance(
    ZigZagLib.Settings.new(
    input.float(5.0, "Price deviation for reversals (%)", 0.00001, 100.0, 0.5, "0.00001 - 100"),
    input.int(10, "Pivot legs", 2),
    input(#2962FF, "Line color"),
    input(true, "Extend to last bar"),
    input(true, "Display reversal price"),
    input(true, "Display cumulative volume"),
    input(true, "Display reversal price change", inline = "priceRev"),
    input.string("Absolute", "", ["Absolute", "Percent"], inline = "priceRev"),
    true)
    )

    // Update 'zigZag' object on each bar with new ​pivots, ​volume, lines, labels.
    zigZag.update()

    // Attempt to extract price of previous pivot
    zz_pivots = array.get(zigZag.pivots,0)
    zz_prevPivot_price = zz_pivots.start.price

    // Attempt to plot price of previous pivot
    plot( zz_prevPivot_price , style = plot.style_stepline_diamond , color = color.rgb(255,255,255,50) , linewidth = 2 )
    "

    The code compiles but I get the following study error: "Error on bar 0: In 'array.get()' function. Index 0 is out of bounds, array size is 0."

    Strangely, when I try to check the size of array 'zigZag.pivots' ( by adding "plot( array.size(zigZag.pivots) , style = plot.style_stepline_diamond )" and commenting out the above plot command ), it shows that the array zigZag.pivots is of size > 0 and monotonically increasing with the number of plotted pivots, which seems to contradict the study error.
    Some guidance would be greatly appreciated. Thanks in advance!
    2023 6月 29
    mrmanifolder, I am having the same issue
    2023 10月 1
    mrmanifolder, Hi 👋,

    The error at bar 0 is due to calling `array.get()` on an empty array, which occurs when your script runs on early bars, as no pivots have yet been identified and the array is unpopulated. To avoid this, ensure to check the array has elements before calling `array.get()`, else, return `na`.

    //@version=5
    indicator("Zig Zag Pivot Data Extractor", overlay = true, max_lines_count = 500, max_labels_count = 500)

    import TradingView/ZigZag/6 as TVzz

    var TVzz.Settings settings = 
     TVzz.Settings.new(
     input.float(5.0,         "Deviation (%)",                       minval = 0.00001, maxval = 100.0),
     input.int(10,            "Depth",                               minval = 1),
     input.color(#2962FF,   "Line Color"),
     input.bool(true,         "Extend to Last Bar"),
     input.bool(true,         "Display Reversal Price"),
     input.bool(true,         "Display Cumulative Volume"),
     input.bool(true,         "Display Reversal Price Change",       inline = "Price Rev"),
     input.string("Absolute", "", options = ["Absolute", "Percent"], inline = "Price Rev"))

    var TVzz.ZigZag zigZag = TVzz.newInstance(settings)
    zigZag.update()

    plot(zigZag.pivots.size() > 0 ? zigZag.pivots.last().end.price : na)
    2023 10月 10
    PineCoders, Thank you. Excellent reply.
    2023 10月 29
    PineCoders, this code shows an error after running .

    9:41:13 PM Script could not be translated from: null
    2023 11月 4
    SEYED98, Replace
    //[user]@version[/user]=5
    with
    //@version=5
    5月 12
    PineCoders, Thank you - using your code, attempted to extract cumulative volume per pivot ( "per zig and per zag" ) without much luck. Could you help?
    9月 11
    PineCoders, Here how to get the last 5 pivot points in an array . so that we can use it and check whther the closing is near support or resistence . please help .Thank you well in advance
    2022 12月 13
    PineCoders Hi Mod,
    Can you make a standard Zigzag indicator like MT4 combined with Multiple TimeFrame Selections ( like your "Moving Average" indicator)?
    Your current Zigzag doesn't have a line, it shows just Price (%) &Volume. For normal users who don't have code skills like me, It is very hard for you.

    2 week ago, I buy MTF(Multiple time frame) Zigzag indicator on Tradingview, but It can not show zigzag M5 in TF M1.
    His code has so many bugs inside.

    Hope you can help us to build the MTF Zigzag Standard indicator!
    Thanks
    2023 1月 6
    TradeDemy, Yes a MTF option would be fantastic
    2023 5月 23
    TradeDemy, If you're unable to see the ZigZag line on your chart, it's likely because both its starting and ending points need to be within your chart's range. To fix this, you can zoom out, scroll through historical data, or decrease the minimum percent deviation setting. This will increase pivot detection and possibly bring two pivots within your chart view, allowing the ZigZag line to render. Adjusting your view or indicator settings can ensure the visibility of the ZigZag line. Cheers and happy trading 💚
    2023 1月 8
    Thank you awesome code :)
    I'm interested in extracting price values to code an indicator. I'm a newbie at coding and couldn't figure it out.Im only interested in pivot price values on labels. I would really appreciate a quick tip on that :)
    2023 4月 16
    Hi! Is it possible to get an array of "calcDev"? And how can I change format labels without "()"? Thanks a lot!
    2022 12月 15
    Nice, now we can actually mimic somewhat key:value pairs.
    2023 9月 25
    Hello I want to reuse this in a paid script. Can I use it if I mention it in my description?
    2023 5月 31
    Hi!
    Can someone help me how to count the consecutive higher highs and lower lows using this library?
    I mean show as a label above the high and below the low. (not the price)
    e.g the actual pivot is higher than the latest pivot high , gets the number 1.
    If the next pivot is higher gets the number 2. If not, gets the number 0., etc.
    2023 4月 18
    Is there a way to plot the last Reversal Prices
    2023 10月 1
    brettkind, Please see the code solution in our response above.
    2023 3月 15
    Thanks for a great job.
    Just a quick urgent questions how can I access the below variable?Is it Global?
    // param start (series Point) The start Point of the Pivot.
    2023 1月 10
    nice work but problem in volume calculate !
    2023 2月 24
    @pratik_Crypto_King, good call
    2022 12月 12
    cheers
    2022 12月 13
    melikatrader94, cheers Melika jan
    2022 12月 13
    2023 2月 24
    melikatrader94, whats wrong? :)
    2022 12月 13
    melikatrader94, Cheers to you! Thank you for taking the time to comment!
    2023 10月 1
    Please reply on how can we plot the Cumulative Volumes and reversals in an indicator
    i am searching this from weeks and not found any method to retrieve it from a Library
    2023 4月 29
    how can i use the values that indicator returns (reversal price change,price,etc)in strategies or show it
    please send an example code for this
    2022 12月 16
    Hi there, awesome work! Just a quick question: currently I see you guys have 3 different ways to find pivot points:
    1. Williams Fractal in ta library.
    2. ta.pivothigh() and ta.pivotlow() in Pivots HL indicator.
    3. findPivotPoint() in this ZigZag library.

    Which one you think is the best method, performance wise and accuracy wise?
    2022 12月 18
    @nioctac, It is not straightforward to determine the best approach, as different methods come with their own advantages and disadvantages. To help you make a more informed decision, here is a breakdown of the pros and cons of each method.

    1. Williams Fractals:
    Pros:
    * Fractals are popular.
    * Williams Fractals use a specific formula to identify pivot points that may be more accurate than other methods.
    Cons:
    * Fractals can be subjective and may require interpretation, which can lead to inconsistent results.
    * False signals: May be more subject to generating whipsaw depending on if the market is trending or choppy comparative to other methods.

    2. `ta.pivothigh()` and` ta.pivotlow()` in the Pivot HL indie:
    Pros:
    * These functions are part of the built-in library and easy to implement.
    * Looks for a clear “chevron” shape and waits until a pivot is confirmed before returning a value providing reliable results.
    Cons:
    * Lag: pivots are based on historical price data, which means they may not provide timely signals for traders looking to make immediate trades.
    * Calculation method could differ from other forms of zig zag that update on each bar, or compensate for edge cases such as making a pivot high and low on the same bar, or where a pivot has not been found for an extended period of time.

    3. `findPivotPoint()` in the ZigZag library:
    Pros:
    * Ease of use. Simply import and calculate zig zag
    * Calculates additional information about the pivot legs like cumulative volume, or price deviation
    Cons:
    * Can be challenging to work with beyond the basic output, as it is an object-oriented algo that requires programming experience and a deeper understanding of the library's functions.
    * Uses loops to calculate the pivot points, which could be more resource intensive than simpler methods.
    2022 12月 18
    PineCoders, that's a very detailed answer, thank you so much for your help, really appreciate it!
    2022 12月 21
    @nioctac, 💚
    2022 12月 13
    thnaks for sharing wisdom
    2022 12月 13
    moonypto, You are very welcome. We are glad you can find usefulness in our work.
    2022 12月 13
    Awsome
    2022 12月 13
    2022 12月 13
    How to get values of last HH and HL . please help me with the code please . and display in table format ?
    8月 21
    do you have some code samples on how to use zigzag? it looks great
    7月 25
    Hi, why is the volume of the first bar/starting point of the ZigZag line not added to the cumulative volume? Why not the first bar instead of the last or why not both?
    7月 24
    Hey, why isn't the volume of the starting bar of a zigzag line added up when summing the volume? Why not the other way round? Because that way the volume of the very first bar (bar index = 0) isn't lost.
    7月 2
    Is this library a bare-bone library? I see no way to access all pivots and connect them with lines.
    5月 19
    Could you add a "line width" parameter, please?

    Other features that could be relevant are % retracement or extension compared to previous swings.
    4月 16
    Thanks. Awesome code.

    On a 1 minute chart, the lookback for the ZZ pattern is less than one day.

    Any ideas as to how to extend this to TWO days?
    I love this library, but have a question.
    How can I change the line width and color?
    For some reason I can't see the zig zag on the chart I think somthings wrong with the code
    sadly this indicator doesn't work as the zigzag is NOT being shown on the charts please fix your code as well add maybe horitantial lines on pivot points with price an % vale from high to low
    2023 12月 9
    hi. thank you.
    it seems that ZigZag Provides calculation and display attributes to ​ZigZag objects at current timeframe.
    how can I add different Timeframes to this zigzag object to provide their calculation.
    2023 12月 7
    Not usable without any access to the historical swings. What is the point in converting an existing code to a library without any additional parameters or customization options. Also, what is the point in creating a 'pinescript' as everything need to be created every time as to do in python.
    2023 11月 6
    How to plot Reversal price change (Display Reversal Price option is given in settings that only provide labels)
    I want to plot it
    Please Provide me code for this
    I am unable to make it a variable which can be used in other Calculations like finding Bos and MSS
    2023 10月 31
    good work but can export methods? i wanna to overwrite update and tryFindPivot isnt exported and also newPivotPointFound isnt exported and it generate a chain of functions i need to copy and paste to my code like a function because you dont export that, and that isn't the objective of use a library
    2023 10月 14
    hi dear Master
    thank you for this Useful Library

    if i want to draw trendline with connecting two green zigzag points and another trend line with connecting red zigzag points . how can i do it? please explain it with a pinescript code . thank you
    2023 10月 12
    Could you update to suport HTF?
    2023 4月 29
    Very nice coding and zig zag.
    2023 4月 17
    Great work!
    But is there a way to plot the reversal price?
    2023 3月 29
    sample code please to extract data frm functions in the library? thanks
    2023 3月 29
    xyzz06599, export type Pivot
    line ln
    label lb
    bool isHigh
    float vol
    Point start
    Point end
    var stend = Pivot.new()
    plot(stend.vol)
    2023 3月 11
    Fantastic! Pine Script is now more like an OO language :-) and it would be nice if all variables could be objectified as well, like in python
    2023 2月 24
    I don't know how to report bugs, the user that publishes this script doesnt respond on private messages.
    It doesn't matter what settings I set, the result is that it just doesn't draw correctly.

    2023 2月 24
    niquedegraaff, Hello there, can you please DM us the code and settings you are using so the issue can be investigated? Thank you for the report.
    2023 2月 24
    I think version 4 has a bug. It draws the lines to the first high, and never update it again. When disabling allowZigZagOnOneBar nothing will be drawn at all.
    2023 2月 24
    moon soon pattern
    2023 2月 23
    Feature request: switch from high/low to just close values to get zig zag on close prices
    2023 5月 23
    niquedegraaff, We will consider this in future versions. Thanks for the suggestion
    2023 1月 19
    That's awesome! Learn from master!
    2023 5月 23
    dandrideng, Cheers! Thanks for taking the time to comment 💚
    2023 1月 11
    I can't view the code properly on Chrome in Windows...
    2022 12月 31
    Hello . What i doing wrong ? i want to draw horisontal line from each extremum. to next extremum

    import TradingView/ZigZag/3 as zz
    .......
    var zz.ZigZag zigZag = zz.newInstance(settings)
    zz.update(zigZag)
    //// before works ok .
    var zz.Point pp = zz.Point.new()
    ppp = pp.price
    iii = pp.barIndex
    var line hiLine = na
    hiLine := line.new(iii[1], ppp,iii, ppp, color = color.rgb(224, 116, 116), width = 1)

    nothing draw and disapear zigzag lines.
    THANK YOu
    2022 12月 26
    Zigzag ist großartieg. Wirklich.
    2022 12月 21
    dont see Demonstration Code
    cant plot and run :(. can u add simple example please
    2022 12月 26
    oslikpjat, an example code is included within the library for your reference. You can copy the entire script into the editor and add it to the chart to view the output of the functions. If you are unable to see the lines, try decreasing the deviation percent.
    2023 1月 4
    PineCoders, After long fighting finally manage to work it . here is code for other users
    //version=5
    indicator("ZZ", overlay=true)
    import TradingView/ZigZag/3 as zz
    ShowPerc = input(true, title="Percent" ,inline = "01")
    ShowZZ = input(true, title="Show ZZ" ,inline = "01")
    ShowExt = input(true, title="Show last" ,inline = "01")

    var zz.Settings settings =
    zz.Settings.new( 1, 10, #2962FF, ShowExt, false, false, ShowPerc, "Percent",ShowZZ)

    var zz.ZigZag zigZag = zz.newInstance(settings)
    zz.update(zigZag)
    2023 1月 20
    oslikpjat, thx. i play with
    //version=5
    indicator("ZZ", overlay = true)
    import TradingView/ZigZag/3 as ZZ

    float deviationInput = input.float(5.0, "Deviation (%)", minval = 0.00001, maxval = 100.0)
    int depthInput = input.int(10, "Depth", minval = 1)
    color lineColorInput = input.color(#2962FF, "Line Color")
    bool extendInput = input.bool(true, "Extend to Last Bar")
    bool showPriceInput = input.bool(true, "Display Reversal Price")
    bool showVolInput = input.bool(true, "Display Cumulative Volume")
    bool showChgInput = input.bool(true, "Display Reversal Price Change", inline = "Price Rev")
    string priceDiffInput = input.string("Absolute", "", options = ["Absolute", "Percent"], inline = "Price Rev")

    float devThreshold = 5.0

    var ZZ.Settings settings =
    ZZ.Settings.new(
    devThreshold, depthInput,
    lineColorInput, extendInput,
    showPriceInput, showVolInput,
    showChgInput, priceDiffInput)

    var ZZ.ZigZag zigZag = ZZ.newInstance(settings)
    ZZ.update(zigZag)

    it's so clean.
    6月 12
    azuzard, hi can you send complete clean code?

    免責事項