# 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 Sway.CandleStore object

· The SWAY.ta library of technical analysis calculations

### 5.1 The SWAY.CandleStore object

The SWAY.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 SWAY.CandleStore({

// Automatically calculate two moving averages

ta: [

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

new SWAY.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 SWAY.CandleStore class. For example:

// Create candle store

var myCandleStore = new SWAY.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 SWAY.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):

### 5.1.2 Loading data into the candle store

There are three ways of loading data into an SWAY.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 SWAY.CandleStore. For example:

Framework.$myCandleStore = new SWAY.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:

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 SWAY.CandleStore();

var candleRequest = { … some candle request … };

// Pass the response(s) from RequestCandles() directly into the SWAY.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 SWAY.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 SWAY.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 SWAY.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 SWAY.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 SWAY.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.

### 5.1.3 Events in the candle store

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.

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

myCandleStore.OnLoad = function(candleStore) {

// Store can be accessed either via the myCandleStore variable

// or via the candleStore parameter to the event handler

};

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

// Create candle store

var myCandleStore = new Sway.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) { … };

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

var myCandleStore = new Sway.CandleStore({

OnLoad: function() { … },

OnCurrentCandleChange: function() { … },

etc

});

### 5.1.4 Reading data from the candle store

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

myCandleStore.LoadCandles(…);

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

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.

The store provides some simple properties for checking its contents:

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.

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.

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:

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.

You can also look up candles by time:

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:

· 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.

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.)

### 5.1.5 Derived properties of each candle

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.

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

### 5.1.6 Technical analysis calculations in the candle store

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

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):

var myCandleStore = new Sway.CandleStore({

// Automatically add a moving average and ATR

ta: [

new Sway.ta.EMA({period: 20, member: "h"}), // EMA of high (.h) price

new Sway.ta.ATR({period: 14}) // ATR

],

… further initialisation settings

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:

var myCandleStore = new Sway.CandleStore({

// Single TA object

ta: new Sway.ta.EMA({period: 20, member: "h"}), // EMA of high (.h) price

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

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

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

Instead of providing an instance of the analysis class, such as new Sway.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 Sway.ta such as DEMA or ATR or Envelope. For example:

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

// Has the same effect as…

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

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:

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

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

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.

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":

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

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:

// 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();

### 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.

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.

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:

// Request M30 candles

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

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

if (!Framework.$myM30) Framework.$myM30 = new Sway.CandleStore({

ta: [new Sway.ta.ATR({period: 14})]

});

// Load initial or subsequent candles into the M30 store

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

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

// The aggregated H1 store will automatically also have an ATR calculation.

if (!Framework.$myH1) {

// Creates H1 candles from the M30 initial candles which have just been loaded

Framework.$myH1 = Framework.$myM30.Aggregate(3600);

} else {

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

// using the new M30 candles

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

}

});

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

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:

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

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

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).

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

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

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

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

### 5.2 Sway.ta technical analysis library

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

// Create MACD calculation

var macd = new Sway.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);

### 5.2.1 Calculation input: bar-based versus value-based calculations

Technical analysis calculations fall into two categories:

· "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.

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

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

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

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

// Calculate a moving average of a series of numbers

var ma1 = new Sway.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 Sway.ta.EMA({period: 10, member: "h"});

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

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:

// Calculate ATR from candle data

var atr = new Sway.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 Sway.ta.Bands({period: 20});

bands.LoadData(atr.GetValueArray());

### 5.2.2 Creating and initialising technical analysis calculations

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

// Create an exponential moving average

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

// Create an RSI calculation

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

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.)

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:

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

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:

// Create EMA with period=20

var myEma = new Sway.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( … );

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

**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.

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:

For example:

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

var myEma = new Sway.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}, … ]);

### 5.2.3 Loading data into a technical analysis calculation

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

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().

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().

**5.2.3.1 Loading candle data into a calculation**

**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:

· 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.

For example, to load an array of candle objects:

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

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

myATR.LoadData({

valueCount: 500, // Compulsory: number of items in the arrays

barData: {

open: [1.2342, 1.2340, 1.2345, …],

high: [ …],

low: [ … ],

close: [ … ],

volume: [ … ] // Volume is optional, and defaults to zero if omitted

}

});

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

