pinescription

package module
v0.0.0-...-d81d3e2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: AGPL-3.0 Imports: 16 Imported by: 0

README

Pinescription

Pinescription

A high-performance Pine Script v6 compiler and runtime for Go.

Pinescription compiles Pine Script code into optimized bytecode and executes it against market data providers, enabling you to run TradingView indicators and strategies in production Go applications without webhooks or external dependencies.


Go version Build License GoDoc



Why Pinescription

  • No webhooks, no lock-in. Run Pine Script indicators directly in your Go backend. Connect to any broker API through a simple provider interface.
  • Native Go performance. The compiler generates optimized bytecode with streaming evaluation. Benchmarks show 164x speedup over full recomputation.
  • Pine Script v6 compatible. Supports language core, arrays, matrices, tuples, 30+ indicators, and the ta.* namespace.
  • Single dependency. Built on gonum for linear algebra. No other external dependencies.

Quick Start

Step 1: Install

go get github.com/woodstock-tokyo/pinescription

Step 2: Write your first indicator

package main

import (
    "fmt"
    pinego "github.com/woodstock-tokyo/pinescription"
)

func main() {
    engine := pinego.NewEngine()
    engine.RegisterMarketDataProvider(&yourProvider{})
    engine.SetDefaultSymbol("AAPL")

    script := `
var ma = sma(close, 20)
var ex = ema(close, 20)
ma + ex
`

    bytecode, err := engine.Compile(script)
    if err != nil {
        panic(err)
    }
    result, err := engine.Execute(bytecode)
    if err != nil {
        panic(err)
    }
    fmt.Println("Result:", result)
}

Step 3: Explore more examples

See examples/basic/main.go for a working demo with sample market data, or examples/volume_profile_pivot_anchored/ for a complex Pine Script v6 execution.


Performance

Benchmarked on Apple M3:

Benchmark Result Notes
Bollinger Bands (streaming) 634 ns/op 164x faster than full recompute
5000-bar indicators ~5.8 ms/op Optimized sliding window
Fisher Transform (5000 bars) ~10.9 ms/op Complex multi-step indicator

The streaming execution model updates only the active bar state, avoiding full recalculation on each iteration.


Features

  • Language Core: var/const declarations, if/else/for/while/switch, functions, arrays, tuples, matrices
  • 30+ Built-in Indicators: SMA, EMA, RSI, ATR, Bollinger Bands, crossover, crossunder, stdev, correlation...
  • Full ta.* Namespace: ta.sma, ta.ema, ta.rsi, ta.atr, ta.bb...
  • math.* Namespace: math.abs, math.pow, math.sqrt, math.log, math.sin...
  • Array Operations: 25+ methods including push, pop, sort, sum, avg...
  • Matrix Operations: Linear algebra helpers, eigenvalues, determinant, transpose...
  • String Operations: str.format, str.split, str.replace, str.contains...
  • Market Data: Multi-symbol queries (close_of, sma_of...), history indexing (close[1])
  • Alerts: alert() and alertcondition() with custom sinks

See docs/features.md for the complete feature reference.


Documentation

Document Description
API Reference Complete API surface: Engine, Runtime, Provider, Alerts
Architecture and Design Compilation pipeline, execution flow, streaming evaluation model
Feature Reference Exhaustive list of supported Pine Script v6 features

Architecture

Pinescription compiles Pine Script source to intermediate representation, then encodes it as bytecode. At runtime, the VM evaluates the bytecode bar-by-bar against market data from your provider. See docs/architecture.md for detailed flow diagrams.


Provider Interface

Your market data provider implements the Provider interface:

type Provider interface {
    GetSeries(seriesKey string) (SeriesExtended, error)  // seriesKey = "symbol|value_type"
    GetSymbols() ([]string, error)
    GetValuesTypes() ([]string, error)
    SetTimeframe(timeframe string) error
    GetTimeframe() string
    SetSession(session string) error
    GetSession() string
}

Common series keys include AAPL|close, AAPL|volume, etc.


Unsupported in Open Source Version - Need Custom Function Hooks

  • Strategy APIs (strategy.entry, strategy.exit...)
  • Request APIs (request.security, request.financial...)
  • Plot APIs (plot, plotshape...)

