OptiPine
An open-source Pine Script optimization library for TradingView. It turns caching, sparse updates, reusable storage and workload-aware data structures into small APIs, so demanding scripts spend their execution budget on the feature instead of on repeated work.
What is OptiPine?
OptiPine is a high-performance architecture library for Pine Script v6, built for algorithms that go beyond ordinary indicator workloads. In a small indicator, optimization is often optional. In a rendering engine, a machine learning library, a simulation, a dashboard or an object system, it can decide whether a feature runs at all.
The idea is simple: do less work, move less data, and let the representation follow the workload. The techniques are the ones used in projects such as Pine3D and NeuraLib. Most scripts never need more than the high-level calls. A Memo with two dependencies looks like this:
// Pseudocode: trendRegime and volatilityRegime are floats;
// rebuildModel() is a pure calculation.
var op.FloatMemo model = op.floatMemo()
if model.staleOn(trendRegime, volatilityRegime)
model.store(rebuildModel(trendRegime, volatilityRegime))
float result = model.get()
// Output: rebuildModel() runs once, then only when either regime changes.Memo owns the previous dependencies, the first-run state, the validity and the cached result. The script only declares what the result depends on.
Where the time goes
The cost of a demanding script is rarely one slow formula. It is the thousands of operations around it:
- Recalculating results whose inputs did not change. Memo and Watch rerun the work only when what it depends on changes.
- Shifting rolling arrays. Row rings overwrite the oldest row and still read in time order.
- Moving stored objects when one disappears. StablePool keeps each object in the slot it was given.
- Scanning a whole collection to find a few changes. DirtySet visits only the entries that were marked.
- Searching keys one by one. Typed stores choose direct indexing, a dense table, a map or binary search from the keys.
What it saves
In our tests against conventional Pine implementations of the same task, OptiPine's optimized paths commonly ran 15% to 40% faster. Sparse updates and indexed lookups exceeded 90% when the alternative scanned or searched the full collection.
- DirtySet ran 93% faster than clearing and scanning the whole collection, with 1% of the entries changed.
- Watch's compare-first array check ran 35% to 60% faster than rewriting a snapshot on every pass.
- A ring's chronological read ran 90% faster than rebuilding a 512-cell, width-four output row by row.
- Direct integer addressing ran 21% faster than a map, and a map 91% faster than repeated linear lookup with 32 entries.
- IntBuckets averaged 19% faster than a wrapper type holding an array, in a 64-key traversal.
Three levels of control
- Tier 1, Quick: ready-to-use calls with automatic defaults. Watch, Memo, CadenceGate, typed stores, StablePool, DirtySet, row rings, double buffers and WeightedSampler.
- Tier 2, Composable: explicit lifecycles, configuration and representation policies. IntIndex, IntBuckets, SlotCache, RingCursor, Revision, WeightedIndex, WeightedPrefix and FloatFenwick.
- Tier 3, Expert: physical addressing, unchecked writes and scoped raw mutation, for hot paths you have measured. Read-only views are not Tier 3.
Start with Tier 1 and go deeper only when a measured workload needs it. Core Concepts explains the tiers, borrowed views and lifecycles.
What it gives you
When native Pine is better
- Ordinary series history such as
close[50]should stay native Pine. - For a few fixed objects, manual indices are simpler than a pool.
- If a producer already gives you one reliable change flag, use the flag instead of a Watch.
- Comparing an array is O(N). Watch it only when the calculation it guards costs more than the comparison.
Where to go next
OptiPine is created by Alien_Algorithms. Import the published library with Alien_Algorithms/OptiPine/1, and see each technique explained interactively on the OptiPine product page.