Library · Pine Script v6 · Library

LabelManagement

by Electrified-Trading· code credited to Electrified

This library manages TradingView chart labels through configuration templates, change-aware updaters, and a named registry.

View on GitHub

GitHub stars2on the repository
Pine versionv6current
Lines of code449
Settings0inputs
LicenceMPL-2.0
Last update1 year ago7 Jul 2025

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

449 lines of Pine Script v6 from LabelManagement.pine, published under MPL-2.0. Keep the author's credit and licence lines when you reuse it.

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

// @version=6
// @description Advanced label management library with fluent configuration, change tracking, and named registry. Makes managing 'sticky' labels easy through expressive fluent APIs, deferred batch changes, and centralized label registries.
library("LabelManagement", overlay=true)

///////////////////////////////////////////////////
// OVERVIEW & USAGE EXAMPLES
///////////////////////////////////////////////////
//
// This library provides three main components for advanced label management:
//
// 1. LabelConfig - Template-based configuration objects
// 2. LabelUpdater - Smart updaters with change tracking
// 3. LabelManager - Named registry for persistent label management
//
// BASIC USAGE PATTERNS:
//
// // Pattern 1: Direct label updates with fluent API
// myLabel = label.new(bar_index, close, "")
// myLabel.update()
//     .xy(bar_index, high)
//     .textValue("🚀")
//     .bgColor(color.green)
//     .textColor(color.white)
//     .apply()
//
// // Pattern 2: Template-based configuration
// config = LabelConfig.new()
// config.textValue := "Signal"
// config.bgColor := color.blue
// config.applyTo(myLabel)
//
// // Pattern 3: Named registry for persistent labels
// var manager = LabelManagement.newManager()
// manager.get("entry")
//   .xy(bar_index, low)
//   .textValue("ENTRY")
//   .bgColor(color.lime)
//   .apply()
//
// ADVANCED FEATURES:
//
// • Change tracking: Only applies properties that actually changed
// • Deferred updates: Build configuration incrementally, apply once
// • Named access: Get labels by string identifiers instead of variables
// • Template reuse: Apply same configuration to multiple labels
// • Performance optimized: Minimal Pine Script API calls through smart diffing
//
// TYPICAL STICKY LABEL WORKFLOW:
//
// var labels = newManager()
//
// // Update label position and content each bar
// if show_signals
//     labels.get("signal")
//       .xy(bar_index, signal_price)
//       .textValue(signal_emoji)
//       .bgColor(signal_color)
//       .apply()

///////////////////////////////////////////////////
// EXPORTED TYPES
///////////////////////////////////////////////////

// @type LabelConfig Configuration object for label appearance and positioning
// @field x (series int) X-coordinate (na = unchanged)
// @field y (series float) Y-coordinate (na = unchanged)
// @field xloc (series string) X-location type (na = unchanged)
// @field yloc (series string) Y-location type (na = unchanged)
// @field size (series string) Text size (na = unchanged)
// @field style (series string) Label style (na = unchanged)
// @field bgColor (series color) Background color (na = unchanged)
// @field textColor (series color) Text color (na = unchanged)
// @field textValue (series string) Label text content (na = unchanged)
// @field tooltip (series string) Tooltip text (na = unchanged)
export type LabelConfig
    int x
    float y
    string xloc
    string yloc
    string size
    string style
    color bgColor
    color textColor
    string textValue
    string tooltip

// @type LabelUpdater Smart label updater with change tracking and minimal updates
// @field label (label) Reference to the label being updated
// @field latest (LabelConfig) Current known state of the label
// @field updates (LabelConfig) Pending changes to apply
export type LabelUpdater
    label label
    LabelConfig latest
    LabelConfig updates

// @type LabelManager Central registry for managing named labels with automatic creation
// @field registry (map<string, LabelUpdater>) Internal storage mapping names to LabelUpdater instances
export type LabelManager
    map<string, LabelUpdater> registry

///////////////////////////////////////////////////
// LABELCONFIG METHODS
///////////////////////////////////////////////////

// @function Creates a new LabelConfig by copying all properties from this instance
// @param this (LabelConfig) The LabelConfig instance
// @returns (LabelConfig) New LabelConfig instance with identical properties
export method clone(LabelConfig this) =>
    LabelConfig.new(
      this.x,
      this.y,
      this.xloc,
      this.yloc,
      this.size,
      this.style,
      this.bgColor,
      this.textColor,
      this.textValue,
      this.tooltip)