These return explicit runtime errors when used unless you register an exact-name custom function hook. Use RegisterFunction("strategy.order", fn) for positional-only hooks, or RegisterFunctionWithParamNames(...) when the Pine call may use named arguments, for example RegisterFunctionWithParamNames("plot", []string{"series", "title", "color"}, fn) or RegisterFunctionWithParamNames("request.security", []string{"symbol", "timeframe", "expression"}, fn). Validation still rejects parser-reserved names, non-hookable implemented built-ins, and Pine type keywords such as int, float, color, and table.

Host applications may also register selected drawing-object hook points such as polyline.new, box.new, label.new, chart.point.from_index, table.cell, and table.clear. Pinescription provides compatibility stubs for those APIs, but a host hook can capture the calls and render the resulting objects outside the runtime.


License

Pinescription is dual-licensed under AGPL-3.0-only and a commercial license.

  • AGPL-3.0-only: See LICENSES/AGPL-3.0-only.txt
  • Commercial: See LICENSES/LICENSE-COMMERCIAL.md

Security

See SECURITY.md for vulnerability reporting.


Built by

Built by Woodstock K.K.

Pine Script™ is a trademark of TradingView. Pinescription is an independent project and is not affiliated with, endorsed by, or associated with TradingView.

Follow on X

Documentation

Overview

Package pinescription compiles Pine Script v6 source code into bytecode and executes it against market data providers, letting you run TradingView-style indicators and Pine-compatible calculations in Go applications without external dependencies.

The typical compile-and-execute cycle looks like this:

engine := pinescription.NewEngine()
engine.RegisterMarketDataProvider(&myProvider{})
engine.SetDefaultSymbol("AAPL")

bytecode, err := engine.Compile(`
    ma := sma(close, 20)
    ema(close, 9)
`)
if err != nil {
    log.Fatal(err)
}

result, err := engine.Execute(bytecode)
// result holds the final expression value, or nil if the script produces NaN

A Provider supplies OHLCV series and other market data. See the Provider interface for the full contract. The engine is safe for concurrent use across multiple goroutines so long as each goroutine uses its own Engine instance or serializes calls to a shared instance.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClearLogs

func ClearLogs()

ClearLogs is a convenience wrapper around defaultEngine.ClearLogs.

func Compile

func Compile(pinescript string) ([]byte, error)

Compile compiles the given Pine Script source code to bytecode using the package-level default Engine. On success the bytecode can be passed to Execute. Compilation errors include the source location of the syntax error.

Use the Engine method directly if you need to control which Engine instance is used, or to access the Runtime after execution.

func Execute

func Execute(bytecode []byte) (interface{}, error)

Execute runs pre-compiled bytecode against the registered market data providers using the package-level default Engine and returns the result. The result is the value of the final expression in the script, or nil if the script produces NaN as its final value. Returns an error if the bytecode is invalid, a provider fails, or a runtime error occurs during execution.

func RegisterFunction

func RegisterFunction(name string, function func(args ...interface{}) (interface{}, error))

RegisterFunction is a convenience wrapper around defaultEngine.RegisterFunction. It registers a user-defined function on the package-level default Engine. This Engine is shared globally, so registration is permanent for the process lifetime. Prefer creating a private Engine with NewEngine when registering functions that should be isolated between different uses.

func RegisterFunctionWithParamNames

func RegisterFunctionWithParamNames(name string, paramNames []string, function func(args ...interface{}) (interface{}, error)) error

RegisterFunctionWithParamNames is a convenience wrapper around defaultEngine.RegisterFunctionWithParamNames. Use it for ordinary custom functions or exact unsupported feature hooks that may receive Pine Script named arguments.

func RegisterMarketDataProvider

func RegisterMarketDataProvider(provider Provider)

RegisterMarketDataProvider is a convenience wrapper around defaultEngine.RegisterMarketDataProvider. It registers a provider on the package-level default Engine. See RegisterFunction for caveats about the shared global Engine.

func SetCurrentTime

func SetCurrentTime(now time.Time)

SetCurrentTime is a convenience wrapper around defaultEngine.SetCurrentTime.

func SetSession

func SetSession(session string)

