Help get this topic noticed by sharing it on Twitter, Facebook, or email.

Pine Script Modules System Proposal: Import one script from another

Hi everyone!

As you know every solid programming language has the module system.

Even Lua, Python, Ruby, JS. All, except Pine Script language.

I think an implementation of this feature could be a colossal step forward for the Pine Script and its users.

What is the reasons to do it? The main reason is sharing already written functions across other pinescripts.

For example, the Super Smoother Filter by John F. Ehlers. The most of Ehlers indicators (and not only his) based on this filter. If the modules were implemented, I would be able to import the ready function for my needs in another script.

This feature could eliminate the need to implement some function every time in the new scripts.

Let's imagine what I propose

//@version=3
study("Script_A")

foo() =>
// ... foo implementation

export(foo)

//@version=3
study("Script_B")

foo = import("@everget/Script_A")

bar() =>
res = foo()
res

export(bar)

Some thoughts about spec:

*) You can export only the functions presented in the script
*) You can export only one function presented in the script
*) Export occurs using the built-in function `export(func_name)`

*) Import can only be used after the declaration of the built-in `study()` function
*) Import occurs using the built-in `import(id)` function where `id` is a string of the form `user_name/script_name`
*) Import can be used as the right-hand of the assignment expression
foo = import("@everget/Script_A")
19 people like
this idea
+1
Reply
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned sad, anxious, confused, frustrated kidding, amused, unsure, silly happy, confident, thankful, excited

  • I'm surprised Pine Script has been active this long without modules. It's incredibly frustrating to program indicators without them! I would amend your idea to include namespacing instead of forcing the exporting of functions. That way you can include the script within the same lexical scope but without having to manually change variable names.

    import("@everget/Script_A", namespace="script_a")

    now a function within that script called "foo" would be named "script_a_foo" and likewise with variables. If you want to keep simple function names, just assign it to a locally scoped variable...

    foo = script_a_foo
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned sad, anxious, confused, frustrated kidding, amused, unsure, silly happy, confident, thankful, excited

  • Yes absolutely this would be hugely beneficial.
    It is not just ftns, it also has to include globals and constants and functions required by the imported ftn
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned sad, anxious, confused, frustrated kidding, amused, unsure, silly happy, confident, thankful, excited

  • Interesting concept everget! Would GLOBAL USER VARIABLES/FUNCTIONS be sufficient in performing this? The problem I foresee is http:/... or https:/... versus file/:.. OR @midtownsk8rguy/... importation protocols AND ***COMP/NETWORK SECURITY***. If
    TVChart>Settings>GLOBAL USER VARIABLES>Upload var/function/memberLibraryPublicOrProtectedOrInviteOnly file functionality existed, would this incorporate the concept presented above?? Pine Script v5.0+ incorporation I must add though... I'm still anticipating from a month ago PSv4.0 availability without a determined release date yet. Sorry fellow members, if I personally delayed v4.0 myself in my previous topics of discussion regarding v4.0 suggestions/addendums... "Done right the first time or not at all" necessity supersedes my patience/aging. Free code everyone, corrected E super smoothing function for Pine Script 3.0, everget, be critical of my ss()! I know you have skillSetsTalentGalore ;) Import this:


    PI = na, PI := not na(PI) ? PI[1] : 2.0 * asin(1.0) // 3.14159265359 Constant
    SQRT2 = na, SQRT2 := not na(SQRT2) ? SQRT2[1] : sqrt(2.0) // 1.41421356237 Constant
    ss(Series, SmoothingDenominator) =>
    sample = na
    if(SmoothingDenominator == 0.0)
    sample := Series
    else
    alpha = exp(-SQRT2 * PI / SmoothingDenominator)
    beta = -alpha * alpha
    gamma = 2.0 * alpha * cos(SQRT2 * PI / SmoothingDenominator)
    priorSample = nz(sample[1])
    sample := (1.0 - gamma - beta) / 2.0 * (Series + Series[1]) + gamma * priorSample + beta * priorSample[1]
    sample


    Food for thought!
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned sad, anxious, confused, frustrated kidding, amused, unsure, silly happy, confident, thankful, excited

  • I can understand this would be very problematic, as it creates dependencies for scripts, which have to then be versioned. For instance, if you write a script that depends on someone else's functions/indicators, what happens when they delete or change those functions? Obviously there are many solutions to this, but they are not as simple as letting people import and create dependencies.

    That said, the fact that Pinescript has no way to reuse code is a travesty, and perhaps biggest reason it's still a toy.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned sad, anxious, confused, frustrated kidding, amused, unsure, silly happy, confident, thankful, excited

  • One other thing I foresee is a liability issue. Yeah, if a user modifies an existing function breaking half of peoples indicators until they arrive back from a 2 week vacation, multiplied by a 1000 frustrated people, has a lot of ramifications. I encapsulate everything in functions where it is applicable and simply copy and paste with ease as needed. Just like ss() up above. Yeah I copy PI twice used in other functions some times resulting in an error, no big deal. Once PSv4.0 is complete, I'm starting a topic to add more functions to Pine4.x-5.0. ss() is the first one. quadreg() would be another I have. Century old mathematical functions are great, sma(), ema(), but there is a whole slew of things from modern times to add, useful across the entire language like a "Homodyne Discriminator" as hd(denominator, K) for measuring period cycles dynamically. This one function alone would yield a whole new species of adaptive indicators. I'm not sure if this a language to library either. This is all mathematical and the permutations of this are infinite, and libraries come and go over time being surpassed by another one.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned sad, anxious, confused, frustrated kidding, amused, unsure, silly happy, confident, thankful, excited

  • Pine scripts already have versions; it shouldn't be an issue to simply reference the version of the import you're using if you really want to rely on someone else's script. An easy workaround would be to import their script into your library and run off of your own file instead of theirs. Just look at how github works in this regard (forking). Versioning is a necessary aspect of programming.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned sad, anxious, confused, frustrated kidding, amused, unsure, silly happy, confident, thankful, excited

  • I only see this working properly and reliably in the near future if there is an "Add Library File" in main chart's "Chart Properties" to manually upload a file. Then once this file(s) is uploaded to your account script library, unrelated to "My Scripts"-but a possibility, then the functions and PSv 4.0 "[type] var" is globally reusable across all scripts for reuse only for that member. Maybe in PSv5.0 we could have a more elaborate system for library versions including semaphores usable between indicators allowing an independent lower indicator to communicate between the overlay chart and back.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned sad, anxious, confused, frustrated kidding, amused, unsure, silly happy, confident, thankful, excited

  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned sad, anxious, confused, frustrated kidding, amused, unsure, silly happy, confident, thankful, excited

  • I’m completely un-stoked
    @midtownsk8rguy, yeah, that'd be sub-optimal. A node.js-like dependency version targeting mechanism could be implemented to revert, or dare I say even advertise changes to shared modules so that consumers could comparitively test versions. That said, given there's no modularity now, this seems a pipe dream...
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned sad, anxious, confused, frustrated kidding, amused, unsure, silly happy, confident, thankful, excited

  • It's a shame nobody mentions script communication & reusability, especially source-protected dependencies. I'm shocked it has so few votes, because it is the single biggest reason I don't sign up to the maximum subscription. I'm always on the look out for platforms like Trading Lite, GoCharting and ExoCharts that might start allowing it.

    Is there another idea on this board that is similar but with more votes?

    I'd like to support this inclusion, with some minor alterations...

    Re OP's suggestion, it's best to use Javascript as the example but I think import/export is too unnecessarily limited, nor does it answer the question of how you use these imports/exports in different scenarios.

    Looking at it as a coder, we want to be able to:
    - reuse functions from one script in another, i.e. run as a subprocess/thread
    - have one script use results from another, i.e. communicate between scripts
    - work with actively charted scripts and their study plots / strategy positions / alerts
    - work with inactive scripts to reuse their functions, return values, drawings, positions
    - in both cases, access another script's data and functions, i.e.
    - input arguments, chart settings, strategy properties
    - variables, functions
    - strategy positions, alert conditions
    - plots/drawings/labels/lines
    - return values

    If we only have a declarative import/export, it would be too limited and not backwards compatible. There'd be no communication and everyone would have to upgrade and implement their specific exports, too. Not very user friendly.

    There is a better way to do this...

    To solve all of the above, you can get away with just two major Pinescript functions:

    - kernel.channel(title, options...) => channel object
    This retrieves a channel-like prototype object that allows two or more scripts to communicate via a_channel.yield().
    Note: Every script automatically signs up to two channels, channel.chart and channel.self, where channel.self's title would be the script's title. That way, you can sign up to other scripts' updates without them explicitly upgrading and adding channel dynamics.

    - kernel.require(title, options...) => script object
    This loads the source code of another script as a prototype object, without revealing the source code itself. The object contains input arguments, chart settings (e.g. timeframe), internal variables, functions, alert conditions, positions, plots and return values.
    Note: Using kernel.require does not add the script to your chart; it runs like a function inside the parent script, meaning it must be given input arguments and initialised as a global variable. Plots could be explicitly permitted, but are less interesting than internal vars, alerts, positions, functions, and return values.

    PineScript would need two new object types, but it seems like they follow a prototype-ish style already, so it shouldn't be terribly difficult to have a Channel and Script object type.

    To accommodate these two object types, you would need to also add:

    - a_channel.yield(values... | self), which broadcasts values to the others on the channel just like a coroutine in Javascript or a block in Ruby/Python

    - a_channel.await(), which forcibly awaits until there is a pending item on the channel (which would include who sent it), just like in Javascript

    I do not wish to hide that these object types would have their own quirks, like how do you find out what variables and functions a script has if its source code is hidden? or how do you make only some of them private? That is later stage stuff. For a first version, it can just give the plotted return values if the source code isn't visible.

    If TradingView wanted to be ambitious, this system could let you create multi-tiered strategies that operated across multiple charts and timeframes too.

    It would be possible without any new commands -- just make charts like scripts and let them talk across a global channel.

    This coroutine style communication is very powerful and there may also be mileage in adding faithful versions of coroutine, async/await, Go-like channels, and pub/sub messaging later on. They each have their uses and pinescripts are no different to any other async script: you need multitasking handlers.

    Anyway, the above modification fits the no-dependency requirements of Pinescript, allows old scripts to still work with this system (default channels are like an 'import') and permits more complex ideas while addressing code reusability in a simple way. It preserves and leverages multitasking too, as that is a critical must-have on time series studies.

    P.S. If I don't see any uptake on this idea as a reply to this existing one, I will post a new topic about cross-script communication & code reusability.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned sad, anxious, confused, frustrated kidding, amused, unsure, silly happy, confident, thankful, excited