# Working with candle data

Note: the features described in this section can be used from any User Defined Indicator, without needing to give it Framework access and turning it into a UDIX. This section of the guide can also be treated as part of the UDI developer reference.

The section above about framework functions describes how RequestCandles() can be used to retrieve candle data from the framework – both historic candles and also optionally streaming updates to the candles as the current price changes.

Separate to that fundamental ability to collect candle data, the framework provides two resources making it easier to work with the candle data:

· The Liquid.CandleStore object

· The Liquid.ta library of technical analysis calculations

### 5.1 The Liquid.CandleStore object

The Liquid.CandleStore object makes it easier to work with candle data:

· It stores, updates, and indexes candles

· It automatically calculates derived properties of each candle such as the high-low range and the median price

· It detects changes such as the start of a new candle, and fires events which you can hook into as a simple way of detecting types of change in the store

· It can automatically update a list of technical analysis calculations

For example, an automated trading algorithm might look broadly as follows:

// Set up a candle store

var myCandleStore = new Liquid.CandleStore({

// Automatically calculate two moving averages

ta: \[

new Liquid.ta.EMA({period: 20}),

new Liquid.ta.EMA({period: 50})

],

OnNewCandle: function() {

// Event which is fired each time a new candle starts.

// Compare the moving averages and potentially carry out some trading action.

}

});

// Use Framework.RequestCandles to load (streaming) data into the store, and set things moving

Framework.RequestCandles({instrumentId: "EUR/USD", timeframe: 3600}, myCandleStore);

### 5.1.1 Creating a candle store

You can create a candle store simply by creating a new instance of the Liquid.CandleStore class. For example:

// Create candle store

var myCandleStore = new Liquid.CandleStore();

// Set up candle store

myCandleStore.OnLoad = function() { … };

… further initialisation, load of data etc

After creation, you can use LoadCandles() to load data into the store, assign event handlers, etc.

However, you can also initialise the candle store "inline", rather than setting it up later. For example, rather than creating a candle store and then assigning an OnLoad() handler, you can instead pass some or all properties in the initialisation of the store:

var myCandleStore = new Liquid.CandleStore({

OnLoad: function() { … called on (re-)load },

OnNewCandle: function() { … called when a new candle starts },

etc

});

The full set of properties which you can optionally pass in the initialisation is as follows. You can also assign any other properties of your own (provided, obviously, that their names don't overlap with the candle store's own values):

&#x20;

| Property                | Description                                                           |
| ----------------------- | --------------------------------------------------------------------- |
| OnCurrentCandleChange() | Event handler. See below.                                             |
| OnNewCandle()           | Event handler. See below.                                             |
| OnLoad()                | Event handler. See below.                                             |
| OnLoadError()           | Event handler. See below.                                             |
| OnUpdate()              | Event handler. See below.                                             |
| candles\[]              | Array of candles to populate with. See below.                         |
| ta\[]                   | Array of technical analysis calculations to populate with. See below. |
| oldestFirst             | Changes the indexing of the store. See below.                         |

&#x20;

### 5.1.2    Loading data into the candle store <a href="#id-5.1.2_loading_data_1" id="id-5.1.2_loading_data_1"></a>

There are three ways of loading data into an Liquid.CandleStore. Firstly, you can take the asynchronous response from RequestCandles() and pass the candles\[] array from the response message into the LoadCandles() function in the Liquid.CandleStore. For example:

Framework.$myCandleStore = new Liquid.CandleStore();

var candleRequest = { … some candle request … };

Framework.RequestCandles(requestDef, function (Msg) {

if (Msg.candles) {

// Process both an initial response to the candle request

// and also streaming updates with changes and additions

Framework.$myCandleStore.LoadCandles(Msg.candles);

} else {

// No candles\[] array. Some problem with the request.

}

});

LoadCandles() can be used both with the initial response to a candle request and also any subsequent streaming updates which contain modified or new candles.

In addition to setting up event handlers, you can detect changes in the store by looking at the return value from LoadCandles(). This can be one of the following values:

&#x20;

| Return value | Description                                                                                                                                                             |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| -1           | Load failed. Invalid candle data.                                                                                                                                       |
| 0            | No change                                                                                                                                                               |
| 1            | Only the current, in-progress candle has changed                                                                                                                        |
| 2            | A new, latest candle has been added to the store. (As with the OnNewCandle() event, there may also have been a final update to what was previously the current candle.) |
| 4            | Initial load                                                                                                                                                            |
| 6            | Load of new candle data which both modifies the history and also adds new current or later candles                                                                      |

&#x20;

The second way of loading data into the store is to assign the candle store as the second parameter to RequestCandles(), instead of providing a callback function. For example:

// Create a candle store

Framework.$myCandleStore = new Liquid.CandleStore();

var candleRequest = { … some candle request … };

// Pass the response(s) from RequestCandles() directly into the Liquid.CandleStore,

// without using an asynchronous callback function or needing to process the messages manually:

Framework.RequestCandles(requestDef, Framework.$myCandleStore);

There are two special considerations here, resulting from the fact that you don't receive the response messages from RequestCandles().

· The framework puts the ID of the candle request into the Liquid.CandleStore as a candleRequestId property. If you need to terminate a streaming request, you can do so using Framework.TerminateCandleRequest(_store_.candleRequestId)

· If the candle request fails, the framework fires an OnLoadError() event in the candle store.

The third way of loading candles into a store is to provide a candles\[] array in the initialisation of the store. For example:

// Note: this method will only normally be suitable for static candle requests,

// not streaming requests where there are multiple callbacks

var candleRequest = { … some candle request … };

Framework.RequestCandles(requestDef, function (Msg) {

if (Msg.candles) {

// Create a store, populating it with the candles\[] array

Framework.$myCandleStore = new Liquid.CandleStore({

candles: Msg.candles,

… any other properties you want to assign

});

} else {

// No candles\[] array. Some problem with the request.

}

});

You can load candle data of your own into an Liquid.CandleStore as well as passing in candle data from the framework. To do this, you provide an array of candle objects, each of which – like the framework's own candle data – must contain ts, o, h, l, and c values (plus, optionally, v).

Finally, the Liquid.CandleStore also has special support for User-Defined Indicators, which receive bar data as separate arrays, in data.barData.open\[], data.barData.close\[] etc, rather than as an array of candle objects. In the UDI.onCalculate() function you can pass the data parameter into a candle store, and that will combine the separate arrays into a list of candles. For example:

UDI.onCalculate = function(data, output) {

var cs = new Liquid.CandleStore({candles: data}); // Can also use LoadCandles(data)

};

It's then possible to do things such as extracting derived prices from the store, such as GetValueArray("median"), or to pass the candle array into a bar-based technical analysis calculation.&#x20;

### 5.1.3    Events in the candle store <a href="#id-5.1.3_events_in" id="id-5.1.3_events_in"></a>

One of the key benefits of the candle store is that it fires "events" when candle data is loaded. This is particularly useful on streaming rather than static candle requests, because it helps you to differentiate between updates of the current candle versus the start of a new candle.

&#x20;

| Event                   | Description / type of change                                                                                                                                                                                                                                                                                                |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| OnCurrentCandleChange() | Called when only the current, in-progress candle is changing                                                                                                                                                                                                                                                                |
| OnNewCandle()           | Called when a new, later candle has been added to the store. What was previously the current candle may also have received a final update as part of the same change, without firing OnCurrentCandleChange()                                                                                                                |
| OnLoad()                | Any other type of change to the candle store. Mainly initial load, but can also be called if a block of additional old candles is later added to the store. In other words, OnLoad() is a notification that the candle data has fundamentally changed, and anything based on it needs to be recalculated.                   |
| OnLoadError()           | Special case: called if you assign the candle store as the output for RequestCandles(), and there is a problem with your candle request                                                                                                                                                                                     |
| OnUpdate()              | Called on any type of change to the candle store – (re-)load, new candle, update of current candle. Designed for callers which only need a notification that the store has changed, regardless of the type of change. The more specific handler such as OnNewCandle() or OnLoad() is called immediately before OnUpdate().  |

&#x20;

The candle store object is passed as a parameter to all event handlers. For example:

&#x20;

myCandleStore.OnLoad = function(candleStore) {

&#x20;      // Store can be accessed either via the myCandleStore variable

&#x20;      // or via the candleStore parameter to the event handler

};

&#x20;

You can assign event handlers after the candle store has been created. For example:

&#x20;

// Create candle store

var myCandleStore = new Liquid.CandleStore();

// Assign a candle request directly into the store

Framework.RequestCandles({…}, myCandleStore);

// Assign event handlers

// Note: candle requests always return asynchronously, and therefore it's safe to assign

// the event handlers immediately after RequestCandles(), rather than doing so before.

myCandleStore.OnLoad = function(candleStore) { … };

myCandleStore.OnNewCandle = function(candleStore) { … };

&#x20;

You can also, instead or as well, provide the event handlers in the initialisation of the candle store. For example:

&#x20;

var myCandleStore = new Liquid.CandleStore({

&#x20;      OnLoad: function() { … },

&#x20;      OnCurrentCandleChange: function() { … },

&#x20;      etc

});

&#x20;

### 5.1.4    Reading data from the candle store <a href="#id-5.1.4_reading_data" id="id-5.1.4_reading_data"></a>

Loading data into the store fills a candles\[] array, and you can read directly from this array:

&#x20;

myCandleStore.LoadCandles(…);

var currentClose = myCandleStore.candles\[0].c;

&#x20;

However, it is not safe for you to _modify_ the candles\[] array in any way. If you need to do any sort of processing on the data, use GetCandleArray() instead as described below.

&#x20;

The store provides some simple properties for checking its contents:

&#x20;

| Property | Description                                                                |
| -------- | -------------------------------------------------------------------------- |
| length   | Number of candles in the store (equivalent to candles.length)              |
| hasData  | Boolean indicating whether there are any candles in the store (length > 0) |