SetSession is a convenience wrapper around defaultEngine.SetSession.

func SetStartTime

func SetStartTime(start time.Time)

SetStartTime is a convenience wrapper around defaultEngine.SetStartTime.

func SetTimeframe

func SetTimeframe(timeframe string)

SetTimeframe is a convenience wrapper around defaultEngine.SetTimeframe.

Types

type AlertEvent

type AlertEvent struct {
	Message   string
	Frequency string
	BarIndex  int
	Time      time.Time
	Symbol    string
}

AlertEvent describes an alert triggered by a Pine Script alert() call during execution. BarIndex is the zero-based index of the bar on which the alert fired. Time is the UTC close time of that bar. Symbol is the active ticker at the time of firing.

type ArrayValue

type ArrayValue interface {
	PineArrayItems() []interface{}
}

ArrayValue exposes Pine array contents to host-registered functions without exporting the runtime's mutable array implementation.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine is the Pine Script compiler and runtime. It holds all configuration for a single execution context: registered providers, user functions, the active symbol and value type, and timing parameters. An Engine may be reused across multiple Compile/Execute cycles, but is not safe for concurrent use by multiple goroutines without external synchronization.

Use NewEngine to create an instance, then configure providers and options before calling Compile and Execute.

func NewEngine

func NewEngine() *Engine

NewEngine returns a new, empty Engine configured with no providers or user functions. Call RegisterMarketDataProvider to add a data source, then RegisterFunction for any custom functions before calling Compile and Execute.

Example:

engine := pinescription.NewEngine()
engine.RegisterMarketDataProvider(myProvider)
Example
package main

import (
	"errors"
	"fmt"
	"strings"

	pinescription "github.com/woodstock-tokyo/pinescription"
	"github.com/woodstock-tokyo/pinescription/series"
)

type exampleProvider struct {
	timeframe string
	session   string
	series    map[string][]float64
}

func (p *exampleProvider) GetSeries(seriesKey string) (pinescription.SeriesExtended, error) {
	values, ok := p.series[seriesKey]
	if !ok {
		return nil, errors.New("unknown series key")
	}
	q := series.NewQueue(len(values) + 1)
	for _, value := range values {
		q.Update(value)
	}
	return q, nil
}

func (p *exampleProvider) GetSymbols() ([]string, error) {
	seen := map[string]bool{}
	out := make([]string, 0, len(p.series))
	for key := range p.series {
		symbol, _, ok := strings.Cut(key, "|")
		if !ok || symbol == "" || seen[symbol] {
			continue
		}
		seen[symbol] = true
		out = append(out, symbol)
	}
	return out, nil
}

func (p *exampleProvider) GetValuesTypes() ([]string, error) {
	seen := map[string]bool{}
	out := make([]string, 0, len(p.series))
	for key := range p.series {
		_, valueType, ok := strings.Cut(key, "|")
		if !ok || valueType == "" || seen[valueType] {
			continue
		}
		seen[valueType] = true
		out = append(out, valueType)
	}
	return out, nil
}

func (p *exampleProvider) SetTimeframe(timeframe string) error {
	p.timeframe = timeframe
	return nil
}

func (p *exampleProvider) GetTimeframe() string {
	if p.timeframe == "" {
		return "1D"
	}
	return p.timeframe
}

func (p *exampleProvider) SetSession(session string) error {
	p.session = session
	return nil
}

func (p *exampleProvider) GetSession() string {
	if p.session == "" {
		return "regular"
	}
	return p.session
}

func main() {
	engine := pinescription.NewEngine()
	engine.RegisterMarketDataProvider(&exampleProvider{
		series: map[string][]float64{
			"DEMO|close": {40, 41, 42},
		},
	})
	engine.SetDefaultSymbol("DEMO")

	bytecode, err := engine.Compile("close + 1")
	if err != nil {
		panic(err)
	}

	result, err := engine.Execute(bytecode)
	if err != nil {
		panic(err)
	}

	fmt.Printf("result=%.0f\n", result.(float64))
}
Output:
result=43

func (*Engine) ClearLogs

func (e *Engine) ClearLogs()

ClearLogs removes all accumulated log entries from the engine.

func (*Engine) ClearRuntime