// 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});

With a barData object:

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

myATR.UpdateCurrent({

barData: {

open: [1.2342, …],

high: [ …],

low: [ … ],

close: [ … ],

volume: [ … ] // Volume is optional, and defaults to zero if omitted

}

});

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:

UDI.onCalculate = function(data, output) {

// Create an ATR calculation if we don't already have one

if (!UDI.$myATR) UDI.$myATR = new Sway.ta.ATR({period: 14});

// Pass the data into the ATR calculation.

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

// rather than a full reload of all the data

UDI.$myATR.LoadData(data);

…

};

**5.2.3.2 Loading value data into a calculation**

**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):

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

var myEma = new Sway.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}, … ]);

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

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

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:

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

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

**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:

var ma = new Sway.ta.EMA({

period: 30,

member: "median",

data: [{o:1.2342, h: 1.2347, l: 12341, c: 1.2343}, … ]

});

### 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).

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

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

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

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

var ma2 = new Sway.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)) {

// 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)) {

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

} else {

// (No cross)

}

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.

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().

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.

### 5.2.5 Indexing order and oldestFirst

As described in the previous section, the default for Sway.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).

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

// 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, … ]);

However, if you prefer, all Sway.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.

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:

// Create a calculation with oldestFirst turned on

var myEma = new Sway.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();

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:

var myEma = new Sway.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();

### 5.2.6 Combining arrays

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

A simple example of ArrayCombine() is as follows:

// Subtract arr2 from arr1

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

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

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

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.

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.)

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

· 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

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.

{

member: "median", // Value to use from each candle, including derived properties

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

}

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

// 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 = Sway.ta.ArrayCombine(

"subtract",

{member: "h", candles: arrCandles},

{member: "l", candles: arrCandles}

);

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

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

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

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:

// 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 Sway.ta.EMA({period: 20, data: candles});

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

// Calculate double the ATR, using ArrayCombine()

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

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

var arrKeltnerUpper = Sway.ta.ArrayCombine("add", ma.GetValueArray(), arrDoubleATR);

### 5.2.7 Moving averages

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

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 Sway.ta.CreateMovingAverage() function.

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:

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 Sway.ta.EMA(parameters);

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

Some calculations in the Sway.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 Sway.ta.Bands calculation takes the parameter you provide, or its default, and does an internal call to CreateMovingAverage():

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

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

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

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

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

…

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

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

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:

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".

### 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 Sway 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 Sway.ta.MACD:

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

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

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

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

**Accumulative Swing Index – **Sway**.ta.ASI**

The Sway.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:

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.

**ADX – **Sway**.ta.ADX**

The Sway.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:

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

**Aroon – **Sway**.ta.Aroon**

The Sway.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:

Note: the Sway.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:

**Aroon oscillator – **Sway**.ta.AroonOsc**

The Sway.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:

**Average True Range – **Sway**.ta.ATR**

The Sway.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:

**Awesome Oscillator – **Sway**.ta.AO**

The Sway.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 Sway.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:

**Bear/Bull power – **Sway**.ta.BearBull**

The Sway.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:

**Bollinger® bands – **Sway**.ta.Bands**

The Sway.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 Sway.ta calculation. Parameters are as follows:

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:

**Centre of Gravity – **Sway**.ta.COG**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Commodity channel index – **Sway**.ta.CCI**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Chaikin Money Flow – **Sway**.ta.CMF**

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

**Chaikin volatility – **Sway**.ta.ChaikinVolatility**

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

**Chande forecast oscillator – **Sway**.ta.CFO**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Chande momentum oscillator – **Sway**.ta.CMO**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Coppock curve – **Sway**.ta.CoppockCurve**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Derived price – **Sway**.ta.DerivedPrice**

The Sway.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:

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

**Detrended price oscillator – **Sway**.ta.DPO**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Ease of movement – **Sway**.ta.EOM**

The Sway.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:

**Ehler Fisher transform – **Sway**.ta.EFT**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Elder Market Thermometer – **Sway**.ta.EMT**

The Sway.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:

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

**Elder Force Index – **Sway**.ta.EFI**

