MaidongAlertLibraryLibrary "MaidongAlertLibrary"
Maidong Alert Library is a Pine Script library built to standardize alert formatting and dispatch across signals, order blocks, setups, and analysis modules.
Instead of building alert text separately inside each part of an indicator, this library centralizes message construction, time formatting, directional labeling, and frequency handling into one reusable component.
Core features:
- Supports `Signal`, `Setup`, `Analysis`, and `Order Block Signal`
- Supports `Bullish` and `Bearish` directional alerts
- Supports both compact and detailed alert output
- Supports timezone-aware timestamp formatting
- Supports common PulseWire alert frequency modes
This library is useful when:
- Your script contains multiple modules that all need alerts
- You want a consistent alert format across your ecosystem
- You want to separate alert formatting from indicator logic
AlertSender(condition, alertSetting, alertName, alertType, detectionType, setupData, frequency, utcZone, moreInfo, message, o, h, l, c, entry, tp, sl, distal, proximal)
Parameters:
condition (bool)
alertSetting (string)
alertName (string)
alertType (string)
detectionType (string)
setupData (string)
frequency (string)
utcZone (string)
moreInfo (string)
message (string)
o (float)
h (float)
l (float)
c (float)
entry (float)
tp (float)
sl (float)
distal (float)
proximal (float) Library

MaidongFVGLibrary## Title
`Maidong FVG Library`
## Short Description
Reusable Pine library for detecting and optionally rendering multi-timeframe imbalance zones with midpoint mitigation and pressure overlays.
## Full Description
This library provides a compact API for working with multi-timeframe imbalance zones inside other PulseWire indicators.
Core capabilities:
- Detects bullish and bearish imbalance zones from a selectable source timeframe
- Applies a displacement filter using the relationship between candle body size and a smoothed body baseline
- Uses confirmed source-timeframe data for stable MTF evaluation
- Optionally draws active zones directly from the library
- Supports midpoint or full-fill mitigation logic
- Can render midpoint guides and directional pressure slices inside each active zone
- Returns the latest active bullish and bearish zone levels for downstream logic
The library is intended for indicator authors who want reusable imbalance-zone logic without embedding a full standalone chart tool in every script.
## Exported Function
### `scanImbalanceZones(...)`
```pine
import username/MaidongFVGLibrary/1 as iz
=
iz.scanImbalanceZones(
sourceTimeframe,
displacementFactor,
mitigateAtMidpoint,
projectionBars,
drawBullish,
drawBearish,
drawMidpoint,
drawPressure,
bullishPressureColor,
bearishPressureColor,
zoneColor)
```
## Parameters
- `sourceTimeframe`: Timeframe used to evaluate imbalance conditions. Use `""` to use the chart timeframe.
- `displacementFactor`: Minimum body-strength multiplier relative to the smoothed body baseline.
- `mitigateAtMidpoint`: When `true`, a zone is cleared after price reaches its midpoint. When `false`, full fill is required.
- `projectionBars`: Number of chart bars used to project the rendered zone forward in time.
- `drawBullish`: Draw bullish zones.
- `drawBearish`: Draw bearish zones.
- `drawMidpoint`: Draw a dashed midpoint line inside each rendered zone.
- `drawPressure`: Draw directional pressure slices inside each rendered zone.
- `bullishPressureColor`: Color used for the upper demand slice.
- `bearishPressureColor`: Color used for the lower supply slice.
- `zoneColor`: Base fill and border color for the full zone.
## Return Values
The function returns 12 values:
1. `newBullish`
2. `bullishStartTime`
3. `bullishUpper`
4. `bullishLower`
5. `bullishMidpoint`
6. `newBearish`
7. `bearishStartTime`
8. `bearishUpper`
9. `bearishLower`
10. `bearishMidpoint`
11. `bullishActiveCount`
12. `bearishActiveCount`
These values let the caller build alerts, filters, dashboards, or custom drawings without reimplementing the zone engine.
## Detection Model
Bullish zone:
- current low is above the high from two source bars back
- current close remains above that earlier high
- body size is at least `displacementFactor` times the smoothed body baseline
- evaluation uses confirmed source-timeframe bars
Bearish zone:
- current high is below the low from two source bars back
- current close remains below that earlier low
- body size is at least `displacementFactor` times the smoothed body baseline
- evaluation uses confirmed source-timeframe bars
## Publishing Notes
- Publish as a `Library`
- Add enough `max_boxes_count` and `max_lines_count` in consuming scripts
- If your published script uses the drawing options, mention that the library manages visual objects internally
## Suggested Release Notes
`v1`
- Initial public release
- Added reusable multi-timeframe imbalance-zone scanning
- Added optional midpoint and pressure rendering
- Added active-zone return values for downstream indicators Library

OrderTicketBuilderLibrary "OrderTicketBuilder"
Assembles broker order ticket payloads as JSON strings.
BuildTicket(licenseId, symbol, action, orderType, tradeType, size, price, tp, sl, risk, trailPrice, trailOffset)
BuildTicket assembles a JSON order ticket string for downstream execution.
Parameters:
licenseId (string) : License identifier
symbol (string) : Symbol to trade
action (string) : "MRKT" or "PENDING"
orderType (string) : "BUY" or "SELL"
tradeType (string) : "SPREAD" or "SINGLE"
size (float) : (Optional) Trade size
price (float) : (Optional) Price for pending orders
tp (float) : (Optional) Take profit
sl (float) : (Optional) Stop loss
risk (float) : (Optional) Percent risk if size unspecified
trailPrice (float) : (Optional) Trailing-stop trigger price
trailOffset (float) : (Optional) Trailing-stop offset
Returns: JSON order ticket string Library

RollingWindow█ OVERVIEW
This a Pine Script™ library to create rolling windows with arrays and matrices.
A rolling window is a first-in-first-out algorithm that stores values over chart updates, removing the oldest element as new values are added. Many programmers implement a form of this algorithm into their scripts currently like this:
var window = array.new(size = 10)
window.push(close) // Append `close` as a new element every new bar.
if 10 < window.size() // Maintain a size of 10 elements.
window.shift() // Remove oldest element.
With the RollingWindow library, you can simply call `roll()` to do the same thing like so:
var window = array.new(size = 10)
window.roll(close) // Rolling window of 10 elements updated each bar with `close`.
█ USAGE
Rolling Window Arrays
Import the RollingWindow library into your script.
import joebaus/RollingWindow/1 as rw
Create a rolling window array by calling `roll()` on an array declared with `var` bar persistence.
var window = array.new()
rw.roll(id = window, source = close, size = 3) // Alternatively: window.roll(close, 3)
Using an array with `varip` intrabar persistence lets `roll()` execute on and update elements intrabar.
varip window = array.new() // Updates intrabar.
rw.roll(id = window, source = close, size = 3) // Executes `roll()` every realtime update.
Ensure arrays are declared with `var` or `varip` keywords to store updated elements. Otherwise, applying `roll()` will not store rolled values.
id = array.new() // No `var` or `varip` keyword.
rw.roll(id, close, 3) // Only updates a single element in `id`!
New elements can be added dynamically to empty arrays with the limit set by the `roll(size)` parameter. Once the array is full, every sequential chart update rolls out , removes, the oldest element.
varip id = array.new()
// Dynamically appends up to 3 elements of `timenow`, then rolls elements.
id.roll(source = timenow, size = 3) // Use `roll()` as a method on `id`.
Arrays with initialized values and sizes can be used as a rolling window array.
var array id = array.from("Hello", "World")
string closeString = str.tostring(close, format.mintick)
id.roll(source = closeString, size = 2) // Rolls elements into `id`, up to 2 elements.
The `roll(size)` parameter becomes optional for arrays with an initialized size, because `roll()` will by default use the initialized size of the array provided if `roll(size)` is not set.
var id = array.new(size = 3) // Returns
color gradient = color.from_gradient(close, low, high, color.red, color.green)
id.roll(source = gradient) // Uses the size of `id` as the rolling window size limit.
An array with initialized values can still grow dynamically if `roll(size)` parameter is greater than the array's initial size.
var id = array.new(size = 3) // Returns
chart.point nowPoint = chart.point.now(close)
id.roll(source = nowPoint, size = 4) // Dynamically grows to
The `roll(size)` parameter must always be equal to or greater than the initial size of the array, or else `roll()` will generate a runtime error.
var id = array.new(size = 3)
id.roll(source = close, size = 2) // Generates a runtime error!
// roll(array id, float source, int size):
// `size` (2) must be greater than or equal to the size of `id` (3), or set to `na`!
When the array size and `roll(size)` parameter are both unspecified, `roll()` will dynamically size the array up to the element limit before rolling new elements.
var id = array.new()
id.roll(timenow) // Adds new elements to `id` up to the element limit, then rolls elements.
From within a conditional local scope , `roll()` can operate on arrays in a higher scope.
var id1 = array.new(size = 3)
float sma50 = ta.sma(close, 50)
float sma200 = ta.sma(close, 200)
if ta.cross(sma50, sma200) // Golden Cross condition.
id1.roll(source = str.format_time(time)) // Rolls up to 3 Golden Cross dates into `id1`.
var id2 = array.new()
footprint reqFootprint = request.footprint(100)
if not na(reqFootprint)
id2.roll(source = reqFootprint, size = 3) // Rolls up to 3 footprint objects into `id2`.
`roll()` returns the element removed from the array, allowing scripts to capture values as they are rolled out.
var id = array.new(size = 3)
float removedElement = id.roll(close, 3) // Returns the removed `close` value from the array.
if not na(removedElement)
label.new(bar_index, removedValue, str.tostring(removedValue))
Reverse Rolling Window Arrays
The roll operation can be done in reverse order using the `rollReverse()` library function; new elements are inserted at the beginning of the array instead, and old elements are removed at the end of the array.
var id1 = array.new()
id1.rollReverse(source = close, size = 3) // Dynamically sized reverse rolling window array.
varip id2 = array.new(size = 3)
id2.rollReverse(source = close) // Initialized size reverse rolling window array.
`rollReverse()` returns the element removed from the array, just like `roll()`.
var id = array.new(size = 3)
int removedValue = id.rollReverse(bar_index, 3)
Sorted Rolling Window Arrays
Rolling window arrays created with `roll()` are unsorted. To create ascending sorted rolling window arrays for `float` or `int` types, use the `rollAscendingVar()` or `rollAscendingVarip()` functions for `var` and `varip` keyword arrays respectively.
var id1 = array.new()
// Ascending sorted, dynamically sized `var` rolling window array.
id1.rollAscendingVar(source = close, size = 3)
varip id2 = array.new(size = 3)
// Ascending sorted, initialized size `varip` rolling window array.
id2.rollAscendingVarip(source = bar_index)
To create descending sorted rolling window arrays for `float` or `int` types, use the `rollDescendingVar()` or `rollDescendingVarip()` functions for `var` and `varip` keyword arrays respectively.
var id1 = array.new()
// Descending sorted, dynamically sized `var` rolling window array.
id1.rollDescendingVar(bar_index, 3)
varip id2 = array.new(3)
// Descending sorted, initialized size `varip` rolling window array.
id2.rollDescendingVarip(close)
Just like with the `array.sort()` built-in function, the ascending and descending rolling window functions do not sort `na` values.
float sma = ta.sma(50, close) // First 49 values are `na`.
var id = array.new()
id.rollAscendingVar(sma, 3) // Rolls nothing until `sma` values are not `na`.
The arrays with unsorted values should be sorted in ascending or descending order before calling the respective sorted rolling window library functions.
var array id = array.from(4, 1, 2, 3, 10, 8, 15, 7) // Unsorted initialized array.
id.sort(order.ascending) // Sort it first!
id.rollAscendingVar(bar_index)
The sorted rolling window functions can return the latest element removed from the array.
var id = array.new(size = 3)
float removedElement = id.rollAscendingVar(close, 3)
Rolling Window Matrices
The `roll()` matrix methods store a rolling window of arrays in row-major order. Rows are "rolled" by adding a new row at index `0`, and removing the oldest row at the end of the matrix.
var closeArray = array.new(10) // Array to store in the rolling window matrix.
var closeMatrix = matrix.new()
// Create a rolling window matrix with up to 3 `closeArray` rows and 10 columns (1 per element).
rw.roll(id = closeMatrix, array_id = closeArray, rows = 3)
A matrix with `varip` intrabar persistence lets `roll()` execute and update matrix rows intrabar.
varip closeArray = array.new(size = 10)
rw.roll(id = closeArray, source = time)
varip closeMatrix = matrix.new()
// Create a rolling window matrix with up to 3 `closeArray` rows and 10 elements (columns).
closeMatrix.roll(array_id = closeArray, rows = 3)
The matrix methods of `roll()` will dynamically create the necessary columns to fit all elements of `roll(array_id)` as long as the array size is greater than the number of matrix columns.
var closeArray = array.new(size = 10000)
closeArray.roll(source = close) // Creating a rolling window array.
// Size empty matrices dynamically with `roll(array_id)`.
var closeMatrix = matrix.new()
// Roll up to 100 rows of `closeArray` with 10000 elements (columns) into `closeMatrix`.
rw.roll(id = closeMatrix, array_id = closeArray, rows = 100)
The size of `array_id` can possibly be too large when dynamically adding columns to a rolling window matrix, generating a runtime error when the new column would exceed the 100,000 matrix size limit.
var closeArray = array.new()
closeArray.roll(source = close, size = 1001)
var closeMatrix = matrix.new()
rw.roll(id = closeMatrix, array_id = closeArray, rows = 100) // Generates a runtime error!
// roll(matrix id, array array_id, int rows):
// `array_id` (1001) and `rows` (100) create 100100 matrix elements!"
// Reduce the size of `array_id` or value of `rows` to stay within the 100,000 matrix size limit!
A matrix with initialized rows and columns can also be used with `roll()`. This requires that the array's size used in `roll(array_id)` must be less than or equal to the number of matrix columns.
var closeArray = array.new(100) // Initialized matrix columns require initialized array sizes.
closeArray.roll(close) // Roll 100 `close` elements into `closeArray`.
var closeMatrix = matrix.new(rows = 10, columns = 100) // 100 array elements, 100 columns.
rw.roll(id = closeMatrix, array_id = closeArray, rows = 10)
The `roll(rows)` parameter is also optional: `roll()` will use the number of rows in the initialized matrix when `roll(rows)` is not set. Plus the number of initialized matrix columns does not have to be the same size as `roll(array_id)`.
var closeArray = array.new(10) // Array initialized with 10 elements.
closeArray.roll(close)
var closeMatrix = matrix.new(rows = 10, columns = 100) // Matrix initialized with 100 columns.
closeMatrix.roll(closeArray) // No `rows` parameter, uses the initialized number of matrix rows.
Managing Drawings
An array or matrix of `line`, `linefill`, `label`, `box`, `polyline`, or `table` types can be used with `roll()` to manage the number of drawing on a chart.
var id = array.new()
// Roll a label in `id` after a bullish bar is confirmed.
if close > open and barstate.isconfirmed
chart.point nowPoint = chart.point.now(high)
label newLabel = label.new(nowPoint, "Bullish")
id.roll(newLabel, 5) // Rolls up to 5 labels in `id`, array grows up to a size of 5.
When drawings are rolled out of an array or matrix, they are deleted with the `.delete()` method of the respective type used. The library functions return `void` for drawing types, so no value is returned when an element is removed.
Library

