Library · Pine Script v5 · Library

ZenLibrary

by Web3Degenerate

ZenLibrary is a custom Pine Script utility library providing standard helper functions for trading scripts.

View on GitHub

GitHub stars2on the repository
Pine versionv5runs as is
Lines of code312
Settings0inputs
LicenceNone statedfile: MPL-2.0
Last update2 years ago13 Sep 2024

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 library, select all of the template text and paste. Press Save and give it a name.
  4. 4Publish or import itA library draws nothing. Publish it from the editor, then import its functions in your own scripts.

Source Code

312 lines of Pine Script v5 from advanced-pine-script/8.Libraries/3.ZenLibrary-Source-Code.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

3.ZenLibrary-Source-Code.pine
// Updated Feb 14, 2024

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

// Last Updated: 14th February, 2024
// @version=5
// @description A collection of custom tools & utility functions commonly used with my scripts
library("ZenLibrary")

// --- BEGIN UTILITY FUNCTIONS {
// @function Calculates how many decimals are on the quote price of the current market
// @returns The current decimal places on the market quote price
export getDecimals() => math.abs(math.log(syminfo.mintick) / math.log(10))

// @function Calculates the pip size of the current market
// @param int multiplier The mintick point multiplier (1 by default, 10 for FX/Crypto/CFD but can be used to override when certain markets require)
// @returns The pip size for the current market
export getPipSize(int multiplier = 1) => syminfo.mintick * ((multiplier == 1 and (syminfo.type == "forex" or syminfo.type == "crypto" or syminfo.type == "cfd")) ? 10 : multiplier)

// @function Truncates (cuts) excess decimal places
// @param float number The number to truncate
// @param float decimalPlaces (default=2) The number of decimal places to truncate to
// @returns The given number truncated to the given decimalPlaces
export truncate(float number, simple float decimalPlaces = 2.0) =>
    factor = math.pow(10, decimalPlaces)
    int(number * factor) / factor

// @function Converts pips into whole numbers
// @param float number The pip number to convert into a whole number
// @returns The converted number
export toWhole(float number) =>
    _return = number / getPipSize() / syminfo.pointvalue

// @function Converts whole numbers back into pips
// @param float number The whole number to convert into pips
// @returns The converted number
export toPips(float number) =>
    number * syminfo.mintick * (syminfo.type == "forex" or syminfo.type == "crypto" ? 10 : 1)

// @function Gets the percentage change between 2 float values over a given lookback period
// @param float value1 The first value to reference
// @param float value2 The second value to reference
// @param int lookback The lookback period to analyze
export getPctChange(float value1, float value2, int lookback) =>
    vChange = value1 - value2
    vDiff   = vChange - vChange[lookback]
    (vDiff / vChange) * 100

// @function Calculates OANDA forex position size for AutoView based on the given parameters
// @param float balance The account balance to use
// @param float risk The risk percentage amount (as a whole number - eg. 1 = 1% risk)
// @param float stopPoints The stop loss distance in POINTS (not pips)
// @param float conversionRate The conversion rate of our account balance currency
// @returns The calculated position size (in units - only compatible with OANDA)
export av_getPositionSize(float balance, float risk, float stopPoints, float conversionRate) =>
    riskAmount = balance * (risk / 100) * conversionRate
    riskPerPoint = stopPoints * syminfo.pointvalue
    positionSize = riskAmount / riskPerPoint / syminfo.mintick
    math.round(positionSize)

// } END UTILITY FUNCTIONS
// --- BEGIN TA FUNCTIONS {

// @function Calculates a bullish fibonacci value
// @param priceLow The lowest price point
// @param priceHigh The highest price point
// @param fibRatio The fibonacci % ratio to calculate
// @returns The fibonacci value of the given ratio between the two price points
export bullFib(float priceLow, float priceHigh, float fibRatio = 0.382) => (priceLow - priceHigh) * fibRatio + priceHigh

// @function Calculates a bearish fibonacci value
// @param priceLow The lowest price point
// @param priceHigh The highest price point
// @param fibRatio The fibonacci % ratio to calculate
// @returns The fibonacci value of the given ratio between the two price points
export bearFib(float priceLow, float priceHigh, float fibRatio = 0.382) => (priceHigh - priceLow) * fibRatio + priceLow

// @function Gets a Moving Average based on type (! MUST BE CALLED ON EVERY TICK TO BE ACCURATE, don't place in scopes)
// @param int length The MA period
// @param string maType The type of MA
// @returns A moving average with the given parameters
export getMA(simple int length, string maType) =>
    switch maType
        "EMA" => ta.ema(close, length)
        "SMA" => ta.sma(close, length)
        "HMA" => ta.hma(close, length)
        "WMA" => ta.wma(close, length)
        "VWMA" => ta.vwma(close, length)
        "VWAP" => ta.vwap
        => 
            e1 = ta.ema(close, length)
            e2 = ta.ema(e1, length)
            2 * e1 - e2

