As experienced Pine Script developers, we frequently build custom logic that we need to reuse across multiple indicators and strategies. Copy-pasting code is inefficient and prone to errors when updating. This is where Pine Script libraries become indispensable. While public libraries are great for sharing with the community, private libraries offer a crucial advantage for proprietary codebases: intellectual property protection and controlled access.
Introduction to Private Libraries in Pine Script
What are Private Libraries and Why Use Them?
A Pine Script library is a special type of script designed specifically to encapsulate reusable functions and variables. Unlike standard indicators or strategies, a library cannot be added directly to a chart. Its sole purpose is to serve as a repository of callable code for other Pine scripts.
Private libraries are libraries published on TradingView with ‘Private’ visibility. This means only the publisher (and potentially users they explicitly grant access to) can see the library’s source code and import its functions into their own private or public scripts.
Benefits of Using Private Libraries
- Code Reusability: Avoid repetitive coding by defining common functions (like custom calculations, complex entry conditions, or visualization helpers) once in a library and importing them into any script that needs them.
- Organization: Centralize your core trading logic. This makes your individual indicator and strategy scripts cleaner, more readable, and easier to maintain. Updates to shared logic only need to happen in one place (the library).
- Intellectual Property Protection: The primary benefit of private libraries. Your core algorithms, custom calculations, and proprietary methods can be bundled into a private library, allowing you to use them in public indicators/strategies without exposing their underlying implementation details.
Limitations of Private Libraries in Pine Script
While highly valuable, private libraries have some limitations you should be aware of:
- Visibility is Script-Level: While the library source is private, any script that uses a private library can be published publicly. Users of the public script can see that it imports functions from your library, but they cannot see the library’s source code unless you grant them access.
- Debugging Complexity: Debugging issues that might originate within library code can be slightly more complex than debugging code directly in your main script.
- Limited Distribution Options: Sharing private libraries requires granting specific TradingView users access, which is not as flexible as public distribution.
Creating Your First Private Library
Creating a private library is straightforward and follows a structure similar to a regular Pine script, with a key difference.
Setting Up a New Private Library Script
Open the Pine Editor and create a new script. Instead of using @version=5 followed by an indicator or strategy declaration, you start with the version and then declare the script as a library.
//@version=5
library("MyCustomLib")
// Library code goes here
Defining Functions and Variables within the Library
Within the library script, you define functions and variables that you intend to export for use by other scripts. Functions declared with the export keyword are accessible outside the library. Variables can also be exported.
//@version=5
library("MyCustomLib")
export add(a, b) =>
a + b
export multiply(a, b) =>
a * b
export PI = math.pi
In this example, add, multiply, and PI are exported and can be imported into another script.
Understanding the Library Declaration Statement (library(title))
The library(title) declaration is essential. It tells Pine Script that this script is a library and assigns it a unique identifier (title). This title is what other scripts will use to import functions from this library. The title should be descriptive and unique to avoid conflicts.
library("MyTradingMath")
Choose a title that reflects the library’s purpose. Best practice is to use a unique prefix (like your initials or a project code) to minimize collision risk, although TradingView’s publishing process also helps manage this.
Publishing the Library with ‘Private’ Visibility
Once your library code is ready, save it. When you are ready to use it in other scripts, you must publish it. Click the ‘Publish Script’ button in the Pine Editor. In the publishing dialog, crucially, select the ‘Private’ visibility option. Fill in the required details and publish.
Publishing makes the library available for import in your other scripts (and those of users you grant access to). You do not need to share the source code file itself. The import mechanism works via the published version on TradingView.
Using Private Libraries in Your Pine Script
Once your private library is published, you can import its exported functions and variables into any other Pine script you write.
Referencing and Importing Functions from a Private Library
To use functions from your library, you use the import statement. The format is import <username>/<library_title>/<version> as <short_name>.
<username>: Your TradingView username.<library_title>: The title you gave your library in thelibrary()declaration.<version>: The version number of the published library you want to use. TradingView assigns versions upon publishing/updating.<short_name>: An alias you create for the library within your script, used to call its functions.
Using the ‘import’ Statement Correctly
The import statement must appear at the very top of your importing script, immediately after the //@version= directive.
//@version=5
import MyTradingViewUser/MyCustomLib/1 as mcl // Import MyCustomLib version 1
indicator("Using My Library", overlay=true)
a = 10
b = 5
sum = mcl.add(a, b) // Call the 'add' function via the alias
product = mcl.multiply(a, b) // Call the 'multiply' function
plot(sum, title="Sum")
plot(product, title="Product")
In this example, mcl is the chosen alias. We access the library’s functions using dot notation: mcl.add() and mcl.multiply(). The exported variable PI would be accessed as mcl.PI.
Understanding Library Versioning and Updates
When you publish an update to your library, TradingView assigns it a new version number. Scripts importing the library explicitly reference a specific version.
- If you update your library (e.g., fix a bug or add a feature) and publish it as version 2, scripts importing version 1 will continue to use the old code.
- To use the updated code, you must manually change the
importstatement in your consuming script to reference the new version (e.g., change.../1 as mclto.../2 as mcl) and save/republish the consuming script.
This explicit versioning provides stability, ensuring that changes in your library don’t unexpectedly break scripts that rely on older versions.
Example: Implementing a Custom Moving Average from a Private Library
Let’s create a simple library for a custom moving average calculation and use it.
Library Script (e.g., ‘MyTALib’):
//@version=5
library("MyTALib")
// Simple Moving Average function
export custom_sma(source, length) =>
math.avg(source, length)
// Weighted Moving Average function
export custom_wma(source, length) =>
sum = 0.0
weight_sum = 0.0
for i = 0 to length - 1
weight = length - i
sum := sum + source[i] * weight
weight_sum := weight_sum + weight
sum / weight_sum
Publish this library as private (let’s say it gets published as version 1 under username MyTradingViewUser).
Indicator Script using the library:
//@version=5
import MyTradingViewUser/MyTALib/1 as mta
indicator("MA from Private Library", overlay=true)
price = close
sma_length = input.int(20, "SMA Length", minval=1)
wma_length = input.int(20, "WMA Length", minval=1)
// Use functions from the imported library
sma_val = mta.custom_sma(price, sma_length)
wma_val = mta.custom_wma(price, wma_length)
plot(sma_val, color=color.blue, title="Library SMA")
plot(wma_val, color=color.red, title="Library WMA")
This indicator uses the custom_sma and custom_wma functions defined in the MyTALib private library without exposing their implementation within the indicator script itself.
Advanced Techniques and Best Practices
Organizing Multiple Functions within a Single Library
A single library can contain numerous exported functions covering related functionality (e.g., technical analysis calculations, utility functions, visualization helpers). Keep functions grouped logically within one or a few well-named libraries rather than creating a separate library for every single function. This simplifies management and importing.
//@version=5
library("MyUtilityLib")
export is_higher_high(series, length) =>
// Logic to check for HH
true // Placeholder
export is_lower_low(series, length) =>
// Logic to check for LL
false // Placeholder
export format_currency(value, decimals) =>
// Logic to format numbers
str.tostring(value, format="#." + str.repeat("0", decimals)) // Placeholder
Handling Errors and Debugging in Private Libraries
Debugging code within a library involves testing it thoroughly before publishing. You can write a temporary indicator script that only imports your library and calls its functions with various inputs to test their behavior. Use log.info() or plot() within this temporary test script to inspect the outputs of library functions.
Errors originating inside a library function will often appear in the consuming script’s console log, sometimes pointing to the line number within the library source, but you cannot view the full library source code unless you have it open separately (if it’s unpublished or you’re the owner) or explicitly open the library script.
Optimizing Library Code for Performance
Performance considerations in libraries are the same as in regular Pine Script. Avoid redundant calculations, minimize the use of complex loops over long lookback periods, and ensure your functions are efficient. Since library code is executed every time the consuming script runs, performance bottlenecks in libraries can significantly impact the overall speed of indicators or strategies.
Collaborating with Others Using Private Libraries (Indirectly)
Direct code collaboration on a single private library script isn’t natively supported like collaborative editing. However, you can grant specific TradingView users access to your private library during the publishing process. This allows them to import and use your library in their own scripts. Collaboration on the library source code itself would typically happen offline using version control systems (like Git) and then coordinating who publishes the next version on TradingView.
Troubleshooting Common Issues and Limitations
Dealing with Permission Issues and Access Rights
If you try to import a private library published by someone else, you need their explicit permission. The library publisher must add your TradingView username to the list of users allowed to access the library via their script’s settings on TradingView. If you encounter an error stating you don’t have permission, contact the library owner.
If you are the owner and cannot import your own private library, ensure:
- The library is successfully published as private.
- You are using the correct username, library title, and version in the
importstatement. - You are logged into the correct TradingView account.
Addressing Compatibility Problems Between Libraries and Scripts
Compatibility issues usually arise from:
- Version Mismatch: Trying to import a non-existent library version. Double-check the version number in your
importstatement against the published versions of the library. - Pine Script Version: Ensure the library and the consuming script are using compatible
@versiondirectives. - Function Signature Changes: If a library function signature changes (e.g., parameter name, type, or order) in a new version, scripts importing the old version will be fine, but scripts updated to import the new version must also update their function calls accordingly.
Handling Conflicts with Built-in Functions or Variables
While less common with library imports (thanks to the alias), it’s good practice to avoid exporting names from your library that are identical to common Pine Script built-in functions (like ta.sma, math.avg, plot, etc.). If a name conflict did occur, the library’s function/variable would be accessed via its alias (alias.conflicting_name), while the built-in would be accessed directly (conflicting_name). Using a unique library alias (as short_name) is the primary mechanism to prevent name clashes in the consuming script’s scope.
Private libraries are a powerful tool for professional Pine Script development. They enhance code reusability, improve project organization, and provide essential protection for your proprietary trading logic, allowing you to build sophisticated systems while keeping your core algorithms secure.