LogLibLibrary "LogLib"
LogLib — unified logger with BUFFERED / PER_BAR / OFF modes,
bit-packed plot encoders, perf timing (tick/tock), load timer.
Step 2 patch: enum LogMode + LogLevel, method-first API, preserved facades.
f_logger_mode_off()
f_logger_mode_buffered()
f_logger_mode_stream()
f_logger_mode_per_bar()
f_q_unsigned(x, scale, maxv)
Quantize unsigned float to N-bit integer
Parameters:
x (float)
scale (float)
maxv (int)
f_q_signed(x, scale, bias, maxv)
Quantize signed float to N-bit integer with bias offset
Parameters:
x (float)
scale (float)
bias (int)
maxv (int)
f_pack3x10(a, b, c)
Pack three 10-bit values into single float for data window
Parameters:
a (int)
b (int)
c (int)
f_pack4x8(a, b, c, d)
Pack four 8-bit values into single float for data window
Parameters:
a (int)
b (int)
c (int)
d (int)
f_unpack3x10_a(packed)
Parameters:
packed (int)
f_unpack3x10_b(packed)
Parameters:
packed (int)
f_unpack3x10_c(packed)
Parameters:
packed (int)
f_unpack4x8_a(packed)
Parameters:
packed (int)
f_unpack4x8_b(packed)
Parameters:
packed (int)
f_unpack4x8_c(packed)
Parameters:
packed (int)
f_unpack4x8_d(packed)
Parameters:
packed (int)
f_encode_flags(s0, s1, s2, s3, s4, s5, s6, s7)
Encode 8 binary flags into 8-bit int
Parameters:
s0 (bool)
s1 (bool)
s2 (bool)
s3 (bool)
s4 (bool)
s5 (bool)
s6 (bool)
s7 (bool)
f_encode_ternary(s0, s1, s2, s3, s4)
Encode 5 ternary states (0,1,2) into base-3 integer
Parameters:
s0 (int)
s1 (int)
s2 (int)
s3 (int)
s4 (int)
f_decode_flag(encoded, bit_index)
Parameters:
encoded (int)
bit_index (int)
f_decode_ternary(encoded, state_index)
Parameters:
encoded (int)
state_index (int)
f_logger_new(mode, label, header, max_lines)
Initialize Logger (legacy signature, preserved)
Parameters:
mode (simple int) : 0=OFF/STREAM-alias, 1=BUFFERED, 2=PER_BAR
label (simple string)
header (simple string)
max_lines (simple int)
f_logger_new_enum(mode, label, header, max_lines)
Enum-aware factory (preferred for new code)
Parameters:
mode (simple LogMode)
label (simple string)
header (simple string)
max_lines (simple int)
f_new_logger_buffered(label, header)
Quick BUFFERED logger with default thresholds (4000 chars / 2500 lines)
Parameters:
label (simple string)
header (simple string)
f_new_logger_per_bar(label, header)
Quick PER_BAR logger
Parameters:
label (simple string)
header (simple string)
f_new_logger_off()
Quick OFF logger (no-op, for production builds)
method append(l, row)
Append a row to the log; routes by mode.
@details OFF: discarded. BUFFERED: auto-flush when chars/lines threshold hit.
PER_BAR: caller must invoke flush() on barstate.isconfirmed.
Namespace types: Logger
Parameters:
l (Logger)
row (string)
method flush(l)
Explicit flush — drains any non-empty buffer.
@details Does NOT depend on barstate.islast. Caller invokes at natural
boundaries (RCOM completion, manual checkpoint, barstate.isconfirmed
for PER_BAR). BUFFERED mode primary flush remains automatic via append().
Namespace types: Logger
Parameters:
l (Logger)
method reset(l)
Reset buffer without flushing (drops accumulated content)
Namespace types: Logger
Parameters:
l (Logger)
method kv(l, key, val)
Append key=value diagnostic line
Namespace types: Logger
Parameters:
l (Logger)
key (string)
val (float)
method event(l, event_type, payload)
Append tagged event with bar_index prefix
Namespace types: Logger
Parameters:
l (Logger)
event_type (string)
payload (string)
method debug(l, msg)
Severity-tagged writers (level prefix added)
Namespace types: Logger
Parameters:
l (Logger)
msg (string)
method info(l, msg)
Namespace types: Logger
Parameters:
l (Logger)
msg (string)
method warn(l, msg)
Namespace types: Logger
Parameters:
l (Logger)
msg (string)
method error(l, msg)
ERROR — appends + immediate flush (drains accumulated buffer too)
Namespace types: Logger
Parameters:
l (Logger)
msg (string)
method tick(l, tag)
Namespace types: Logger
Parameters:
l (Logger)
tag (string)
method tock(l, tag)
Namespace types: Logger
Parameters:
l (Logger)
tag (string)
method get_last_timing(l)
Namespace types: Logger
Parameters:
l (Logger)
f_load_timer_new()
method update(lt)
Namespace types: LoadTimer
Parameters:
lt (LoadTimer)
method get_time(lt)
Namespace types: LoadTimer
Parameters:
lt (LoadTimer)
method get_formatted(lt)
Namespace types: LoadTimer
Parameters:
lt (LoadTimer)
method get_color(lt)
Namespace types: LoadTimer
Parameters:
lt (LoadTimer)
method log_time(lt, prefix)
Namespace types: LoadTimer
Parameters:
lt (LoadTimer)
prefix (string)
method log_to_logger(lt, logger)
Namespace types: LoadTimer
Parameters:
lt (LoadTimer)
logger (Logger)
method add_to_table(lt, t, col, row)
Namespace types: LoadTimer
Parameters:
lt (LoadTimer)
t (table)
col (int)
row (int)
Logger
Logger state. Mode field stays int for backward compat with persisted
Fields:
mode (series int) : 0=OFF, 1=BUFFERED, 2=PER_BAR (matches LogMode ordinal)
buffer (series string)
line_count (series int)
max_lines (series int)
max_chars (series int)
header (series string)
header_written (series bool)
label (series string)
markers (map)
last_delta_ms (series float)
last_tag (series string)
LoadTimer
Fields:
start_ms (series int)
load_secs_latched (series float)
captured (series bool) Library

taLibrary "ta"
Collection of all custom and enhanced TA indicators
ma(source, maType, length)
returns custom moving averages
Parameters:
source (float) : Moving Average Source
maType (simple string) : Moving Average Type : Can be sma, ema, hma, rma, wma, vwma, swma, highlow, linreg, median
length (simple int) : Moving Average Length
Returns: moving average for the given type and length
atr(maType, length)
returns ATR with custom moving average
Parameters:
maType (simple string) : Moving Average Type : Can be sma, ema, hma, rma, wma, vwma, swma, highlow, linreg, median
length (simple int) : Moving Average Length
Returns: ATR for the given moving average type and length
atrpercent(maType, length)
returns ATR as percentage of close price
Parameters:
maType (simple string) : Moving Average Type : Can be sma, ema, hma, rma, wma, vwma, swma, highlow, linreg, median
length (simple int) : Moving Average Length
Returns: ATR as percentage of close price for the given moving average type and length
bb(source, maType, length, multiplier, sticky)
returns Bollinger band for custom moving average
Parameters:
source (float) : Moving Average Source
maType (simple string) : Moving Average Type : Can be sma, ema, hma, rma, wma, vwma, swma, highlow, linreg, median
length (simple int) : Moving Average Length
multiplier (float) : Standard Deviation multiplier
sticky (simple bool) : - sticky boundaries which will only change when value is outside boundary.
Returns: Bollinger band with custom moving average for given source, length and multiplier
bbw(source, maType, length, multiplier, sticky)
returns Bollinger bandwidth for custom moving average
Parameters:
source (float) : Moving Average Source
maType (simple string) : Moving Average Type : Can be sma, ema, hma, rma, wma, vwma, swma, highlow, linreg, median
length (simple int) : Moving Average Length
multiplier (float) : Standard Deviation multiplier
sticky (simple bool) : - sticky boundaries which will only change when value is outside boundary.
Returns: Bollinger Bandwidth for custom moving average for given source, length and multiplier
bpercentb(source, maType, length, multiplier, sticky)
returns Bollinger Percent B for custom moving average
Parameters:
source (float) : Moving Average Source
maType (simple string) : Moving Average Type : Can be sma, ema, hma, rma, wma, vwma, swma, highlow, linreg, median
length (simple int) : Moving Average Length
multiplier (float) : Standard Deviation multiplier
sticky (simple bool) : - sticky boundaries which will only change when value is outside boundary.
Returns: Bollinger Percent B for custom moving average for given source, length and multiplier
kc(source, maType, length, multiplier, useTrueRange, sticky)
returns Keltner Channel for custom moving average
Parameters:
source (float) : Moving Average Source
maType (simple string) : Moving Average Type : Can be sma, ema, hma, rma, wma, vwma, swma, highlow, linreg, median
length (simple int) : Moving Average Length
multiplier (float) : Standard Deviation multiplier
useTrueRange (simple bool) : - if set to false, uses high-low.
sticky (simple bool) : - sticky boundaries which will only change when value is outside boundary.
Returns: Keltner Channel for custom moving average for given souce, length and multiplier
kcw(source, maType, length, multiplier, useTrueRange, sticky)
returns Keltner Channel Width with custom moving average
Parameters:
source (float) : Moving Average Source
maType (simple string) : Moving Average Type : Can be sma, ema, hma, rma, wma, vwma, swma, highlow, linreg, median
length (simple int) : Moving Average Length
multiplier (float) : Standard Deviation multiplier
useTrueRange (simple bool) : - if set to false, uses high-low.
sticky (simple bool) : - sticky boundaries which will only change when value is outside boundary.
Returns: Keltner Channel Width for custom moving average
kpercentk(source, maType, length, multiplier, useTrueRange, sticky)
returns Keltner Channel Percent K Width with custom moving average
Parameters:
source (float) : Moving Average Source
maType (simple string) : Moving Average Type : Can be sma, ema, hma, rma, wma, vwma, swma, highlow, linreg, median
length (simple int) : Moving Average Length
multiplier (float) : Standard Deviation multiplier
useTrueRange (simple bool) : - if set to false, uses high-low.
sticky (simple bool) : - sticky boundaries which will only change when value is outside boundary.
Returns: Keltner Percent K for given moving average, source, length and multiplier
dc(length, useAlternateSource, alternateSource, sticky)
returns Custom Donchian Channel
Parameters:
length (simple int) : - donchian channel length
useAlternateSource (simple bool) : - Custom source is used only if useAlternateSource is set to true
alternateSource (float) : - Custom source
sticky (simple bool) : - sticky boundaries which will only change when value is outside boundary.
Returns: Donchian channel
dcw(length, useAlternateSource, alternateSource, sticky)
returns Donchian Channel Width
Parameters:
length (simple int) : - donchian channel length
useAlternateSource (simple bool) : - Custom source is used only if useAlternateSource is set to true
alternateSource (float) : - Custom source
sticky (simple bool) : - sticky boundaries which will only change when value is outside boundary.
Returns: Donchian channel width
dpercentd(length, useAlternateSource, alternateSource, sticky)
returns Donchian Channel Percent of price
Parameters:
length (simple int) : - donchian channel length
useAlternateSource (simple bool) : - Custom source is used only if useAlternateSource is set to true
alternateSource (float) : - Custom source
sticky (simple bool) : - sticky boundaries which will only change when value is outside boundary.
Returns: Donchian channel Percent D
oscillatorRange(source, method, highlowLength, rangeLength, sticky)
oscillatorRange - returns Custom overbought/oversold areas for an oscillator input
Parameters:
source (float) : - Osillator source such as RSI, COG etc.
method (simple string) : - Valid values for method are : sma, ema, hma, rma, wma, vwma, swma, highlow, linreg, median
highlowLength (simple int) : - length on which highlow of the oscillator is calculated
rangeLength (simple int) : - length used for calculating oversold/overbought range - usually same as oscillator length
sticky (simple bool) : - overbought, oversold levels won't change unless crossed
Returns: Dynamic overbought and oversold range for oscillator input
oscillator(type, length, shortLength, longLength, source, highSource, lowSource, method, highlowLength, sticky)
oscillator - returns Choice of oscillator with custom overbought/oversold range
Parameters:
type (simple string) : - oscillator type. Valid values : cci, cmo, cog, mfi, roc, rsi, stoch, tsi, wpr
length (simple int) : - Oscillator length - not used for TSI
shortLength (simple int) : - shortLength only used for TSI
longLength (simple int) : - longLength only used for TSI
source (float) : - custom source if required
highSource (float) : - custom high source for stochastic oscillator
lowSource (float) : - custom low source for stochastic oscillator
method (simple string) : - Valid values for method are : sma, ema, hma, rma, wma, vwma, swma, highlow, linreg, median
highlowLength (simple int) : - length on which highlow of the oscillator is calculated
sticky (simple bool) : - overbought, oversold levels won't change unless crossed
Returns: Oscillator value along with dynamic overbought and oversold range for oscillator input Library

RegimeLibLibrary "RegimeLib"
RegimeLib — Bayesian online change-point detection (BOCPD) with score-driven variance.
Implements Tsaknaki, Lillo, Mazzarisi 2023 (arXiv:2307.02375) score-driven extension
to Adams & MacKay 2007 BOCPD. Maintains run-length distribution P(r_t | data_{1:t})
and detects regime changes when MAP run length resets.
Layer L0 (imports NumLib/4 for math helpers only).
DESIGN DECISIONS:
1. Score-driven variance adaptation (GARCH-like) handles heteroskedasticity.
2. Broadcast pattern: single BOCPD instance shared across multiple setups via regime_id.
3. varip state arrays (run_length_probs, run_means, run_variances) persist across bars.
4. Compute cost: O(L) per bar where L = max_run_length (default 100).
f_default_regime_reading()
Create default RegimeReading
Returns: Empty RegimeReading
f_bocpd_regime_score_driven(x, hazard, max_run_length, omega, alpha, beta, rl_probs, run_means, run_vars, prev_map, regime_counter)
BOCPD with score-driven variance adaptation (Tsaknaki et al. 2023)
Parameters:
x (float) : Current observation (e.g. log return)
hazard (simple float) : Hazard rate H (probability of regime change per bar), default 1/250
max_run_length (simple int) : Maximum run length L to track (caps array size), default 100
omega (simple float) : Score-driven variance ω parameter, default 1e-4
alpha (simple float) : Score-driven variance α parameter (score weight), default 0.05
beta (simple float) : Score-driven variance β parameter (persistence), default 0.94
rl_probs (array) : varip array run-length probabilities (size L+1, caller-managed)
run_means (array) : varip array online means per run (size L+1, caller-managed)
run_vars (array) : varip array online variances per run (size L+1, caller-managed)
prev_map (int) : varip int previous MAP run length (caller-managed)
regime_counter (float) : varip float regime ID counter (caller-managed)
Returns: RegimeReading
f_bocpd_regime(x, hazard, max_run_length, rl_probs, run_means, run_vars, prev_map, regime_counter)
Vanilla BOCPD (fixed variance, no score-driven adaptation)
Parameters:
x (float) : Current observation
hazard (simple float) : Hazard rate H
max_run_length (simple int) : Maximum run length L
rl_probs (array) : varip array run-length probabilities (caller-managed)
run_means (array) : varip array online means per run (caller-managed)
run_vars (array) : varip array online variances per run (caller-managed)
prev_map (int) : varip int previous MAP run length (caller-managed)
regime_counter (float) : varip float regime ID counter (caller-managed)
Returns: RegimeReading
f_init_bocpd_state(max_run_length, initial_mean, initial_var)
Initialize BOCPD state arrays (call once on first bar)
Parameters:
max_run_length (simple int) : Maximum run length L
initial_mean (float) : Initial mean estimate
initial_var (float) : Initial variance estimate
Returns: Tuple of (rl_probs, run_means, run_vars)
RegimeReading
RegimeReading — output of BOCPD regime detector
Fields:
map_run_length (series int) : Current MAP run length (bars since last regime change)
change_point_detected (series bool) : True if regime change detected on this bar
regime_id (series float) : Incrementing counter per regime (resets on change-point)
predictive_likelihood (series float) : Diagnostic: P(x_t | data_in_run_r*)
current_variance (series float) : Score-driven variance estimate at MAP run length Library

TPOLibLibrary "TPOLib"
TPOLib — Classical Time Price Opportunity (TPO) primitives.
Provides tick/row conversion, POC/Value Area calculation, TPO letter encoding,
Initial Balance tracking, and profile shape classification.
Note: Function bodies for f_price_to_tick, f_tick_to_row, f_row_to_price,
f_calc_row_ticks, f_poc_from_vals, f_value_area, and f_find_key_sorted are
copied from TPOSmartMoneyLib/3 (immutable on PulseWire). No extraction or
migration - legacy consumers unaffected.
Architecture: L0 (no library dependencies, uses ta.* and math.* primitives only)
f_price_to_tick(p)
Convert price to tick
Parameters:
p (float) : Price value
Returns: Tick value
f_tick_to_row(t, row_ticks_in)
Convert tick to row
Parameters:
t (int) : Tick value
row_ticks_in (int) : Number of ticks per row
Returns: Row index
f_row_to_price(row, row_ticks_in)
Convert row to price (midpoint)
Parameters:
row (int) : Row index
row_ticks_in (int) : Number of ticks per row
Returns: Price at row midpoint
f_calc_row_ticks(natr_ref, row_gran_mult)
Calculate dynamic row size based on normalized ATR
Parameters:
natr_ref (float) : Daily normalized ATR reference value
row_gran_mult (float) : Row granularity multiplier
Returns: Number of ticks per row
f_poc_from_vals(keys, vals)
Calculate Point of Control from volume distribution
Parameters:
keys (array) : Sorted array of row keys
vals (array) : Array of volume values
Returns: POC row key
f_value_area(keys, vals, poc_key, va_pct)
Calculate Value Area from volume distribution
Parameters:
keys (array) : Sorted array of row keys
vals (array) : Array of volume values
poc_key (int) : POC row key
va_pct (float) : Value Area percentage (typically 0.70)
Returns: Tuple of
f_find_key_sorted(keys, target)
Find key in sorted array using binary search
Parameters:
keys (array) : Sorted array of keys
target (int) : Target key to find
Returns: Index of key, or -1 if not found
f_tpo_letter_idx(bracket_idx)
Get TPO letter for bracket index (A-Z, then AA-AZ, etc.)
Parameters:
bracket_idx (int) : Bracket index (0-based)
Returns: Letter string
f_initial_balance_from_brackets(brackets, ib_bracket_count, row_ticks)
Calculate Initial Balance from first N brackets
Parameters:
brackets (array) : Array of TPOBracket (sorted by time)
ib_bracket_count (int) : Number of brackets in IB period (typically 2 for 1hr)
row_ticks (int) : Number of ticks per row
Returns: InitialBalance
f_detect_tpo_singles(brackets)
Detect TPO singles (rows with only one TPO print)
Parameters:
brackets (array) : Array of TPOBracket
Returns: Array of row indices that are singles
f_classify_profile(poc, val, vah, range_low, range_high)
Classify profile shape based on POC position and VA width
Parameters:
poc (int) : POC row
val (int) : VAL row
vah (int) : VAH row
range_low (int) : Lowest row in profile
range_high (int) : Highest row in profile
Returns: ProfileShape
TPOBracket
TPO bracket (single time period at a price level)
Fields:
letter (series string) : Letter identifier (A-Z for 30min brackets in RTH session)
row (series int) : Row index (price level)
volume (series float) : Volume accumulated in this bracket
ValueArea
Value Area calculation result
Fields:
poc (series int) : Point of Control (row with highest volume)
val (series int) : Value Area Low (row)
vah (series int) : Value Area High (row)
poc_volume (series float) : Volume at POC
va_volume (series float) : Total volume in Value Area
InitialBalance
Initial Balance (first hour of RTH session)
Fields:
ib_high (series float) : Highest price in IB period
ib_low (series float) : Lowest price in IB period
ib_range (series float) : IB range (high - low)
extended_up (series bool) : IB extended upward
extended_down (series bool) : IB extended downward
ProfileShape
Profile shape classification
Fields:
shape (series string) : "normal", "b_shape", "p_shape", "d_shape", "neutral"
poc_position (series float) : POC position relative to range (0.0=low, 1.0=high)
va_width (series float) : Value Area width as % of total range Library