// @function Performs EAP stop loss size calculation (eg. ATR >= 20.0 and ATR < 30, returns 20)
// @param float atr The given ATR to base the EAP SL calculation on
// @returns The EAP SL converted ATR size
export getEAP(float atr) =>
    atrWhole = toWhole(atr) // First convert ATR to whole number for consistency across markets
    eapStopWhole = atrWhole // Then if ATR is above 1 full integer, leave it alone as it's already a whole number
    // If ATR is between 20 and 30 pips, set stop distance to 20 pips
    if atrWhole >= 20.0 and atrWhole < 30.0
        eapStopWhole := 20.0
    // If ATR is between 30 and 50 pips, set stop distance to 30 pips
    if atrWhole >= 30.0 and atrWhole < 50.0
    // If ATR is between 50 and 100 pips, set stop distance to 50 pips
        eapStopWhole := 30.0
    if atrWhole >= 50.0 and atrWhole < 100.0
        eapStopWhole := 50.0
    // If ATR is above 100 pips, set stop distance to 100 pips
    if atrWhole >= 100.0
        eapStopWhole := 100.0
    // Convert EAP SL from whole number back into pips
    toPips(eapStopWhole)

// @function Performs secondary EAP stop loss size calculation (eg. ATR < 40, add 5 pips, ATR between 40-50, add 10 pips etc)
// @param float atr The given ATR to base the EAP SL calculation on
// @returns The EAP SL converted ATR size
export getEAP2(float atr) =>
    atrWhole = toWhole(atr) // First convert ATR to whole number for consistency across markets
    eapStopWhole = atrWhole
    // If ATR is below 40, add 5 pips
    if atrWhole < 40.0
        eapStopWhole := eapStopWhole + 5.0
    // If ATR is between 40-50, add 10 pips
    if atrWhole >= 40.0 and atrWhole <= 50.0
        eapStopWhole := eapStopWhole + 10.0
    // If ATR is between 50-200, add 20 pips
    if atrWhole > 50.0 and atrWhole <= 200.0
        eapStopWhole := eapStopWhole + 20.0
    // Convert EAP SL from whole number back into pips
    toPips(eapStopWhole)

// @function Counts how many candles are above the MA
// @param int lookback The lookback period to look back over
// @param float ma The moving average to check
// @returns The bar count of how many recent bars are above the MA
export barsAboveMA(int lookback, float ma) =>
    counter = 0
    for i = 1 to lookback by 1
        if close[i] > ma[i]
            counter := counter + 1
    counter

// @function Counts how many candles are below the MA
// @param int lookback The lookback period to look back over
// @param float ma The moving average to reference
// @returns The bar count of how many recent bars are below the EMA
export barsBelowMA(int lookback, float ma) =>
    counter = 0
    for i = 1 to lookback by 1
        if close[i] < ma[i]
            counter := counter + 1
    counter

// @function Counts how many times the EMA was crossed recently
// @param int lookback The lookback period to look back over
// @param float ma The moving average to reference
// @returns The bar count of how many times price recently crossed the EMA
export barsCrossedMA(int lookback, float ma) =>
    counter = 0
    for i = 1 to lookback by 1
        if open[i] > ma[i] and close[i] < ma[i] or open[i] < ma[i] and close[i] > ma[i]
            counter := counter + 1
    counter

// @function Counts how many green & red bars have printed recently (ie. pullback count)
// @param int lookback The lookback period to look back over
// @param int direction The color of the bar to count (1 = Green, -1 = Red)
// @returns The bar count of how many candles have retraced over the given lookback & direction
export getPullbackBarCount(int lookback, int direction) =>
    recentCandles = 0
    for i = 1 to lookback by 1
        if direction == 1 and close[i] > open[i]  // Count green bars
            recentCandles := recentCandles + 1
        if direction == -1 and close[i] < open[i]  // Count red bars
            recentCandles := recentCandles + 1
    recentCandles

// @function Gets the current candle's body size (in POINTS, divide by 10 to get pips)
// @returns The current candle's body size in POINTS
export getBodySize() => math.abs(close - open) / syminfo.mintick

// @function Gets the current candle's top wick size (in POINTS, divide by 10 to get pips)
// @returns The current candle's top wick size in POINTS
export getTopWickSize() => math.abs(high - (close > open ? close : open)) / syminfo.mintick

// @function Gets the current candle's bottom wick size (in POINTS, divide by 10 to get pips)
// @returns The current candle's bottom wick size in POINTS
export getBottomWickSize() => math.abs((close < open ? close : open) - low) / syminfo.mintick

// @function Gets the current candle's body size as a percentage of its entire size including its wicks
// @returns The current candle's body size percentage
export getBodyPercent() => math.abs(open - close) / math.abs(high - low)