func (e *Engine) ClearRuntime()

ClearRuntime releases the Runtime from the last Execute call and clears the bytecode cache. Call this to force a full recompilation on the next Compile or to free memory between unrelated executions.

func (*Engine) Compile

func (e *Engine) Compile(pinescript string) ([]byte, error)

Compile compiles Pine Script source to bytecode. The result is cached internally so that repeated calls with the same source do not re-parse. Compilation validates the AST and applies lowering passes before encoding.

Returns an error describing the parse failure with source location if the script has syntax errors.

func (*Engine) CurrentTime

func (e *Engine) CurrentTime() time.Time

CurrentTime returns the currently configured current time.

func (*Engine) Execute

func (e *Engine) Execute(bytecode []byte) (interface{}, error)

Execute runs pre-compiled bytecode against the registered market data providers. The result is the value of the last expression in the compiled script, or nil if the script produces NaN. After execution, Runtime returns the Runtime instance for inspection.

Returns an error if no market data provider is registered, the bytecode is corrupt, a provider fails to supply a required series, or a runtime error occurs (such as an unknown identifier or unsupported operation).

func (*Engine) ExecuteWithRuntime

func (e *Engine) ExecuteWithRuntime(bytecode []byte) (*Runtime, interface{}, error)

ExecuteWithRuntime is like Execute but also returns the Runtime instance, which holds the execution state after the run completes. Use Runtime.Snapshot to inspect variables, Runtime.Series to retrieve computed series, and Runtime.ValueTypes to list available value types per symbol.

After this call, Runtime returns the same Runtime until the next Execute or ClearRuntime. The caller must not mutate the returned Runtime.

Example
package main

import (
	"errors"
	"fmt"
	"strings"

	pinescription "github.com/woodstock-tokyo/pinescription"
	"github.com/woodstock-tokyo/pinescription/series"
)

type exampleProvider struct {
	timeframe string
	session   string
	series    map[string][]float64
}

func (p *exampleProvider) GetSeries(seriesKey string) (pinescription.SeriesExtended, error) {
	values, ok := p.series[seriesKey]
	if !ok {
		return nil, errors.New("unknown series key")
	}
	q := series.NewQueue(len(values) + 1)
	for _, value := range values {
		q.Update(value)
	}
	return q, nil
}

func (p *exampleProvider) GetSymbols() ([]string, error) {
	seen := map[string]bool{}
	out := make([]string, 0, len(p.series))
	for key := range p.series {
		symbol, _, ok := strings.Cut(key, "|")
		if !ok || symbol == "" || seen[symbol] {
			continue
		}
		seen[symbol] = true
		out = append(out, symbol)
	}
	return out, nil
}

func (p *exampleProvider) GetValuesTypes() ([]string, error) {
	seen := map[string]bool{}
	out := make([]string, 0, len(p.series))
	for key := range p.series {
		_, valueType, ok := strings.Cut(key, "|")
		if !ok || valueType == "" || seen[valueType] {
			continue
		}
		seen[valueType] = true
		out = append(out, valueType)
	}
	return out, nil
}

func (p *exampleProvider) SetTimeframe(timeframe string) error {
	p.timeframe = timeframe
	return nil
}

func (p *exampleProvider) GetTimeframe() string {
	if p.timeframe == "" {
		return "1D"
	}
	return p.timeframe
}

func (p *exampleProvider) SetSession(session string) error {
	p.session = session
	return nil
}

func (p *exampleProvider) GetSession() string {
	if p.session == "" {
		return "regular"
	}
	return p.session
}

func main() {
	engine := pinescription.NewEngine()
	engine.RegisterMarketDataProvider(&exampleProvider{
		series: map[string][]float64{
			"DEMO|close": {10, 11, 12},
		},
	})
	engine.SetDefaultSymbol("DEMO")

	bytecode, err := engine.Compile("scaled = close * 2\nscaled")
	if err != nil {
		panic(err)
	}

	runtime, result, err := engine.ExecuteWithRuntime(bytecode)
	if err != nil {
		panic(err)
	}

	snapshot := runtime.Snapshot()
	fmt.Printf("result=%.0f\n", result.(float64))
	fmt.Printf("bar_index=%d\n", snapshot.BarIndex)
	fmt.Printf("symbol=%s\n", snapshot.ActiveSymbol)
}
Output:
result=24
bar_index=2
symbol=DEMO