OscLibLibrary "OscLib"
OscLib — Oscillator primitives and normalization utilities.
Provides centered/clamped normalization for bounded and unbounded oscillators,
multi-oscillator dispatcher, and pivot-based divergence detection.
Architecture: L0 (no library dependencies, uses ta.* primitives only)
f_center_bounded(raw, midpoint)
Centered normalization for bounded oscillators (RSI, MFI, Stoch, WPR)
Parameters:
raw (float) : Raw oscillator value
midpoint (float) : Center point (typically 50.0 for RSI/MFI/Stoch)
Returns: Centered value in range
f_clamp_normalize(raw, threshold)
Clamped normalization for unbounded oscillators (CCI, MACD Hist, ATR)
Parameters:
raw (float) : Raw oscillator value
threshold (float) : Scaling threshold (e.g., 200 for CCI, 2*ATR for MACD)
Returns: Clamped value in range
f_compute_osc(kind, src, len)
Multi-oscillator dispatcher
Parameters:
kind (string) : Oscillator type: "RSI", "CCI", "MFI", "STOCH", "WPR"
src (float) : Source series (typically close or hlc3)
len (simple int) : Oscillator period/length
Returns: Raw oscillator value
f_divergence_pivot(osc, price, lb_left, lb_right)
Pivot-based divergence detection (matches REOS production pattern)
Parameters:
osc (float) : Oscillator series
price (float) : Price series (typically close)
lb_left (int) : Left lookback for pivot detection
lb_right (int) : Right lookback for pivot detection
Returns:
bearish_div: price makes higher high, oscillator doesn't
bullish_div: price makes lower low, oscillator doesn't Library

SessionLibLibrary "SessionLib"
SessionLib — timezone, session detection, and timeframe utilities.
Extracted from TaUtilityLib during Step 13 decomposition.
Layer L0 (leaf utility, depends only on Pine builtins).
CHANGELOG v1:
- SessionState UDT for US/Asia/EU session detection
- Timeframe navigation: f_get_next_tf, f_get_prev_tf, f_get_lower_tf
- Session parsing: f_sess_part, f_hhmm_to_h, f_hhmm_to_m, f_session_tz
- Symbol activity: f_symbol_activity_1m, f_is_trading_now, f_is_active_symbol
- Status icons: f_status_icon, f_status_icon_from_1m, f_symbol_status_icon
- Utilities: f_tf_ms, f_symbol_base
f_session_state()
Detect RTH session (US/Asia/EU)
Returns: SessionState with session flags and label
f_tf_ms(tf)
Convert timeframe to milliseconds
Parameters:
tf (string) : Timeframe string (e.g., "15", "240", "D")
Returns: Milliseconds as int
f_get_next_tf(tf, steps)
Gets next higher timeframe(s) from current
Parameters:
tf (string) : Current timeframe string
steps (string) : "1 TF Higher" for next TF, any other value for 2 TFs higher
Returns: Next timeframe string or na if at maximum
f_get_prev_tf(tf)
Gets previous lower timeframe from current
Parameters:
tf (string) : Current timeframe string
Returns: Previous timeframe string or na if at minimum
f_get_lower_tf(tf)
Gets standard lower timeframe mapping
Parameters:
tf (string) : Current timeframe string
Returns: Lower timeframe string or empty if at minimum
f_sess_part(sess, want_start)
Extract start or end part from session string
Parameters:
sess (string) : Session string (e.g., "0900-1600")
want_start (bool) : true for start, false for end
Returns: Time part string (HHMM format)
f_hhmm_to_h(hhmm)
Extract hour from HHMM string
Parameters:
hhmm (string) : Time string in HHMM format
Returns: Hour as int (0-23)
f_hhmm_to_m(hhmm)
Extract minute from HHMM string
Parameters:
hhmm (string) : Time string in HHMM format
Returns: Minute as int (0-59)
f_session_tz(session_tz_sel)
Convert session timezone selector to IANA timezone string
Parameters:
session_tz_sel (string) : Session timezone selector
Returns: IANA timezone string
f_symbol_activity_1m(s_timeClose_1m, s_inAnySess_1m, fresh_secs)
Check symbol activity from 1m security data
Parameters:
s_timeClose_1m (float) : 1m bar close time from request.security
s_inAnySess_1m (bool) : 1m session status from request.security
fresh_secs (float) : Freshness threshold in seconds
Returns:
f_is_trading_now(sym, fresh_secs)
Check if symbol is actively trading
Parameters:
sym (string) : Symbol string
fresh_secs (float) : Freshness threshold in seconds
Returns:
f_is_active_symbol(sym, fresh_secs)
Check if symbol is active (trading now)
Parameters:
sym (string) : Symbol string
fresh_secs (float) : Freshness threshold in seconds
Returns: true if trading
f_is_active_symbol(tradingNow)
Check if symbol is active (boolean overload)
Parameters:
tradingNow (bool) : Trading status boolean
Returns: Same boolean (passthrough for API consistency)
f_status_icon(sym, fresh_secs)
Get status icon from symbol
Parameters:
sym (string) : Symbol string
fresh_secs (float) : Freshness threshold in seconds
Returns: Status emoji string
f_symbol_status_icon(tradingNow, exchangeClosed, sessionOpenButStale)
Get status icon from boolean flags
Parameters:
tradingNow (bool) : Is trading
exchangeClosed (bool) : Is exchange closed
sessionOpenButStale (bool) : Session open but stale
Returns: Status emoji string
f_status_icon_from_1m(s_timeClose_1m, s_inAnySess_1m, fresh_secs)
Get status icon from 1m data
Parameters:
s_timeClose_1m (float) : 1m bar close time
s_inAnySess_1m (bool) : 1m session status
fresh_secs (float) : Freshness threshold in seconds
Returns: Status emoji string
f_symbol_base(ticker_id)
Extract symbol base from ticker (removes USDT suffix)
Parameters:
ticker_id (string) : Ticker ID string (e.g., "BINANCE:BTCUSDT")
Returns: Base symbol string (e.g., "BTC")
SessionState
SessionState — session detection container
Fields:
inUS (series bool) : US session active (14:30-22:00 UTC)
inAsia (series bool) : Asia session active (00:00-07:00 UTC)
inEU (series bool) : EU session active (07:00-14:30 UTC)
label (series string) : Session label string ("US", "Asia", "EU", "Off") Library

SimTradeIndicatorsLibrary "SimTradeIndicators"
SimTrade indicator library — exact parity with Python pipeline (TA-Lib + pandas_ta).
Each function replicates the formula used in base.py / signals.py so that
PulseWire charts match the GPU hunt / validator / live engine outputs.
Formula sources:
TA-Lib → RSI, ATR, EMA, MACD, CCI, Stoch, WILLR, MFI, ADX, PSAR, OBV, BBANDS, AROON, PPO, AD
pandas_ta → SuperTrend, Vortex, Ichimoku, Donchian, HMA, TSI, CMF, EFI, CHOP, Heikin-Ashi
Manual → Keltner (EMA+ATR Wilder), TTM Squeeze, Chandelier Exit, VWAP reset, Pivot Points
Known intentional deviations (documented):
- Stoch trigger 11 uses Full %D (double-smoothed), not single %K
- OBV filter 206 uses windowed 800-bar OBV (GPU-aligned, not cumulative)
- Pivot Points use rolling window, not session-based (see pivot_pp notes)
- EMA has longer warmup in TA-Lib (~50 bars unstable period) vs TW (from bar 1); steady-state identical
smma(src, length)
SMMA / Wilder RMA. alpha = 1/length. Matches talib "RMA" used for ATR/RSI internally.
Parameters:
src (float) : Source series
length (simple int) : Period
Returns: RMA value
hma(src, length)
HMA (Hull Moving Average). HMA = WMA(2·WMA(N/2) − WMA(N), √N). Matches pandas_ta.hma.
Parameters:
src (float) : Source series
length (simple int) : Period
Returns: HMA value
dema(src, length)
DEMA (Double EMA) = 2·EMA − EMA(EMA). Matches talib.DEMA.
Parameters:
src (float) : Source series
length (simple int) : Period
Returns: DEMA value
tema(src, length)
TEMA (Triple EMA) = 3·EMA − 3·EMA² + EMA³. Matches talib.TEMA.
Parameters:
src (float) : Source series
length (simple int) : Period
Returns: TEMA value
atr_wilder(length)
ATR using Wilder RMA. Identical to talib.ATR and TW ta.atr.
Parameters:
length (simple int) : Period (default 14)
Returns: ATR value
atr_percentile_pct(length, lookback)
ATR percentile rank over a rolling window. Matches Python vol_filter 201.
Logic: for each bar count how many ATR values in are <= current ATR,
return that fraction as 0..100. Warmup bars (< lookback + length) return 50.0.
Parameters:
length (simple int) : ATR period / Wilder RMA (default 14). Matches params .
lookback (simple int) : Rolling window for percentile rank (default 30). Matches params .
Returns: Percentile rank 0..100 (pass filter when >= pct_min / params )
bbands(src, length, mult)
Bollinger Bands. Returns .
mid = SMA. Matches talib.BBANDS (matype=0 = SMA).
Parameters:
src (float) : Source series (typically close)
length (simple int) : Period (default 20)
mult (float) : Standard deviation multiplier (default 2.0)
Returns:
bb_pctb(src, length, mult)
Bollinger Bands %B = (close − lower) / (upper − lower).
Returns 0.5 during warmup (matches Python _nan50 fallback in base.bb_pctb).
Parameters:
src (float) : Source series
length (simple int) : Period (default 20)
mult (float) : Multiplier (default 2.0)
Returns: %B value
bb_width_x1000(src, length, mult)
BB bandwidth × 1000 / mid. Used by vol filter 202 (bb_width).
Parameters:
src (float) : Source series
length (simple int) : Period (default 20)
mult (float) : Multiplier (default 2.0)
Returns: (upper − lower) / |mid| × 1000
keltner(ema_period, atr_period, mult)
Keltner Channel. mid = EMA(close, ema_period), band = ATR(atr_period) Wilder RMA.
IMPORTANT: this is the TW-standard formula. NOT pandas_ta kc(mamode="ema") which uses EMA(TR).
That version produces ~40% narrower bands than TW. This library uses the correct RMA(ATR) band.
Parameters:
ema_period (simple int) : EMA period for midline (default 20)
atr_period (simple int) : ATR period for band width (default 10)
mult (float) : ATR multiplier (default 1.5)
Returns:
keltner_width_x1000(period, mult)
Keltner Channel bandwidth × 1000 / mid. Used by vol filter 204 (keltner_width).
Parameters:
period (simple int) : Period for both EMA and ATR (default 20)
mult (float) : ATR multiplier (default 1.5)
Returns: (upper − lower) / |mid| × 1000
choppiness(length)
Choppiness Index. CHOP = 100·log10(Σ ATR1 / (HH − LL)) / log10(N).
Matches pandas_ta.chop and TW built-in CHOP. Returns 50.0 during warmup.
Parameters:
length (simple int) : Period (default 14)
Returns: CHOP value
rsi_val(src, length)
RSI using Wilder RMA. Identical to talib.RSI and TW ta.rsi.
Returns 50.0 during warmup (matches Python _nan50 fallback).
Parameters:
src (float) : Source series (typically close)
length (simple int) : Period (default 14)
Returns: RSI value
cci_val(length)
CCI = (typical − SMA(typical)) / (0.015 · mean_deviation). Matches talib.CCI.
Returns 0.0 during warmup (matches Python _nan0 fallback).
Parameters:
length (simple int) : Period (default 20)
Returns: CCI value
stoch_raw_k(k_period)
Stochastic raw %K (no smoothing). Matches base.stoch_k (talib slowk_period=1).
NOTE: TW ta.stoch default smooths %K with SMA(3). This is the unsmoothed fast %K.
Used by filter 103 (stoch_k_below).
Parameters:
k_period (simple int) : Lookback period (default 14)
Returns: Raw %K (50.0 during warmup)
stoch_full_d(k_period, d_period)
Full Stochastic %D = SMA(SMA(raw%K, d_period), d_period). Matches talib.STOCH output.
Used by trigger 11 (stoch_cross). NOT single-smoothed %K — lag is +2-3 bars vs TW default.
Parameters:
k_period (simple int) : Raw %K lookback (default 14)
d_period (simple int) : Smoothing applied twice (default 3)
Returns: Full Stochastic %D (50.0 during warmup)
williams_r(length)
Williams %R = −100 · (HH − close) / (HH − LL). Matches talib.WILLR.
Range: −100 to 0. Returns −50.0 during warmup.
Parameters:
length (simple int) : Period (default 14)
Returns: Williams %R value
mfi_val(length)
MFI (Money Flow Index). Matches talib.MFI.
Returns 50.0 during warmup.
Parameters:
length (simple int) : Period (default 14)
Returns: MFI value
macd_val(src, fast, slow, signal_period)
MACD. Returns . Identical to talib.MACD.
All NaN values replaced with 0.0 (matches Python _nan0).
Parameters:
src (float) : Source series
fast (simple int) : Fast EMA period (default 12)
slow (simple int) : Slow EMA period (default 26)
signal_period (simple int) : Signal EMA period (default 9)
Returns:
ppo_val(src, fast, slow)
PPO = (EMA(fast) − EMA(slow)) / EMA(slow) × 100. Matches talib.PPO.
Returns 0.0 during warmup.
Parameters:
src (float) : Source series
fast (simple int) : Fast period (default 12)
slow (simple int) : Slow period (default 26)
Returns: PPO value
tsi_val(src, long_period, short_period)
TSI (True Strength Index). Matches pandas_ta.tsi parameter order.
TSI = 100 · EMA(EMA(Δclose, slow), fast) / EMA(EMA(|Δclose|, slow), fast)
slow is the OUTER (first) smoothing, fast is the INNER (second). Same as TW.
Parameters:
src (float) : Source series
long_period (simple int) : Outer (slow) EMA period (default 25)
short_period (simple int) : Inner (fast) EMA period (default 13)
Returns: TSI value (0.0 during warmup)
adx_di(length)
ADX + DI lines. Returns . Matches talib.ADX/PLUS_DI/MINUS_DI.
Uses Wilder RMA (identical to TW ta.dmi / ta.adx).
Parameters:
length (simple int) : Period (default 14)
Returns: — 0.0 during warmup
supertrend_val(length, mult)
SuperTrend direction and value. Matches pandas_ta.supertrend (RMA ATR).
Returns : direction = 1 (bull) or −1 (bear).
Parameters:
length (simple int) : ATR period (default 10)
mult (float) : ATR multiplier (default 3.0)
Returns:
psar_val(start, inc, max_af)
Parabolic SAR. Returns . Matches talib.SAR.
direction = 1 if close > SAR (bull), −1 bear.
Parameters:
start (simple float) : Initial AF / step (default 0.02)
inc (simple float) : AF increment per bar (default 0.02)
max_af (simple float) : Maximum AF cap (default 0.2)
Returns:
aroon_val(length)
Aroon Up and Down. Returns . Matches talib.AROON.
ta.aroon does not exist in Pine v6 — computed manually:
Aroon Up = (length − bars since highest high over length+1 bars) / length × 100
Aroon Down = (length − bars since lowest low over length+1 bars) / length × 100
This is identical to talib.AROON and PulseWire's built-in Aroon indicator.
Returns 50.0 during warmup (matches Python _nan50).
Parameters:
length (simple int) : Period (default 25)
Returns:
vortex_diff(length)
Vortex Indicator difference (VI+ − VI−). Matches base.vortex.
Positive = bullish regime, negative = bearish. Returns 0.0 during warmup.
Parameters:
length (simple int) : Period (default 14)
Returns: VI+ minus VI−
linreg_slope(src, length)
Linear Regression Slope. Matches talib.LINEARREG_SLOPE exactly.
Computes OLS slope for x = 0..N-1 (oldest=0, newest=N-1).
Positive = uptrend, negative = downtrend. Returns 0.0 during warmup.
Parameters:
src (float) : Source series
length (simple int) : Period (default 20)
Returns: Slope value
obv_val()
OBV (On-Balance Volume). Cumulative. Matches talib.OBV.
Returns: Cumulative OBV
vwap_reset(reset_bars)
VWAP with periodic session reset. Matches base.vwap(reset_bars).
reset_bars=24 on H1 ≈ daily VWAP (crypto 24/7). reset_bars=6 on H4 ≈ daily.
reset_bars=0 uses TW built-in ta.vwap (session anchor).
Parameters:
reset_bars (simple int) : Bars per session (0 = TW session anchor, 24 = H1 daily, 6 = H4 daily)
Returns: VWAP value
cmf_val(length)
CMF (Chaikin Money Flow) = Σ(CLV·vol) / Σvol. Matches pandas_ta.cmf.
CLV = ((close − low) − (high − close)) / (high − low). Returns 0.0 during warmup.
Parameters:
length (simple int) : Period (default 20)
Returns: CMF value (−1 to 1)
ad_val()
Accumulation/Distribution Line. Matches talib.AD.
Returns: Cumulative A/D value
efi_val(length)
EFI (Elder Force Index). EFI = EMA((close − close ) · volume, length).
Matches pandas_ta.efi. Returns 0.0 during warmup.
Parameters:
length (simple int) : EMA period (default 13)
Returns: EFI value
ichimoku_val(tenkan_period, kijun_period, senkou_b_period)
Ichimoku lines. Returns .
Matches pandas_ta.ichimoku with CORRECTED column mapping (ISA, ISB, ITS, IKS, ICS).
senkou_a/b are plotted 26 bars AHEAD in TW — values here are for current bar alignment.
Parameters:
tenkan_period (simple int) : Tenkan-sen period (default 9)
kijun_period (simple int) : Kijun-sen period (default 26)
senkou_b_period (simple int) : Senkou B period (default 52)
Returns:
donchian_val(length)
Donchian Channel. Returns .
upper = highest(high, N), lower = lowest(low, N). Matches pandas_ta.donchian.
NOTE: lookback may differ ±1 bar from TA-Lib; consistent across all pipeline stages.
Trigger 37 (donchian_break) compares close > upper — use upper in Pine.
Parameters:
length (simple int) : Period (default 20)
Returns:
ttm_squeeze_val(bb_period, bb_mult, kc_period, kc_mult)
TTM Squeeze. Returns .
squeeze_on: BB inside KC (volatility compression).
momentum: ta.linreg(close − (donchian_mid + SMA) / 2, bb_period)
EXACT match with John Carter formula and base.ttm_squeeze after fix.
Parameters:
bb_period (simple int) : BB period (default 20)
bb_mult (float) : BB multiplier (default 2.0)
kc_period (simple int) : KC period — same for EMA midline and ATR band (default 20)
kc_mult (float) : KC ATR multiplier (default 1.5)
Returns:
chandelier_val(period, mult)
Chandelier Exit. Returns .
long_exit = highest(high, period) − mult · ATR(period)
short_exit = lowest(low, period) + mult · ATR(period)
Exact match with base.chandelier_exit. Both include current bar in rolling max/min.
Trigger 45 fires when close crosses long_exit or short_exit (up = bull, down = bear).
Parameters:
period (simple int) : Lookback and ATR period (default 22)
mult (float) : ATR multiplier (default 3.0)
Returns:
ha_close()
Heikin Ashi close. HA_close = (open + high + low + close) / 4. Matches pandas_ta.ha.
Returns: HA close value
ha_open()
Heikin Ashi open. HA_open = (HA_open + HA_close ) / 2.
Trigger 48 fires on HA candle color flip: HA_close vs HA_open.
Returns: HA open value
pivot_pp(period)
Rolling Pivot Point (floor method). Matches base.pivot_points.
pp = (max(high, period bars ago) + min(low, period bars ago) + close ) / 3
NOTE: Rolling window, NOT session-based. H1 default period=24 ≈ 1 day (crypto 24/7).
For H4 set period=6 (6 × 4h = 1 day). TW Pivot Points use session H/L/C — differs.
Parameters:
period (simple int) : Rolling lookback (default 24)
Returns: Pivot point value
pivot_r1_s1(period)
Rolling R1 and S1 levels. Matches base.pivot_points r1/s1.
r1 = 2·pp − lowest_low, s1 = 2·pp − highest_high
Parameters:
period (simple int) : Rolling lookback (default 24)
Returns: Library