&#x20;

By default, like the framework's array returned from RequestCandles(), the candles in a store are indexed newest-first. Item #0 in the array is the current, in-progress candle. Item #1 is the most recent complete candle. Item #\[length-1] is the oldest candle etc.

&#x20;

This is generally the easiest and most processor-efficient way of working with candle data, but you can optionally invert the indexing by setting oldestFirst:true. This can be done either in the initialisation of the store, or at any later time by changing the oldestFirst property of the store.

&#x20;

If you set oldest-first mode, then the store's own candles\[] array is unchanged, and continues to have the newest candle in #0. However, oldestFirst does alter the following functions which the store provides:

&#x20;

| Function              | Description                                                                                                                                                                                                                 |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GetCandleArray()      | Returns a copy of the candle array (using .slice(0), which means that it is safe for you to modify the result). The order of the array depends on oldestFirst.                                                              |
| GetCandle(idx)        | Returns a specific zero-based candle, or null if the index is not valid. The oldestFirst property controls whether idx=0 means the most recent candle or the oldest candle etc.                                             |
| GetValueArray(member) | Helper function which returns an array of a single member from all the candles. For example, GetValueArray("h") returns an array containing all the high prices, and GetValueArray("median") returns all the median prices. |

&#x20;

In other words: setting oldestFirst is only meaningful if you then access the candle data using GetCandleArray() and GetCandle(), rather than reading the candles\[] array directly. Setting oldestFirst on the store also affects the indexing of any technical analysis calculations in the store.

&#x20;

You can also look up candles by time:

&#x20;

| Function             | Description                                                                                         |
| -------------------- | --------------------------------------------------------------------------------------------------- |
| GetByTime(tm, exact) | Finds the candle which starts with or contains the time tm (specified as a number of milliseconds). |

&#x20;

If exact=true, then tm must exactly match a candle's start time or else GetByTime() returns null. If exact=false, then the following rules apply:

&#x20;

·      If tm is later than the start of the current candle – in other words, any date into the future – then GetByTime() returns the current candle.

·      If tm is earlier than the start of the earliest candle, then GetByTime() returns null.

·      Otherwise, GetByTime() returns the candle where tm is greater or equal to its start but before the start of the next candle.

&#x20;