// @function Applies configuration to specified label (required parameter)
// @param this (LabelConfig) The LabelConfig instance
// @param target (label) Label to apply config to
// @returns (LabelConfig) Self-reference for method chaining
export method applyTo(LabelConfig this, label target) =>

    if not na(this.yloc)
        label.set_yloc(target, this.yloc)

    if not na(this.xloc)
        label.set_xloc(target, na(this.x) ? target.get_x() : this.x, this.xloc)
    else if not na(this.x)
        label.set_x(target, this.x)

    if not na(this.y)
        label.set_y(target, this.y)

    if not na(this.textValue)
        label.set_text(target, this.textValue)

    if not na(this.style)
        label.set_style(target, this.style)

    if not na(this.bgColor)
        label.set_color(target, this.bgColor)

    if not na(this.textColor)
        label.set_textcolor(target, this.textColor)

    if not na(this.size)
        label.set_size(target, this.size)

    if not na(this.tooltip)
        label.set_tooltip(target, this.tooltip)

    this

///////////////////////////////////////////////////
// LABEL EXTENSIONS
///////////////////////////////////////////////////

// @function Creates a new LabelUpdater with change tracking for this label
// @param this (label) The label instance
// @param updates (LabelConfig) Optional existing config to apply and reuse (if provided, applies to label first)
// @returns (LabelUpdater) New LabelUpdater with blank configs for change tracking
export method update(label this, LabelConfig updates = na) =>
    if not na(updates)
        updates.applyTo(this)

    LabelUpdater.new(
      label = this,
      latest = na(updates) ? LabelConfig.new() : updates.clone(),
      updates = LabelConfig.new())

///////////////////////////////////////////////////
// LABELUPDATER FLUENT METHODS
///////////////////////////////////////////////////

// POSITION METHODS
// @function Sets the X coordinate with change tracking (fluent interface)
// @param this (LabelUpdater) The LabelUpdater instance
// @param value (int) New X coordinate
// @returns (LabelUpdater) Self-reference for method chaining
export method x(LabelUpdater this, int value) =>
    if na(this.latest.x) or this.latest.x != value
        this.updates.x := value
    this

// @function Sets the Y coordinate with change tracking (fluent interface)
// @param this (LabelUpdater) The LabelUpdater instance
// @param value (float) New Y coordinate
// @returns (LabelUpdater) Self-reference for method chaining
export method y(LabelUpdater this, float value) =>
    if na(this.latest.y) or this.latest.y != value
        this.updates.y := value
    this

// @function Sets both X and Y coordinates with change tracking (fluent interface)
// @param this (LabelUpdater) The LabelUpdater instance
// @param x (int) New X coordinate
// @param y (float) New Y coordinate
// @returns (LabelUpdater) Self-reference for method chaining
export method xy(LabelUpdater this, int x, float y) =>
    if na(this.latest.x) or this.latest.x != x
        this.updates.x := x
    if na(this.latest.y) or this.latest.y != y
        this.updates.y := y
    this

// TEXT METHODS
// @function Sets the text content with change tracking (fluent interface)
// @param this (LabelUpdater) The LabelUpdater instance
// @param value (string) New text content
// @returns (LabelUpdater) Self-reference for method chaining
export method textValue(LabelUpdater this, string value) =>
    if na(this.latest.textValue) or this.latest.textValue != value
        this.updates.textValue := value
    this

// @function Sets the text color with change tracking (fluent interface)
// @param this (LabelUpdater) The LabelUpdater instance
// @param value (color) New text color
// @returns (LabelUpdater) Self-reference for method chaining
export method textColor(LabelUpdater this, color value) =>
    if na(this.latest.textColor) or this.latest.textColor != value
        this.updates.textColor := value
    this

// @function Sets the size with change tracking (fluent interface)
// @param this (LabelUpdater) The LabelUpdater instance
// @param value (string) The new size
// @returns (LabelUpdater) Self-reference for method chaining
export method size(LabelUpdater this, string value) =>
    if na(this.latest.size) or this.latest.size != value
        this.updates.size := value
    this

// VISUAL STYLE METHODS
// @function Sets the background color with change tracking (fluent interface)
// @param this (LabelUpdater) The LabelUpdater instance
// @param value (color) New background color
// @returns (LabelUpdater) Self-reference for method chaining
export method bgColor(LabelUpdater this, color value) =>
    if na(this.latest.bgColor) or this.latest.bgColor != value
        this.updates.bgColor := value
    this

// @function Sets the label style with change tracking (fluent interface)
// @param this (LabelUpdater) The LabelUpdater instance
// @param value (string) New style
// @returns (LabelUpdater) Self-reference for method chaining
export method style(LabelUpdater this, string value) =>
    if na(this.latest.style) or this.latest.style != value
        this.updates.style := value
    this