Library

fpa_unified_libLibrary "fpa_unified_lib"
lineStyle(styleText)
Parameters:
styleText (string)
labelSize(sizeText)
Parameters:
sizeText (string)
normalizeSession(sessionInput, hideWeekends)
Parameters:
sessionInput (string)
hideWeekends (bool)
isSessionActive(sessionInput, timezoneInput)
Parameters:
sessionInput (string)
timezoneInput (string)
tfInRange(lowTf, highTf)
Parameters:
lowTf (string)
highTf (string)
parseTradingDayOpenMinutes(sessionInput)
Parameters:
sessionInput (string)
safeColor(c, transp)
Parameters:
c (color)
transp (int)
updateRay(lineRef, shouldShow, startBarIndex, yPrice, lineColor, lineWidth, lineStyleText, rightOffsetBars, lookbackBars)
Parameters:
lineRef (line)
shouldShow (bool)
startBarIndex (int)
yPrice (float)
lineColor (color)
lineWidth (int)
lineStyleText (string)
rightOffsetBars (int)
lookbackBars (int)
updateLabel(labelRef, shouldShow, yPrice, textValue, labelColor, rightOffsetBars, sizeText)
Parameters:
labelRef (label)
shouldShow (bool)
yPrice (float)
textValue (string)
labelColor (color)
rightOffsetBars (int)
sizeText (string)
trimLines(arr, limit)
Parameters:
arr (array)
limit (int)
trimLabels(arr, limit)
Parameters:
arr (array)
limit (int)
parseFloatList(textArea)
Parameters:
textArea (string) Library

ICOptimizerLibLibrary "ICOptimizerLib"
ICOptimizerLib v2 — IC-based parameter optimization with 4 Bayesian strategies.
Publish target: ICOptimizer/2 (hard break from v1 — see §A below).
Layer 1: primitive IC estimators (Pearson, Spearman, Kendall, Partial).
Layer 2: Optimizer UDT with 4 strategies: argmax | ucb | thompson | bayesian.
Layer 3: RegimeGate, ObjectiveWeights, composite scoring, serialize/restore.
Layer 4: diagnostics table and panel.
L2 library — depends only on NumLib.
─── §A v1 BACKWARD-COMPAT DECISION (follow-up 1) ────────────────────────
HARD BREAK. v1 (ICOptimizer/1) used bare strings ("argmax", "ucb", …).
v2 uses the OptimizerKind enum. Reason: Pine v6 enums are type-safe and
produce CE10 errors at compile time if a caller passes an invalid string,
whereas bare strings fail silently at runtime. The compat shim route
(string→enum dispatch wrapper) was considered and rejected: it would
re-introduce series-string branching inside a hot method, defeating the
purpose of the enum migration.
Migration for v1 callers:
OLD: f_find_optimal_param(params, ics, cur, 0.2) ← v1 API
NEW: opt = f_optimizer_new(OptimizerKind.ARGMAX, …) ← v2 API
idx = opt.propose()
opt.observe(idx, ic)
The free function f_find_optimal_param() is retained in §4 as a one-line
compat wrapper producing identical output to v1 findOptimalParam() for
callers that only used ARGMAX and do not need the UDT.
Publish target: ICOptimizer/2 (same publisher namespace as kNNLib/28,
LearningLib/1, etc. Parallel to v1, not a rename.)
─── §B UDT INDEPENDENCE AUDIT (follow-up 2) ─────────────────────────────
All 4 UDTs are independently constructable with no required coupling:
UDT Constructor Depends on
─────────────── ─────────────────────────── ────────────────────────────
Optimizer f_optimizer_new(…) nothing (grid is caller-owned)
RollingIC f_rolling_ic_new(capacity) nothing
RegimeGate f_regime_gate_new(…) nothing
ObjectiveWeights f_obj_weights_new(…) nothing
Valid combinations:
• Optimizer alone — minimal usage (ARGMAX strategy, no IC classification)
• Optimizer + RollingIC — IC classification per bar, classify() method
• Optimizer + ObjectiveWeights — composite scoring for multi-objective grids
• Optimizer + RegimeGate — gate-filtered observe() calls
• All 4 — full stack
Initialization order: any order; there are no cross-UDT init dependencies.
The caller is responsible for pushing IC values into RollingIC before
calling classify(); a fresh buffer returns 0.0 thresholds (safe default).
─── §C GP MATH VERIFICATION (follow-up 3) ───────────────────────────────
Jacobi solver convergence domain: guaranteed for diagonally dominant K.
K is diagonally dominant when kernel_noise > 0 (K = kernel(xi,xi) +
noise ≥ 1 + noise > Σ_{j≠i} kernel(xi,xj) for RBF/Matern52 with ls > 0).
NaN propagation guard: f_optimizer_new() enforces noise ≥ 1e-6 at
construction (see implementation below). NaN in ic_sample is gated by
the na(ic_sample) check in observe() before any array writes.
Grid size constraints (enforced at f_optimizer_new):
grid_size == 1 → runtime.error (BAYESIAN is undefined for a single cell)
grid_size > 30 → runtime.error for BAYESIAN only (Jacobi O(n²×20) budget)
grid_size ≥ 2 → all strategies valid
ARGMAX/UCB/THOMPSON have no upper grid-size constraint.
Unit test specification (see test_icoptimizer_v2_unit.pine):
T1: grid= + BAYESIAN → should hit error log (na guard)
T2: grid= + BAYESIAN, 50 observe() calls → ic_var shrinks
T3: grid size=30 + BAYESIAN → no silent NaN on bar 500 / 1000
T4: rising IC synthetic trajectory → propose() returns idx 6 after warmup
T5: peak-in-middle IC → propose() converges to idx 3 (center)
─── §D v5→v6 DELTA (Phase E-2a) ─────────────────────────────────────────
1. //@version=5 → //@version=6
2. type ICOptimizer → decomposed to 4 independent UDTs (§B)
3. `series float` qualifiers explicit; `simple int` for all ta.* lengths (CE10297)
4. Enum OptimizerKind / KernelKind / ReturnMode replaces bare strings
5. classifyIC scalar bug → RollingIC ring buffer + sort-based percentile
6. detectAndAdjustDomination orphan → method check_domination on Optimizer
7. Monotonic counter → reset_decay(decay) method
8. S9: all multi-line ternaries collapsed to single lines
9. f_ma_for_idx() dispatch in demo for simple-int ta.sma constraint
10. Nested array.get() in f_build_gram / observe() split to locals (COMMA_STATEMENTS)
f_ic_pearson(signal, ret, n)
Pearson IC: correlation of signal with forward return
Parameters:
signal (float) : Signal series (e.g. z-score oscillator)
ret (float) : Forward return series (aligned: ret = realized return for signal )
n (simple int) : Rolling window (simple int — required by ta.correlation)
f_ic_spearman(signal, ret, n)
Spearman IC via rank correlation approximation
Parameters:
signal (float) : Signal series
ret (float) : Forward return series
n (simple int) : Rolling window
Returns: Spearman rank-correlation approximation
f_ic_kendall(signal, ret, n)
Kendall IC approximation (via concordant/discordant sign correlation)
Parameters:
signal (float) : Signal series
ret (float) : Forward return series
n (simple int) : Rolling window
Returns: Kendall tau approximation
f_ic_partial(signal, ret, control, n)
Partial IC: correlation of signal with ret after removing control variable
Parameters:
signal (float) : Signal series
ret (float) : Forward return series
control (float) : Control variable to partial out
n (simple int) : Rolling window
Returns: Partial Pearson IC
f_forward_return(src, horizon, mode, benchmark)
Compute forward return from source series
Parameters:
src (float) : Source price series
horizon (simple int) : Look-forward bars
mode (series ReturnMode) : ReturnMode enum
benchmark (float) : Optional benchmark (used only in EXCESS mode; pass na otherwise)
f_label_from_signal(sig, ret, eps)
Label from signal × return sign match
Parameters:
sig (float) : Signal value
ret (float) : Realized return
eps (float) : Dead-zone threshold (returns within ±eps labelled 0)
Returns: 1 = correct direction, -1 = wrong direction, 0 = inside dead-zone
f_rolling_ic_new(capacity)
Create a new RollingIC buffer
Parameters:
capacity (simple int) : Number of IC samples to retain
method push(self, ic_val)
Push a new IC observation into the ring buffer
Namespace types: RollingIC
Parameters:
self (RollingIC)
ic_val (float)
method classify(self, ic_val, good_pct, bad_pct)
Classify current IC against ring buffer distribution
Namespace types: RollingIC
Parameters:
self (RollingIC) : RollingIC buffer (must have been pushed at least once)
ic_val (float) : Current IC to classify
good_pct (float) : Percentile above which IC is "good" (0–100)
bad_pct (float) : Percentile below which IC is "bad" (0–100)
Returns:
f_optimizer_new(kind, grid, lr, c_ucb, cooldown, kernel_kind, kernel_ls, kernel_noise)
Create a new Optimizer
Parameters:
kind (series OptimizerKind) : Strategy
grid (array) : Parameter grid (array, size ≤ 30 for BAYESIAN)
lr (float) : EWM learning rate for ic_ema / ic_var updates (0–1)
c_ucb (float) : UCB exploration constant (ignored for non-UCB)
cooldown (simple int) : Minimum bars between switches
kernel_kind (series KernelKind) : Kernel for BAYESIAN (ignored otherwise)
kernel_ls (float) : Kernel lengthscale (ignored otherwise)
kernel_noise (float) : Observation noise (ignored otherwise)
method propose(self)
Propose next parameter index to try
Namespace types: Optimizer
Parameters:
self (Optimizer)
Returns: Selected grid index
method observe(self, idx, ic_sample)
Record observed IC for a grid cell and update posterior
Namespace types: Optimizer
Parameters:
self (Optimizer)
idx (int) : Grid index that was evaluated
ic_sample (float) : Observed IC value
method reset_decay(self, decay)
Apply exponential decay to ic_ema and ic_var (prevents monotonic drift)
Namespace types: Optimizer
Parameters:
self (Optimizer)
decay (float) : Decay factor 0..1 (e.g. 0.95 = retain 95% of past)
method check_domination(self, long_n, short_n, ratio_threshold)
Detect directional signal domination and bump current grid index
Namespace types: Optimizer
Parameters:
self (Optimizer)
long_n (int) : Count of long signals in evaluation window
short_n (int) : Count of short signals in evaluation window
ratio_threshold (float) : Domination ratio (e.g. 4 = 4:1 imbalance)
Returns: direction_str = "long" | "short" | "none"
method current_param(self)
Get current parameter value from grid
Namespace types: Optimizer
Parameters:
self (Optimizer)
f_find_optimal_param(testParams, icValues, currentParam, smoothing)
Find optimal parameter from arrays (v1-compatible, wraps Optimizer.propose)
Parameters:
testParams (array) : Grid array
icValues (array) : IC values for each grid cell (same size)
currentParam (float) : Current param (for EWM smoothing)
smoothing (simple float) : EWM lr (0–1)
Returns:
f_regime_gate_new(mode, threshold, confirm_bars)
Create RegimeGate
Parameters:
mode (string)
threshold (float)
confirm_bars (simple int)
method is_open(self, ic_val, bars_above)
Check if gate is open given current IC and a rolling counter
Namespace types: RegimeGate
Parameters:
self (RegimeGate) : RegimeGate
ic_val (float) : Current IC
bars_above (int) : Rolling bars-above-threshold counter (caller maintains)
Returns: bool gate_open
f_obj_weights_new(w_ic, w_hitrate, w_freq_penalty, w_drawdown_penalty)
Create ObjectiveWeights
Parameters:
w_ic (float)
w_hitrate (float)
w_freq_penalty (float)
w_drawdown_penalty (float)
f_composite_score(w, ic, hitrate, freq, drawdown)
Compute composite score for a grid cell
Parameters:
w (ObjectiveWeights) : ObjectiveWeights
ic (float) : IC value for cell
hitrate (float) : Hit rate 0..1 for cell
freq (float) : Signal frequency 0..1 (higher = more signals = penalized)
drawdown (float) : Max drawdown magnitude (positive float)
Returns: Composite score (higher = better)
f_optimizer_serialize(self)
Serialize Optimizer state to a compact CSV string
Parameters:
self (Optimizer) : Optimizer to serialize
Returns: string blob (pass to f_optimizer_restore to reconstruct ic_ema/ic_var)
f_optimizer_restore(self, blob)
Restore ic_ema/ic_var/visits from serialized blob into an existing Optimizer
Parameters:
self (Optimizer) : Optimizer (grid must already be initialized with correct size)
blob (string) : String from f_optimizer_serialize
Returns: self (mutated in place)
f_diag_table(self, gate, weights, pos, max_rows)
Render diagnostics table for Optimizer state
Parameters:
self (Optimizer) : Optimizer
gate (RegimeGate) : RegimeGate (pass na if unused)
weights (ObjectiveWeights) : ObjectiveWeights (pass na if unused)
pos (string) : Table position (e.g. position.bottom_right)
max_rows (simple int) : Maximum grid rows to display (capped at array.size(grid))
Returns: table reference
f_diag_panel(self, height)
Render sparkline-style panel (one plot bar per grid cell, height = ic_ema)
Parameters:
self (Optimizer) : Optimizer
height (float) : Panel height in price units (caller scales)
Returns: label(na) (renders labels directly)
f_kind_str(k)
Parameters:
k (series OptimizerKind)
f_kernel_str(k)
Parameters:
k (series KernelKind)
f_return_mode_str(m)
Parameters:
m (series ReturnMode)
RollingIC
Rolling IC ring buffer for proper percentile computation
Fields:
samples (array) : Circular buffer of IC observations
head (series int) : Write head (mod capacity)
capacity (series int) : Max samples to retain
Optimizer
Optimizer — unified UDT for all 4 strategies
Fields:
kind (series OptimizerKind) : Strategy: ARGMAX | UCB | THOMPSON | BAYESIAN
grid (array) : Discrete parameter grid (size ≤ 30 for BAYESIAN)
ic_ema (array) : Posterior mean per cell (EWM updated)
ic_var (array) : Posterior variance per cell (UCB/Thompson/Bayes)
visits (array) : Visit count per cell
lr (series float) : EWM learning rate for ic_ema / ic_var updates
c_ucb (series float) : Exploration coefficient (UCB only)
cooldown (series int) : Minimum bars between parameter changes
last_change_bar (series int) : Bar index of last change
current_idx (series int) : Currently selected grid index
kernel_matrix (array) : Flattened len(grid)² Gram matrix (BAYESIAN only)
kernel_kind (series KernelKind) : RBF | MATERN52 (BAYESIAN only)
kernel_ls (series float) : Kernel lengthscale (BAYESIAN only)
kernel_noise (series float) : Observation noise σ² (BAYESIAN only)
total_visits (series int) : Cumulative visit count (for UCB log normalizer)
decay_factor (series float) : EWM decay applied by reset_decay (0..1; 1=no decay)
RegimeGate
RegimeGate — IC regime filter
Fields:
mode (series string) : "positive" | "any" | "top_pct"
threshold (series float) : IC threshold for "positive" or percentile for "top_pct"
confirm_bars (series int) : Bars IC must stay above threshold before gate opens
ObjectiveWeights
ObjectiveWeights — composite scoring weights
Fields:
w_ic (series float) : Weight on IC component
w_hitrate (series float) : Weight on hit-rate component
w_freq_penalty (series float) : Penalty for excessive signal frequency
w_drawdown_penalty (series float) : Penalty for drawdown Library

