Appearance
Libraries
How do you use the same functions in several scripts without copying them into each one? Put them in a library: a script that starts with library() and marks what it shares with export. Save it, then bring it into any script with import, and call what it exports through the alias you give it.
pine
//@version=6
library("Bands")
export type Band
float mid
float upper
float lower
// Each call site keeps its own sma and stdev, as a plain function does
export band(float src, simple int len, float mult) =>
float mid = ta.sma(src, len)
float dev = ta.stdev(src, len)
Band.new(mid, mid + mult * dev, mid - mult * dev)
export method width(Band b) => (b.upper - b.lower) / b.mid
// Drawn only when the library runs alone, to test it
plot(band(close, 20, 2.0).width(), "Width")pine
//@version=6
indicator("Band width")
import Me/Bands/1 as bands // found by its name, Bands
b = bands.band(close, 20, 2.0)
plot(b.width(), "Width")Writing a library
A library starts with library("Name") in place of indicator() or strategy(). Put export in front of each function, method, type and enum that another script may use. A function without it is the library's own helper.
A library can draw, so you can test it on a chart before you import it: its own plot() calls show when the library runs alone, and an importer never runs them. library() lists its arguments.
Give every parameter of an exported function a type, as in float src. TradingView asks for one, and our engine runs an untyped parameter without a word, so nothing here tells you one is missing.
Importing it
Write import <publisher>/<name>/<version> as <alias> after the declaration line, then call each export as <alias>.<name>, as in bands.band(close, 20, 2.0). A type comes through the same way, as bands.Band, and a method needs no alias: b.width() finds it from the object.
Only the name counts: the last part of the path that isn't a number. The import finds the newest library saved under that name in your scripts, whatever publisher and version the path gives, so Me/Bands/1 and Anyone/Bands/7 find the same library. The name is the one you saved the script under. An import that finds none stops the run and names the path: save the library, then run again. What an import finds has the rule in full.
The importer gets the exports and nothing else of the library. The library's text is written into your script before any engine runs it, so an imported function runs exactly as if you had written it there, with its own state at each call site.
TradingView's ta library and the built-in helpers
import TradingView/ta/<any version> as tvta brings in TradingView's own ta library, whatever version the path names, so a script published on TradingView with that import runs here unchanged. Terminal/ta names the same library. A port of TradingView's RelativeValue library answers TradingView/RelativeValue.
pine
//@version=6
indicator("DEMA from TradingView's ta library", overlay = true)
import TradingView/ta/9 as tvta
plot(tvta.dema(close, 10), "DEMA 10")A few helpers from TradingView's strategy and risk libraries are there with no import at all, as tvstrat.* and tvrisk.*. They aren't TradingView's own names, so a script that calls them won't compile there. A call to one leaves the text Pine, so strict Pine doesn't flag it either: take them out before you publish on TradingView. Built-in helpers lists them.
A whole script as a function
A library shares functions. To use a whole indicator or strategy inside another script, with its inputs set by name, AmenoScript imports the script itself and runs it with .run(). See A script as a function.
Traps
- One library a name. Two libraries saved under one name can't both be imported: the newest wins, whatever the paths say.
- What you forgot to export still works here. An importer can call a library function that has no
export, and TradingView refuses that. Export everything an importer calls, or the script fails when you take it there. - A version means nothing here. Changing
/1to/2in the path doesn't pick an older or newer library: saving the library again is what changes what every importer runs. export constdoesn't parse. A library constant markedexportstops the library itself with "Expected '(' here". Declare the constant withoutexport, or hand the value out from an exported function.
See also
- Imports and libraries, what an import finds and the built-in helpers
- library(), its arguments
- Functions, what an exported function can be
- Types and enums, what an exported type holds