// @function Sets the Y location mode with change tracking (fluent interface)
// @param this (LabelUpdater) The LabelUpdater instance
// @param value (string) New yloc
// @returns (LabelUpdater) Self-reference for method chaining
export method yloc(LabelUpdater this, string value) =>
    if na(this.latest.yloc) or this.latest.yloc != value
        this.updates.yloc := value
    this

// @function Sets the X location mode with change tracking (fluent interface)
// @param this (LabelUpdater) The LabelUpdater instance
// @param value (string) New xloc
// @returns (LabelUpdater) Self-reference for method chaining
export method xloc(LabelUpdater this, string value) =>
    if na(this.latest.xloc) or this.latest.xloc != value
        this.updates.xloc := value
    this

// UTILITY METHODS
// @function Sets the tooltip content with change tracking (fluent interface)
// @param this (LabelUpdater) The LabelUpdater instance
// @param value (string) New tooltip content
// @returns (LabelUpdater) Self-reference for method chaining
export method tooltip(LabelUpdater this, string value) =>
    if na(this.latest.tooltip) or this.latest.tooltip != value
        this.updates.tooltip := value
    this

// @function Applies pending changes to linked label and updates tracking
// @param this (LabelUpdater) The LabelUpdater instance
// @returns (LabelUpdater) Self-reference for method chaining
export method apply(LabelUpdater this) =>
    // Apply only the pending changes
    if not na(this.updates.xloc)
        x = na(this.updates.x) ? this.label.get_x() : this.updates.x
        label.set_xloc(this.label, x, this.updates.xloc)
        this.latest.xloc := this.updates.xloc
        this.updates.xloc := na
        if not na(this.updates.x)
            this.latest.x := x
            this.updates.x := na
    else if not na(this.updates.x)
        label.set_x(this.label, this.updates.x)
        this.latest.x := this.updates.x
        this.updates.x := na

    if not na(this.updates.yloc)
        label.set_yloc(this.label, this.updates.yloc)
        this.latest.yloc := this.updates.yloc
        this.updates.yloc := na

    if not na(this.updates.y)
        label.set_y(this.label, this.updates.y)
        this.latest.y := this.updates.y
        this.updates.y := na

    if not na(this.updates.size)
        label.set_size(this.label, this.updates.size)
        this.latest.size := this.updates.size
        this.updates.size := na

    if not na(this.updates.style)
        label.set_style(this.label, this.updates.style)
        this.latest.style := this.updates.style
        this.updates.style := na

    if not na(this.updates.bgColor)
        label.set_color(this.label, this.updates.bgColor)
        this.latest.bgColor := this.updates.bgColor
        this.updates.bgColor := na

    if not na(this.updates.textValue)
        label.set_text(this.label, this.updates.textValue)
        this.latest.textValue := this.updates.textValue
        this.updates.textValue := na

    if not na(this.updates.textColor)
        label.set_textcolor(this.label, this.updates.textColor)
        this.latest.textColor := this.updates.textColor
        this.updates.textColor := na

    if not na(this.updates.tooltip)
        label.set_tooltip(this.label, this.updates.tooltip)
        this.latest.tooltip := this.updates.tooltip
        this.updates.tooltip := na

    this

///////////////////////////////////////////////////
// LABELMANAGER METHODS
///////////////////////////////////////////////////

// @function Creates a new label and LabelUpdater
// @returns (LabelUpdater) Newly created LabelUpdater containing the label
export newLabel() =>
    // Create new label and LabelUpdater, register and return
    label.new(bar_index, close, "", size=size.normal).update()

// @function Gets or creates a LabelUpdater for the specified name
// @param this (LabelManager) The LabelManager instance
// @param name (string) Unique identifier for the label
// @returns (LabelUpdater) Existing or newly created LabelUpdater for the name
export method get(LabelManager this, string name) =>
    if this.registry.contains(name)
        // Return existing LabelUpdater
        this.registry.get(name)
    else
        newUpdater = newLabel()
        this.registry.put(name, newUpdater)
        newUpdater

// @function Checks if a label with the specified name exists
// @param this (LabelManager) The LabelManager instance
// @param name (string) Name to check for existence
// @returns (bool) True if label exists, false otherwise
export method has(LabelManager this, string name) =>
    this.registry.contains(name)

// @function Removes a label from the registry and deletes the underlying Pine Script label
// @param this (LabelManager) The LabelManager instance
// @param name (string) Name of the label to remove
// @returns (LabelManager) Self-reference for method chaining
export method remove(LabelManager this, string name) =>
    if this.registry.contains(name)
        updater = this.registry.get(name)
        label.delete(updater.label)  // Delete the actual Pine Script label
        this.registry.remove(name)   // Remove from registry
    this