func (*Engine) Logs

func (e *Engine) Logs() []EngineLogEntry

Logs returns a copy of all log entries produced during the last execution. Each entry includes the UTC timestamp, level, and formatted message.

func (*Engine) RegisterFunction

func (e *Engine) RegisterFunction(name string, function UserFunction)

RegisterFunction registers a user-defined function callable from Pine Script. The function's name in Pine Script is the name string provided here. Functions are invoked with positional arguments evaluated according to Pine Script rules. A function with the same name replaces any previously registered function.

func (*Engine) RegisterFunctionWithParamNames

func (e *Engine) RegisterFunctionWithParamNames(name string, paramNames []string, function UserFunction) error

RegisterFunctionWithParamNames registers an ordinary custom function or an exact unsupported feature hook with parameter names used to bind Pine Script named arguments. Positional calls are still passed through in source order. A function with the same name replaces any previously registered function and parameter metadata.

It returns an error when name is empty, parser-reserved, a Pine type keyword that is not an unsupported hook target, or already handled by the built-in runtime dispatcher. It also returns an error when paramNames contains empty or duplicate names.

func (*Engine) RegisterMarketDataProvider

func (e *Engine) RegisterMarketDataProvider(provider Provider)

RegisterMarketDataProvider adds a market data provider to the engine. Providers are queried in the order they were registered when fetching symbol and value-type data. At least one provider must be registered before Execute is called. If multiple providers are registered, the first provider's timeframe and session values are used as defaults unless overridden by SetTimeframe or SetSession.

func (*Engine) Runtime

func (e *Engine) Runtime() *Runtime

Runtime returns the Runtime instance produced by the most recent Execute call, or nil if Execute has not been called or ClearRuntime was called. The returned Runtime is retained by the Engine and released on the next Execute or on ClearRuntime. Call Snapshot on the returned Runtime to inspect variables and series after execution.

func (*Engine) Session

func (e *Engine) Session() string

Session returns the currently configured trading session string.

func (*Engine) SetAlertSink

func (e *Engine) SetAlertSink(sink func(AlertEvent))

SetAlertSink installs a callback invoked each time a Pine Script alert() call executes. The callback receives an AlertEvent describing the alert. SetAlertSink is optional; if not set, alerts are silently dropped.

func (*Engine) SetCurrentTime

func (e *Engine) SetCurrentTime(now time.Time)

SetCurrentTime sets the wall-clock time used as the current moment during script execution. If not set, time.Now().UTC() is used. This is useful for deterministic testing or for replaying historical data at a known timestamp.

func (*Engine) SetDefaultSymbol

func (e *Engine) SetDefaultSymbol(symbol string)

SetDefaultSymbol sets the symbol used as the default source of OHLCV data when Pine Script references price identifiers like close, open, or high without an explicit symbol prefix. If not set, the first symbol from the first registered provider is used.

func (*Engine) SetDefaultValueType

func (e *Engine) SetDefaultValueType(valueType string)

SetDefaultValueType sets the default value type used when Pine Script references a price identifier without an explicit value type suffix. Common values are "close", "open", "high", "low", "volume". If not set, "close" is preferred if available, otherwise the first value type from the provider.

func (*Engine) SetSession

func (e *Engine) SetSession(session string)

SetSession sets the trading session used for time-based filtering in the runtime.

func (*Engine) SetStartTime

func (e *Engine) SetStartTime(start time.Time)

SetStartTime sets the time of the first bar in the dataset. When combined with the bar timeframe, this determines the timestamp of every bar in the series. If not set, it is inferred from CurrentTime and the number of bars.

func (*Engine) SetTimeframe

func (e *Engine) SetTimeframe(timeframe string)

SetTimeframe sets the bar timeframe for all registered providers. Common values include "1m", "5m", "1h", "4h", "1D". This overrides any timeframe returned by individual providers.

func (*Engine) StartTime

func (e *Engine) StartTime() time.Time

StartTime returns the currently configured start time.

func (*Engine) Symbols

func (e *Engine) Symbols() ([]string, error)