PDArraysLibrary "PDArrays"
Hi all!
This library will help you to draw fair value gaps and order blocks and their broken version; breaker blocks, mitigation blocks and inversion fair value gaps.
It does not contain any example code, but I will create an indicator called 'PD Arrays' that uses this library.
Best of luck trading!
Remove(zones, settings)
Removes the zone in 'zones.Remove' and its visuals. The visuals will be kept if 'settings.KeepHistoryZones' is true.
Parameters:
zones (Zones) : The current zone.
settings (Settings) : Set all values in this parameter to define the settings for the zones.
Interactions(zones, settings, trend)
Sets the interactions (retests\false breakouts\breakouts) from the library 'Touched'.
Parameters:
zones (array)
settings (Settings) : set all values in this parameter to define the settings for the order block creation.
trend (int) : the market structure trend that's used for the integrations direction. 1 = bullish, -1 = bearish, 0 = both.
HiddenInteractions(zones, settings, marketStructureInfo, trend)
Sets the hidden interactions (only breakouts) from the library 'Touched'.
Parameters:
zones (Zones)
settings (Settings) : set all values in this parameter to define the settings for the order block creation.
marketStructureInfo (MarketStructureInfo) : The state of market structure needed.
trend (int) : the market structure trend that's used for the integrations direction. 1 = bullish, -1 = bearish, 0 = both.
Pivots(settings)
Creates pivots (high and low) to be used for order block creation.
Parameters:
settings (Settings) : set all values in this parameter to define the settings for the order block creation.
Returns: a tuple containing two pivot values (high and low) or 'na'
OrderBlock(settings, pivotHigh, pivotLow)
Creates an order block if one is found according to the settings parameter.
Parameters:
settings (Settings) : set all values in this parameter to define the settings for the order block creation.
pivotHigh (float) : The high pivot to use.
pivotLow (float) : The low pivot to use.
Returns: a Zone object if an order block is found, na otherwise
FairValueGap(settings)
Creates a fair value gap if one is found according to the settings parameter.
Parameters:
settings (Settings) : set all values in this parameter to define the settings for the fair value gap creation.
Returns: a Zone object if a fair value gap is found, na otherwise
SetBarIndex(zone)
Sets the 'BarIndex' value of the 'zone' object according to 'zone.ChartBaseTime'.
Parameters:
zone (Zone) : The 'Zone' object to set the bar index on.
MarketStructureZones(marketStructureInfo, foundZones, zones, priceAction, settings)
Creates/draws zones (order blocks and fair value gaps) depending on the current market structure from the price action.
Parameters:
marketStructureInfo (MarketStructureInfo) : The infirmation about the market structure from the price action.
foundZones (array) : All zones (order blocks and fair value gaps) to take action on.
zones (Zones) : The 'Zones' object that holds the current context.
priceAction (PriceAction type from mickes/PriceAction/5) : The 'PriceAction.PriceAction' object from the library 'PriceAction'.
settings (Settings) : set all values in this parameter to define the settings for the fair value gap creation.
Visual
Holds the visual elements or the zone.
Fields:
Boxes (array) : All the visual boxes.
Lines (array) : All the visual lines.
Labels (array) : All the visual labels.
Zone
Holds the values for visuals for the zone and to handle interactions (retests, false breakouts and breakouts).
Fields:
BaseTimeClose (series int) : The time close for the start of the zone.
FoundTimeClose (series int) : The time close for the zone when it's found.
ChartBaseTime (series int) : The time for the start of the zone according to the chart bar.
High (series float) : The maximimum price of the zone.
Low (series float) : The minimum price of the zone.
ReactionLimit (series float) : Set a factor (%) of the Average True Range (of length 14) that the total reaction must have.
TouchedZone (Zone type from mickes/Touched/17) : Zone object that will be created and sent to the library 'Touched'.
Visual (Visual) : An object that holds the visual elements for the zone.
SourceTimeframeSeconds (series int) : The 'timeframe.in_seconds' for the zone.
Direction (series int) : Defines if the found zone is bullish (1) or bearish (-1).
LatestRetestBarIndex (series int) : The latest 'bar_index' for a retest.
LatestFalseBreakoutBarIndex (series int) : The latest 'bar_index' for a false breakout.
LatestBreakoutBarIndex (series int) : The latest 'bar_index' for a breakout.
BarIndex (series int) : The chart's timeeframe 'bar_index'.
OriginType (series Type) : The 'Type' for the origin (order block or fair value gap).
Type (series Type) : The type of the zone.
Visible (series bool) : If the zone is drawn and not removed or re-drawn.
Zones
Holds the values for the charts zones.
Fields:
Zones (array) : The currently active zones.
Removes (array) : Reprsents the zones that will be replaced.
HiddenZones (array) : The currently hidden zones.
OrderBlockSettings
The settings specific for order block creation.
Fields:
TakeOut (series bool) : If the bas candle needs to be higher\lower than the previous candle (liquidity sweep\grab).
FairValueGap (series bool) : If there needs o be a fair value gap between the first and the last (third) candle of the order block.
ConsecutiveRisingOrFalling (series bool) : The candles in the reaction must consecutivly rise or fall (the 'hl2' must be rising/falling).
ReactionFactor (series float) : A factor of the Average True Range (of length 14) that the total reaction must have. A higher value will create fewer zones with a bigger reaction. And check the checkbox if you want the limit to be displayed.
ShowReaction (series bool) : Show a solid line for the reaction limit.
HideConsecutiveZones (series bool) : If multiple order blocks are found after each other only the first one will be found by the indicator.
FairValueGapSettings
The settings specific for fair value gap creation.
Fields:
ConsecutiveRisingOrFalling (series bool) : The candles in the reaction must consecutivly rise or fall (the 'hl2' must be rising/falling).
Strong (series bool) : If this is enabled it will force the FVG middle candle to have a higher/lower 'hl2' (middle of the entire candle) than the first candle's high.
HideConsecutiveZones (series bool) : If multiple order blocks are found after each other only the first one will be found by the indicator.
MinimumSizeFactor (series float) : A factor of the Average True Range (of length 14) that the size of the fair value gap must have.
Settings
The settings for the creation of order blocks and fair value gaps. You will need to set all the containing values in here.
Fields:
KeepHistoryZones (series bool) : Set to true if you want removed (from previous trend) zones to be displayed.
Bull (series color) : The color of bullish zones.
Bear (series color) : The color of bearish zones.
CreateCreationZone (series bool) : Set to true if you want a box with a border to be drawn at the creation of the zone. This is usefull when the zones comes from a higher timeframe, but not from a lower. If this is false the 'Draw()' function will start at 'time - time_close'.
AlertRetests (series bool) : Enable if you want alerts to fire when the 'Touched' library signals that a retest of the order block has occured.
AlertFalseBreakouts (series bool) : Enable if you want alerts to fire when the 'Touched' library signals that a false breakout of the order block has occured.
AlertBreakouts (series bool) : Enable if you want alerts to fire when the 'Touched' library signals that a breakout of the order block has occured.
AlertMessageFormat (series string) : Set the format of the fired alert uppon 'Touched' library signals. Need to be in the format of '{0} on order block from ...' where '{0}' is replaced with 'retest', 'false breakout' or 'breakout'.
Types (array) : All types that should be displayed.
FairValueGapSettings (FairValueGapSettings) : The settings for the creation of fair value gaps.
OrderBlockSettings (OrderBlockSettings) : The settings for the creation of order blocks.
MarketStructurePivot
Pivot The 'PriceAction.Pivot' for the market structure.
Fields:
BrokenBarIndex (series int)
Pivot (Pivot type from mickes/PriceAction/5)
MarketStructureInfo
Holds the needed market structure pivots needed for this library.
Fields:
LatestBreakOfStructure (MarketStructurePivot) : The latest break of structure (BOS) found by the 'PriceAction' library.
LatestChangeOfCharacter (MarketStructurePivot) : The latest change of character (CHoCH\CHoCH+) found by the 'PriceAction' library. Library

ChopEngineLibrary "ChopEngine"
chopBase(_high, _low, _len)
Parameters:
_high (float)
_low (float)
_len (simple int)
gaugeFromCi(_ci, _tl, _cl)
Parameters:
_ci (float)
_tl (simple float)
_cl (simple float)
chopGauge(_high, _low, _tl, _cl, _len)
Parameters:
_high (float)
_low (float)
_tl (simple float)
_cl (simple float)
_len (simple int)
getChopBase(_sym, _tf)
Parameters:
_sym (simple string)
_tf (simple string)
getChop(_ciPrev, _ci, _tl, _cl)
Parameters:
_ciPrev (simple float)
_ci (simple float)
_tl (simple float)
_cl (simple float)
chgStateLabel(_g)
Parameters:
_g (float)
chgColor(_chg)
Parameters:
_chg (float)
chgCell(_chg, _prefix)
Parameters:
_chg (float)
_prefix (string)
method init(this, _ciPrev, _ci, _tl, _cl)
Namespace types: Chop
Parameters:
this (Chop)
_ciPrev (float)
_ci (float)
_tl (simple float)
_cl (simple float)
method update(this, _ciPrev, _ci, _tl, _cl)
Namespace types: Chop
Parameters:
this (Chop)
_ciPrev (float)
_ci (float)
_tl (simple float)
_cl (simple float)
method chgVsPrev(this)
Namespace types: Chop
Parameters:
this (Chop)
method chgVsEod(this)
Namespace types: Chop
Parameters:
this (Chop)
method state(this)
Namespace types: Chop
Parameters:
this (Chop)
method isTrending(this)
Namespace types: Chop
Parameters:
this (Chop)
method isChoppy(this)
Namespace types: Chop
Parameters:
this (Chop)
method isImproving(this)
Namespace types: Chop
Parameters:
this (Chop)
method isDeteriorating(this)
Namespace types: Chop
Parameters:
this (Chop)
Chop
Fields:
now (series float)
prev (series float)
eod (series float) Library

Library

