█ KEY FEATURES
• Rich expression support:
• Built-in constants (e.g., `10`, `2.5`, `5e-2`, `true`, `false`, `na`)
• Custom constants
• Variables
• Arithmetic operators: `+`, `-`, `*`, `/`, `%`
• Comparison operators: `>`, `<`, `>=`, `<=`, `==`, `!=`
• Logical operators: `AND`, `OR`, `NOT` (with aliases)
• Ternary operator: `condition ? if_true : if_false`
• Parentheses: `(`, `)`
• Built-in functions: `na()`, `nz()`, `max()`, `pow()`, `sqrt()`, `random()`, and more!
• Graceful error handling during parsing and evaluation
• Optimized for evaluation performance (RPN-based approach)
█ NOTE
Since the library description cannot be changed or removed after publication, some information here may be outdated. However, you can always get the latest version of the documentation at the bottom of the source code.
█ QUICK START
An example of an indicator that colors areas on a chart where the expression evaluates to `true`:
█ EXPRESSION SYNTAX REFERENCE
❱❱ Components
An expression can include:
• Constants
• Variables
• Operators
• Functions
• Parentheses
• Spaces, tabs, or newlines
❱❱ Data Types
Constants and variables can have the following data types:
• Numeric (`int`, `float`)
• Boolean (`bool`)
• Undefined (`na`)
❱❱ Identifiers
Identifiers are names used to refer to named constants, variables, and functions.
Identifier naming rules:
• Must start with a letter (`a-z`, `A-Z`) or underscore (`_`).
• May contain letters (`a-z`, `A-Z`), digits (`0-9`), and underscores (`_`).
Identifiers cannot contain spaces or other characters.
Identifiers are case-sensitive.
❱❱ Constants
Numeric Constants
Examples:
Named Constants
Available built-in named constants:
It is possible to add custom constants.
❱❱ Variables
It is possible to add variables, just like custom constants, except that variable values can be changed before each evaluation.
❱❱ Operators
The following operators are supported:
Logical operator names are case-insensitive.
Operator precedence:
Operator associativity:
• Unary `+`, Unary `-`, `NOT`, and ternary are right-associative
• Other operators are left-associative
❱❱ Parentheses
Parentheses are used to group sub-expressions and override the default operator precedence.
Example:
❱❱ Functions
Functions are called by an identifier followed immediately by parentheses: `func(arg1, arg2)`.
Arguments are separated by commas. Each argument can be any valid expression, including another function call.
Available built-in functions:
The number of arguments can be either fixed or variable.
For example, the `max(x1, x2, ...)` function supports 2 to 999 arguments, so the following calls to this function are valid:
Other functions may have optional arguments. For example, the following calls to the `random(min, max, seed)` function are valid:
❱❱ Whitespace
Spaces, tabs, and line breaks are ignored between symbols. For example, an expression can be formatted across multiple lines:
█ PARSING
❱❱ Workflow
Before evaluating an expression, it must be parsed. To do this:
• Create a parser in advance using the `createExpressionParser()` function.
• Call the `parse()` method, passing the expression string as an argument.
Example:
❱❱ Error Handling
A user may enter an invalid expression. In this case, the parser will return `na` instead of a valid expression object. The parser stores the result of the last parse. You can use that result to retrieve the status and error information.
Parser and error field structures:
For example, suppose we want to display an error message on the chart if one of the expressions is invalid:
A blank expression (e.g., "") is allowed and will evaluate to `na` (or `false` when returning a boolean value).
❱❱ Custom Constants
You can add your own named constants during the parsing stage. To do this:
• Create a constant pool in advance using the `createConstantPool()` function.
• Set constants and their values using the `set()` method.
• Pass the constant pool to the `parse()` method.
Example:
The `set()` method returns the same constant pool object, so you can chain calls together. This is more convenient and more elegant:
You can also override built-in constants:
█ EVALUATION
❱❱ Type Coercion
An expression can consist of values of different data types. ExprLib does not have strict data type checking. Instead, all values are converted to `float` and then back if necessary.
Converting `bool` to `float`:
• `true` -> `1.0`
• `false` -> `0.0`
Converting `float` to `bool`:
• `0.0` or `na` -> `false`
• Any other value -> `true`
Thus, expressions that incorrectly combine different data types are allowed. For example, `true + 2` will return `3.0`. Strict typing requires additional memory as well as additional computational resources during evaluation, which is a critical concern. Therefore, it was decided not to implement it.
As in Pine Script, most operations with an `na` operand results in `na` or `false`, but logical operations first convert `na` to `false`, so their result follows boolean logic. For example:
• `3 - na` returns `na`
• `3 > na` returns `false`
• `3 <= na` also returns `false`
• `na AND true` returns `false`
• `na OR true` returns `true`
• `NOT na` returns `true`
❱❱ Workflow
To evaluate an expression:
• Create an evaluator in advance using the `createExpressionEvaluator()` function.
• Set variables and their values in the expression using the `setVariable()` method.
• Call the `evaluate()` or `evaluateToBool()` method, passing the expression as an argument.
The `evaluate()` and `evaluateToBool()` methods differ in their return types. The former returns a `float` result, while the latter returns a `bool` result. The method to call depends on the expected result type.
Example:
❱❱ Variables
If an expression contains an identifier that is neither a function nor a constant, and this identifier has not been assigned a variable value, then this identifier is considered a constant with the value `na` (or `false` in boolean operations).
The `setVariable()` method overrides existing constants (both built-in and custom). For example, by default, the identifier `e` is used as the constant Euler's number (~2.71828). However, you can make `e` your own variable:
The `setVariable()` method does not need to be called on each bar if the variable's value does not change. The expression always stores and uses the last value set.
You can clear all previously set variables using the `clearVariables()` method. This can be useful if you have many variables and want to reset them all and set values for only a small subset.
❱❱ Error Handling
In some cases (for example, when dividing by zero), evaluation results in an error. In this case, `evaluate()` will return `na`, and `evaluateToBool()` will return `false`. Like the parser, the evaluator stores the result of the last evaluation.
Evaluator and error field structures:
Example:
Currently, the only possible cause of this error is division by zero. You can disable this error and have the evaluator interpret the result of division by zero as `na`. To do this, disable the corresponding flag in the evaluator:
Thus, an expression like `na(5 / 0) ? 1 : 2` will return `1` instead of an error.
█ BEST PRACTICES
• Reuse `ExpressionParser` and `ExpressionEvaluator` objects whenever possible.
• Parse expressions only once, and evaluate them as needed. Parsing is slow. Evaluation is fast.
• If certain variable values change rarely, call `setVariable()` only when necessary.
• Try to avoid excessive numbers of variables whose values change frequently. This can impact performance even if they're not used in the expression.
█ API REFERENCE
❱❱ Expression Parser
ExpressionParser
Expression parser.
Fields:
isParsed (series bool): `true` if the last parse completed successfully, `false` otherwise.
error (ParseError): Error from the last parse attempt. If the last parse was successful, then this field is `na`.
createExpressionParser()
Creates an expression parser.
Returns: Expression parser.
method parse(parser, exprStr, constantPool)
Parses an expression.
Namespace types: ExpressionParser
Parameters:
parser (ExpressionParser): Expression parser.
exprStr (string): Expression string. Can be empty, blank, or 'na'. That way expression is valid and will return `na` on evaluation.
constantPool (ExpressionConstantPool): (Optional) Named constants.
Returns: Parsed expression. If an error occurs during parsing, then the returned expression will be `na`.
You can check validity and error details accessing parser's `isParsed` and `error` fields.
❱❱ Expression
Expression
Parsed expression.
method setVariable(expr, identifier, value)
Assigns a numeric value to a variable.
Namespace types: Expression
Parameters:
expr (Expression): Expression.
identifier (string): Variable name.
value (float): Value.
Returns: This expression.
method setVariable(expr, identifier, value)
Assigns a boolean value to a variable.
Namespace types: Expression
Parameters:
expr (Expression): Expression.
identifier (string): Variable name.
value (bool): Value.
Returns: This expression.
method clearVariables(expr)
Clears all variable values.
Namespace types: Expression
Parameters:
expr (Expression): Expression.
Returns: This expression.
❱❱ Constant Pool
ExpressionConstantPool
Expression constant pool.
createConstantPool()
Creates an expression constant pool.
Returns: Expression constant pool.
method set(pool, identifier, value)
Assigns a numeric constant value.
Namespace types: ExpressionConstantPool
Parameters:
pool (ExpressionConstantPool): Expression constant pool.
identifier (string): Constant name.
value (float): Value.
Returns: This expression constant pool.
method set(pool, identifier, value)
Assigns a boolean constant value.
Namespace types: ExpressionConstantPool
Parameters:
pool (ExpressionConstantPool): Expression constant pool.
identifier (string): Constant name.
value (bool): Value.
Returns: This expression constant pool.
method clear(pool)
Clears all constants.
Namespace types: ExpressionConstantPool
Parameters:
pool (ExpressionConstantPool): Expression constant pool.
Returns: This expression constant pool.
❱❱ Expression Evaluator
ExpressionEvaluator
Expression evaluator.
Fields:
isEvaluated (series bool): `true` if the last evaluation completed successfully, `false` otherwise.
error (EvaluationError): Error from the last evaluation attempt. If the last evaluation was successful, then this field is `na`.
result (series float): Numeric result of the last evaluation.
boolResult (series bool): Boolean result of the last evaluation.
createExpressionEvaluator()
Creates an expression evaluator.
Returns: Expression evaluator.
method evaluate(evaluator, expr)
Evaluates an expression.
Namespace types: ExpressionEvaluator
Parameters:
evaluator (ExpressionEvaluator): Expression evaluator.
expr (Expression): Expression to evaluate.
Returns: Numeric evaluation result.
For boolean-result expressions `1.0` means `true` and `0.0` means `false`.
Returns `na` if expression is empty.
method evaluateToBool(evaluator, expr)
Evaluates an expression.
Namespace types: ExpressionEvaluator
Parameters:
evaluator (ExpressionEvaluator): Expression evaluator.
expr (Expression): Expression to evaluate.
Returns: Boolean evaluation result.
Returns `false` if expression is empty.
method setFailOnDivisionByZero(evaluator, value)
Sets whether division or modulo by zero should fail evaluation.
Namespace types: ExpressionEvaluator
Parameters:
evaluator (ExpressionEvaluator): Expression evaluator.
value (bool): If `true`, division or modulo by zero fails evaluation. If `false`, it produces `na`.
Returns: This expression evaluator.
❱❱ Errors
ParseError
Error that occurred during expression parsing.
Fields:
message (series string): Error message.
index (series int): Character index where the parser detected the error.
EvaluationError
Error that occurred during expression evaluation.
Fields:
reason (series EvaluationErrorReason): Error reason.
message (series string): Error message.
Perpustakaan pine
Dengan semangat TradingView yang sesungguhnya, penulis telah menerbitkan kode Pine ini sebagai pustaka sumber terbuka agar programmer Pine lain dari komunitas kami dapat menggunakannya kembali. Salut untuk penulis! Anda dapat menggunakan pustaka ini secara pribadi atau dalam publikasi sumber terbuka lainnya, tetapi penggunaan kembali kode ini dalam publikasi diatur oleh Tata Tertib.
Pernyataan Penyangkalan
Perpustakaan pine
Dengan semangat TradingView yang sesungguhnya, penulis telah menerbitkan kode Pine ini sebagai pustaka sumber terbuka agar programmer Pine lain dari komunitas kami dapat menggunakannya kembali. Salut untuk penulis! Anda dapat menggunakan pustaka ini secara pribadi atau dalam publikasi sumber terbuka lainnya, tetapi penggunaan kembali kode ini dalam publikasi diatur oleh Tata Tertib.
