3.6 Technical analysis: moving averages, ATR etc

Many indicators are based on other technical analysis calculations such as moving averages, standard deviation, or values such as ATR or RSI. (For example, an "Awesome Oscillator" is simply a 5-period moving average minus a 34-period moving average.)

UDIs have access to a library, Sway.ta, of technical analysis calculations. Two of the example UDI files use this library, to calculate a moving average and to build up multiple averages into a MACD calculation.

The Sway.ta library is documented separately, because it is also available as part of the Sway Charts Pro scripting framework. UDIs also have access to an Sway.CandleStore helper.

One of the features of the Sway.ta library is creating a configurable type of moving average from a user-controlled setting in your UDI. This is illustrated by the MACD example file, and works as follows:

In the settings for your UDI, you include a field with type:"maType". In your UDI code, you read the value of the user field (and typically also of a user-defined period for the average), and use Sway.ta.CreateMovingAverage() to create the moving average object. For example:

// Read user-controlled maType and period fields from settings 
var maType = data.parameters["maType"];
var period = data.parameters["period"];
// Create a moving average calculation if we don't already have one 
if (!UDI.$myMA) UDI.$myMA = Sway.ta.CreateMovingAverage(maType, {period: period});
// Load the data into the calculation. If data.currentBarUpdateOnly is set then 
// this automatically becomes an efficient fast update of just the current value.
UDI.$myMA.LoadData(data);

You can pass the data parameter from UDI.onCalculate() directly into the LoadData() of a technical analysis calculation – for both "bar-based" and "value-based" calculations. The LoadData() function automatically checks currentBarUpdateOnly and does an efficient update of only the current value if only the current bar is changing. This is demonstrated by the example above, and also the following instance of a bar-based calculation (ATR):

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

The Sway.CandleStore can also be helpful here. You can pass the data parameter from UDI.onCalculate() into a candle store, and it will convert it into an array of candle objects. That array can then be sent into a bar-based technical analysis calculation such as ATR. For example:

UDI.onCalculate = function(data, output) {
	// If we haven't already done so in a previous call, create a candle store
	if (!UDI.$cs) UDI.$cs = new Sway.CandleStore();
	// Load data into the candle store. This will efficiently update just the current 
	// candle if data.currentBarUpdateOnly = true 
	UDI.$cs.LoadCandles(data);
	// Create an ATR calculation if we haven’t already done so
	if (!UDI.$atr) UDI.$atr = new Sway.ta.ATR({period: 20});
	// Is this a full (re-)calculation?
	if (!data.currentBarUpdateOnly) {
		// Full recalculation
		// Load the entire candle data from the store into the ATR.
		UDI.$atr.LoadData(UDI.$cs.GetCandleArray());
	} else {
		// Only the current bar is changing.
		// Update the ATR just with the current candle from the store.
		UDI.$atr.UpdateCurrent(UDI.$cs.GetCandle(0));
	}
}}

Last updated