// @function Gets the count of registered labels
// @param this (LabelManager) The LabelManager instance
// @returns (int) Number of labels in the registry
export method size(LabelManager this) =>
    this.registry.size()

// @function Removes all labels from registry and deletes all underlying Pine Script labels
// @param this (LabelManager) The LabelManager instance
// @returns (LabelManager) Self-reference for method chaining
export method clear(LabelManager this) =>
    // Delete all Pine Script labels before clearing registry
    for [name, updater] in this.registry
        label.delete(updater.label)
    this.registry.clear()
    this

///////////////////////////////////////////////////
// FACTORY FUNCTIONS
///////////////////////////////////////////////////

// @function Creates a new LabelManager with empty registry
// @returns (LabelManager) New LabelManager instance ready for use
export newManager() =>
    LabelManager.new(registry = map.new<string, LabelUpdater>())

///////////////////////////////////////////////////
// DEMO / EXAMPLE USAGE
///////////////////////////////////////////////////

// Demo: Create persistent labels for high, low, and close
var labels = newManager()
if(barstate.islast)
    // High label - above the last bar
    labels.get("high")
      .style(label.style_label_lower_left)
      .bgColor(color.yellow)
      .xy(bar_index, high)
      .textValue("H: " + str.tostring(high, "#.##"))
      .textColor(color.black)
      .tooltip("This is the high price")
      .apply()

    // Low label - below the last bar
    labels.get("low")
      .style(label.style_label_upper_left)
      .bgColor(color.blue)
      .xy(bar_index, low)
      .textValue("L: " + str.tostring(low, "#.##"))
      .textColor(color.white)
      .tooltip("This is the low price")
      .apply()

    // Close label - to the right of the last bar
    labels.get("close")
      .style(label.style_label_left)
      .bgColor(color.gray)
      .xy(bar_index, close)
      .textValue("C: " + str.tostring(close, "#.##"))
      .textColor(color.white)
      .tooltip("This is the close price")
      .apply()

Overview

LabelManagement lets callers set position, text, colors, style, size, and tooltips with a fluent interface, then apply only properties that differ from the last known state. Deferred updates batch several changes into one apply call, and a manager retrieves persistent labels by string name. It draws labels on the price chart and does not generate trading signals or orders.

Details

Published by

Electrified-Trading on GitHub

Code credit

Electrified, as written in the script's header

Type

Library, Pine Script v6

Draws

Library (no plots)

Markets

Any symbol

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

FunctionLinearRegression

by ricardosantos79
261 stars

This Pine Script v5 library provides functions to calculate and plot linear regression channels using sample point arrays. It evaluates paired X and Y arrays to calculate the regression slope, intercept, fitted values, maximum deviation, minimum deviation, and

Library v5 Trend
Updated 4 years ago · None stated GitHub repository of FunctionLinearRegression

PositionSizing

by iamrichardD
57 stars

This Pine Script v6 library calculates trade position sizes and provides risk management functions for external scripts. It computes position sizes from account equity, percentage risk, and stop-loss distance, and offers dynamic sizing adjustments based on vol

Library v6
Updated 1 year ago · Apache-2.0 GitHub repository of PositionSizing

Chart Patterns

by deepentropy
13 stars

Chart Patterns is a Pine Script v6 library designed to scan for and render technical chart patterns directly on the price chart. It defines custom user-defined types to configure scanning parameters, such as Zigzag pivot offsets, error ratios, flat ratios, and

Library v6 Repaints
Updated 6 months ago · MIT GitHub repository of Chart Patterns

AuthLib

by alboogycOdR
6 stars

AuthLib is a Pine Script utility library providing access control and state management structures for technical indicators. It checks callers against a hardcoded array of authorized TradingView usernames before executing operations. The library exports user-de

Library v5 SMC / ICT / price actionSessions & time
Updated 7 months ago · None stated GitHub repository of AuthLib

WebhookMessageLibrary

by TradersPost
6 stars

WebhookMessageLibrary is a helper library designed to construct structured JSON payload messages for automated trading integrations like TradersPost. It defines custom exported types and constants for trade actions, market sentiments, quantities, limit prices,

Library v5
Updated 1 year ago · None stated GitHub repository of WebhookMessageLibrary

PineDraw

by 345-strategies
5 stars

PineDraw is a Pine Script v6 library that provides object primitives for drawing and updating price levels on the chart. It enables indicators and strategies to maintain lines, boxes, and labels in place by updating existing objects instead of deleting and rec

Library v6 Support & resistance
Updated 2 days ago · MPL-2.0 GitHub repository of PineDraw

More libraries

Trade Your Charts With a Regulated Broker

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

Compare brokers