Liquid Charts API Docs
Liquid Charts Pro Scripts Documentation
Liquid Charts Pro Scripts Documentation
  • Liquid Charts Pro User-Defined Indicators
    • Introduction
      • 1.1 Access to the Liquid Charts scripting framework (UDI vs UDIX)
      • 1.2 Example UDI code
      • 1.3 Adding a UDI to a chart
      • 1.4 Lifecycle
      • 1.5 Alerts
      • 1.6 Indicator-on-indicator
      • 1.7 Technical note: web workers
      • 1.8 Technical note: dates
    • Initialisation: UDI.onInit()
      • 2.1 Return value from UDI.onInit()
      • 2.2 The plots[] array
      • 2.3 The settingsFields[] array
      • 2.4 Context data passed to UDI.onInit()
    • Calculating data: UDI.onCalculate()
      • 3.1 Reading settings fields
      • 3.2 Input data for the UDI
      • 3.3 Updates of the current bar only
      • 3.4 Calculating output data
      • 3.5 Requesting out-of-band updates
      • 3.6 Technical analysis: moving averages, ATR etc
    • Changes to the chart or parameters
      • 4.1 UDI.onContextChange()
      • 4.2 UDI.onParameterChange()
    • Creating drawings, event markers, and bar highlights
      • 5.1 Creating drawings
      • 5.1.1 Drawing properties
      • 5.2 Creating event markers
      • 5.2.1 Click notifications from event markers
      • 5.3 Creating bar highlights
    • Notifying the user
      • 6.1 Creating toast
      • 6.2 Changing the panel background colour
    • Adding HTML to the chart
      • 7.1 Adding HTML
      • 7.2 Positioning the HTML
      • 7.3 Sending messages from the HTML to the UDI
      • 7.4 Sending messages from the UDI to the HTML
    • Recommended trade
      • 8.0 Recommended trade
    • Other indicator topics
      • 9.1 Collecting external data
      • 9.2 Converting dates to chart time
      • 9.3 Multi-timeframe (MTF) indicators
  • Liquid Charts Pro Framework
    • Examples
    • Collections, objects, and properties in the framework
    • Functions in the framework
    • Messages and event handlers
    • Working with candle data
    • Widget HTML and CSS reference
    • Liquid.utils and other helper functions
    • Framework error codes
    • Script contexts
    • Sending mail into Liquid Charts Pro from outside the platform
    • language variables
Powered by GitBook
On this page
  1. Liquid Charts Pro User-Defined Indicators
  2. Calculating data: UDI.onCalculate()

3.4 Calculating output data

You put the results of your UDI's calculations into the output object which is passed to your UDI.onCalculate().

The output has a values member which is an array of arrays. The length, and order, of output.values depends on the plots defined for your indicator. For example:

plots: [
	{type: "channel", …}, 	// Requires 2 output series
	{type: "line", …}, 	// Requires 1 output series
	{type: "candles", …} 	// Requires 4 output series
]

In this example, output.values will contain 7 sub-arrays. Items [0] and [1] will be for the channel plot; item [2] will be for the line plot; and items [3] to [6] will be for the candle plot.

Each sub-array inside output.values will already have been initialised so that it contains the required number of elements (matching the number of bars on the chart). In other words, the length of each sub-array, such as output.values[0].length, will be the same as data.valueCount. (Therefore, you assign values into the sub-arrays rather than using push() to add data.)

If UDI.onCalculate() is being called for an update of the current bar only, with data.currentBarUpdateOnly set, then the contents of output.values will be the last results you passed back. Typically, you only then need to re-calculate the latest value in each sub-array. For example (not fully efficient!):

UDI.onCalculate = function(data, output)
{
	// Get the user-selected value of the "period" parameter
	var period = data.parameters["period"];
	
	if (!data.currentBarUpdateOnly) {
		// Need to do a full recalculation (repeating the example above)
		for (var i = 0; i < data.valueCount - period; i++) {
			var sum = 0;
			for (var j = 0; j < period; j++) sum += data.valueData[i + j];
			output.values[0][i] = sum / period;
		}
	} else {
		// Only the current bar is changing, and we only need to recalculate
		// the current indicator value. (Note: the 02-udi-efficient-sma.js example
		// demonstrates a more efficient version of this which avoids having 
		// to use a loop.)
		var sum = 0;
		for (var j = 0; j < period; j++) sum += data.valueData[j];
		output.values[0][0] = sum / period;
	}
};

Although the framework pre-creates and pre-populates the arrays inside output.values, it's permissible for you to replace them with new arrays instead of writing your values into the existing arrays. This is typically most relevant when working with technical analysis calculations. For example, let's say that you have used the Liquid.ta library to calculate a moving average of the input values:

// Create and store a moving average calculation. (The $ has no special meaning.
// It just makes clear what is a built-in UDI function/property and what is a private 
// addition by our code.)
UDI.$myMA = new Liquid.ta.EMA({period: 20});
UDI.$myMA.LoadData(data.valueData);

You can then copy the moving average results into a system-provided output array such as [1]:

// Copy each EMA value into output buffer #1
for (var i = 0; i < data.valueCount; i++) {
	output.values[1][i] = UDI.$myMA.GetValue(i);
}

However, it is both simpler and faster just to take the array from the technical analysis calculation and use that to replace the pre-prepared buffer:

output.values[1] = UDI.$myMA.GetValueArray();  // Replaces the array, rather than writing into it

Previous3.3 Updates of the current bar onlyNext3.5 Requesting out-of-band updates

Last updated 3 months ago