The Sway.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:

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

**Envelope around a moving average – **Sway**.ta.Envelope**

The Sway.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 Sway.ta calculation. Parameters are as follows:

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:

**Fractal bands – **Sway**.ta.FractalBands**

The Sway.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:

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

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.

**Gopalakrishnan range index – **Sway**.ta.GRI**

The Sway.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:

**Highest of the last N values – **Sway**.ta.Highest**

The Sway.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 Sway.ta calculation. Parameters are as follows:

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.

**Historical Volatility – **Sway**.ta.HV**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Intraday momentum index – **Sway**.ta.IMI**

The Sway.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:

**Keltner channel and STARC – **Sway**.ta.Keltner**

The Sway.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:

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:

**Klinger volume oscillator – **Sway**.ta.KVO**

The Sway.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:

The oscillator sets both primary and signal outputs.

**Linear regression forecast – **Sway**.ta.LRF**

The Sway.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 Sway.ta calculation. Parameters are as follows:

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

**Linear regression intercept – **Sway**.ta.LRI**

The Sway.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 Sway.ta calculation. Parameters are as follows:

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

**Lowest of the last N values – **Sway**.ta.Lowest**

The Sway.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 Sway.ta calculation. Parameters are as follows:

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.

**MACD – **Sway**.ta.MACD**

The Sway.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 Sway.ta calculation. Parameters are as follows:

The MACD has three outputs:

· 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.

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

**Market facilitation index – **Sway**.ta.MktFacilitation**

The Sway.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.

**Mass index – **Sway**.ta.MassIndex**

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

**Momentum oscillator – **Sway**.ta.Momentum**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Money Flow Index – **Sway**.ta.MoneyFlowIndex**

The Sway.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:

**Moving average oscillator – **Sway**.ta.MAOscillator**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**On-balance volume – **Sway**.ta.OBV**

The Sway.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:

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.

**Parabolic stop and reverse – **Sway**.ta.PSAR**

The Sway.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:

**Performance – **Sway**.ta.Performance**

The Sway.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 Sway.ta calculation. The calculation has one optional parameter.

**Pretty Good oscillator – **Sway**.ta.PGO**

The Sway.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:

**Price Oscillator – **Sway**.ta.PO**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**QStick – **Sway**.ta.QStick**

The Sway.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:

**Rainbow oscillator – **Sway**.ta.Rainbow**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Random Walk Index – **Sway**.ta.RWI**

The Sway.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:

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

**Rank – **Sway**.ta.Rank**

The Sway.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 Sway.ta calculation. Parameters are as follows:

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

**Rate of change – **Sway**.ta.ROC**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**RAVI – **Sway**.ta.RAVI**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Relative Strength Index – **Sway**.ta.RSI**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Relative Vigor Index – **Sway**.ta.RVI**

The Sway.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:

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.

**R-squared – **Sway**.ta.RSquared**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Schaff trend cycle – **Sway**.ta.STC**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Slope of linear regression – **Sway**.ta.Slope**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Standard deviation – **Sway**.ta.Stdev**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Stochastic momentum index – **Sway**.ta.SMI**

The Sway.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:

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

**Stochastic oscillator – **Sway**.ta.Stochastic**

The Sway.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:

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

**Stochastic RSI – **Sway**.ta.StochRSI**

The Sway.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 Sway.ta.Stochastic, with the addition of an extra parameter for specifying the RSI period:

**Sum – **Sway**.ta.Sum**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Swing index – **Sway**.ta.SwingIndex**

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

**TRIX – **Sway**.ta.Trix**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**True range – **Sway**.ta.TrueRange**

The Sway.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.

**Twiggs Money Flow – **Sway**.ta.TMF**

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

**Ultimate oscillator – **Sway**.ta.UO**

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

**Vertical horizontal filter – **Sway**.ta.VHF**

The Sway.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 Sway.ta calculation. Parameters are as follows:

**Volume Index – **Sway**.ta.VolumeIndex**

The Sway.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:

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.

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.

**Williams Accumulation Distribution – **Sway**.ta.WAD**

The Sway.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.

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.

**Williams %R – **Sway**.ta.WilliamsPctR**

The Sway.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:

Last updated