WealthScript: Syntax


This article is an overview of the WealthScript syntax reference


In the following, we assume that the reader has already some experience with WealthScript and is already familiar with how to access the Knowledge Base for further information.


Pro Tip to begin with: WealthScript is a case-insensitive language. This means that it doesn't matter if you prefer to type letters in lower-case, upper-case, or a mixture of the two. All of the examples provided in this section use the _camelCase_ convention, but you can write your own code following the convention that you prefer!



Types


WealthScript is a strongly typed language where type is usually inferred from usage. Basic types are:


- integer

- number

- string

- bool


Warning: Numeric values are always represented as a double even when the `integer` type is used. The `integer` keyword allows WealthCharts to better perform tasks like the verification of input parameters, but it doesn't affect how the code is executed.


See the operands section for additional information.



Numbers


Numbers are double-precision (64-bit) floating-point values and can be expressed both in decimal form or through scientific notations. Examples include:


- 1

- 1.25

- 1e2

- 1.25e3


The underscore `_` may be used as a digit separator. The benefit of this is to improve the code readability when dealing with large numbers. For example:


- 1_000_000


Strings


Strings are a sequence of characters delimited by double quotes `"`.


Certain characters need to be escaped before the can be included in a string.

These escape sequences are:


| Escape sequence | Use |
| :-------------: | -------------------- |
| `\a` | bell |
| `\b` | back space |
| `\f` | form feed |
| `\n` | newline |
| `\r` | carriage return |
| `\t` | horizontal tab |
| `\v` | vertical tab |
| `\\` | backslash |
| `\"` | double quote |
| `\'` | single quote |
| `\[` | left square bracket |
| `\]` | right square bracket |

String literals can be concatenated together just by juxtaposing them and in this case a single space will be automatically added.

For example, writing "hello" "world` is exactly the same as writing "hello world" but it makes it easier to wrap long strings.


The + operand must always be used when concatenating one or more string variables.


See the operands section for additional information.

Booleans


Boolean values can either be `true` or `false`.


Colors


Colors are useful values to distinguish and give meaning to the visuals of your script.

The WealthScript Language offers a predefined set of color constants for easy use:


| Name | Color |
| :----------------: | -------- |
| `Black` |
----------
|
| `Blue` |
----------
|
| `Cyan` |
----------
|
| `Green` |
----------
|
| `Magenta` |
----------
|
| `Red` |
----------
|
| `Yellow` |
----------
|
| `White` |
----------
|
| `DarkBlue` |
----------
|
| `DarkCyan` |
----------
|
| `DarkGreen` |
----------
|
| `DarkMagenta` |
----------
|
| `DarkRed` |
----------
|
| `DarkBrown` |
----------
|
| `DarkGray` |
----------
|
| `LightGray` |
----------
|

If these predefined values don't do it for you, colors can also be created on the go with the RGB(<red>, <green>, <blue>). The function lets you set the values of `red`, `green` and `blue` from `0` to `255` to find the perfect mix for the color you need.


let myColor = RGB(248, 0, 0) // a slightly darker Red but lighter than DarkRed

Statements


A WealthScript is composed of a series of _statements_.


Each statement is preferably put on its own separate line in the code editor and, in this case, using the semi-colon `;` at the end of each line is optional.


Common examples of statements are:


- [declarations and assignments]

- [indicator definitions]

- [trading statements]

- [plotting statements]

- [conditional checks]


Comments


Comments are lines of code that do not get executed and can contain anything


Pro Tip: Use comments for useful notes to explain your process so that you don't get lost

if you need to edit your formula in the future



Line comments start with //.

Block comments start with {` and are closed by `}.



// This is a single line comment
...code...

{
This is
a multiline
comment
}


Operands


Unary operators


| Operand | Effect |

| :-----: | ---------------- |

| `-` | Negates a number |


Binary operators


| Operand | Effect |

| :-----: | -------------------------------------------------------------------- |

| `+` | Sums two numbers or concatenates two strings |

| `-` | Subtracts one number from another |

| `*` | Multiplies two numbers together |

| `/` | Divides two floating-point numbers |

| `div` | Divides two integer numbers |

| `mod` | Calculates the remainder of the integer division between two numbers |


Logical operators


| Operand | Effect |

| :-----: | --------------------------------------------- |

| `not` | Negates a boolean value (unary) |