// } END TA FUNCTIONS
// --- BEGIN CANDLE SETUP DETECTION {

// @function Checks if the current bar is a hammer candle based on the given parameters
// @param float fib (default=0.382) The fib to base candle body on
// @param bool colorMatch (default=false) Does the candle need to be green? (true/false)
// @returns A boolean - true if the current bar matches the requirements of a hammer candle
export isHammer(float fib = 0.382, bool colorMatch = false) =>
    bullFib = bullFib(low, high, fib)
    lowestBody = close < open ? close : open
    lowestBody >= bullFib and (not colorMatch or close > open)

// @function Checks if the current bar is a shooting star candle based on the given parameters
// @param float fib (default=0.382) The fib to base candle body on
// @param bool colorMatch (default=false) Does the candle need to be red? (true/false)
// @returns A boolean - true if the current bar matches the requirements of a shooting star candle
export isStar(float fib = 0.382, bool colorMatch = false) =>
    bearFib = bearFib(low, high, fib)
    highestBody = close > open ? close : open
    highestBody <= bearFib and (not colorMatch or close < open)
    
// @function Checks if the current bar is a doji candle based on the given parameters
// @param float wickSize (default=2) The maximum top wick size compared to the bottom (and vice versa)
// @param bool bodySize (default=0.05) The maximum body size as a percentage compared to the entire candle size
// @returns A boolean - true if the current bar matches the requirements of a doji candle
export isDoji(float wickSize = 2.0, float bodySize = 0.05) =>
    getTopWickSize() <= getBottomWickSize() * wickSize and getBottomWickSize() <= getTopWickSize() * wickSize and getBodyPercent() <= bodySize

// @function Checks if the current bar is a bullish engulfing candle
// @param float allowance (default=0) How many POINTS to allow the open to be off by (useful for markets with micro gaps)
// @param float rejectionWickSize (default=disabled) The maximum rejection wick size compared to the body as a percentage
// @param bool engulfWick (default=false) Does the engulfing candle require the wick to be engulfed as well?
// @returns A boolean - true if the current bar matches the requirements of a bullish engulfing candle
export isBullishEC(float allowance = 0.0, float rejectionWickSize = 0.0, bool engulfWick = false) =>
  (close[1] <= open[1] and close >= open[1] and open <= close[1] + allowance) and (not engulfWick or close >= high[1]) and 
  (rejectionWickSize == 0.0 or getTopWickSize() / getBodySize() < rejectionWickSize)

// @function Checks if the current bar is a bearish engulfing candle
// @param float allowance (default=0) How many POINTS to allow the open to be off by (useful for markets with micro gaps)
// @param float rejectionWickSize (default=disabled) The maximum rejection wick size compared to the body as a percentage
// @param bool engulfWick (default=false) Does the engulfing candle require the wick to be engulfed as well?
// @returns A boolean - true if the current bar matches the requirements of a bearish engulfing candle
export isBearishEC(float allowance = 0.0, float rejectionWickSize = 0.0, bool engulfWick = false) =>
  (close[1] >= open[1] and close <= open[1] and open >= close[1] - allowance) and (not engulfWick or close <= low[1]) and
  (rejectionWickSize == 0.0 or getBottomWickSize() / getBodySize() < rejectionWickSize)

// @function Detects inside bars
// @returns Returns true if the current bar is an inside bar
export isInsideBar() => high < high[1] and low > low[1]

// @function Detects outside bars
// @returns Returns true if the current bar is an outside bar
export isOutsideBar() => high > high[1] and low < low[1]

// } END CANDLE SETUP DETECTION
// --- BEGIN FILTER FUNCTIONS {

// @function Determines if the current price bar falls inside the specified session
// @param string sess The session to check
// @param bool useFilter (default=true) Whether or not to actually use this filter
// @returns A boolean - true if the current bar falls within the given time session
export barInSession(simple string sess, bool useFilter = true) => na(time(timeframe.period, sess + ":1234567")) == false or not useFilter

// @function Determines if the current price bar falls outside the specified session
// @param string sess The session to check
// @param bool useFilter (default=true) Whether or not to actually use this filter
// @returns A boolean - true if the current bar falls outside the given time session
export barOutSession(simple string sess, bool useFilter = true) => na(time(timeframe.period, sess + ":1234567")) or not useFilter

// @function Determines if this bar's time falls within date filter range
// @param int startTime The UNIX date timestamp to begin searching from
// @param int endTime the UNIX date timestamp to stop searching from
// @returns A boolean - true if the current bar falls within the given dates
export dateFilter(int startTime, int endTime) => time >= startTime and time <= endTime