Symbols returns the sorted list of all ticker symbols available from the registered market data providers. Returns an error if no provider is registered.

func (*Engine) Timeframe

func (e *Engine) Timeframe() string

Timeframe returns the currently configured bar timeframe string.

func (*Engine) ValueTypes

func (e *Engine) ValueTypes() ([]string, error)

ValueTypes returns the sorted list of all value types available across all registered providers. Common values include "close", "open", "high", "low", "volume", as well as derived types such as "hl2", "hlc3", "ohlc4". Returns an error if no provider is registered.

type EngineLogEntry

type EngineLogEntry struct {
	Timestamp time.Time
	Level     string
	Message   string
}

EngineLogEntry represents a single log entry produced during script execution. Level is one of "info", "warning", or "error". Timestamp is the wall-clock time at which the entry was recorded (UTC). Message contains the formatted log text.

func Logs

func Logs() []EngineLogEntry

Logs is a convenience wrapper around defaultEngine.Logs.

type Expr

type Expr struct {
	Kind string `json:"kind"`
	KOp  uint8  `json:"kop,omitempty"`

	Number float64 `json:"number,omitempty"`
	String string  `json:"string,omitempty"`
	Bool   bool    `json:"bool,omitempty"`
	Name   string  `json:"name,omitempty"`

	Op    string `json:"op,omitempty"`
	UOp   uint8  `json:"uop,omitempty"`
	BOp   uint8  `json:"bop,omitempty"`
	BID   uint16 `json:"bid,omitempty"`
	Left  *Expr  `json:"left,omitempty"`
	Right *Expr  `json:"right,omitempty"`
	Else  *Expr  `json:"else,omitempty"`

	Args  []*Expr `json:"args,omitempty"`
	Elems []*Expr `json:"elems,omitempty"`

	SwitchExpr *Expr        `json:"switch_expr,omitempty"`
	Cases      []SwitchCase `json:"cases,omitempty"`
	Default    []Stmt       `json:"default,omitempty"`
}

Expr represents a Pine Script expression. Kind is the node kind (e.g. "number", "ident", "call"). KOp is the internal opcode used by the runtime evaluator. For literals, Number, String, and Bool hold the value. For identifiers, Name holds the name string. For calls, Left is the function identifier and Args holds the argument list. For binary and unary operators, BOp and UOp hold the opcode. For ternary, Left is the condition, Right is the consequent, and Else is the alternate.

func (*Expr) NamedArgValue

func (e *Expr) NamedArgValue() *Expr

NamedArgValue returns the value expression for a "named_arg" expression node, or nil if the receiver is nil or not a named argument.

type FunctionDef

type FunctionDef struct {
	Name          string        `json:"name"`
	Params        []string      `json:"params"`
	ParamDefaults map[int]*Expr `json:"param_defaults,omitempty"`
	Body          []Stmt        `json:"body"`
	Expr          *Expr         `json:"expr,omitempty"`
}

FunctionDef describes a user-defined Pine Script function, including its name, parameter names, body statements, and optionally a single-expression body.

type Matrix

type Matrix struct {
	Data [][]float64
}

Matrix represents a two-dimensional matrix of float64 values backed by a slice of row slices. Matrices are used internally by Pine Script's matrix operations (matrix.new, matrix.* functions) and are also returned by matrix-valued built-in functions.

type Program

type Program struct {
	Stmts      []Stmt                 `json:"stmts"`
	Functions  map[string]FunctionDef `json:"functions"`
	Types      map[string]TypeDef     `json:"types,omitempty"`
	Symbols    []string               `json:"symbols,omitempty"`
	ValueTypes []string               `json:"value_types,omitempty"`
	SeriesKeys []string               `json:"series_keys,omitempty"`
}

Program is the top-level intermediate representation of a compiled Pine Script script. It contains the list of top-level statements (Stmts), user-defined functions (Functions), and custom type definitions (Types). Symbols, ValueTypes, and SeriesKeys are populated by the compiler to record all market data referenced in the script.

type Provider

