Expressions
Introduction
A chart can visualize not only symbols (financial instruments), but also a mathematical expression.
This is commonly used for spreads, where you chart the price difference between related instruments (for example Crack Spread or Crush Spread).
Expressions support all standard arithmetic operators and numeric constants like 2 or 3.45.
Barchart symbology uses characters that overlap with math syntax (for example * in futures notation). To avoid ambiguity, symbol names must be wrapped in curly braces: { and }.
For example, at the time of writing this (mid-June 2017), the following {ES*2} is S&P 500 E-Mini September '17 (ESU17) while ES*2 is Eversource Energy (ES) multiplied by 2.
Syntax
Expressions consist of:
- symbol names:
{SYMBOL}(symbol text cannot contain{or}) - optional field selector on symbol:
{SYMBOL}.FIELD(field names use letters only, for example.CLOSE) - constants: floating-point values like
2.35(scientific notation such as1.72E5is not supported) - unary operator:
-(negation) - binary operators:
+,-,*,/,^(from lowest to highest precedence) - parentheses:
(and)for explicit grouping - line comments:
// ...(leading and trailing comments are supported)
A very contrived example with the purpose to showcase everything:
{ESM17} * 4.75 - (-(1.5 + {ES*2} / 33) ^ 2 * 4.25)Example with comments:
// header{MSFT}.CLOSE // base price* 2 // doubledHow to parse expressions
If your UI accepts user expressions, parse and validate them before sending them to chart API (for example via MainPlot, documented here).
Use:
parseExpression(text, (useCache = false), (expandAliases = true));It returns either a success object or an error object.
Success fields:
text: original inputmodel: expression ASTclean: formatted expression with comments removedverbose: formatted expression with comments preservedsymbols: list of symbols found in the expression
Error fields:
text: original inputerror: human-friendly parse error messageloc: optional source location object (start/endwithoffset,line,column)
Please note that the expression parser does not interpret symbol names in any way. So if you pass in something like {NOT-A-SYMBOL}*2, the list of symbol names will be [NOT-A-SYMBOL].
Comments and AST metadata
Comment-aware parsing also populates optional AST metadata:
- root
model.leadingComments: string[] - per-node
trailingComment?: string - per-node
loc?: { start, end }
This is useful for advanced editors (syntax highlighting, inline diagnostics, round-trip editing, etc.).
Formatting with and without comments
cleanis equivalent toformatExpression(model)(comments removed)verboseis equivalent toformatExpression(model, true)(comments preserved)
Using expressions standalone
The expression functionality can be used outside of the charts package. In order to evaluate an expression, you only need a function providing the value of a given symbol because symbols are the only unknown (not a constant) value in the expression.
Having parsed the expression and obtained the model (see above), call evaluateExpression(model, valueProvider).
valueProvider receives symbol name and (optionally) field name, then returns the numeric value to use in evaluation.
A few notes on expressions
When you add an expression plot to the chart, behavior is similar to adding a study.
However, if you set the main plot to an expression, some studies may be removed because they cannot be calculated from expression output. In practice, studies that require fields beyond Close cannot be based on expressions (expression output is a single value mapped to Close).