| `and` | Computes the logical AND between two booleans |

| `or` | Computes the logical OR between two booleans |


Logical expressions are always short-circuited. Short-circuiting is a feature in many programming languages where the evaluation of these expressions stops as soon as the final outcome is determined. In other words, if the result can be decided before evaluating all the conditions, the remaining conditions are not checked.


In a logical AND expression, if any of the conditions is `false`, the entire expression is guaranteed to be `false`. Therefore, the evaluation of the expression stops as soon as a `false` condition is encountered.

In a similar way OR expressions only get evaluated until a `true` condition is found.


Relational operators


These operators _(also known as comparison operators)_, compare their operands from left to right.


| Operand | Effect |

| :-----: | --------------------------------------------- |

| `>` | Checks if the first value is greater than the second |

| `<` | Checks if the first value is less than the second |

| `==` | Checks if the first value and the second are equal |

| `!=` | Checks if the first value and the second are different |

| `>=` | Checks if the first value is greater than the second or if they are equal |

| `<=` | Checks if the first value is less than the second or if they are equal |

| `cross over` | Checks if a value goes from being less than the other to being greater than it |

| `cross under` | Checks if a value goes from being greater than the other to being less than it |


Relational operators return a `boolean` value reflecting the outcome of the comparison between the two operands



let condition3 = (10 < 5) // false
let condition1 = (10 > 5) // true

let condition2 = (10 == 5) // false
let condition3 = (10 != 5) // true

let condition4 = (10 > 10) // false
let condition5 = (10 >= 10) // true


Precedence


The standard C precedence rules apply.

In the WealthScript Language, operator precedence determines the order in which different operators are evaluated in an expression. When you have an expression that contains multiple operators, the operators with higher precedence are evaluated before operators with lower precedence. If two operators have the same precedence, the order of evaluation is determined by their associativity, which can be _left-to-right_ or _right-to-left_.


Here are the standard operator precedence rules, with operators listed from highest to lowest precedence:


1. Postfix operators: These operators follow the operand. Examples include the function call `()` and array subscript `[]`.


2. Unary operators: These operators act on a single operand. Examples include the unary minus `-`, unary plus `+`, logical NOT `not`.


3. Multiplicative operators: These operators perform multiplication, division, and modulus operations. Examples include `*` (multiplication), `/` (division), and `%` (modulus).


4. Additive operators: These operators perform addition and subtraction operations. Examples include `+` (addition) and `-` (subtraction).


5. Relational operators: These operators compare values. Examples include `<` (less than), `>` (greater than), `<=` (less than or equal to), and `>=` (greater than or equal to).


6. Equality operators: These operators compare for equality and inequality. Examples include `==` (equal) and `!=` (not equal).


7. Logical AND: The `and` operator performs a logical AND operation.


8. Logical OR: The `or` operator performs a logical OR operation.


9. Conditional operator: The `? :` operator is the conditional operator, used for conditional expressions.


10. Assignment operators: The `=` operator is used to assign values to variables.


It's important to note that you can use parentheses `()` to override the default precedence and enforce a specific order of evaluation in your expressions. Expressions enclosed in parentheses are always evaluated first.


Declared identifiers


WealthScript has different ways to assign names to values and, even if not all of them are technically variables, they will all be discussed in this sub-section.


Except for **Aliases** the order of declaration **does not** apply for these statements so its good practice to put them at the beginning of the script and outside any conditional checks to avoid confusion.


Aliases


The simplest way to use the result of an expression multiple times without computing it every single time, is to assign a name to it by using the keyword `let`.


let minutesInADay = 24 * 60

Once an alias has been assigned to an expression, the same alias cannot be assigned to a different expression. This essentially make aliases read-only variables.


Warning: You can only define up to a certain number of aliases (currently around 200) in your script. You will get a compilation error if you attempt to define more than that.


Aliases can also be defined inside closed scopes like [conditional checks]


if close > open then
let value1 = high[1]
// value1 is only available from here until the end of this scope
end
// value1 is not available from here to the end of the script


Variables


If you're already familiar with computer languages in general then you should already have an idea of what a variable is but, as a quick definition, imagine variables as storage boxes that you can use to hold some values.


You can either get stuff from the box (i.e. _read the variable_) or put new stuff into it (i.e. _write the variable_) and you can do that however many times you need.