NeuraLib Expansion: Advanced Model LayersNeuraLib_Models is the companion model expansion for NeuraLib .
NeuraLib provides the runtime: tensors, graph execution, datasets, scalers, losses, optimizers, training, inference, and validation tools. NeuraLib_Models builds on that foundation with higher-level neural architectures that are difficult and repetitive to write by hand.
The purpose of this expansion is to keep the main NeuraLib runtime clean, compact, and general, while giving researchers ready-to-use model families for sequence learning, attention, temporal pattern extraction, and Reinforcement Learning workflows.
----------------------------------------------------------------------------------------------------------------
🔷 HOW IT FITS INTO NEURALIB
NeuraLib_Models is built entirely on top of the public NeuraLib API. It does not replace the main runtime and it does not introduce a separate training engine.
After importing NeuraLib_Models, its fluent methods become available directly on NeuraLib `Sequential` models. The expansion alias can remain unused in the layer chain.
//@version=6
indicator("NeuraLib Models Quick Start", overlay = false, calc_bars_count = 600)
import Alien_Algorithms/NeuraLib/1 as nl
import Alien_Algorithms/NeuraLib_Models/1 as models
var nl.Sequential model = nl.sequential("advanced_model")
var float qLong = na
var float qFlat = na
var float qShort = na
if barstate.isfirst
model := model
.input(array.from(8), "sequence")
.temporalConvStack(4, 2, 2, 2, 1, 1, nl.ActivationKind.relu, 0.0, "temporal")
.globalAvgPool1d(3, 2, "pool")
.duelingQHead(4, 3, nl.ActivationKind.relu, "dueling_head")
.build(nl.rng(7))
float ret0 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float ret1 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float ret2 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float ret3 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float atrValue = ta.atr(14)
float atr0 = close == 0.0 ? 0.0 : atrValue / close
float atr1 = close == 0.0 ? 0.0 : atrValue / close
float atr2 = close == 0.0 ? 0.0 : atrValue / close
float atr3 = close == 0.0 ? 0.0 : atrValue / close
bool ready = not na(ret3) and not na(atr3)
if ready
nl.Tensor state = nl.vector(array.from(ret3, atr3, ret2, atr2, ret1, atr1, ret0, atr0), "state_window")
nl.Tensor qValues = model.predict(state)
qLong := qValues.get1d(0)
qFlat := qValues.get1d(1)
qShort := qValues.get1d(2)
plot(qLong, "Q long", color = color.lime, linewidth = 2)
plot(qFlat, "Q flat", color = color.gray)
plot(qShort, "Q short", color = color.red, linewidth = 2)
hline(0.0, "Zero", color = color.new(color.gray, 70))
The model is still a normal NeuraLib model. You still call `.compile()`, `.trainOnBatch()`, `.predict()`, `.evaluate()`, `.getWeightsArray()`, and `.softUpdateFrom()` from the main library.
----------------------------------------------------------------------------------------------------------------
🔷 WHY THIS EXPANSION EXISTS
The main NeuraLib library is the foundation. It exposes a graph engine powerful enough to create custom architectures, but repeatedly building LSTM gates, attention projections, residual blocks, Conv1D stacks, or Transformer paths from raw graph operations would be too verbose for everyday research.
NeuraLib_Models packages those patterns into readable blocks:
Temporal models : Conv1D blocks, temporal convolution stacks, global average pooling, and global max pooling for flattened sequence inputs.
Recurrent models : LSTM and GRU blocks for compact sequence memory.
Attention models : Self-attention, multi-head self-attention, cross-attention, Transformer encoder blocks, Transformer encoder stacks, and Transformer decoder blocks.
Residual models : Residual dense blocks for deeper feedforward paths.
Reinforcement Learning heads : Q-head blocks and dueling Q-heads for action-value style outputs.
Replay utilities : Deterministic Prioritized Experience Replay for reproducible Pine research.
Sequence helpers : Positional encoding for token, sequence, and attention workflows.
----------------------------------------------------------------------------------------------------------------
🔷 PRACTICAL EXAMPLES
🔸 Temporal Conv Model With Dueling Q-Head
This pattern is useful when a flattened sequence contains recent market states and the output represents action values.
//@version=6
indicator("NeuraLib Models Temporal Q Example", overlay = false, calc_bars_count = 600)
import Alien_Algorithms/NeuraLib/1 as nl
import Alien_Algorithms/NeuraLib_Models/1 as models
var nl.Sequential qModel = nl.sequential("temporal_q_model")
var nl.WindowDataset qDataset = nl.windowDataset(8, 3, 400, "q_rows")
var float qDown = na
var float qNeutral = na
var float qUp = na
var float qLoss = na
if barstate.isfirst
nl.CompileConfig cfg = nl.compileConfig()
cfg := cfg
.presetQValues()
.optimizer(nl.adamW(0.001))
.withTrainingGate(true)
qModel := qModel
.input(array.from(8), "state_window")
.temporalConvStack(4, 2, 2, 2, 1, 1, nl.ActivationKind.relu, 0.0, "temporal")
.globalAvgPool1d(3, 2, "pool")
.duelingQHead(4, 3, nl.ActivationKind.relu, "dueling_head")
.compile(cfg)
qDataset := qDataset
.setInputScaler(nl.ScalerKind.zScore)
.setTargetScaler(nl.ScalerKind.none)
float ret0 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float ret1 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float ret2 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float ret3 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float ret4 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float atrValue = ta.atr(14)
float atr0 = close == 0.0 ? 0.0 : atrValue / close
float atr1 = close == 0.0 ? 0.0 : atrValue / close
float atr2 = close == 0.0 ? 0.0 : atrValue / close
float atr3 = close == 0.0 ? 0.0 : atrValue / close
float atr4 = close == 0.0 ? 0.0 : atrValue / close
bool rowReady = not na(ret4) and not na(atr4)
if rowReady
array features = array.from(ret4, atr4, ret3, atr3, ret2, atr2, ret1, atr1)
float downTarget = math.max(-ret0, 0.0)
float neutralTarget = math.max(0.002 - math.abs(ret0), 0.0)
float upTarget = math.max(ret0, 0.0)
qDataset := qDataset.pushRow(features, array.from(downTarget, neutralTarget, upTarget))
if qDataset.ready(48)
if barstate.islastconfirmedhistory
nl.Batch train = qDataset.trainBatch(12)
qModel := qModel.trainOnBatch(train.inputTensor, train.targetTensor)
qLoss := qModel.trainStats.lastLoss
nl.Tensor liveState = nl.vector(array.from(ret3, atr3, ret2, atr2, ret1, atr1, ret0, atr0), "live_state")
nl.Tensor scaledState = qDataset.scaleInput(liveState)
nl.Tensor qValues = qModel.predict(scaledState)
qDown := qValues.get1d(0)
qNeutral := qValues.get1d(1)
qUp := qValues.get1d(2)
plot(qDown, "Q down", color = color.red, linewidth = 2)
plot(qNeutral, "Q neutral", color = color.gray)
plot(qUp, "Q up", color = color.lime, linewidth = 2)
plot(qLoss, "Training loss", color = color.orange)
hline(0.0, "Zero", color = color.new(color.gray, 70))
Input shape `array.from(8)` represents a flattened 4 step by 2 feature sequence. The temporal stack extracts short sequence structure, pooling compresses the sequence, and the dueling head separates value and advantage paths before producing action scores. The example trains only on the last confirmed historical bar so it remains safe to paste onto long charts.
🔸 Transformer Encoder For Token Rows
Attention models are useful when each row is a token or time step, and each column is a feature dimension.
//@version=6
indicator("NeuraLib Models Transformer Encoder Example", overlay = false, calc_bars_count = 600)
import Alien_Algorithms/NeuraLib/1 as nl
import Alien_Algorithms/NeuraLib_Models/1 as models
var nl.Sequential encoder = nl.sequential("encoder_model")
var float tokenSignal = na
var float tokenContext = na
var float tokenVolatility = na
if barstate.isfirst
encoder := encoder
.input(array.from(4), "tokens")
.multiHeadSelfAttention(4, 2, true, "mha")
.transformerEncoder(4, true, 2, nl.ActivationKind.geluApprox, "encoder", 0.05, 2)
.build(nl.rng(11))
float emaValue = ta.ema(close, 21)
float atrValue = ta.atr(14)
float ret0 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float ret1 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float ret2 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float ret3 = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float emaGap0 = emaValue == 0.0 ? 0.0 : close / emaValue - 1.0
float emaGap1 = emaValue == 0.0 ? 0.0 : close / emaValue - 1.0
float emaGap2 = emaValue == 0.0 ? 0.0 : close / emaValue - 1.0
float emaGap3 = emaValue == 0.0 ? 0.0 : close / emaValue - 1.0
float atr0 = close == 0.0 ? 0.0 : atrValue / close
float atr1 = close == 0.0 ? 0.0 : atrValue / close
float atr2 = close == 0.0 ? 0.0 : atrValue / close
float atr3 = close == 0.0 ? 0.0 : atrValue / close
bool ready = not na(ret3) and not na(emaGap3) and not na(atr3)
if ready
nl.Tensor tokens = nl.vector(array.from(
ret3, emaGap3, atr3, -1.0,
ret2, emaGap2, atr2, -0.33,
ret1, emaGap1, atr1, 0.33,
ret0, emaGap0, atr0, 1.0), "tokens").reshape(array.from(4, 4))
nl.Tensor encoded = encoder.predict(tokens)
tokenSignal := encoded.get1d(12)
tokenContext := encoded.get1d(13)
tokenVolatility := encoded.get1d(14)
plot(tokenSignal, "Latest token signal", color = color.aqua, linewidth = 2)
plot(tokenContext, "Latest token context", color = color.purple)
plot(tokenVolatility, "Latest token volatility", color = color.orange)
hline(0.0, "Zero", color = color.new(color.gray, 70))
In this example, each input row has 4 features. `headCount` is 2, so the model dimension is split into two attention heads.
Attention rule: `modelDim` must be divisible by `headCount`, and the current implementation supports up to 8 heads.
🔸 Prioritized Experience Replay
Prioritized Experience Replay stores examples with priorities, then returns reproducible weighted samples. This is especially useful for Reinforcement Learning experiments where high-error transitions should be revisited more often.
//@version=6
indicator("NeuraLib Models PER Example", overlay = false, calc_bars_count = 1200)
import Alien_Algorithms/NeuraLib/1 as nl
import Alien_Algorithms/NeuraLib_Models/1 as models
var models.PrioritizedReplayBuffer replay = models.prioritizedReplayBuffer(4, 2, 300, "replay")
var nl.Sequential replayModel = nl.sequential("replay_q_model")
var float replayLoss = na
var float firstImportanceWeight = na
var float replayRows = na
if barstate.isfirst
nl.CompileConfig cfg = nl.compileConfig()
cfg := cfg
.presetQValues()
.optimizer(nl.adamW(0.001))
.trainEveryCall()
replayModel := replayModel
.input(array.from(4), "state")
.dense(8, nl.ActivationKind.relu, "hidden")
.qHead(2, nl.ActivationKind.linear, "q_values")
.compile(cfg)
float rsiValue = ta.rsi(close, 14)
float emaValue = ta.ema(close, 21)
float atrValue = ta.atr(14)
float atrPct = close == 0.0 ? 0.0 : atrValue / close
float momentum = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float nextReturn = na(close ) ? 0.0 : nl.nextReturnValue(close , close)
bool rowReady = not na(rsiValue ) and not na(emaValue ) and not na(atrPct ) and not na(momentum )
if rowReady
float prevEma = emaValue
float priceVsEma = prevEma == 0.0 ? 0.0 : close / prevEma - 1.0
array stateFeatures = array.from(rsiValue / 100.0, priceVsEma, atrPct , momentum )
array targetValues = array.from(math.max(-nextReturn, 0.0), math.max(nextReturn, 0.0))
float priority = math.abs(nextReturn) + 0.0001
replay := replay.pushExperience(stateFeatures, targetValues, priority)
replayRows := float(replay.size())
if replay.ready(32)
models.PrioritizedReplaySample sample = replay.sampleBatch(32, 0.6, 0.4, 17)
replayModel := replayModel.trainOnBatch(sample.batch.inputTensor, sample.batch.targetTensor)
replayLoss := replayModel.trainStats.lastLoss
firstImportanceWeight := sample.weightArray.size() > 0 ? sample.weightArray.get(0) : na
if sample.indexArray.size() > 0
replay := replay.updatePriority(sample.indexArray.get(0), replayLoss + 0.0001)
plot(replayLoss, "Replay training loss", color = color.orange, linewidth = 2)
plot(firstImportanceWeight, "First sample weight", color = color.aqua)
The returned sample includes:
batch : A normal NeuraLib `Batch` containing sampled inputs and targets.
indexArray : Logical replay indices that can be passed back to `updatePriority()`.
weightArray : Normalized importance weights for custom loss weighting or diagnostics.
sampleRows : Number of sampled rows.
PER sampling is deterministic for a given buffer, `batchSize`, and `seed`. That makes Pine tests and live research easier to reproduce.
----------------------------------------------------------------------------------------------------------------
🔷 MODEL FAMILIES
🔸 Residual Dense Blocks
`residualDense()` adds a feedforward residual block. Residual paths help preserve information through deeper models and reduce the chance that a dense stack destroys useful features too early.
🔸 Conv1D And Temporal Convolution Stacks
`conv1d()` and `temporalConvStack()` operate on flattened sequence inputs. A sequence with `timeSteps = 4` and `featureCount = 2` is represented as 8 input features. These blocks are useful for local temporal structure, short rolling windows, feature rhythm, and compact pattern extraction.
🔸 Global Pooling
`globalAvgPool1d()` and `globalMaxPool1d()` compress flattened sequence outputs into feature-level summaries. Average pooling captures broad sequence behavior, while max pooling emphasizes the strongest activation per feature.
🔸 LSTM And GRU Blocks
`lstm()` and `gru()` provide recurrent sequence memory over flattened time-series inputs. They are useful when the order of recent states matters more than a single snapshot.
🔸 Attention And Transformers
`selfAttention()`, `multiHeadSelfAttention()`, `crossAttention()`, `transformerEncoder()`, `transformerEncoderStack()`, and `transformerDecoder()` bring attention-style modeling into Pine. They are designed for compact token matrices, packed target-memory layouts, and small Transformer-style research models that fit PulseWire limits.
🔸 Q-Heads And Dueling Q-Heads
`qHeadBlock()` creates action-value style outputs. `duelingQHead()` splits the model into value and advantage branches, then recombines them into Q-values. This is useful when you want the model to estimate both the overall state value and the relative value of each action.
🔸 Positional Encoding
`pushPositionalEncoding()` adds sinusoidal position features to a NeuraLib `FeatureBuilder`. This helps attention-style models distinguish where a token or time step sits in a sequence.
----------------------------------------------------------------------------------------------------------------
🔷 FEATURE QUICK REFERENCE
Built on NeuraLib : Uses the main NeuraLib graph, tensor, training, optimizer, dataset, and inference runtime.
Fluent API : Adds methods directly to NeuraLib `Sequential` models after import.
Block factories : Provides standalone `GraphBlock` factories for users who want lower-level composition.
Temporal modeling : Conv1D, temporal convolution stacks, and 1D pooling.
Recurrent modeling : LSTM and GRU sequence blocks.
Attention modeling : Self-attention, multi-head self-attention, cross-attention, encoders, encoder stacks, and decoders.
Reinforcement Learning support : Q-heads, dueling Q-heads, target-model soft updates through NeuraLib, and Prioritized Experience Replay.
Reproducible replay : PER sampling is deterministic for a given seed.
Shape guardrails : Advanced builders validate expected model feature counts and attention head compatibility.
----------------------------------------------------------------------------------------------------------------
🔷 IMPORTANT USAGE NOTES
Import order matters : Import `NeuraLib` first, then `NeuraLib_Models`.
The alias can be unused : The imported expansion registers methods on NeuraLib types, so `.lstm()`, `.gru()`, `.transformerEncoder()`, and similar methods can be called in the model chain.
Keep models compact : Pine Script has execution limits. Start with small hidden sizes, short sequences, and low head counts.
Control chart history : Use `calc_bars_count = 600` in `indicator()` when needed to balance available training history against model size and execution time.
Respect sequence shapes : Conv1D, temporal stacks, LSTM, and GRU methods expect flattened sequence sizes of `timeSteps * featureCount`.
Respect attention shapes : Attention methods expect each input row to have `modelDim` columns. Cross-attention and decoder blocks use packed rows.
Use NeuraLib guardrails : Train/validation splits, scalers, EarlyStopper, training gates, and gradient clipping remain part of the main NeuraLib workflow.
----------------------------------------------------------------------------------------------------------------
🔷 API REFERENCE
🔸 Sequential Methods
residualDense(hiddenUnits, activationKind, dropoutRate, name) : Adds a residual dense block.
duelingQHead(hiddenUnits, actionCount, activationKind, name) : Adds a dueling value/advantage Q-head.
conv1d(timeSteps, featureCount, filters, kernelSize, stride, activationKind, name) : Adds a Conv1D block for flattened sequences.
temporalConvStack(timeSteps, featureCount, filters, kernelSize, layers, stride, activationKind, dropoutRate, name) : Adds stacked temporal Conv1D layers.
globalAvgPool1d(timeSteps, featureCount, name) : Adds global average pooling over a flattened 1D sequence.
globalMaxPool1d(timeSteps, featureCount, name) : Adds global max pooling over a flattened 1D sequence.
lstm(timeSteps, featureCount, units, activationKind, name) : Adds an LSTM scan block.
gru(timeSteps, featureCount, units, activationKind, name) : Adds a GRU scan block.
selfAttention(modelDim, causal, name) : Adds row-wise self-attention.
multiHeadSelfAttention(modelDim, headCount, causal, name) : Adds multi-head self-attention.
crossAttention(queryRows, memoryRows, modelDim, headCount, name) : Adds packed query-memory cross-attention.
transformerEncoder(modelDim, causal, ffMultiplier, activationKind, name, dropoutRate, headCount) : Adds one Transformer encoder block.
transformerEncoderStack(modelDim, layers, causal, ffMultiplier, activationKind, dropoutRate, headCount, name) : Adds repeated Transformer encoder blocks.
transformerDecoder(targetRows, memoryRows, modelDim, headCount, ffMultiplier, activationKind, dropoutRate, name) : Adds a packed target-memory Transformer decoder.
🔸 GraphBlock Factories
qHeadBlock(inputFeatures, actionCount, activationKind, name) : Creates a Q-head block.
duelingQHeadBlock(inputFeatures, hiddenUnits, actionCount, activationKind, name) : Creates a dueling Q-head block.
residualDenseBlock(inputFeatures, hiddenUnits, activationKind, dropoutRate, name) : Creates a residual dense block.
conv1dBlock(timeSteps, featureCount, filters, kernelSize, stride, activationKind, name) : Creates a Conv1D block.
temporalConvStackBlock(timeSteps, featureCount, filters, kernelSize, layers, stride, activationKind, dropoutRate, name) : Creates a temporal convolution stack.
globalAvgPool1dBlock(timeSteps, featureCount, name) and globalMaxPool1dBlock(timeSteps, featureCount, name) : Create pooling blocks.
lstmBlock(timeSteps, featureCount, units, activationKind, name) and gruBlock(timeSteps, featureCount, units, activationKind, name) : Create recurrent blocks.
selfAttentionBlock(modelDim, causal, name) , multiHeadSelfAttentionBlock(modelDim, headCount, causal, name) , and crossAttentionBlock(queryRows, memoryRows, modelDim, headCount, name) : Create attention blocks.
transformerEncoderBlock(modelDim, causal, ffMultiplier, activationKind, name, dropoutRate, headCount) and transformerDecoderBlock(targetRows, memoryRows, modelDim, headCount, ffMultiplier, activationKind, dropoutRate, name) : Create Transformer blocks.
🔸 Prioritized Experience Replay
prioritizedReplayBuffer(featureCount, targetCount, maxRows, name) : Creates a replay buffer.
pushExperience(featureRowArray, targetRowArray, priority) : Adds or overwrites one replay row.
sampleBatch(batchSize, alpha, beta, seed) : Returns a deterministic weighted sample.
updatePriority(index, priority) : Updates a sampled row priority.
toBatch() : Returns all replay rows in chronological order.
ready(minRows) , size() , and clear() : Replay buffer utilities.
🔸 Feature Helpers
pushPositionalEncoding(position, dimensions, maxPeriod, featurePrefix) : Appends sinusoidal positional encoding values to a NeuraLib `FeatureBuilder`.
NeuraLib_Models is for Pine Script developers who want higher-level neural architecture blocks without leaving the NeuraLib runtime. It is built for compact research models inside PulseWire's execution limits, not for oversized GPU-style networks.
All the diagrams in this publication are rendered natively on PulseWire using Pine3D
----------------------------------------------------------------------------------------------------------------
This work is licensed under (CC BY-NC-SA 4.0) , meaning usage is free for non-commercial purposes given that Alien_Algorithms is credited in the description for the underlying software. For commercial use licensing, contact Alien_Algorithms
Library