GetByTime() has no notion of any timeframe which candles cover. For example, if you have hourly candles on a 24x5 market such as forex, and you supply a time over a weekend with exact=false, then what you will get back is the final candle on the preceding Friday. (You can obviously check whether a time actually falls within a candle by adding the timeframe of your data to the candle's start time.)

&#x20;

### 5.1.5    Derived properties of each candle <a href="#id-5.1.5_derived_properties" id="id-5.1.5_derived_properties"></a>

When candles are loaded into the store, it automatically adds in derived properties for each candle such as the high-low range. These are available when you read data back from the store, using GetCandle() etc.

&#x20;

The derived candle properties which are added by the store are as follows:

&#x20;

| Property  | Description                                                                    |
| --------- | ------------------------------------------------------------------------------ |
| range     | High minus low                                                                 |
| median    | Average of high and low                                                        |
| typical   | "Typical" price: (high + low + close) / 3                                      |
| weighted  | "Weighted" price: (high + low + close + close) / 4                             |
| ohlc4     | Average of open + high + low + close                                           |
| change    | Close minus open                                                               |
| abschange | Absolute value of change; converted from negative to positive where applicable |

&#x20;

### 5.1.6    Technical analysis calculations in the candle store <a href="#id-5.1.5_technical_analysis" id="id-5.1.5_technical_analysis"></a>

A candle store lets you set a list of any technical analysis calculations from the Liquid.ta library, and have these automatically updated when the candle data changes.

&#x20;

For example, you can initialise the candle store with a moving average and ATR. These calculations then automatically update whenever candles are loaded into the store (and before any event handlers are called):

&#x20;

var myCandleStore = new Liquid.CandleStore({

&#x20;      // Automatically add a moving average and ATR

&#x20;      ta: \[

&#x20;                  new Liquid.ta.EMA({period: 20, member: "h"}),  // EMA of high (.h) price

&#x20;                  new Liquid.ta.ATR({period: 14})  // ATR

&#x20;      ],

&#x20;      … further initialisation settings

&#x20;

You can set up technical analysis calculations in two ways. You can provide a ta\[] array in the initialisation of the store, like the example above. It's also permissible to pass a single item rather than an array:

&#x20;

var myCandleStore = new Liquid.CandleStore({

&#x20;      // Single TA object

&#x20;      ta: new Liquid.ta.EMA({period: 20, member: "h"}),  // EMA of high (.h) price

&#x20;

Or, at any time after creation of the store, you can use the AddTA() function:

&#x20;

myCandleStore.AddTA(new Liquid.ta.RSI({period: 30}));

myCandleStore.AddTA(new Liquid.ta.Stochastic({kPeriod: 5, dPeriod: 3, slowing: 3}));

&#x20;

Instead of providing an instance of the analysis class, such as new Liquid.ta.ATR(), in the store's initialisation or in a call to AddTA(), you can instead pass a definition containing the parameters for the calculation plus an indicatorType value. The indicatorType should be the class within Liquid.ta such as DEMA or ATR or Envelope. For example:

&#x20;

myCandleStore.AddTA({indicatorType: "Stochastic", kPeriod: 5, dPeriod: 3, slowing: 3});

// Has the same effect as…

myCandleStore.AddTA(new Liquid.ta.Stochastic({kPeriod: 5, dPeriod: 3, slowing: 3}));

&#x20;

You can subsequently read the calculations using the candle store's ta\[] array. The order of items within this is simply the order in which you added them. For example:

&#x20;

var currentRSI = myCandleStore.ta\[0].GetCurrentValue();

var currentStochastic = myCandleStore.ta\[1].GetCurrentValue();

&#x20;

You can add calculations, using AddTA(), after loading candle data as well as during the initial set-up of the store. And it's safe to modify the store's ta\[] array directly to remove or even replace calculations.

&#x20;

As a service to make your code easier to read, there is a further way of addressing technical analysis calculations. When creating a calculation you can include an alias property, such "ema20":

&#x20;

myCandleStore.AddTA(new Liquid.ta.EMA({period: 20, alias: "ema20"}));

&#x20;

You can then refer to calculations via their alias using a $ta() function in the candle store, making the code easier to read than referring to the calculation via a numeric index such as \[1]. For example:

&#x20;

// Calculations can always be addressed via their numeric index, in order of creation…

var currentEma = myCandleStore.ta\[1].GetCurrentValue();

// But the code becomes more readable if the access is given a name rather than a number…

var currentEma = myCandleStore.$ta("ema20").GetCurrentValue();

&#x20;

### 5.1.7    Aggregation to higher timeframes

It is common to need multiple timeframes on a single market, such as both M30 and H1. Rather than making two separate candle requests, it can be more efficient to make a request only for the lower timeframe, such as M30, and then to create the higher timeframe(s), such as H1, by aggregating upwards.

&#x20;

Obvious note: the disadvantage of aggregation compared to a separate candle request is that you get fewer candles on the higher timeframe(s). If aggregating from M30 to H1, then N candles on M30 become N/2 candles on H1. An aggregation such as H1 to D1 causes a much larger reduction in data: the number of available daily candles is the number of hourly candles divided by 24.

&#x20;

You can create aggregated candles using the Aggregate() function. This creates a copy of a candle store, including any technical analysis calculations, and combines the candles into a higher timeframe. The new candle store can then subsequently be updated in the usual way, using LoadData(). For example:

&#x20;

// Request M30 candles

Framework.RequestCandles({"instrumentId": "EUR/USD", timeframe: 1800}, function(Msg) {

&#x20;      // If this is the first call, create a store for the M30 candles, including an ATR calculation

&#x20;      if (!Framework.$myM30) Framework.$myM30 = new Liquid.CandleStore({

&#x20;          ta: \[new Liquid.ta.ATR({period: 14})]  &#x20;

&#x20;      });

&#x20;      // Load initial or subsequent candles into the M30 store

&#x20;      Framework.$myM30.LoadCandles(Msg.candles);

&#x20;      // If this is the first call, create an aggregated H1 store from the M30 store.

&#x20;      // The aggregated H1 store will automatically also have an ATR calculation.

&#x20;      if (!Framework.$myH1) {

&#x20;                  // Creates H1 candles from the M30 initial candles which have just been loaded

&#x20;                  Framework.$myH1 = Framework.$myM30.Aggregate(3600);

&#x20;      } else {

&#x20;                  // If it's not the initial load of candles, then update the H1 store

&#x20;                  // using the new M30 candles

&#x20;                  Framework.$myH1.LoadCandles(Msg.candles);

&#x20;      }

});

&#x20;

As in the above example, Aggregate() requires a timeframe parameter for the aggregation, such as 3600 (=H1).

&#x20;

For timeframes between H2 and D1 inclusive, there is a further consideration: the time zone for the aggregation. Like the time zone when making candle requests, you may want to specify how the candles should be combined. Aggregate() can be given a time zone as a second parameter. For example:

&#x20;

// Aggregate into daily candles, using standard fx time (UTC+2/3 changing on US schedule)

cs.Aggregate(86400, {offset: 120, dstMode: 1});

&#x20;

If you don't provide a time zone parameter, then the default is UTC (and the setting is redundant and ignored if the timeframe is below H1 or above D1).

&#x20;

In a widget or script, you can get the user's standard time zone for charts using Framework.GetUserChartTimezone(). For example:

&#x20;

cs.Aggregate(86400, Framework.GetUserChartTimezone());

&#x20;

In a UDI, you can get the time zone of the indicator's chart from the context. For example:

&#x20;

cs.Aggregate(86400, data.context.timezone);

&#x20;

### 5.2      Liquid.ta technical analysis library <a href="#id-5.2_fxb.ta_technical" id="id-5.2_fxb.ta_technical"></a>

The framework provides an Liquid.ta library of core technical analysis calculations: moving averages, oscillators such as MACD and Stochastic, RSI and ATR etc. For example:

&#x20;

// Create MACD calculation

var macd = new Liquid.ta.MACD({fast: 12, slow: 26, signal: 9});

// Load some data

macd.LoadData( … );

// Get current value (item #0) of histogram

var histo = macd.GetHistogramValue(0);

&#x20;

### 5.2.1    Calculation input: bar-based versus value-based calculations <a href="#id-5.2.1_calculation_input" id="id-5.2.1_calculation_input"></a>

Technical analysis calculations fall into two categories:

&#x20;

·      "Bar-based" calculations which can only be used with candle data, because they need multiple properties from each candle such as both the high and the low. Examples include ATR and the Stochastic Oscillator.

·      "Value-based" calculations which can be used with any array of values. For example, all types of moving average can be calculated on candle data, using a specific single value from each candle such as its close or high, but can also be calculated on _any_ series of numbers.

&#x20;

For example, ATR must be calculated from candle data (where each item includes an o, h, l, and c):

&#x20;

var atr = new Liquid.ta.ATR({period: 14});

atr.LoadData(\[{o:1.2342, h: 1.2347, l: 12341, c: 1.2343}, … ]);

&#x20;

Whereas a moving average can be calculated from any array of numbers, as well as on candle data:

&#x20;

// Calculate a moving average of a series of numbers

var ma1 = new Liquid.ta.EMA({period: 5});

ma1.LoadData(\[2, 3, 14, 7, 5, 10, 12, 20, 13, 4, 8]);

// Calculate a moving average of the high of a series of candles

var ma2 = new Liquid.ta.EMA({period: 10, member: "h"});

ma2.LoadData(\[{o:1.2342, h: 1.2347, l: 1.2341, c: 1.2343}, … ]);

&#x20;

This also means that a value-based calculation can be applied to any other technical analysis calculation. For example, you can calculate ATR, and then take the output and calculate Bollinger® Bands on those ATR results:

&#x20;

// Calculate ATR from candle data

var atr = new Liquid.ta.ATR({period: 14});

atr.LoadData(\[{o:1.2342, h: 1.2347, l: 12341, c: 1.2343}, … ]);

// Calculate Bollinger Bands on the ATR results

var bands = new Liquid.ta.Bands({period: 20});

bands.LoadData(atr.GetValueArray());

&#x20;

### 5.2.2    Creating and initialising technical analysis calculations <a href="#id-5.2.3_creating_and" id="id-5.2.3_creating_and"></a>

You set up a technical analysis calculation by creating an instance of the corresponding class in the Liquid.ta library. For example:

&#x20;

// Create an exponential moving average

var myEma = new Liquid.ta.EMA({period: 20});

// Create an RSI calculation

var myRSI = new Liquid.ta.RSI({period: 14});

&#x20;

All calculations require initialisation with parameters, such as a period value, and these are described below in relation to each individual calculation. (All parameters have defaults, but you will generally want to set them explicitly.)

&#x20;

You can include a data\[] array in the initialisation of a calculation. This is simply a shortcut for creating the calculation and then calling LoadData() with the array:

&#x20;

var myEma = new Liquid.ta.EMA({period: 20, data: \[ … ]};

&#x20;

Parameters can be changed after a calculation has been created (rather than replacing the existing object with a new instance of the class). But changes do not take effect until/unless you completely re-load new data into the calculation. For example:

&#x20;

// Create EMA with period=20

var myEma = new Liquid.ta.EMA({period: 20});

// Load data

myEma.LoadData( … );

// Change period parameter. Does not have any immediate effect.

myEma.period = 14;

// Values in the calculation do not change until after LoadData() is called again

myEma.LoadData( … );

&#x20;

### **5.2.2.1        The member parameter, and derived prices**

There is one special initialisation parameter, the member. This is applicable when (a) the calculation is value-based rather than bar-based, and (b) you load candle data into the calculation rather than giving it an array just of close prices, or just of highs. It is not applicable to candle-based calculations, or to value-based calculations where you load in an array of values rather than of candles.

&#x20;

The member tells the value-based calculation which value to use from each candle. It can be any of the following, and defaults to c (close price) if not explicitly set. Note that the candle data which you load into the calculation does not need to include derived properties such as the range or median. The calculation automatically works these out from the open/high/low/close if required:

&#x20;

| member    | Description                                                                    |
| --------- | ------------------------------------------------------------------------------ |
| c         | Close price                                                                    |
| o         | Open price                                                                     |
| h         | High price                                                                     |
| l         | Low price                                                                      |
| range     | High minus low                                                                 |
| median    | Average of high and low                                                        |
| typical   | "Typical" price: (high + low + close) / 3                                      |
| weighted  | "Weighed" price: (high + low + close + close) / 4                              |
| ohlc4     | Average of open, high, low, and close                                          |
| change    | Close minus open                                                               |
| abschange | Absolute value of change; converted from negative to positive where applicable |

&#x20;

For example:

&#x20;

// Create an exponential moving average of the high prices of candles

var myEma = new Liquid.ta.EMA({period: 20, member: "h"});

// Load candle data into the calculation (rather than an array just of the highs)

myEma.LoadData(\[{o:1.2342, h: 1.2347, l: 12341, c: 1.2343}, … ]);

&#x20;

### 5.2.3    Loading data into a technical analysis calculation <a href="#id-5.2.4_loading_data" id="id-5.2.4_loading_data"></a>

All the technical analysis calculations are optimised so that they have two functions for loading data:

&#x20;

| Property              | Description                                                                                                                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| LoadData(array)       | Loads or re-loads the full array of data for the calculation. By default, the array should be ordered so that it is newest-first: the most recent item is in #0 and the oldest item is in #length-1 |
| UpdateCurrent(object) | Updates the value for the current bar/value only. You can also pass an array into UpdateCurrent(), but only the first value, \[0], is then used.                                                    |

&#x20;

In other words, LoadData() does a complete load or replacement of the data for the calculation, whereas UpdateCurrent() is a much faster function for doing updates when only the current value is changing. For example, using hourly candles, a full reload/recalculation is only required once per hour, and the thousands of ticks within an hour can be processed much more efficiently by passing just the new price data to UpdateCurrent().

&#x20;

Both LoadData() and UpdateCurrent() have boolean return values indicating whether the new data was successfully processed. Failure can be because your input data was invalid, for example attempting to load an array of numbers rather than of candles into a bar-based calculation. It can also be because you didn’t supply enough data. For example, if you have a 30-period moving average, you must supply at least 30 values in the call to LoadData().

&#x20;

### **5.2.3.1        Loading candle data into a calculation**

As described above, calculations can be either bar-based or value-based. For bar-based calculations, what you pass to LoadData() can be one of two things:

&#x20;

·      An array of candles: objects containing an o, h, l, c, and v (optional, defaults to zero).

·      An object containing a barData object which in turn contains separate arrays for the open, close etc: open\[], close\[], etc. This option means that you can pass in the data object from a user-defined indicator's UDI.onCalculate() function.

&#x20;

For example, to load an array of candle objects:

&#x20;

myATR.LoadData(\[{o:1.2342, h: 1.2347, l: 12341, c: 1.2343}, … ]);

&#x20;

Or, to load in a barData object with the candle values in multiple separate arrays:

&#x20;

myATR.LoadData({

&#x20;      valueCount: 500, // Compulsory: number of items in the arrays

&#x20;      barData: {

&#x20;                  open: \[1.2342, 1.2340, 1.2345, …],

&#x20;                  high: \[ …],

&#x20;                  low: \[ … ],

&#x20;                  close: \[ … ],

&#x20;                  volume: \[ … ] // Volume is optional, and defaults to zero if omitted

&#x20;      }

});

&#x20;

Similarly, in a bar-based calculation, what you pass to UpdateCurrent() must also be a candle object, or an object containing barData:

&#x20;

// When the current candle changes, use UpdateCurrent() with the single current candle object

myATR.UpdateCurrent({o:1.2342, h: 1.2347, l: 12340, c: 1.2340});

&#x20;

With a barData object:

&#x20;

// In UpdateCurrent(), only the first entry in each array is used

myATR.UpdateCurrent({

&#x20;      barData: {

&#x20;                  open: \[1.2342, …],

&#x20;                  high: \[ …],

&#x20;                  low: \[ … ],

&#x20;                  close: \[ … ],

&#x20;                  volume: \[ … ] // Volume is optional, and defaults to zero if omitted

&#x20;      }

});

&#x20;

However, there is a further refinement. LoadData() understands the currentBarUpdateOnly value supplied by a UDI, and automatically turns LoadData() into a faster call to UpdateCurrent() where applicable. For example:

&#x20;

UDI.onCalculate = function(data, output) {

&#x20;      // Create an ATR calculation if we don't already have one

&#x20;      if (!UDI.$myATR) UDI.$myATR = new Liquid.ta.ATR({period: 14});

&#x20;      // Pass the data into the ATR calculation.

&#x20;      // If data.currentBarUpdateOnly is set then the calculation does a fast call to UpdateCurrent()

&#x20;      // rather than a full reload of all the data

&#x20;      UDI.$myATR.LoadData(data);

&#x20;      …

};

&#x20;

### **5.2.3.2        Loading value data into a calculation**

For value-based calculations, you can load in either a candle array or just any array of numbers. If you use a candle array, then you need to set a member value in the calculation's initialisation, specifying which candle property to use such as the median price (automatically derived from the high and low):

&#x20;

// Create an exponential moving average of the median prices of candles

var myEma = new Liquid.ta.EMA({period: 20, member: "median"});

// Load candle data into the calculation

myEma.LoadData(\[{o:1.2342, h: 1.2347, l: 12341, c: 1.2343}, … ]);

&#x20;

Or you can just load into a value-based calculation an array of the median prices, or of any numeric values at all:

&#x20;

myEma.LoadData(\[1.2349, 1.2368, 1.2392, 1.2347, … ]);

&#x20;

When you are updating the current data for a value-based calculation, you can supply either a candle object or just the relevant property from the candle. For example:

&#x20;

myEma.UpdateCurrent({o:1.2342, h: 1.2347, l: 12341, c: 1.2343});  // Update with candle

…

myEma.UpdateCurrent(1.2344);  // Update just with median price

&#x20;

### **5.2.3.3        Loading data in the calculation's initialisation**

Finally, there is another way of loading initial data into a technical analysis calculation: providing a data array/object in the calculation's initialisation. This is simply equivalent to setting up the calculation and then doing LoadData() on that same array/object:

&#x20;

var ma = new Liquid.ta.EMA({

&#x20;      period: 30,

&#x20;      member: "median",

&#x20;      data: \[{o:1.2342, h: 1.2347, l: 12341, c: 1.2343}, … ]

});

&#x20;

### 5.2.4    Reading calculation output

All calculations have a primary output value, but some calculations produce other secondary values as well. For example, the Stochastic Oscillator generates not only a primary value but also a "signal" value (typically represented on a chart as a dotted or dashed line).

&#x20;

All classes in the Liquid.ta library have some standard functions for reading their primary values:

&#x20;

| Function          | Description                                                                                                                                                                                                                    |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| GetValueArray()   | Returns an array of all the primary output values                                                                                                                                                                              |
| GetValue(idx)     | Returns a single output value, using a zero-based index. By default, calculations are indexed newest-first, and #0 is the current, latest value of the calculation. Returns null if the index is not valid (< 0 or >= length). |
| GetCurrentValue() | Shortcut for GetValue(0)                                                                                                                                                                                                       |
| GetLength()       | Get the number of output values. Should always match the number of items in the array passed to LoadData(), unless LoadData() failed and returned false                                                                        |
| length            | Length property; alternative and equivalent to GetLength() function                                                                                                                                                            |
| HasData()         | Shortcut for checking whether a calculation has been initialised. Equivalent to GetLength() > 0                                                                                                                                |
| hasData           | Has-data property; alternative and equivalent to HasData() function                                                                                                                                                            |

&#x20;

For example, testing whether two moving averages have crossed over since the previous bar:

&#x20;

// Create two moving averages for different periods and load the same data into them

var ma1 = new Liquid.ta.EMA({period: 20});

var ma2 = new Liquid.ta.EMA({period: 50});

ma1.Load(myDataArray);

ma2.Load(myDataArray);

// Compare the moving averages in the current bar versus the previous bar

if (ma1.GetValue(0) > ma2.GetValue(0) && ma1.GetValue(1) < ma2.GetValue(1)) {

&#x20;      // MA 1 has crossed above MA 2 during current bar (is now > and was <)

} else if (ma1.GetValue(0) < ma2.GetValue(0) && ma1.GetValue(1) > ma2.GetValue(1)) {

&#x20;      // MA 1 has crossed below MA 2 during current bar (is now < and was >)

} else {

&#x20;      // (No cross)

}

&#x20;

As described above, the number of output values will always be the same as the number of input values in the array passed to LoadData(). But some of the output values may be – usually, will be – null. For example, if you are calculating a 20-period simple moving average, no average can be calculated for the first 19 values. If you supply an array of 1000 input values, then GetLength() on the output will be 1000 but the oldest 19 values – from GetValue(981) to GetValue(999) – will be null.

&#x20;

For calculations which produce more than one output, the details are described below in relation to each calculation. But there is some standard functionality where a secondary value is returned via GetSignalArray(), GetSignalValue(), and GetCurrentSignalValue().

&#x20;

| Function                | Description                                                   |
| ----------------------- | ------------------------------------------------------------- |
| GetSignalArray()        | Returns an array of all the secondary, "signal" output values |
| GetSignalValue(idx)     | Returns a single signal value, using a zero-based index       |
| GetCurrentSignalValue() | Equivalent to GetSignalValue(0)                               |

&#x20;

Some calculations then have further functions for retrieving their output. For example, the Keltner and Bollinger band calculations have GetUpper(idx) and GetLower(idx) functions for returning their upper and lower band values.

&#x20;

### 5.2.5    Indexing order and oldestFirst <a href="#id-5.2.5_indexing_order" id="id-5.2.5_indexing_order"></a>

As described in the previous section, the default for Liquid.ta calculations is that output is indexed with newest values first: the current, latest result is #0. This is simply because a test such as GetValue(0) > GetValue(1) is a less cumbersome and more readable way of checking the current versus previous value than a test such as GetValue(length - 1) > GetValue(length - 2).

&#x20;

This also means that you should _load_ data newest-first. For example:

&#x20;

// The 1.2349 value in array #0 should be the most recent value, not the oldest value

myEma.LoadData(\[1.2349, 1.2368, 1.2392, 1.2347, … ]);

&#x20;

However, if you prefer, all Liquid.ta calculations can be changed so that they are indexed the other way round, with the oldest value in #0 and the newest value in length-1.

&#x20;

You do this by setting oldestFirst:true, either in the initialisation of the calculation or by changing the oldestFirst property at any later point. For example:

&#x20;

// Create a calculation with oldestFirst turned on

var myEma = new Liquid.ta.EMA({period: 20, oldestFirst: true});

// Data should now be loaded oldest-first, not newest-first

myEma.LoadData(\[ …, …, …, 1.2347, 1.2392, 1.2368, 1.2349]);

// Because of oldestFirst, GetCurrentValue() is now equivalent to GetValue(length-1),

// not to GetValue(0)

var currentValue = myEma.GetCurrentValue();

&#x20;

At the risk of creating considerable potential confusion and bugs for yourself, it's possible to load data newest-first (because that is how the framework provides it by default) and then to change the indexing to oldest-first before reading the results:

&#x20;

var myEma = new Liquid.ta.EMA({period: 20});

// oldestFirst is not yet turned on, and data should be loaded newest-first

myEma.LoadData(\[1.2349, 1.2368, 1.2392, 1.2347, … ]);

// Turn on oldestFirst, after loading

myEma.oldestFirst = true;

// Because of oldestFirst, the current latest item is in #length-1

var currentValue = myEma.GetValue(myEma.length - 1);

// And GetCurrentValue() is now equivalent to GetValue(length-1), not to GetValue(0)

var alsoCurrentValue = myEma.GetCurrentValue();

&#x20;

### 5.2.6    Combining arrays

The Liquid.ta library contains a helper function for combining the results from different arrays: Liquid.ta.ArrayCombine(). For example, you can take an array of moving averages and an array of ATR values and add them together.

&#x20;

A simple example of ArrayCombine() is as follows:

&#x20;

// Subtract arr2 from arr1

var arr1 = \[2, 4, 7, 8];

var arr2 = \[5, 3, 7, 2];

var res = Liquid.ta.ArrayCombine("subtract", arr1, arr2);  // Returns \[-3, 1, 0, 6]

&#x20;

ArrayCombine() takes three or more parameters: the operation to perform on the arrays, such as addition or subtraction, and two or more arrays to combine. The output of ArrayCombine() is an array of the combined results (or null if your inputs are not valid). If your input arrays have different lengths, then the length of the output is controlled by the first array you provide.

&#x20;

Valid operations to perform on the arrays are "add", "subtract", "multiply", "divide", "average", "minimum", "maximum", and "percent". (The "percent" mode divides the first array by the second array and multiplies by 100.)

&#x20;

Each "array" parameter can in fact be one of three things:

&#x20;

·      A simple array of values, as in the example above

·      A list of candles plus the value to use from each candle

·      A single fixed value

&#x20;

You define a candle input as follows – an object containing a candles\[] array of the candle objects, plus a member defining which value to use from the candles.

&#x20;

{

&#x20;      member: "median", // Value to use from each candle, including derived properties

&#x20;      candles: \[{o:1.2342, h: 1.2347, l: 12341, c: 1.2343}, …] // Array of candle data

}

&#x20;

For example, you can calculate the range – the difference between high and low – of an array of candles as follows:

&#x20;

// Array of candles to calculate from

var arrCandles = \[{o:1.2342, h: 1.2347, l: 12341, c: 1.2343}, …];

// Subtract the low of each candle from the high of each candle – uses the same arrCandles

// for both parameters, but different members

var ranges = Liquid.ta.ArrayCombine(

&#x20;      "subtract",

&#x20;      {member: "h", candles: arrCandles},

&#x20;      {member: "l", candles: arrCandles}

);

&#x20;

An input parameter can also be a {fixedValue: X}. For example, you can double all the values in an array as follows:

&#x20;

var arr1 = \[2, 4, 7, 8];

var res = Liquid.ta.ArrayCombine("multiply", arr1, {fixedValue: 2}); // Returns \[4, 8, 14, 16]

&#x20;

Putting these examples together, you can do something such as calculating a moving average, calculating ATR, doubling the value of the ATR, and adding that to the moving average – which creates the upper band of a Keltner channel. For example:

&#x20;

// Calculate a moving average and ATR on an array of candles

var candles = \[{o:1.2342, h: 1.2347, l: 12341, c: 1.2343}, …];

var ma = new Liquid.ta.EMA({period: 20, data: candles});

var atr = new Liquid.ta.ATR({period: 10, data: candles});

// Calculate double the ATR, using ArrayCombine()

var arrDoubleATR = Liquid.ta.ArrayCombine("multiply", atr.GetValueArray(), {fixedValue: 2});

// Add double the ATR to the moving average, using ArrayCombine()

var arrKeltnerUpper = Liquid.ta.ArrayCombine("add", ma.GetValueArray(), arrDoubleATR);&#x20;

### 5.2.7    Moving averages <a href="#id-5.2.6_moving_averages" id="id-5.2.6_moving_averages"></a>

The Liquid.ta library provides several classes for creating different types of moving average, such as Liquid.ta.EMA and Liquid.ta.DEMA, listed below (and also widely used in the examples above).

&#x20;

However, the library also provides a way of creating moving-average calculations where the type of moving average is supplied as a variable, using the Liquid.ta.CreateMovingAverage() function.

&#x20;

CreateMovingAverage() takes two parameters: the type of moving average, and the usual initialisation parameters which are then passed into the moving-average calculation in the normal way. For example:

&#x20;

var maType = "ema";

var parameters = {period: 30, member: "typical"};

// Create a type of moving average via the maType variable.

// Ends up being equivalent to:    someMA = new Liquid.ta.EMA(parameters);

var someMA = Liquid.ta.CreateMovingAverage("ema", parameters);

&#x20;

Some calculations in the Liquid.ta library use moving averages internally, and let you change the type of average by setting an initialisation parameter. For example, the Bollinger band calculation defaults to using a simple moving average but can be changed to using any other type of moving average. The Liquid.ta.Bands calculation takes the parameter you provide, or its default, and does an internal call to CreateMovingAverage():

&#x20;

// Change the bands calculation to use a Hull MA instead of the default SMA

var bands = new Liquid.ta.Bands({period: 20, deviations: 2, maType: "hull"});

&#x20;

The types of moving average are as follows. Each has both a numeric and a textual ID, and you can use either:

&#x20;

| Numeric | Textual  | Liquid.ta. | Description                                                 |
| ------- | -------- | ---------- | ----------------------------------------------------------- |
| 0       | sma      | SMA        | Simple moving average                                       |
| 1       | ema      | EMA        | Exponential moving average                                  |
| 4       | vma      | VMA        | Variable moving average                                     |
| 5       | vidya    | VIDYA      | Volatility Index Dynamic Average                            |
| 7       | wma      | WMA        | Weighted moving average                                     |
| 8       | smma     | SMMA       | Smoothed moving average                                     |
| 9       | hull     | HullMA     | Hull moving average                                         |
| 10      | lsma     | LSMA       | Least-squares moving average                                |
| 11      | alma     | ALMA       | Arnaud Legoux moving average                                |
| 12      | dema     | DEMA       | Double exponential moving average                           |
| 13      | tema     | TEMA       | Triple exponential moving average                           |
| 14      | smaofsma | SMAofSMA   | Simple moving average of a simple moving average            |
| 15      | emaofema | EMAofEMA   | Exponential moving average of an exponential moving average |
| 16      | mcginley | McGinleyMA | McGinley dynamic moving average                             |
| 17      | ama      | AMA        | Adaptive moving average                                     |

&#x20;

Giving another version of the example above, you can create a least-squares moving average in two ways:

&#x20;

var ma = new Liquid.ta.LSMA({period: 20});

…

var ma = Liquid.ta.CreateMovingAverage(10, {period: 20});  // 10 = "lsma" = Liquid.ta.LSMA()

&#x20;

All moving averages need a period parameter in their initialisation – as widely used in various examples above.

&#x20;

Some of the types of moving average also require other parameters, though these have standard defaults and you may not want to change them or specify them explicitly:

&#x20;

| Moving average | Extra parameters                                                                                                                                                                                                                                              |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ALMA           | Uses offset and sigma parameters. The standard values are 0.85 and 6.                                                                                                                                                                                         |
| AMA            | Uses fast and slow parameters for smoothing, defaulting to 2 and 10 respectively.                                                                                                                                                                             |
| SMAofSMA       | Uses a subPeriod parameter. The calculation does a moving average using the main period parameter, and then a moving average of that moving average using the subPeriod. If you do not provide a value for subPeriod, then it defaults to the same as period. |
| EMAofEMA       | Same as SMAofSMA                                                                                                                                                                                                                                              |
| VIDYA          | Uses a cmoPeriod parameter, defaulting to the same as the main period                                                                                                                                                                                         |

&#x20;

These extra parameters can be added to the ID of a moving average when creating an instance of the calculation via a variable. For example, the ID "alma:0.9:5" (or "11:0.9:5") means "ALMA, with an offset of 0.9 and sigma of 5". Similarly, "ama:5:15" (or "17:5:15") means "AMA, with a fast period of 5 and slow period of 15".

&#x20;

### 5.2.8    List of technical analysis calculations

Currently available technical analysis calculations are as follows. This list may be extended in future releases of Liquid Charts Pro. Many other common calculations can be easily derived from the types here. For example, an "Awesome Oscillator" is simply the difference between the 5- and 34-period simple moving averages of the median price. It can be calculated using Liquid.ta.MACD:

&#x20;

// The signal and smoothing values are irrelevant; only need/use the main "MACD" value for AO

var ao = new Liquid.ta.MACD({fast: 5, slow: 34, member: "median", maType: "sma"});

&#x20;

The following list does not include moving averages, such Liquid.ta.EMA or Liquid.ta.HullMA. The moving averages are listed separately above.

&#x20;

The list shows the class within Liquid.ta, such as Liquid.ta.Slope(), and whether the calculation is bar-based or value-based.

&#x20;

| Calculation class | Bar/value-based | Description                                                                                               |
| ----------------- | --------------- | --------------------------------------------------------------------------------------------------------- |
| ADX               | Bar             | Directional movement system                                                                               |
| AO                | Value           | Awesome Oscillator                                                                                        |
| Aroon             | Bar             | Aroon                                                                                                     |
| AroonOsc          | Bar             | Aroob oscillator                                                                                          |
| ASI               | Bar             | Accumulative swing index                                                                                  |
| ATR               | Bar             | Average true range                                                                                        |
| Bands             | Value           | Bollinger® bands: a moving average plus/minus standard deviation                                          |
| BearBull          | Bar             | Bear/bull power – one candle property minus an average of another candle property                         |
| CCI               | Value           | Commodity channel index                                                                                   |
| CFO               | Value           | Chande forecast oscillator                                                                                |
| ChaikinVolatility | Bar             | Chaikin Volatility                                                                                        |
| CMF               | Bar             | Chaikin Money Flow                                                                                        |
| CMO               | Value           | Chande momentum oscillator                                                                                |
| COG               | Value           | Centre of gravity                                                                                         |
| CoppockCurve      | Value           | Coppock curve                                                                                             |
| DerivedPrice      | Bar             | Derived prices from candle data                                                                           |
| DPO               | Value           | Detrended price oscillator                                                                                |
| EFI               | Bar             | Elder force index                                                                                         |
| EFT               | Value           | Ehler Fisher transform                                                                                    |
| EMT               | Bar             | Elder market thermometer                                                                                  |
| EOM               | Bar             | EaseOfMovement                                                                                            |
| Envelope          | Value           | Envelopes around a moving average: the average plus/minus a fixed percentage                              |
| GRI               | Bar             | Gopalakrishnan range index                                                                                |
| Highest           | Value           | Highest of the last N values                                                                              |
| HV                | Value           | Historical volatility                                                                                     |
| IMI               | Bar             | Intraday momentum index                                                                                   |
| Keltner           | Bar             | Keltner channel (and STARC): moving average plus/minus ATR                                                |
| KVO               | Bar             | Klinger volume oscillator                                                                                 |
| Lowest            | Value           | Lowest of the last N values                                                                               |
| LRF               | Value           | Linear forecast                                                                                           |
| LRI               | Value           | Linear intercept                                                                                          |
| MACD              | Value           | Moving-average convergence/divergence: difference between two averages, with smoothing of that difference |
| MAOscillator      | Value           | Oscillator of a moving average                                                                            |
| MassIndex         | Bar             | Mass index                                                                                                |
| MktFacilitation   | Bar             | Market facilitation index                                                                                 |
| Momentum          | Value           | Momentum oscillator                                                                                       |
| MoneyFlowIndex    | Bar             | Money Flow Index oscillator                                                                               |
| Performance       | Value           | Performance index                                                                                         |
| PGO               | Bar             | Pretty Good oscillator                                                                                    |
| PO                | Value           | Price oscillator                                                                                          |
| PSAR              | Bar             | Parabolic stop and reverse                                                                                |
| QStick            | Bar             | QStick                                                                                                    |
| Rainbox           | Value           | Rainbow oscillator                                                                                        |
| Rank              | Value           | Ranking                                                                                                   |
| RAVI              | Value           | RAVI                                                                                                      |
| RSI               | Value           | Relative strength index                                                                                   |
| RVI               | Bar             | Relative vigor index                                                                                      |
| RWI               | Bar             | Random walk index                                                                                         |
| RSquared          | Value           | R-squared                                                                                                 |
| Slope             | Value           | Slope of linear regression                                                                                |
| Stdev             | Value           | Standard deviation                                                                                        |
| SMI               | Bar             | Stochastic momentum index                                                                                 |
| STC               | Value           | Schaff trend cycle                                                                                        |
| Stochastic        | Bar/Value       | Stochastic oscillator                                                                                     |
| StochRSI          | Value           | Stochastic RSI                                                                                            |
| Sum               | Value           | Sum of the last N items                                                                                   |
| SwingIndex        | Bar             | Swing index                                                                                               |
| TMF               | Bar             | Twiggs money flow                                                                                         |
| TRIX              | Value           | TRIX oscillator                                                                                           |
| TrueRange         | Bar             | True range                                                                                                |
| UO                | Bar             | Ultimate oscillator                                                                                       |
| VHF               | Value           | Vertical horizontal filter                                                                                |
| VolumeIndex       | Bar             | Positive and negative volume index                                                                        |
| WAD               | Bar             | Williams accumulation/distribution                                                                        |
| WilliamsPctR      | Bar             | Williams %R                                                                                               |

&#x20;

**Accumulative Swing Index –** Liqui&#x64;**.ta.ASI**

The Liquid.ta.ASI class calculates accumulative swing index – simply the running total of the swing index. It is a bar-based calculation, and requires candle data as an input. Parameters are the same as for the swing index:

&#x20;

| Parameter | Description                             |
| --------- | --------------------------------------- |
| limit     | Movement limit value, defaulting to 0.5 |

&#x20;

Note: because it is a running total, the value changes depending on the starting point/length of candle history. It is therefore mostly useful as a relative measure, not as an absolute value.

&#x20;

**ADX –** Liqui&#x64;**.ta.ADX**

The Liquid.ta.ADX class calculates the directional movement system, ADX. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

The primary output value – GetValue() – of the calculation is the ADX. The calculation also provides the DI+ and DI- values:

&#x20;

| Parameter             | Description                        |
| --------------------- | ---------------------------------- |
| GetPositiveValue(idx) | Gets the DI+ value at index #idx   |
| GetNegativeValue(idx) | Gets the DI- value at index #idx   |
| GetPositiveArray()    | Returns an array of all DI+ values |
| GetNegativeArray()    | Returns an array of all DI- values |

&#x20;

**Aroon –** Liqui&#x64;**.ta.Aroon**

The Liquid.ta.Aroon class calculates the Aroon indicator: a measure of the number of bars since the high and low of a period (expressed on a scale of 0 to 100). It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

Note: the Liquid.ta.Aroon is exceptional because the standard GetValue() function returns the value of the Aroon oscillator, not of the Aroon itself. To get the high and low values of the Aroon, use the following functions:

&#x20;

| Parameter              | Description                              |
| ---------------------- | ---------------------------------------- |
| GetAroonUpArray()      | Returns an array of all the high values  |
| GetAroonDownArray()    | Returns an array of all the low values   |
| GetAroonUpValue(idx)   | Returns the high value at bar index #idx |
| GetAroonDownValue(idx) | Returns the low value at bar index #idx  |

&#x20;

**Aroon oscillator –** Liqui&#x64;**.ta.AroonOsc**

The Liquid.ta.AroonOsc class calculates the oscillator of the Aroon indicator: its high value minus its low value (leading to output in the range -100 to +100). It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Average True Range –** Liqui&#x64;**.ta.ATR**

The Liquid.ta.ATR class calculates average true range (a rolling average of true range). It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                                                            |
| --------- | ---------------------------------------------------------------------- |
| period    | Rolling period for the calculation                                     |
| maType    | Type of moving average. Defaults to a simple moving average (sma / 0). |

&#x20;

**Awesome Oscillator –** Liqui&#x64;**.ta.AO**

The Liquid.ta.AO class calculates the Awesome Oscillator: the difference between two moving averages (therefore similar to the main value of MACD). It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. For candle-based calculations, the default member for the Awesome Oscillator is the typical price, not the close price. Other parameters are as follows:

&#x20;

| Parameter | Description                                                                                           |
| --------- | ----------------------------------------------------------------------------------------------------- |
| fast      | Period for fast moving average (defaults to 5)                                                        |
| slow      | Period for slow moving average (defaults to 34)                                                       |
| maType    | Type of moving average for the fast and slow averages. Defaults to a simple moving average (sma / 0). |

&#x20;

**Bear/Bull power –** Liqui&#x64;**.ta.BearBull**

The Liquid.ta.BearBull class calculates one candle value minus an average of another candle value. It is normally used to calculate "bull power", the high minus an average of closes, or "bear power", the low minus an average of closes, but can be used with any pair of candle properties. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                                                                                                                                                               |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| member    | Member of each candle to use – normally either h for the high (for "bull power") or l for the low (for "bear power"), but can be any candle data including derived prices |
| averageOf | Member of each candle from which to calculate an average. Defaults to the close (c)                                                                                       |
| period    | Rolling period for the average                                                                                                                                            |
| maType    | Type of moving average. Defaults to an exponential moving average (ema / 1).                                                                                              |

&#x20;

**Bollinger® bands –** Liqui&#x64;**.ta.Bands**

The Liquid.ta.Bands class calculates Bollinger bands: a moving average plus/minus a multiple of standard deviation. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter  | Description                                                            |
| ---------- | ---------------------------------------------------------------------- |
| period     | Rolling period for the calculation                                     |
| deviations | Multiple of standard deviation (typical value is 2)                    |
| maType     | Type of moving average. Defaults to a simple moving average (sma / 0). |

&#x20;

The primary output value – GetValue() – of the calculation is the moving average. The calculation also sets the signal value – GetSignalValue() – to the standard deviation. And the calculation provides some helper functions for getting the upper and lower bands:

&#x20;

| Parameter       | Description                                                                                             |
| --------------- | ------------------------------------------------------------------------------------------------------- |
| GetUpper(idx)   | Gets the upper band at index #idx: the main value plus the deviations parameter times the signal value  |
| GetLower(idx)   | Gets the lower band at index #idx: the main value minus the deviations parameter times the signal value |
| GetUpperArray() | Returns an array of all upper-band values                                                               |
| GetLowerArray() | Returns an array of all lower-band values                                                               |

&#x20;

**Centre of Gravity –** Liqui&#x64;**.ta.COG**

The Liquid.ta.COG class calculates Centre of Gravity. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Commodity channel index –** Liqui&#x64;**.ta.CCI**

The Liquid.ta.CCI class calculates the commodity channel index. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Chaikin Money Flow –** Liqui&#x64;**.ta.CMF**

The Liquid.ta.CMFclass calculates Chaikin money flow. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Chaikin volatility –** Liqui&#x64;**.ta.ChaikinVolatility**

The Liquid.ta.ChaikinVolatility class calculates Chaikin volatility. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter       | Description                                                                                 |
| --------------- | ------------------------------------------------------------------------------------------- |
| period          | Rolling period for the calculation                                                          |
| maType          | Type of moving average, for smoothing. Defaults to an exponential moving average (ema / 1). |
| smoothingPeriod | Smoothing period, for the moving average                                                    |

&#x20;

**Chande forecast oscillator –** Liqui&#x64;**.ta.CFO**

The Liquid.ta.CFO class calculates the Chande forecast oscillator. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Chande momentum oscillator –** Liqui&#x64;**.ta.CMO**

The Liquid.ta.CMO class calculates the Chande momentum oscillator. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Coppock curve –** Liqui&#x64;**.ta.CoppockCurve**

The Liquid.ta.CoppockCurve class calculates the Coppock curve. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Derived price –** Liqui&#x64;**.ta.DerivedPrice**

The Liquid.ta.DerivedPrice simply returns a derived price such as "median" or "typical" from an array of candles. It is therefore a bar-based calculation, and it has no parameters apart from the derived member to return. For example, calculating a list of median prices from a candle array:

&#x20;

var medians = new Liquid.ta.DerivedPrice({member: "median", data: \[{o: 1.2456, …}, { … }]);

&#x20;

**Detrended price oscillator –** Liqui&#x64;**.ta.DPO**

The Liquid.ta.DPO class calculates the Detrended Price Oscillator. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                                                                  |
| --------- | ---------------------------------------------------------------------------- |
| period    | Rolling period for the calculation                                           |
| maType    | Type of moving average. Defaults to an exponential moving average (ema / 1). |

&#x20;

**Ease of movement –** Liqui&#x64;**.ta.EOM**

The Liquid.ta.EOM class calculates the ease of movement index. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                                                                  |
| --------- | ---------------------------------------------------------------------------- |
| period    | Rolling period for the moving average                                        |
| maType    | Type of moving average. Defaults to an exponential moving average (ema / 1). |

&#x20;

**Ehler Fisher transform –** Liqui&#x64;**.ta.EFT**

The Liquid.ta.EFT class calculates the Ehler Fisher transform. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Elder Market Thermometer –** Liqui&#x64;**.ta.EMT**

The Liquid.ta.EMT class calculates the Elder market thermometer, and a moving average of the thermometer. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                                                                  |
| --------- | ---------------------------------------------------------------------------- |
| period    | Rolling period for the moving average                                        |
| maType    | Type of moving average. Defaults to an exponential moving average (ema / 1). |

&#x20;

The primary output values – GetValue() etc – contain the thermometer. The signal values – GetSignalValue() etc – contain the moving average.

&#x20;

**Elder Force Index –** Liqui&#x64;**.ta.EFI**

The Liquid.ta.EFI class calculates the Elder force index, and a moving average of the index. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                                                                  |
| --------- | ---------------------------------------------------------------------------- |
| period    | Rolling period for the moving average                                        |
| maType    | Type of moving average. Defaults to an exponential moving average (ema / 1). |

&#x20;

The primary output values – GetValue() etc – contain the force index. The signal values – GetSignalValue() etc – contain the moving average.

&#x20;

**Envelope around a moving average –** Liqui&#x64;**.ta.Envelope**

The Liquid.ta.Envelope class calculates the "envelope" around a moving average: the average plus/minus a fixed percentage. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter   | Description                                                                                                                         |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| period      | Rolling period for the calculation                                                                                                  |
| bandPercent | Fixed percentage for the plus/minus envelope (defaults to 0.1 – in other words, addition/subtraction of the moving average x 0.001) |
| maType      | Type of moving average. Defaults to a simple moving average (sma / 0).                                                              |

&#x20;

The primary output value – GetValue() – of the calculation is the moving average. The calculation also sets the signal value – GetSignalValue() – to the size of the envelope: each moving average multiplied by the bandPercent divided by 100. And the calculation provides some helper functions for getting the upper and lower bands:

&#x20;

| Parameter       | Description                                                                                             |
| --------------- | ------------------------------------------------------------------------------------------------------- |
| GetUpper(idx)   | Gets the upper band at index #idx: the main value plus the deviations parameter times the signal value  |
| GetLower(idx)   | Gets the lower band at index #idx: the main value minus the deviations parameter times the signal value |
| GetUpperArray() | Returns an array of all upper-band values                                                               |
| GetLowerArray() | Returns an array of all lower-band values                                                               |

&#x20;

**Fractal bands –** Liqui&#x64;**.ta.FractalBands**

The Liquid.ta.FractalBands class calculates fractal bands: the high and low from the last confirmed fractal. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                                                                                                                         |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| period    | Number of bars required to form a fractal; the number either side of the mid-point. Defaults to 2, for a standard five-bar battern. |

&#x20;

The calculation sets the primary output – GetValue() etc – to the high values. The signal values – GetSignalValue() etc – contain the low values.

&#x20;

The calculation only uses "confirmed" fractals, starting from the time at which a fractal was known to be confirmed. For example, with the standard period:2, when a new high forms that will only become the value of the band 3 bars later.

&#x20;

**Gopalakrishnan range index –** Liqui&#x64;**.ta.GRI**

The Liquid.ta.GRI class calculates the Gopalakrishnan range index. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Highest of the last N values –** Liqui&#x64;**.ta.Highest**

The Liquid.ta.Highest class calculates a rolling series of the highest of the last N values. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

In addition to putting the rolling highest values into the main output – GetValue() etc – the calculation also puts the relative offset of the highest value into the signal output – GetSignalValue(). For example, a signal value of 1 means that the highest value is the preceding one.

&#x20;

**Historical Volatility –** Liqui&#x64;**.ta.HV**

The Liquid.ta.HV class calculates historical volatility: the standard deviation of the changes in a value, multiplied by a factor such as 260 to create an annualised figure. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter  | Description                                              |
| ---------- | -------------------------------------------------------- |
| period     | Rolling period for the calculation                       |
| deviations | Number of standard deviations to calculate               |
| factor     | Factor (calculation uses the square root of this number) |

&#x20;

**Intraday momentum index –** Liqui&#x64;**.ta.IMI**

The Liquid.ta.IMI class calculates the intraday momentum index. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Keltner channel and STARC –** Liqui&#x64;**.ta.Keltner**

The Liquid.ta.Keltner class calculates a Keltner channel: a moving average plus/minus ATR. Changing the default maType from EMA to SMA in effect turns the Keltner channel into a Stoller channel (STARC). It is a bar-based calculation (because it uses ATR), and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter   | Description                                                                                                          |
| ----------- | -------------------------------------------------------------------------------------------------------------------- |
| maPeriod    | Period for the moving average which forms the centre of the channel (defaulting to 20)                               |
| maType      | Type of moving average. Defaults to an exponential moving average (ema / 1).                                         |
| atrPeriod   | Period for the ATR calculation (doesn't have to be same as the moving-average period, and separately defaults to 10) |
| atrMultiple | Multiple of the ATR value for calculating the upper and lower bands (defaults to 2)                                  |

&#x20;

The primary output value – GetValue() – of the calculation is the moving average. The calculation also sets the signal value – GetSignalValue() – to the ATR value. And the calculation provides some helper functions for getting the upper and lower bands:

&#x20;

| Parameter       | Description                                                                                              |
| --------------- | -------------------------------------------------------------------------------------------------------- |
| GetUpper(idx)   | Gets the upper band at index #idx: the main value plus the atrMultiple parameter times the signal value  |
| GetLower(idx)   | Gets the lower band at index #idx: the main value minus the atrMultiple parameter times the signal value |
| GetUpperArray() | Returns an array of all upper-band values                                                                |
| GetLowerArray() | Returns an array of all lower-band values                                                                |

&#x20;

**Klinger volume oscillator –** Liqui&#x64;**.ta.KVO**

The Liquid.ta.KVO class calculates the Klinger volume oscillator. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter     | Description                                                                                                 |
| ------------- | ----------------------------------------------------------------------------------------------------------- |
| fast          | Period for fast moving average (e.g. 12)                                                                    |
| slow          | Period for slow moving average (e.g. 26)                                                                    |
| signal        | Signal/smoothing period (e.g. 9)                                                                            |
| maType        | Type of moving average for the fast and slow averages. Defaults to an exponential moving average (ema / 1). |
| smoothingType | Type of moving average for the smoothing of the differences. Defaults to a simple moving average (sma / 0). |

&#x20;

The oscillator sets both primary and signal outputs.

&#x20;

**Linear regression forecast –** Liqui&#x64;**.ta.LRF**

The Liquid.ta.LRF class calculates linear forecast. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

In addition to the primary output, the class also sets the signal values to the slope of the linear regression (same as Liquid.ta.Slope).

&#x20;

**Linear regression intercept –** Liqui&#x64;**.ta.LRI**

The Liquid.ta.LRI class calculates linear intercept. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

In addition to the primary output, the class also sets the signal values to the slope of the linear regression (same as Liquid.ta.Slope).

&#x20;

**Lowest of the last N values –** Liqui&#x64;**.ta.Lowest**

The Liquid.ta.Lowest class calculates a rolling series of the lowest of the last N values. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

In addition to putting the rolling lowest values into the main output – GetValue() etc – the calculation also puts the relative offset of the lowest value into the signal output – GetSignalValue(). For example, a signal value of 1 means that the lowest value is the preceding one.

&#x20;

**MACD –** Liqui&#x64;**.ta.MACD**

The Liquid.ta.MACD class calculates moving average convergence/divergence. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter     | Description                                                                                                 |
| ------------- | ----------------------------------------------------------------------------------------------------------- |
| fast          | Period for fast moving average (e.g. 12)                                                                    |
| slow          | Period for slow moving average (e.g. 26)                                                                    |
| signal        | Signal/smoothing period (e.g. 9)                                                                            |
| maType        | Type of moving average for the fast and slow averages. Defaults to an exponential moving average (ema / 1). |
| smoothingType | Type of moving average for the smoothing of the differences. Defaults to a simple moving average (sma / 0). |

&#x20;

The MACD has three outputs:

&#x20;

·      The primary value (GetValue): the difference between the fast and slow moving averages

·      The signal value (GetSignalValue): the smoothed moving average of the differences

·      "Histogram" (so named because that's how it's usually drawn on a chart): the difference minus the smoothing of the difference.

&#x20;

In addition to the usual functions for getting the primary and signal values, the Liquid.ta.MACD has further helpers for getting the histogram values:

&#x20;

| Parameter              | Description                                                                                        |
| ---------------------- | -------------------------------------------------------------------------------------------------- |
| GetHistogramValue(idx) | Returns the histogram value at index #idx                                                          |
| GetHistogramArray()    | Returns an array of all the histogram values, similar to GetValueArray() and GetSignalValueArray() |

&#x20;

**Market facilitation index –** Liqui&#x64;**.ta.MktFacilitation**

The Liquid.ta.MktFacilitation class calculates the market facilitiation index: the high-low range of a bar divided by volume. It is a bar-based calculation, and requires candle data as an input. The calculation has no parameters.

&#x20;

**Mass index –** Liqui&#x64;**.ta.MassIndex**

The Liquid.ta.MassIndex class calculates mass index. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                             |
| --------- | --------------------------------------- |
| period    | Period for totalling, typically 25      |
| subperiod | Period for moving averages, typically 9 |

&#x20;

**Momentum oscillator –** Liqui&#x64;**.ta.Momentum**

The Liquid.ta.Momentum class calculates the momentum oscillator: simply the change in value compared to N periods ago. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                           |
| --------- | ------------------------------------- |
| period    | Rolling period for the moving average |

&#x20;

**Money Flow Index –** Liqui&#x64;**.ta.MoneyFlowIndex**

The Liquid.ta.MoneyFlowIndex class calculates the Money Flow index oscillator. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Period for totalling, typically 25 |

&#x20;

**Moving average oscillator –** Liqui&#x64;**.ta.MAOscillator**

The Liquid.ta.MAOscillator class calculates the oscillator of a moving average: the change since the previous value. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                           |
| --------- | ------------------------------------- |
| period    | Rolling period for the moving average |
| maType    | Type of moving average                |

&#x20;

**On-balance volume –** Liqui&#x64;**.ta.OBV**

The Liquid.ta.OBV class calculates on-balance volume: addition or subtraction of current volume to/from previous volume depending on whether a candle metric (usually, the close price) has risen or fallen. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                                         |
| --------- | --------------------------------------------------- |
| member    | Candle member to compare. Defaults to the close (c) |

&#x20;

Note: the absolute current value of the OBV changes depending on the starting point/length of candle history. It is therefore mostly useful as a relative measure, not as an absolute value.

&#x20;

**Parabolic stop and reverse –** Liqui&#x64;**.ta.PSAR**

The Liquid.ta.PSAR class calculates Parabolic Stop and Reverse. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description      |
| --------- | ---------------- |
| minAF     | Defaults to 0.02 |
| maxAF     | Defaults to 2    |

&#x20;

**Performance –** Liqui&#x64;**.ta.Performance**

The Liquid.ta.Performance class calculates performance: the percentage change of each item compared to the initial starting value (not compared to each previous value). It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. The calculation has one optional parameter.

&#x20;

| Parameter | Description                                                                                                               |
| --------- | ------------------------------------------------------------------------------------------------------------------------- |
| initial   | If not zero (or null), the initial value to compare all the values to. If omitted, the first value in the series is used. |

&#x20;

**Pretty Good oscillator –** Liqui&#x64;**.ta.PGO**

The Liquid.ta.PGO class calculates the Pretty Good oscillator. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Price Oscillator –** Liqui&#x64;**.ta.PO**

The Liquid.ta.PO class calculates the "price oscillator": the difference between fast and slow moving averages divided into the slow moving average. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                                                                                                 |
| --------- | ----------------------------------------------------------------------------------------------------------- |
| fast      | Period for fast moving average (e.g. 12)                                                                    |
| slow      | Period for slow moving average (e.g. 26)                                                                    |
| maType    | Type of moving average for the fast and slow averages. Defaults to an exponential moving average (ema / 1). |

&#x20;

**QStick –** Liqui&#x64;**.ta.QStick**

The Liquid.ta.QStick class calculates QStick – a moving average of the open-close change of each bar. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Rainbow oscillator –** Liqui&#x64;**.ta.Rainbow**

The Liquid.ta.Rainbow class calculates the Rainbow oscillator. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                                                            |
| --------- | ---------------------------------------------------------------------- |
| period    | Number of iterations for the rainbow                                   |
| maType    | Type of moving average. Defaults to a simple moving average (sma / 0). |

&#x20;

**Random Walk Index –** Liqui&#x64;**.ta.RWI**

The Liquid.ta.RWI class calculates the Random Walk index. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

The primary output value – GetValue() – of the calculation is the high values. The calculation puts the low values into the signal values – GetSignalValue() etc.

&#x20;

**Rank –** Liqui&#x64;**.ta.Rank**

The Liquid.ta.Rank class ranks each value among the rolling group of the last N items, largest/highest first. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |
| mode      | See below                          |

&#x20;

The mode can be any of the following, defaulting to "percentile":

&#x20;

| mode:X     | Description                                                                                                                                                            |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| percentile | Percentile ranking. Larger values have higher rankings; the largest value in a series will have percentile rank=100                                                    |
| absolute   | Absolute ranking. Larger values have higher rankings. For example, with period=14, the largest item in a series will have rank=14 (and the smallest will have rank=1). |
| quartile   | Quartile ranking. Larger values have lower rankings; the largest item in a series will have quartile rank=1                                                            |
| decile     | Decile ranking. Larger values have lower rankings; the largest item in a series will have decile rank=1                                                                |

&#x20;

**Rate of change –** Liqui&#x64;**.ta.ROC**

The Liquid.ta.ROC class calculates rate of change: the difference between the current value versus N bars ago, divided into the value N bars ago, times 100. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**RAVI –** Liqui&#x64;**.ta.RAVI**

The Liquid.ta.RAVI class calculates RAVI: very similar to the Price Oscillator except that the numerator in the calculation is the absolute difference between the averages rather than a directional positive/negative. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                                                                                                 |
| --------- | ----------------------------------------------------------------------------------------------------------- |
| fast      | Period for fast moving average (e.g. 12)                                                                    |
| slow      | Period for slow moving average (e.g. 26)                                                                    |
| maType    | Type of moving average for the fast and slow averages. Defaults to an exponential moving average (ema / 1). |

&#x20;

**Relative Strength Index –** Liqui&#x64;**.ta.RSI**

The Liquid.ta.RSI class calculates the Relative Strength Index oscillator. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Relative Vigor Index –** Liqui&#x64;**.ta.RVI**

The Liquid.ta.RVI class calculates the Relative Vigor Index oscillator. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

The primary output value – GetValue() – of the calculation is the RVI. The calculation also sets the signal value – GetSignalValue() – to the smoothed average of the RVI.

&#x20;

**R-squared –** Liqui&#x64;**.ta.RSquared**

The Liquid.ta.RSquared class calculates rolling R-squared of a series of values (comparing the values to their position index). It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Schaff trend cycle –** Liqui&#x64;**.ta.STC**

The Liquid.ta.STC class calculates the Schaff trend cycle. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter       | Description                                                                                                 |
| --------------- | ----------------------------------------------------------------------------------------------------------- |
| fast            | Period for fast moving average (e.g. 12)                                                                    |
| slow            | Period for slow moving average (e.g. 26)                                                                    |
| smoothingPeriod | Smoothing period (e.g.109)                                                                                  |
| maType          | Type of moving average for the fast and slow averages. Defaults to an exponential moving average (ema / 1). |

&#x20;

**Slope of linear regression –** Liqui&#x64;**.ta.Slope**

The Liquid.ta.Slope class calculates the slope of linear regression of the last N rolling items. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Standard deviation –** Liqui&#x64;**.ta.Stdev**

The Liquid.ta.Stdev class calculates the standard deviation of the last N rolling items. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter  | Description                                                  |
| ---------- | ------------------------------------------------------------ |
| period     | Rolling period for the calculation                           |
| deviations | Multiple of the standard deviation to return. Defaults to 1. |

&#x20;

**Stochastic momentum index –** Liqui&#x64;**.ta.SMI**

The Liquid.ta.SMI class calculates the Stochastic momentum index. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter        | Description                                                                                     |
| ---------------- | ----------------------------------------------------------------------------------------------- |
| kPeriod          | Period for the %K values (scanning bar high and lows)                                           |
| kSmoothing       | First smoothing period                                                                          |
| kDoubleSmoothing | Second smoothing period                                                                         |
| maType           | Type of moving average for the smoothing. Defaults to a simple moving average (sma / 0).        |
| dPeriod          | Period for the %D signal values                                                                 |
| maTypeD          | Type of moving average for the %D signal values. Defaults to a simple moving average (sma / 0). |

&#x20;

The primary output – GetValue() etc – is the %K values. The signal output – GetSignalValue() etc – contains the %D values.

&#x20;

**Stochastic oscillator –** Liqui&#x64;**.ta.Stochastic**

The Liquid.ta.Stochastic class calculates the Stochastic oscillator. It is unusual because it can be either bar-based or value-based depending on the mode. Parameters are as follows:

&#x20;

| Parameter | Description                                                                                                                                                                                                                                        |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| mode      | Type of calculation: either "hl" (high-low) or "value", defaulting to "hl". In high-low mode, the calculation is bar-based and requires candle data. In "value" mode, the calculation is value-based and can be calculated on any array of values. |
| kPeriod   | Period for the %K values                                                                                                                                                                                                                           |
| dPeriod   | Period for the %D values                                                                                                                                                                                                                           |
| slowing   | Slowing/smoothing which is applied to the %K values                                                                                                                                                                                                |
| maType    | Type of moving average for the smoothing. Defaults to a simple moving average (sma / 0).                                                                                                                                                           |

&#x20;

The primary output – GetValue() etc – is the %K values. The signal output – GetSignalValue() etc – contains the %D values.

&#x20;

**Stochastic RSI –** Liqui&#x64;**.ta.StochRSI**

The Liquid.ta.StochRSI class calculates the Stochastic oscillator of RSI values. It is a value-based calculation because RSI is value-based. Parameters and output are the same as for Liquid.ta.Stochastic, with the addition of an extra parameter for specifying the RSI period:

&#x20;

| Parameter | Description                                                                              |
| --------- | ---------------------------------------------------------------------------------------- |
| kPeriod   | Period for the %K values                                                                 |
| dPeriod   | Period for the %D values                                                                 |
| slowing   | Slowing/smoothing which is applied to the %K values                                      |
| maType    | Type of moving average for the smoothing. Defaults to a simple moving average (sma / 0). |
| rsiPeriod | Number of bars for the RSI calculation                                                   |

&#x20;

**Sum –** Liqui&#x64;**.ta.Sum**

The Liquid.ta.Sum class calculates a rolling total of the last N values (like a simple moving average, but without doing the division by the number of values). It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Swing index –** Liqui&#x64;**.ta.SwingIndex**

The Liquid.ta.SwingIndex class calculates the Swing index. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                             |
| --------- | --------------------------------------- |
| limit     | Movement limit value, defaulting to 0.5 |

&#x20;

**TRIX –** Liqui&#x64;**.ta.Trix**

The Liquid.ta.TRIX class calculates the TRIX Oscillator: the change in a triple-smoothed exponential moving average. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**True range –** Liqui&#x64;**.ta.TrueRange**

The Liquid.ta.TrueRange class calculates "true range": the maximum of the high-low range of the current bar, the current high minus the previous close, and the current low minus the previous close. It is a bar-based calculation, and requires candle data as an input. It has no parameters.

&#x20;

**Twiggs Money Flow –** Liqui&#x64;**.ta.TMF**

The Liquid.ta.TMF class calculates Twiggs money flow. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                                                                  |
| --------- | ---------------------------------------------------------------------------- |
| period    | Rolling period for the calculation                                           |
| maType    | Type of moving average. Defaults to an exponential moving average (ema / 1). |

&#x20;

**Ultimate oscillator –** Liqui&#x64;**.ta.UO**

The Liquid.ta.UO class calculates the Ultimate oscillator. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Vertical horizontal filter –** Liqui&#x64;**.ta.VHF**

The Liquid.ta.VHF class calculates the vertical horizontal filter. It is a value-based calculation, and can be applied to any series of values including the output of another Liquid.ta calculation. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

**Volume Index –** Liqui&#x64;**.ta.VolumeIndex**

The Liquid.ta.VolumeIndex class calculates positive and negative volume index. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                              |
| --------- | ---------------------------------------- |
| member    | Candle member. Defaults to the close (c) |

&#x20;

The primary output values – GetValue() etc – are set to the positive volume index. The signal values – GetSignalValue() etc – are set to the negative volumed index.

&#x20;

Note: the absolute current value of the indexes changes depending on the starting point/length of candle history. It is therefore mostly useful as a relative measure, not as an absolute value.

&#x20;

**Williams Accumulation Distribution –** Liqui&#x64;**.ta.WAD**

The Liquid.ta.WAD class calculates Williams accumulation/distribution. It is a bar-based calculation, and requires candle data as an input. The calculation has no parameters.

&#x20;

Note: the absolute current value of the WAD changes depending on the starting point/length of candle history. It is therefore mostly useful as a relative measure, not as an absolute value.

&#x20;

**Williams %R –** Liqui&#x64;**.ta.WilliamsPctR**

The Liquid.ta.WilliamsPctR class calculates the Williams %R value. It is a bar-based calculation, and requires candle data as an input. Parameters are as follows:

&#x20;

| Parameter | Description                        |
| --------- | ---------------------------------- |
| period    | Rolling period for the calculation |

&#x20;

&#x20;

&#x20;

&#x20;

&#x20;

&#x20;

&#x20;

&#x20;