type Provider interface {
	// GetSeries returns the time series identified by seriesKey, which is
	// formatted as "symbol|valueType" (e.g. "AAPL|close"). Returns an error
	// if the series is unavailable. The series must contain at least one data point.
	GetSeries(seriesKey string) (SeriesExtended, error)
	// GetSymbols returns the list of ticker symbols this provider can serve.
	GetSymbols() ([]string, error)
	// GetValuesTypes returns the list of value types available for each symbol.
	// Common types include "open", "high", "low", "close", "volume", and derived
	// types such as "hl2", "hlc3", "ohlc4".
	GetValuesTypes() ([]string, error)
	// SetTimeframe sets the bar timeframe for subsequent GetSeries calls.
	// Common values are "1m", "5m", "1h", "1D". Providers may ignore this
	// if they only serve a single timeframe.
	SetTimeframe(timeframe string) error
	// GetTimeframe returns the current bar timeframe string.
	GetTimeframe() string
	// SetSession sets the trading session for time-based filtering.
	SetSession(session string) error
	// GetSession returns the current trading session string.
	GetSession() string
}

Provider is the interface that market data backends must implement to supply time-series data to the engine. A provider is registered on an Engine with RegisterMarketDataProvider. The same provider instance can serve multiple symbols and value types, but each distinct symbol/value-type pair is keyed as "symbol|valueType" in calls to GetSeries.

Example provider implementation skeleton:

type myProvider struct{}

func (p *myProvider) GetSeries(key string) (pinego.SeriesExtended, error) {
    // key is "SYMBOL|valueType", e.g. "AAPL|close"
    symbol, vt, _ := strings.Cut(key, "|")
    return myLoadSeries(symbol, vt)
}
func (p *myProvider) GetSymbols() ([]string, error) { return []string{"AAPL"}, nil }
func (p *myProvider) GetValuesTypes() ([]string, error) { return []string{"close"}, nil }
func (p *myProvider) SetTimeframe(tf string) error { return nil }
func (p *myProvider) GetTimeframe() string { return "1D" }
func (p *myProvider) SetSession(s string) error { return nil }
func (p *myProvider) GetSession() string { return "" }

type Runtime

type Runtime struct {
	// contains filtered or unexported fields
}

Runtime represents the execution state of a compiled Pine Script program. It is produced by Engine.ExecuteWithRuntime and must not be mutated by callers. After a Runtime is no longer needed, call Release to return pooled memory.

func (*Runtime) Release

func (r *Runtime) Release()

Release returns all internal memory held by the Runtime to the object pools. After Release the Runtime is in an invalid state and must not be used. Release is safe to call on a nil Runtime.

func (*Runtime) Series

func (r *Runtime) Series(seriesKey string) (SeriesExtended, bool)

Series returns the SeriesExtended for the given series key (e.g. "AAPL|close") and a boolean indicating whether it was found. For price-derived value types (hl2, hlc3, ohlc4), this lazily computes the series from the base OHLC data.

func (*Runtime) SeriesKeys

func (r *Runtime) SeriesKeys() []string

SeriesKeys returns the sorted list of all series keys in the format "symbol|valueType" that were loaded or derived during execution.

func (*Runtime) SetBarIndex

func (r *Runtime) SetBarIndex(i int)

SetBarIndex advances the runtime to the given zero-based bar index. This updates the cached OHLCV values and the barstate.islast flag. It is called automatically by Engine during ExecuteWithRuntime, but can also be called manually for step-through inspection or replay.

func (*Runtime) Snapshot

func (r *Runtime) Snapshot() RuntimeSnapshot

Snapshot returns a snapshot of the current runtime state, including the active bar index, last numeric result, the active symbol and value type, all available symbols and series keys, and a copy of the top-level variable map.

Example:

rt, result, _ := engine.ExecuteWithRuntime(bytecode)
snap := rt.Snapshot()
fmt.Println("bar_index:", snap.BarIndex, "result:", snap.LastValue)

func (*Runtime) Symbols

func (r *Runtime) Symbols() []string

Symbols returns the sorted list of all symbols referenced during execution. This includes the active symbol, any symbol explicitly used in Pine Script calls like close_of, and symbols discovered from multi-symbol indicators.

func (*Runtime) Value

func (r *Runtime) Value(name string) (interface{}, bool)