Variables are declared using the `var` keyword in a dedicated statement. Their initial value can be specified by wrapping it in parenthesis just after the variable name.

The type of the variable will be inferred from the type of the initial value.

See the following examples:


var numeric(42), str("hello world"), boolean(false)

Pro Tip: You can declare multiple variables on a single line or have multiple `var` statements. If the initial value is optional and if left empty the variable will be initialized with the number **zero**.

WealthScript variables have a _super-power_ where values for previous candles are automatically preserved and you can access those previous values with squared bracket expressions. For example:


var numeric(42)
let previous = numeric[1] // get the previous bar value
let threeAgo = numeric[3] // get the value from 3 bars ago


Warning: You cannot set the value of previous bars for variables



var numeric(42)
numeric[0] = 43 // this is a valid way to assign a value to our variable
numeric[3] = 44 // this is not allowed

Constants


Constants are values that cannot be changed after they're initially defined.

Their value is simply used as-is every time the constant is referenced, making them faster and more efficient than aliases, but they can only hold simple values and not expressions.


const numeric(42), str("hello world"), boolean(false)

Reminder: Memory is never allocated for constants.



Inputs


Inputs are a special type of constants whose value can be changed by the user before the script is executed.

Indicator parameters are a primary example of inputs.



input numeric(42), str("hello world"), boolean(false)


Pro Tip: You can force a numeric input to be treated as an integer by using the following syntax:

input integer numeric(42)

Doing this allows the chart's UI to validate the input thus preventing the user from passing decimal values.



Predefined Values


The **WealthScript Language** offers a list of predefined keywords to access useful values for your script.