NeuraLib: A Native AI and Deep Learning RuntimeNeuraLib is a tensor-based, auto-differentiating Machine Learning runtime built natively for Pine Script™.
It brings real Deep Learning mechanisms that power modern Artificial Intelligence systems into PulseWire. Instead of relying on fixed formulas, static regressions, or rigid structures, NeuraLib gives Pine developers a different tool: a compact neural runtime that can learn from the features you feed it, using the architecture you define.
This means users are no longer limited to classical methods like Linear Regression, Logistic Regression, KNN, Naive Bayes, Kalman Filters, or Markov Chains. One can build adaptive architectures perfectly suited for custom indicators, strategies, regime detection, directional prediction, price transforms, and AI-assisted signal generation.
Using NeuraLib, one can build a model, collect market data, normalize it, run predictions, train through backpropagation, track validation behavior, and update weights directly inside PulseWire.
Furthermore, it is not necessary to directly display trained variables. The process can be a part of a larger script functionality, where AI-powered decision making changes how an indicator behaves.
The goal is to make real neural network workflows usable in Pine Script without hiding the important controls, being scalable with evolving market dynamics, and abstracting away the complexity that comes with such software. The provided API is highly modular and intuitive, using chained object-oriented programming for easy readability and use. The backend is engineered with fault-tolerance in mind, providing users with sanity checks and preventing common pitfalls by default.
Think of NeuraLib as a comprehensive machine learning ecosystem, containing:
A Model Builder : Define neural networks with readable chained calls like `.input()`, `.dense()`, and `.dropout()`.
An In-Pine Training Engine : Models calculate losses, backpropagate gradients, update weights, and produce predictions directly on chart data.
Automated Data Pipelines : Built-in datasets handle feature collection, robust scaling (Z-Score, Min-Max), validation holdout splits, and time-series rolling windows.
Finance-Native Loss Functions : Beyond standard error metrics, the engine includes Directional, Quantile, Multi-Horizon Weighted, and Sharpe-style losses tailored for trading.
Practical Training Controls : Layer Normalization, AdamW weight decay, gradient clipping, gradient accumulation, and early stopping are built in to prevent overfitting.
Advanced Optimizers : Train networks using RMSProp, Adam, or AdamW, paired with learning rate schedules like Warmup Cosine and Step Decay.
For newer users, this means you can start with a simple dense model. For advanced users, the same runtime exposes graph operations, custom blocks, tensors, matrix operations, optimizers, schedules, losses, and extension hooks.
In plain terms, a model receives a row of numbers called features, compares its output against a target, measures the error with a loss function, and then adjusts its internal weights to reduce that error next time.
----------------------------------------------------------------------------------------------------------------
🔷 WHAT MAKES IT DIFFERENT
🔸 Parity-tested neural math
NeuraLib’s core operations have been tested against established Machine Learning Runtimes outside of PulseWire (Such as Keras / TensorFlow / PyTorch).
The goal was not to imitate the appearance of Machine Learning, but to reproduce the math that is proven to work. Standard forward passes, gradients, losses, and optimizer behavior were checked for 1:1 algorithmic parity, with negligible differences coming from normal floating-point behavior.
That means the matrix math, backpropagation, and gradient updates running on your chart follow the same underlying logic expected from professional Machine Learning environments.
🔸 Matrix-first computation
NeuraLib uses tensor and matrix abstractions as the foundation of the runtime. Under the hood, it supports the operations needed for neural computation, including matrix multiplication, broadcasting, activation functions, softmax, slicing, concatenation, reductions, normalization, attention scoring, convolution-style operations, and recurrent scan blocks.
🔸 Auto-differentiating graph engine
NeuraLib makes the computational graph a first-class object.
You can use high-level Sequential models, or build custom GraphBlocks from lower-level operations. Once a custom block is connected to a model, the same runtime handles the backward pass. That means your custom architecture can be trained with the same `.trainOnBatch()` workflow as standard layers.
----------------------------------------------------------------------------------------------------------------
🔷 CUSTOM GRAPHS
The Sequential API is the easiest way to start, but NeuraLib is not just a list of built-in layers.
You can create a `GraphBlock`, add operations, set an output node, and plug that block into a model. Once connected, the runtime handles the backward pass and parameter updates.
Useful graph operations include:
Matrix multiplication, transpose, add, subtract, multiply, divide, and scale.
Activation functions and softmax.
Layer Normalization and Dropout.
Causal masking, slicing, concatenation, row reduction, and column reduction.
Global average pooling and global max pooling for 1D sequences.
Attention score and attention apply operations.
Conv1D, LSTM scan, and GRU scan primitives.
This is the foundation that allows companion model libraries to add advanced AI and Machine Learning architectures without changing the main NeuraLib runtime.
----------------------------------------------------------------------------------------------------------------
🔷 BUILT-IN DATA GUARDRAILS
NeuraLib is not only a training mechanism. It also includes guardrails for cleaner research:
Invalid rows are rejected : Dataset rows must match the configured feature and target counts, and rows containing `na` values are not inserted.
Shape checks protect model calls : Forward, training, backward, and evaluation paths validate input and target shapes before running expensive graph code.
Train and validation splits are separated : `trainBatch()` and `validationBatch()` use holdout rows instead of blending all rows into one batch.
Scaler leakage is controlled : Validation batches are scaled from the training-side profile where the dataset split requires it, so validation normalization does not learn from the holdout slice.
Rolling windows respect time order : `RollingDataset` supports target offsets and wrapped ring buffers while preserving chronological reads.
These checks help reduce common data poisoning and data leakage mistakes: wrong row widths, missing values, validation contamination, target-offset leakage, and accidental overtraining across every historical bar.
----------------------------------------------------------------------------------------------------------------
🔷 A FIRST MODEL
The basic API is intentionally readable. This creates a small model with dropout, one hidden layer, Huber loss, AdamW optimization, and MAE tracking.
//@version=6
indicator("NeuraLib Basic Model", overlay = false, calc_bars_count = 600)
import Alien_Algorithms/NeuraLib/1 as nl
var nl.Sequential model = nl.sequential("basic_model")
var float modelOutput = na
if barstate.isfirst
nl.CompileConfig cfg = nl.compileConfig()
cfg := cfg
.optimizer(nl.adamW(0.001))
.loss(nl.LossKind.huber)
.metric(nl.MetricKind.mae)
.withTrainingGate(true)
model := model
.input(array.from(4), "features")
.dropout(0.15)
.dense(8, nl.ActivationKind.relu, "hidden")
.dense(1, nl.ActivationKind.linear, "output")
.compile(cfg)
float rsiValue = ta.rsi(close, 14)
float emaValue = ta.ema(close, 21)
float atrValue = ta.atr(14)
float atrPct = close == 0.0 ? 0.0 : atrValue / close
float momentum = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
bool ready = not na(rsiValue) and not na(emaValue) and not na(atrPct) and not na(momentum)
if ready
float priceVsEma = emaValue == 0.0 ? 0.0 : close / emaValue - 1.0
nl.Tensor inputTensor = nl.vector(array.from(rsiValue, priceVsEma, atrPct, momentum), "features")
nl.Tensor outputTensor = model.predict(inputTensor)
modelOutput := outputTensor.get1d(0)
plot(modelOutput, "Untrained model output", color = color.aqua, linewidth = 2)
hline(0.0, "Zero", color = color.new(color.gray, 70))
The same model can then receive scaled batches from a dataset and train with `.trainOnBatch()`. The plot in this first example is the untrained forward output, included so the block can be pasted directly into an indicator.
----------------------------------------------------------------------------------------------------------------
🔷 A PRACTICAL DATA FLOW
Machine Learning models usually fail when the data pipeline is careless. Price, volume, volatility, and oscillators often live on very different scales. NeuraLib includes dataset and scaling helpers so the common workflow stays explicit:
Build a feature row.
Build a target row.
Push the row into a dataset.
Request a training batch.
Request a validation batch when needed.
Train, evaluate, predict, and inverse-scale targets when appropriate.
//@version=6
indicator("NeuraLib Return Validation Example", overlay = false, calc_bars_count = 600)
import Alien_Algorithms/NeuraLib/1 as nl
var nl.Sequential model = nl.sequential("returns_model")
var nl.WindowDataset dataset = nl.windowDataset(4, 1, 500, "returns_dataset")
var float predictedReturn = na
var float validationLossValue = na
var float trainingLossValue = na
if barstate.isfirst
nl.CompileConfig cfg = nl.compileConfig()
cfg := cfg
.optimizer(nl.adamW(0.003))
.loss(nl.LossKind.huber)
.metric(nl.MetricKind.mae)
.trainEveryCall()
model := model
.input(array.from(4), "features")
.dense(8, nl.ActivationKind.relu, "hidden")
.dropout(0.10, "dropout")
.dense(1, nl.ActivationKind.linear, "next_return")
.compile(cfg)
dataset := dataset
.setInputScaler(nl.ScalerKind.zScore)
.setTargetScaler(nl.ScalerKind.zScore)
float rsiValue = ta.rsi(close, 14)
float emaValue = ta.ema(close, 21)
float atrValue = ta.atr(14)
float atrPct = close == 0.0 ? 0.0 : atrValue / close
float momentum = na(close ) or close == 0.0 ? 0.0 : close / close - 1.0
float realizedReturn = na(close ) ? na : nl.nextReturnValue(close , close)
bool rowReady = not na(rsiValue ) and not na(emaValue ) and not na(atrPct ) and not na(momentum ) and not na(close )
if rowReady
float prevEma = emaValue
float priceVsEma = prevEma == 0.0 ? 0.0 : close / prevEma - 1.0
array features = array.from(
rsiValue ,
priceVsEma,
atrPct ,
momentum )
array target = array.from(nl.nextReturnValue(close , close))
dataset := dataset.pushRow(features, target)
if dataset.ready(64)
nl.Batch train = dataset.trainBatch(16)
nl.Batch validation = dataset.validationBatch(16)
model := model.trainOnBatch(train.inputTensor, train.targetTensor)
trainingLossValue := model.trainStats.lastLoss
nl.LossResult validationLoss = model.evaluate(validation.inputTensor, validation.targetTensor)
validationLossValue := validationLoss.value
bool liveReady = not na(rsiValue) and not na(emaValue) and not na(atrPct) and not na(momentum)
if liveReady
float livePriceVsEma = emaValue == 0.0 ? 0.0 : close / emaValue - 1.0
array liveFeatures = array.from(rsiValue, livePriceVsEma, atrPct, momentum)
nl.Tensor liveInput = nl.vector(liveFeatures, "live_features")
nl.Tensor scaledInput = dataset.scaleInput(liveInput)
nl.Tensor scaledPrediction = model.predict(scaledInput)
nl.Tensor rawPrediction = dataset.inverseScaleTarget(scaledPrediction)
predictedReturn := rawPrediction.get1d(0)
plot(realizedReturn, "Last realized return", color = color.gray)
plot(predictedReturn, "Predicted next return", color = color.aqua, linewidth = 2)
plot(validationLossValue, "Validation loss", color = color.orange)
plot(trainingLossValue, "Training loss", color = color.new(color.blue, 35))
hline(0.0, "Zero", color = color.new(color.gray, 70))
This example trains from completed historical pairs. The feature row comes from the previous bar, and the target is the return from that previous bar to the current bar. That keeps the example easy to inspect and avoids using future information in the feature row. When pasted into an indicator, it plots the last realized return, the model's predicted next return, training loss, and validation loss.
----------------------------------------------------------------------------------------------------------------
🔷 TWO PRACTICAL EXECUTION MODES
Deep Learning in Pine requires careful execution control. NeuraLib supports two main workflows.
🔸 1. Live-edge training
Use this when you want safer execution for larger models.
The dataset can collect rows across the chart, while the expensive training step only runs on the last confirmed historical bar. This helps avoid timeouts while still allowing the model to learn from recent prepared data.
cfg := cfg.withTrainingGate(true)
Use this for:
Larger models
More features
Rolling sequence inputs
Heavier architectures
Safer live-edge updates
🔸 2. Full-history training and inference
Use this when the model is intentionally small.
The model can train and infer across historical bars, which makes it possible to create lightweight adaptive indicators, such as an AI Moving Average that learns from recent local structure instead of using a fixed smoothing formula.
cfg := cfg.trainEveryCall()
Use this for:
Tiny dense models
Small batches
Fast adaptive filters
AI-assisted moving averages
Lightweight feature transforms
For full-history workflows, start small. A shallow model with 4 to 8 hidden units and a batch size of 8 or 16 is usually a better starting point than a deep architecture.
----------------------------------------------------------------------------------------------------------------
🔷 ADVANCED MODEL EXPANSION
NeuraLib is designed to act as the foundation for larger model libraries and community-built extensions.
To demonstrate this, NeuraLib Expansion: Advanced Model Layers is built entirely on top of the public NeuraLib API and is launched in parallel on day one. The expansion library is published as NeuraLib_Models . It extends the runtime with higher-level builders for LSTMs, GRUs, temporal convolution stacks, residual dense blocks, dueling Q-heads for Reinforcement Learning, Transformer-style attention blocks, and Prioritized Experience Replay utilities.
The important part is architectural: advanced models plug into the same runtime. NeuraLib remains the foundation for tensors, graph execution, optimization, training, inference, datasets, and scaling. After importing `NeuraLib_Models`, its fluent methods become available on NeuraLib `Sequential` models, so the expansion alias does not need to be referenced directly in the layer chain.
//@version=6
indicator("NeuraLib Models Extension Demo", overlay = false, calc_bars_count = 600)
import Alien_Algorithms/NeuraLib/1 as nl
import Alien_Algorithms/NeuraLib_Models/1 as models
var nl.Sequential model = nl.sequential("advanced_demo")
if barstate.isfirst
model := model
.input(array.from(8), "sequence")
.temporalConvStack(4, 2, 3, 2, 2, 1, nl.ActivationKind.relu, 0.0, "temporal")
.globalAvgPool1d(2, 3, "pool")
.duelingQHead(4, 2, nl.ActivationKind.relu, "q_head")
.build(nl.rng(7))
----------------------------------------------------------------------------------------------------------------
🔷 FEATURE QUICK REFERENCE
Runtime : Matrix-first auto-differentiating neural graph runtime for Pine Script.
Model API : Chainable `Sequential` builder with `input`, `dense`, `dropout`, `layerNorm`, `activation`, `flatten`, `reshape`, and custom `block` support.
Training : Forward pass, loss calculation, backpropagation, gradient accumulation, optimizer steps, train stats, and history buffers.
Inference : `.predict()` for deterministic inference and `.predictMC()` for dropout-based uncertainty sampling.
Datasets : `WindowDataset` for flat rows and `RollingDataset` for time-series windows.
Scaling : None, Z-Score, Min-Max, Running Z-Score scalers, dataset input scaling, target scaling, and inverse target scaling.
Optimizers : SGD, Momentum, RMSProp, Adam, and AdamW.
Schedulers : Constant, Step Decay, Cosine Decay, and Warmup Cosine.
Activations : Linear, ReLU, Leaky ReLU, ELU, GELU Approx, Sigmoid, Tanh, Softplus, Swish, and Softmax.
Losses : MSE, MAE, Huber, LogCosh, Binary Cross Entropy, Binary Cross Entropy From Logits, Categorical Cross Entropy, Softmax Cross Entropy From Logits, Directional, Quantile, Multi-Horizon Weighted, and Sharpe.
Metrics : MAE, RMSE, Directional Accuracy, Binary Accuracy, Binary Accuracy From Logits, Categorical Accuracy, and Cosine Similarity.
Guardrails : Shape validation, invalid-row rejection, train/validation split helpers, leakage-aware scaler profiles, training gates, gradient clipping, and EarlyStopper.
Advanced expansion : Conv1D, temporal stacks, recurrent blocks, attention, Transformers, dueling Q-heads, positional encodings, and Prioritized Experience Replay.
----------------------------------------------------------------------------------------------------------------
🔷 IMPORTANT CONSIDERATIONS
Start small : Pine Script is not a GPU training environment. Compact models are the right starting point.
Control chart history : Use `calc_bars_count = 600` in `indicator()` when needed to balance available training history against model size and execution time.
Use the training gate : For heavier models, use `.withTrainingGate(true)` so backpropagation runs only at the confirmed historical edge.
Scale your inputs : Raw market features often differ by orders of magnitude. Use dataset scalers unless you have a deliberate reason not to.
Validate separately : Use `trainBatch()` and `validationBatch()` to monitor generalization instead of only watching training loss.
Avoid lookahead : Build feature rows only from information available at the time of the row. Use completed target rows for training.
Treat outputs as research signals : NeuraLib provides model mechanics. Strategy design, risk management, and market assumptions remain the user's responsibility.
----------------------------------------------------------------------------------------------------------------
🔷 API REFERENCE
🔸 Model Setup
sequential(name) : Creates an empty `Sequential` model.
compileConfig() : Creates a model configuration object.
build(rng) : Builds model parameters with a deterministic random stream.
compile(config) : Builds the model when needed and applies the training configuration.
rng(seed, streamId) : Creates a deterministic random stream.
🔸 Sequential Methods
input(dimsArray, name) : Defines the input shape.
dense(units, activation, name) : Adds a fully connected layer.
qHead(actionCount, activation, name) : Adds a Q-value output head.
activation(activationKind, alpha, name) : Adds an activation block.
dropout(rate, name) : Adds dropout regularization.
layerNorm(name) : Adds layer normalization.
flatten(name) and reshape(outputDimsArray, name) : Adjust model shape metadata.
block(graphBlock) : Adds a custom `GraphBlock`.
trainOnBatch(inputTensor, targetTensor) : Runs training when the active gate allows it.
backward(targetTensor) : Accumulates gradients from the last forward pass without stepping.
step() : Applies the optimizer step to accumulated gradients.
predict(inputTensor) : Runs inference.
predictMC(inputTensor, samples) : Runs dropout-enabled Monte Carlo prediction and returns mean and variance.
evaluate(inputTensor, targetTensor) : Calculates loss without updating weights.
fitDataset(dataset) and fitRollingDataset(dataset, targetOffset) : Train through dataset adapters.
getWeightsArray() and setWeightsArray(weightsArray) : Export and import flat model weights.
softUpdateFrom(sourceModel, tau) : Soft-update parameters from another model.
🔸 CompileConfig Methods
optimizer(optimizerState) : Sets the optimizer.
schedule(scheduleState) : Sets the learning-rate schedule.
loss(lossKind) : Sets the training loss.
reduction(reductionKind) : Sets loss reduction behavior.
metric(metricKind) : Adds a metric.
batchSize(size) , epochsPerBar(count) , evalStride(stride) , and historyLength(length) : Store batch and cadence preferences, and set the metric history length.
clipNorm(value) and clipValue(value) : Apply gradient clipping.
gradAccumSteps(steps) : Accumulates gradients before stepping.
withTrainingGate(enabled) : Restricts training to the last confirmed historical bar when enabled.
trainEveryCall() : Allows training whenever `.trainOnBatch()` is called.
presetPriceRegression() , presetReturnRegression() , presetBinaryDirection() , presetBinaryDirectionLogits() , presetQValues() , and presetSharpe() : Apply common loss and metric presets.
🔸 Datasets
windowDataset(featureCount, targetCount, maxRows, name) : Stores flat feature and target rows.
rollingDataset(timeSteps, featureCount, targetCount, maxRows, name) : Stores time-series windows.
pushRow(featureArray, targetArray) : Adds one validated row.
pushBuilderRow(featureBuilder, targetArray) : Adds a row from a `FeatureBuilder`.
pushNextReturnRow(featureBuilder, currentValue, futureValue) : Adds a next-return target.
pushNextDirectionRow(featureBuilder, currentValue, futureValue, threshold, zeroOne) : Adds a direction target.
ready(minRows or minWindows, targetOffset) and size() : Check dataset readiness.
lastBatch(batchSize) : Returns the most recent scaled rows from a `WindowDataset`.
toBatch() : Returns all rows from a `WindowDataset`.
unrollBatch(targetOffset) : Returns all rolling windows from a `RollingDataset`.
trainBatch(validationRows or validationWindows, targetOffset) : Returns the training side of the split.
validationBatch(validationRows or validationWindows, targetOffset) : Returns the validation side of the split.
setInputScaler(kind) , setTargetScaler(kind) , scaleInput(tensor) , scaleTarget(tensor) , and inverseScaleTarget(tensor) : Configure and apply scaling.
clear() : Clears stored rows.
🔸 Tensor, Matrix, and Feature Helpers
scalar(value) , vector(valuesArray) , matrix2d(rows, cols, fillValue) , zeros(shape) , ones(shape) , and full(shape, fillValue) : Create tensors.
shapeFromDims(dimsArray) : Creates a shape.
matrixTensor(tensor) , matrixTensor2d(rows, cols, fillValue) , and matrixTensorFromMatrix(sourceMatrix) : Create matrix tensors.
reshape(dimsArray) , flatten() , row(rowIndex) , get1d(index) , sum() , mean() , variance() , normL2() , argmax() , and dot(other) : Tensor methods.
matmul() , transpose() , add() , subtract() , multiply() , divide() , scale() , activate() , softmax() , sliceRows() , sliceCols() , concatRows() , concatCols() , globalAvgPool1d() , and globalMaxPool1d() : MatrixTensor methods.
featureBuilder(name) , push(value, featureName) , addFeature(value, featureName) , toTensor(tensorName) , toArray() , size() , and clear() : Feature row helpers.
🔸 Scalers, Optimizers, and Schedules
zScoreScaler() , minMaxScaler() , runningZScoreScaler() , and noneScaler() : Standalone scaler states.
fit(tensor) , partialFit(tensor) , transform(tensor) , and inverseTransform(tensor) : Scaler methods.
sgd(learningRate) , momentum(learningRate, momentum) , rmsprop(learningRate, rho, epsilon) , adam(learningRate, beta1, beta2, epsilon) , and adamW(learningRate, beta1, beta2, epsilon, weightDecay) : Optimizers.
constantSchedule(learningRate) , stepDecay(baseLearningRate, decaySteps, gamma) , cosineDecay(baseLearningRate, minLearningRate, decaySteps) , and warmupCosine(baseLearningRate, minLearningRate, warmupSteps, decaySteps) : Schedules.
currentRate(stepCount) : Reads a schedule's learning rate at a step.
paramBank() , append() , zeroGrad() , globalGradNorm() , step(optimizerState) , and softUpdateFrom(sourceBank, tau) : Low-level parameter bank utilities.
🔸 Losses and Metrics
mse() , mae() , huber() , logCosh() , binaryCrossEntropy() , binaryCrossEntropyFromLogits() , categoricalCrossEntropy() , softmaxCrossEntropyFromLogits() , directionalLoss() , quantileLoss() , multiHorizonWeighted() , and sharpeLoss() : Direct loss helpers.
metricValue(metricKind, predictionTensor, targetTensor) : Direct metric helper.
earlyStopper(patience, minDelta) , update(validationLoss) , and reset() : Validation stopping helper.
nextReturnValue(currentValue, futureValue) and nextDirectionValue(currentValue, futureValue, threshold, zeroOne) : Common target helpers.
🔸 GraphBlock Operations
graphBlock(name) : Creates a custom trainable graph block.
input() , param() , constScalar() , constMatrix() , and output() : Define graph inputs, parameters, constants, and output metadata.
matmul() , add() , subtract() , multiply() , divide() , scale() , activate() , softmax() , transpose() , layerNorm() , and dropout() : NeuraLib graph math.
causalMask() , sliceRows() , concatRows() , sliceCols() , concatCols() , reduceRows() , and reduceCols() : Structural graph operations.
globalAvgPool1d() , globalMaxPool1d() , attentionScore() , attentionApply() , conv1d() , scanLstm() , and scanGru() : Sequence and architecture primitives.
🔸 NeuraLib_Models API
prioritizedReplayBuffer(featureCount, targetCount, maxRows, name) : Creates a replay buffer.
pushExperience(featureRowArray, targetRowArray, priority) , sampleBatch(batchSize, alpha, beta, seed) , updatePriority(index, priority) , toBatch() , ready(minRows) , size() , and clear() : Prioritized Experience Replay helpers.
pushPositionalEncoding(position, dimensions, maxPeriod, featurePrefix) : Adds positional encoding values to a `FeatureBuilder`.
residualDense() , duelingQHead() , conv1d() , temporalConvStack() , globalAvgPool1d() , globalMaxPool1d() , lstm() , gru() , selfAttention() , multiHeadSelfAttention() , crossAttention() , transformerEncoder() , transformerEncoderStack() , and transformerDecoder() : NeuraLib_Models `Sequential` methods.
NeuraLib is for Pine Script developers who want to move beyond fixed formulas and experiment with real neural network workflows directly inside PulseWire. It is a research framework, not a guarantee of market performance. Use validation, avoid lookahead, control risk, and keep models small enough for Pine's execution limits.
All the diagrams in this publication are rendered natively on PulseWire using Pine3D
----------------------------------------------------------------------------------------------------------------
This work is licensed under (CC BY-NC-SA 4.0) , meaning usage is free for non-commercial purposes given that Alien_Algorithms is credited in the description for the underlying software. For commercial use licensing, contact Alien_Algorithms
Library