// @function Checks if the current bar's day is in the list of given days to analyze
// @param bool monday Should the script analyze this day? (true/false)
// @param bool tuesday Should the script analyze this day? (true/false)
// @param bool wednesday Should the script analyze this day? (true/false)
// @param bool thursday Should the script analyze this day? (true/false)
// @param bool friday Should the script analyze this day? (true/false)
// @param bool saturday Should the script analyze this day? (true/false)
// @param bool sunday Should the script analyze this day? (true/false)
// @returns A boolean - true if the current bar's day is one of the given days
export dayFilter(bool monday, bool tuesday, bool wednesday, bool thursday, bool friday, bool saturday, bool sunday) => 
  dayofweek == dayofweek.monday and monday or
  dayofweek == dayofweek.tuesday and tuesday or
  dayofweek == dayofweek.wednesday and wednesday or
  dayofweek == dayofweek.thursday and thursday or
  dayofweek == dayofweek.friday and friday or
  dayofweek == dayofweek.saturday and saturday or
  dayofweek == dayofweek.sunday and sunday

// @function Checks the current bar's size against the given ATR and max size
// @param float atrValue (default=ATR 14 period) The given ATR to check
// @param float maxSize The maximum ATR multiplier of the current candle
// @returns A boolean - true if the current bar's size is less than or equal to atr x maxSize
_atr = ta.atr(14)
export atrFilter(float atrValue = 1111, float maxSize) => maxSize == 0.0 or math.abs(high - low) <= (atrValue == 1111 ? _atr : atrValue) * maxSize

// } END FILTER FUNCTIONS
// --- BEGIN DISPLAY FUNCTIONS {

// @function This updates the given table's cell with the given values
// @param table tableID The table ID to update
// @param int column The column to update
// @param int row The row to update
// @param string title The title of this cell
// @param string value The value of this cell
// @param color bgcolor The background color of this cell
// @param color txtcolor The text color of this cell
// @returns A boolean - true if the current bar falls within the given dates
export fillCell(table tableID, int column, int row, string title, string value, color bgcolor, color txtcolor) =>
    cellText = title + "\n" + value
    table.cell(tableID, column, row, cellText, bgcolor=bgcolor, text_color=txtcolor)

// } END DISPLAY FUNCTIONS

Overview

ZenLibrary includes calculations for quote currency decimal precision, market pip sizes, decimal truncation, pip conversions, percentage change over lookback periods, and AutoView position sizing for OANDA forex accounts. It also contains routines for calculating Fibonacci levels and detecting candlestick patterns. As an exported library, it produces no direct chart plots or standalone trading signals on its own.

Details

Published by

Web3Degenerate on GitHub

Draws

Library (no plots)

Markets

Forex, Crypto

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

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

261 stars

AIActivationFunctionsBipolarSigmoid is a Pine Script library that provides mathematical implementations of the bipolar sigmoid activation function and its derivatives for machine learning algorithms. It calculates bipolar sigmoid values bounded between -1 and

Library v5 AI / machine learning
Updated 4 years ago · None stated GitHub repository of AIActivationFunctionsBipolarSigmoid

KernelFunctions

by artificial-intelligence-edge
75 stars

KernelFunctions is a Pine Script v5 library that exports kernel weight functions for Nadaraya-Watson style estimation. It calculates a Rational Quadratic kernel, a Gaussian kernel based on a radial basis function, and a periodic kernel that models repeating be

Library v5
Updated 4 days ago · MIT GitHub repository of KernelFunctions

Ta

by nersent
29 stars

This Pine Script v5 library exports thin wrappers around built-in technical analysis functions. It covers moving averages, momentum measures such as RSI and CCI, volatility tools including ATR and standard deviation, range extremes, cross detection, and runnin

Library v5
Updated 11 months ago · Custom licence GitHub repository of Ta

Bands

by heyphat
26 stars

This library exports a Band type and functions that build a simple-moving-average basis with upper and lower envelopes from standard deviation. It classifies a source as above, below, or inside those envelopes, measures band width, and scales an imported z-sco

Library v6 Volatility & bandsMoving averages
Updated 2 months ago · AGPL-3.0 GitHub repository of Bands

Mylib

by ferranbt
21 stars

This script serves as a minimal utility library written in Pine Script v6. It provides an exported helper function that calculates the sum of two numeric arguments. As a reusable code library, it produces no visual plots, charts, or trading signals, and it con

Library v6
Updated 7 weeks ago · MPL-2.0 GitHub repository of Mylib

HLevel

by stupenkov
14 stars

HLevel is a Pine Script v5 utility library designed to manage horizontal price levels for cryptocurrency charts. It defines custom types for pivots and levels, along with methods to initialize, add, track, and expire price levels based on pivot high and pivot

Library v5
Updated 3 years ago · None stated GitHub repository of HLevel

More libraries

Related on ForexR

Trade Your Charts With a Regulated Broker

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

Compare brokers