All of these predefined keywords are **readonly** and you can access their past values using square bracket indexes same as [variables](./#{#declared-identifiers-variables}).


| Name | Description |

| :-----: | ------------------------------------- |

| `close` | The last price _(C in short)_|

| `open` | The opening price _(O in short)_|

| `low` | The lowest price _(L in short)_|

| `high` | The highest price _(H in short)_|

| `volume` | The volume value _(V in short)_|

| `range` | The range of the bar |

| `truehigh` | The true high of the bar |

| `truelow` | The true low of the bar |

| `truerange` | The true range of the bar |


Some of those keywords refer to commonly used equations in the trading world.


| Name | Description |

| :-----: | ------------------------------------- |

| `hl2` | $(H + L) \by 2$ |

| `hlc3` | $(H + L + C) \by 3$ |

| `ohlc4` | $(O + H + L + C) \by 4$ |


Conditions


Conditional checks are a powerful way to add complexity to your code.

The code inside the body of these statements will only be executed based on whether one or more conditions are met or not.


These blocks of code always start with the `if` keyword followed by a `<boolean condition>` which can be pre evaluated in a [declaration] or evaluated inline without allocating any memory.

After the `<boolean condition>` use `then` to start listing the code to execute when the condition is met.


if close[0] > close[1] then
// The code only runs when the current close is higher then the close of yesterday
... code ...
end

You can use the [relational operators] in the conditions and concatenate them using the [logical operators](./#logical-operators)


let condition1 = close[0] > close[1]
let condition2 = close[0] > close[2]
let condition3 = condition1 and condition2 and (close[0] > close[3])
let condition4 = close[0] > open
let condition5 = close crosses over low

if condition5 or (condition4 and condition5) then
... code ...
end

Remember: Standard [precedence] rules apply


You can also add a list of code statements as a fallback when the condition is not met using the `else` keyword.


if close[0] > close[1] then
// The code only runs when the current close is higher then the close of yesterday
... code ...
else
// The code only runs when the current close is NOT higher then the close of yesterday
... code ...
end

Indicators


One of the most powerful tools of the WealthScript Language is the option to reuse logic from other scripts you wrote and tap into any of the Indicators you have access to on your account to enhance your own scripts.


To use any Indicator you must first import it using the button on the left called Indicators. Once we click it, a window with all of the indicators you've already imported will pop up on the screen _(should be empty when starting from scratch)_. From here you can add as many of the indicators that you have access to by clicking the button on the bottom left of the window + Add Indicator.


Once you add any indicator you'll see it in the window.

After you successfully import an Indicator you are going to need to define it by assigning it to an [alias] and then access its values from the alias you've defined.


// Define my indicator's alias
let myIndicator = Indicator()

// Use its values (for example in a condition)
if (myIndicator.value > close) then
... code ...
end


Warning: Do not define indicators inside conditional statements as they need to be calculated bar by bar, and some need to access their previous values.



// Leads to unreliable logic
if condition1 then
let mySMA = SMA(input: close, Len: 30)
plot1(mySMA.value)
end


// Correct way to define indicators
let mySMA = SMA(input: close, Len: 30)
if condition1 then
plot1(mySMA.value)
end

Pro Tip:

if you don't know the correct way to define every indicator or the parameters to use no worries - we have a tip for you!

After you import an indicator you can access a list of ready to use snippets by clicking the import or by opening the Additional Options menu and clicking on Code Snippets

The info panel contains the definition of the indicator and the list of values you can access from it.


MACD Example

Importing the "Moving Average Convergence Divergence (MACD)" indicator will present you with these snippets


Definition:


let myMACD = MACD(data: data1, Avg1Len: 12, Avg2Len: 26, SignLen: 9)


Outputs:


let MACD_histogram = myMACD.histogram[0]
let MACD_value = myMACD.value[0]
let MACD_sign = myMACD.sign[0]

The values of the Indicators correspond directly to the ones that get plotted on the chart when they are applied and can be accessed by following your alias with a `.` and the name of the value you need (`myIndicator.<name>`).

You can wrap the value you want to access in double quotes like this `myIndicator."<name>"` if it contains spaces or reserved/special characters


ADX / DMI Example

Some outputs of the "ADX / DMI" indicator contain a reserved character (`+` and `-`) so they must be wrapped in double quotes


let value1 = myADXDMI."+DI"[0] // MUST be wrapped in double quotes
let value2 = myADXDMI."-DI"[0] // MUST be wrapped in double quotes
let value3 = myADXDMI.ADX[0] // good either way, could be wrapped in double quotes

In your Indicator definitions we can distinguish between `sources` and `parameters`.


A `parameter` is a value taking one of the [standard supported types].

You can specify any parameter using the following syntax in the Indicator definition: `let myIndicator = Indicator(<param1>: <value1>, <param2>: <value2>, ...)`

Every `parameter` is optional and the Indicator will use its default when it gets defined, this way you only need to write the parameters you want to change and leave the rest of them alone.


Warning (Important): Indicators only get defined with the first parameters they are given so changing them in future bars will not have any effect. If you need two different versions of the same indicator on different occasions, define it twice and use the values accordingly:


var length(30)

// This defines the SMA to the current value of the variable "length"
// making it a 30 period SMA
let mySMA = SMA(input: close, Len: length)

// Even though from here "length" will have a value of 45
// On the next bar SMA wont change to 45 periods
// It will still be a 30 period SMA
length[0] = 45

Pro Tip: You can always skip any parameter that is only tied to visual changes _(like offsets, colors, visibility toggles, ...)_ since the indicators you import do not get plotted when you define them.



Reminder: Just like accessing an Indicator's value you may need to wrap parameters' names in double quotes if needed.


Breakout Forecaster Example


// These two lines of code define the BreakoutForecaster indicator in the same way
let myBreakoutForecaster1 = BreakoutForecaster(Lookback: 20, "Dot space": 60, "Draw mode": "Both", "Bullish color": rgb(86, 255, 87), "Bullish font color": rgb(0, 0, 0), "Bearish color": rgb(255, 1, 0), "Bearish font color": rgb(255, 255, 255))
let myBreakoutForecaster2 = BreakoutForecaster()

// This is like the two prior but it has a Lookback of 40
let myBreakoutForecaster3 = BreakoutForecaster(Lookback: 40)

A `source` is an array of values taken from the [predefined title series] a [variable]or another indicators value (`myIndicator.<name>`). You can specify any source using the following syntax in the Indicator definition: `let myIndicator = Indicator(<source1>: <var1>, <source2>: <var2>, ...)`.

If an indicator needs sources they must be explicit. For example a Simple Moving Average has one source called input so it is required.


// Compiler error, missing the input source
let mySMA = SMA()

// Explicit source input
let mySMA = SMA(input: close)


Warning (Important): The WealthScript engine will start calculations right away with the first bar available, but will wait for every indicator to be defined to be ready to draw on the chart.

So if for example you have two Moving Averages, one of 5 periods and one of 30, the plots will show up once the 30-bar MA is ready _(after 30 bars)_.

Keep this in mind when applying your scripts and using them.


Trading


Trading is a fundamental part of any strategy with the following syntax: `<action> <quantity> <time> <price>`.


Action


The action sets the trade direction.

Some actions need a position already opened or otherwise they do nothing.


| Keyword | Effect |

| :-----: | --------------------------------------- |

| `buy` | Opens a Long position |

| `sell` | Closes an opened Long position |

| `sellshort` | Opens a Short position |

| `buy to cover` | Closes an opened Short position |


Pro Tip: You can use just the opening and closing actions on the current bar like so:


if buy_condition then
buy this bar
end
if sell_condition then
sell this bar
end

But it's best to specify the rest of the parameters as well!


Quantity


This parameter specifies how many shares to trade.

If you want to specify the number of shares to trade you can use the `shares` _(or `share`)_ keyword prefixed by a numeric value



buy 3 shares this bar // Buys 3 shares

let shareNumber = 3
buy shareNumber shares this bar // Buys 3 share


Time


This parameter specifies the bar to trigger the trade.

You can choose between two values `this bar` which triggers the trade at `close` of the current bar

and `next bar` which triggers the trade in the next bar



buy this bar // Buys on the current bar
buy next bar // Buys on the next bar


Pro Tip: Using next bar lets you further customize the [price] option


Price


This parameter specifies the price of the trade using the following keywords:

| Keyword | Effect |

| :-----: | --------------------------------------- |

| `at close` | The price the bar closes with |

| `at market` | The market price **(only available for [next bar](./#trading-time) trades)** |

| `at open` | The opening price of the bar **(only available for [next bar](./#trading-time) trades)** |

| `at <value> limit` | The price as soon it goes **over** the `<value>` specified |

| `at <value> stop` | The price as soon it goes **under** the `<value>` specified |


**limit** and **stop** orders only get triggered if the bar price crosses the specified value, otherwise nothing happens.

In the prices that specify a **value** you can use any numeric value _(like for [specific shares].



buy 1 share this bar close // Buys 1 share on the current bar at closing price
buy 3 shares next bar at open // Buys 3 shares at the opening price of next bar

buy 2 shares next bar at ((open + close) / 2) stop // If the price goes under (open + close / 2) buys 2 shares at current price.

let myLimit = ((high + close + low) / 3)
buy 6 shares next bar at myLimit limit // If the price goes over ((high + close + low) / 3) buys 6 shares at current price.

Plotting


Plotting refers to drawings that reoccur every bar.

They are part of almost any indicator you've ever applied to your chart and are extremely useful for visual cues and controls.


Every plot follows this syntax `Plot<N>(<source>, <...optional parameters...>)`


- N: is the integer number acting as a unique identifier for each plot

- source: is the numeric value that is drawn on the chart


plot1(100) // Plots the number 100 for each bar
plot2(close) // Plots the close for each bar
plot3("text") // This is not allowed since value has to be a number


The optional parameters are not required but much recommended for more complete control over your script's visuals


- name: a string that identifies the value being plotted

- color: the color used for the drawing


// This will plot the close value of the title
// showing up in the data window as "Close price"
plot1(close, "Close price")

// This will plot the open value of the title
// showing up in the data window as "Open price"
// colored as red
plot2(open, "Open price", red)

Warning: You can't define two plots with the same identifier and different name



// This throws a compiler error
plot1(low, "Low bar")
plot1(high, "High bar")

-----


// This is a valid syntax
plot1(low, "Low bar")
plot2(high, "High bar")

The default way of plotting is to represent the values as a line on the main chart, but if you need more customization

for your script, check out the following attributes:


Attributes (advanced):


In this section we'll look at the PlotStyle and PlotSubchart attributes to further customize your plots.

For both of the attributes the first parameter is the unique number that identifies the plot.


PlotStyle follows this syntax `[PlotStyle(<N>, <style>, <size>)]`


- N: is the integer number acting as a unique identifier for each plot.

- style: is the shape to give the values you want to draw with `line` being the default. These are the possible values for the plot style:

- `line`

- `histogram`

- `hbands`

- `dots`

- `dashes`

- `crosses`

- `squares`

- `triangleUp`

- `triangleDown`

- `levels`

- `columns`

- `diamonds`

- size: is the numeric value from 1 to 7 representing the size of your drawing where `1` is the minimum and the default value.


// Plot 1 will be a dashed line with the default size of 1
[PlotStyle(1, Dashes, 1)]

// Plot 2 will be a series of diamonds with the maximum possible size of 7
[PlotStyle(2, Diamonds, 7)]

PlotSubchart follows this syntax `[PlotSubchart(<N>, <subchart>)]`


- N: is the integer number acting as a unique identifier for each plot.

- subchart: is a positive number identifying the section of the chart where the drawing will be located. The default value is `0` which stands for the main chart window. Any number above 0 will create a new section under the main one and draw there.


// Plot 1 will be drawn in a new section under the chart
[PlotSubchart(1, 1)]

// Plot 2 will be drawn in the same section as Plot 1
[PlotSubchart(2, 1)]

Warning (Important): The WealthScript engine will start calculations right away with the first bar available but will wait for every indicator defined to be ready to draw on the chart.

So if for example you have two Moving Averages: one of 5 periods and one of 30, the drawings will show up once the 30-bar MA is ready _(after 30 bars)_.

Keep this in mind when applying your scripts and using them.



Best Practices


Here are some things to keep in mind to make your creations stable, and easy to use:


- Use aliases instead of variables if you need to store a value with no need to access its past values

- Use constants if you need a value that stays the same during the whole script

- It's best to never leave the body of conditional statements empty


// Compiles but not great code

if conditions then
else
... code ...
end

---

// Compiles and much better code

if not conditions then
... code ...
end

- It's best to concatenate nested conditional statements


// Works but not great code

if condition1 then
if condition2 then
if condition3 then
... code ...
end
end
end

---


// Works and much better code

if condition1 and condition2 and condition3 then
... code ...
end

Here is a good script structure for statements to avoid any inconsistency and keep your formula solid:


<code>
// 1: Any optional attributes
[PlotStyle(1, Dashes, 5)]
[PlotStyle(2, Dashes, 5)]
// 2: Input definitions
input integer longTermLen(200)
// 3: Constants definitions
const shortTermLen(50)
// 4: Variables definitions
var tradesCounter(0)
// 5: Indicator definitions
let longTermSMA = SMA(input: close, Len: longTermLen)
let shortTermSMA = SMA(input: close, Len: shortTermLen)
// 6: All of your script logic, operations, conditions and endpoint checks
if (shortTermSMA.value crosses over longTermSMA.value) then
buy next bar at market
tradesCounter[0] = tradesCounter[0] + 1
end
if (shortTermSMA.value crosses under longTermSMA.value) then
sell next bar at market
tradesCounter[0] = tradesCounter[0] + 1
end
// 7: Any endpoint reoccurring every bar
plot1(longTermSMA.value, "Long Term SMA", red)
plot2(shortTermSMA.value, "Short Term SMA", green)
{
Here is a basic template to help you get started with your indicator.
Any code between curly brackets is "block commented" which means the script
does not read this when compiling or running.
}
{
Plot Styles
Remember, these are formatted by (signal number, signal visual, signal size)
[PlotStyle(1, Dots, 1)]
}
[PlotStyle(1, Dots, 10)]
[PlotStyle(2, Dots, 10)]
{
Setting Variables and conditionals
Defining the rules
}
var buyDot(false)
var sellDot(false)
let newBuy = (close > close[1]) and (close[1] > close[2]) and (close[2] > open[3])
let newSell = (close < close[1]) and (close[1] < close[2]) and (close[2] < open[3])
{
Creating some conditional checks/statements

}

if newBuy and not buyDot then
buyDot = true
sellDot = false
plot1(low, "New Buy Entry", RGB(0,255,0))
elseif newBuy and buyDot then
plot1(low, "New Buy Entry", RGB(0,255,0), 0, 5) // This resizes the dot to a size of 5
end
if newSell and not sellDot then
sellDot = true
buyDot = false
plot2(high, "New Sell Entry", RGB(255,0,0))
elseif newSell and sellDot then
plot2(high, "New Sell Entry", RGB(255,0,0), 0, 5) // This resizes the dot to a size of 5
end

Check out related articles for further information!


Related Articles

How to combine indicatorsMathematical OperatorsStandard IndicatorsStrategy Back TesterSymbol InfoWealthScript: IntroductionWealthScript: Strategy ExampleWealthScript: Visual Builder