BoaBiasVwapSwingRxStatsLibrary "BoaBiasVwapSwingRxStats"
reset_slot_rx(idx, slotTouched, firstTouchBar, cohortConsec, kMetInWindow, atrMetInWindow, feFirstSwingBar, feFirstOppBar, feFirstBeyondBar, noTouchSent, feUnset)
Parameters:
idx (int)
slotTouched (array)
firstTouchBar (array)
cohortConsec (array)
kMetInWindow (array)
atrMetInWindow (array)
feFirstSwingBar (array)
feFirstOppBar (array)
feFirstBeyondBar (array)
noTouchSent (int)
feUnset (int)
chart_cum_pass(anchorBars, cumTPVs, cumVols, tested, maxLines, bar_index, high, low, close, volume)
Parameters:
anchorBars (array)
cumTPVs (array)
cumVols (array)
tested (array)
maxLines (int)
bar_index (int)
high (float)
low (float)
close (float)
volume (float)
chart_build_snap(snapVwap, anchorBars, cumTPVs, cumVols, tested, maxLines, bar_index)
Parameters:
snapVwap (array)
anchorBars (array)
cumTPVs (array)
cumVols (array)
tested (array)
maxLines (int)
bar_index (int)
chart_slot_rx_close(i, snapVwap, anchorBars, fromHigh, tested, consecBars, slotTouched, firstTouchBar, cohortConsec, kMetInWindow, atrMetInWindow, feFirstSwingBar, feFirstOppBar, feFirstBeyondBar, rxCounts, sumLifeHolder, bar_index, high, low, close, swingHighPx, swingLowPx, lastSwingHighPx, lastSwingLowPx, pivotLen, confirmMode, confirmBars, kHoldBars, mBarsAfterTouch, atrVal, atrRMult, mAtrWindow, noTouchSent, feUnset, maxLines)
Parameters:
i (int)
snapVwap (array)
anchorBars (array)
fromHigh (array)
tested (array)
consecBars (array)
slotTouched (array)
firstTouchBar (array)
cohortConsec (array)
kMetInWindow (array)
atrMetInWindow (array)
feFirstSwingBar (array)
feFirstOppBar (array)
feFirstBeyondBar (array)
rxCounts (array)
sumLifeHolder (array)
bar_index (int)
high (float)
low (float)
close (float)
swingHighPx (float)
swingLowPx (float)
lastSwingHighPx (float)
lastSwingLowPx (float)
pivotLen (int)
confirmMode (string)
confirmBars (int)
kHoldBars (int)
mBarsAfterTouch (int)
atrVal (float)
atrRMult (float)
mAtrWindow (int)
noTouchSent (int)
feUnset (int)
maxLines (int) Library

TP_Ephem_LibLibrary "TP_Ephem_Lib"
Cowan-tailored heliocentric ephemeris (VSOP87D) for PulseWire.
@description Returns heliocentric ecliptic longitudes for Mercury through Neptune
@description (tropical or sidereal/Lahiri), synodic phases between any two planets,
@description and Cowan-canon helpers: 3-Step Astro cumulative advance (V4:L5079),
@description pentagram vertex dates (V4:L449), and cube-face boundary dates
@description (V1:L2106-2114, V1:L2962-2997). All math validated to <0.01 deg vs
@description Swiss Ephemeris (DE441) across 1899-2026. Frame: ecliptic of date.
jd_to_t_millennia(jd)
Parameters:
jd (float)
jd_from_timestamp(unix_ms)
Parameters:
unix_ms (int)
timestamp_from_jd(jd)
Parameters:
jd (float)
normalize_longitude(deg)
Parameters:
deg (float)
get_ayanamsa(jd)
Parameters:
jd (float)
get_helio_longitude(planet, jd, useSidereal)
Parameters:
planet (simple Planet)
jd (float)
useSidereal (simple bool)
get_sun_geo_longitude(jd, useSidereal)
Parameters:
jd (float)
useSidereal (simple bool)
get_synodic_phase(p1, p2, jd)
Parameters:
p1 (simple Planet)
p2 (simple Planet)
jd (float)
get_aspect_angle(p1, p2, jd)
Parameters:
p1 (simple Planet)
p2 (simple Planet)
jd (float)
average_speed_deg_per_day(planet)
Parameters:
planet (simple Planet)
speed_deg_per_day(planet, jd)
Parameters:
planet (simple Planet)
jd (float)
is_retrograde(planet, jd)
Parameters:
planet (simple Planet)
jd (float)
cumulative_advance_deg(planet, origin_jd, target_jd, useSidereal)
Parameters:
planet (simple Planet)
origin_jd (float)
target_jd (float)
useSidereal (simple bool)
cumulative_synodic_advance_deg(p1, p2, origin_jd, target_jd)
Parameters:
p1 (simple Planet)
p2 (simple Planet)
origin_jd (float)
target_jd (float)
find_advance_jd(planet, origin_jd, target_advance_deg, useSidereal)
Parameters:
planet (simple Planet)
origin_jd (float)
target_advance_deg (float)
useSidereal (simple bool)
find_synodic_advance_jd(p1, p2, origin_jd, target_synodic_advance_deg)
Parameters:
p1 (simple Planet)
p2 (simple Planet)
origin_jd (float)
target_synodic_advance_deg (float)
pentagram_vertex_jd(planet, origin_jd, n, useSidereal)
Parameters:
planet (simple Planet)
origin_jd (float)
n (simple int)
useSidereal (simple bool)
cube_face_boundary_jd(origin_jd, face_n)
Parameters:
origin_jd (float)
face_n (simple int) Library

K21CommonLibrary "K21Common"
minDollarMove()
Calculates the minimum dollar move per tick for the current symbol
Returns: (float) Dollar value per tick movement
@description Uses syminfo.pointvalue (contract value per point) and syminfo.minmove
(minimum tick movement) to calculate the dollar value of a single tick.
This works across all futures contracts without manual configuration.
replaceTradeTemplateTags(template, entry_num, description, entry_price, stop_price, tp_price, contracts, risk_dollars, reward_dollars, rr_ratio, max_risk)
Replaces trade related template tags with actual values
Parameters:
template (string) : (string) Template string with tags
entry_num (int) : (int) Entry number (1-5)
description (string) : (string) Entry description
entry_price (float) : (float) Entry price
stop_price (float) : (float) Stop price
tp_price (float) : (float) TP price
contracts (int) : (int) Number of contracts
risk_dollars (float) : (float) Risk in dollars
reward_dollars (float) : (float) Reward in dollars
rr_ratio (float) : (float) Risk:Reward ratio
max_risk (float) : (float) Maximum allowed risk
Returns: (string) Processed template string
isLightColor(clr)
Checks if a color is light based on luminance calculation
Parameters:
clr (color) : (color) The color to check
Returns: (bool) True if the color is light
isDarkColor(clr)
Checks if a color is dark based on luminance calculation
Parameters:
clr (color) : (color) The color to check
Returns: (bool) True if the color is dark
isLightScheme()
Checks if the current chart color scheme is light
Returns: (bool) True if the chart uses a light color scheme
isDarkScheme()
Checks if the current chart color scheme is dark
Returns: (bool) True if the chart uses a dark color scheme
getBarIndexFromTime(target_time)
Finds the bar_index for a given timestamp by searching historical bars
Parameters:
target_time (int) : (int) The timestamp to find
Returns: (int) The bar_index where time matches or is closest to target_time Library

Library