Value returns the most recent value of the named variable in the execution scope, and a boolean indicating whether the variable exists. For history-tracked variables it returns the value at the last bar; for function parameters it returns the current stack value.

func (*Runtime) ValueTypes

func (r *Runtime) ValueTypes(symbol string) []string

ValueTypes returns the sorted list of value types available for the given symbol, such as "close", "high", "volume". Returns nil if the symbol was not used.

type RuntimeSnapshot

type RuntimeSnapshot struct {
	BarIndex        int
	LastValue       float64
	ActiveSymbol    string
	ActiveValueType string
	Symbols         []string
	SeriesKeys      []string
	Variables       map[string]interface{}
}

RuntimeSnapshot is a point-in-time view of the execution state produced by Runtime.Snapshot. BarIndex is the zero-based index of the current bar. LastValue is the numeric result of the last evaluated expression. Symbols and SeriesKeys describe the data in use. Variables holds the current value of every top-level variable and function parameter in scope, keyed by name.

type SeriesExtended

type SeriesExtended = series.SeriesExtend

SeriesExtended is an alias for the series extension interface defined in the woodstock-utils series package. It represents a time series of float values with variable-length lookback, used to supply OHLCV and derived data to the runtime. The interface includes Length, Last, and arithmetic methods.

type Stmt

type Stmt struct {
	Kind string `json:"kind"`
	SOp  uint8  `json:"sop,omitempty"`

	Name       string   `json:"name,omitempty"`
	TypeName   string   `json:"type_name,omitempty"`
	Const      bool     `json:"const,omitempty"`
	Expr       *Expr    `json:"expr,omitempty"`
	Target     *Expr    `json:"target,omitempty"`
	TupleNames []string `json:"tuple_names,omitempty"`

	Cond *Expr  `json:"cond,omitempty"`
	Then []Stmt `json:"then,omitempty"`
	Else []Stmt `json:"else,omitempty"`

	Body []Stmt `json:"body,omitempty"`

	ForVar string `json:"for_var,omitempty"`
	From   *Expr  `json:"from,omitempty"`
	To     *Expr  `json:"to,omitempty"`
	By     *Expr  `json:"by,omitempty"`
	ForIn  *Expr  `json:"for_in,omitempty"`

	Func *FunctionDef `json:"func,omitempty"`
	Type *TypeDef     `json:"type,omitempty"`

	SwitchExpr *Expr        `json:"switch_expr,omitempty"`
	Cases      []SwitchCase `json:"cases,omitempty"`
	Default    []Stmt       `json:"default,omitempty"`
}

Stmt represents a single statement in the Pine Script AST. Kind is one of: "decl", "assign", "tuple_assign", "expr", "if", "switch", "while", "for", "break", "continue", "return". The remaining fields hold the operands specific to each statement kind, as defined by the Pine Script v6 grammar.

type SwitchCase

type SwitchCase struct {
	Match *Expr  `json:"match,omitempty"`
	Body  []Stmt `json:"body,omitempty"`
}

SwitchCase represents a single case clause within a switch statement. Match is the expression to compare against the switch expression. Body holds the statements executed when the case matches.

type TypeDef

type TypeDef struct {
	Name   string      `json:"name"`
	Fields []TypeField `json:"fields,omitempty"`
}

TypeDef describes a user-defined composite type in Pine Script, including its name and the ordered list of fields. Instances of the type are created by calling the TypeName.new constructor from Pine Script.

type TypeField

type TypeField struct {
	Name     string `json:"name"`
	TypeName string `json:"type_name,omitempty"`
	Default  *Expr  `json:"default,omitempty"`
}

TypeField describes a single field within a TypeDef. TypeName is the Pine Script type of the field (e.g. "float", "string"). Default is an optional expression evaluated at instantiation time if the field is omitted.

type UserFunction

type UserFunction func(args ...interface{}) (interface{}, error)

UserFunction is the signature for functions registered via RegisterFunction. The function receives the evaluated Pine Script argument values and returns a result (float, string, bool, or nil) and an error. Returning a non-nil error aborts script execution with that error.

Directories

Path Synopsis
examples
basic command
Package series provides time series data structures and mathematical operations for the Pinescription runtime.
Package series provides time series data structures and mathematical operations for the Pinescription runtime.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL