Multi-Series Custom Indicators
Many powerful indicators are not just a single line on a chart, but a combination of multiple data series. A classic example is the MACD, which consists of the MACD line, a signal line, and a histogram.
Stochastix allows your custom indicators to compute and expose multiple, distinct Series objects. This is achieved by using the $this->resultSeries property as an associative array.
The $resultSeries Property
As we saw on the previous page, the final step in the calculateBatch() method is to store your calculated data in the $this->resultSeries property.
This property is an associative array where:
- The key is a
stringthat uniquely identifies a specific data series (e.g.,'rsi','rsi_ma'). - The value is the final, padded
Seriesobject for that data.
By adding multiple key-value pairs to this array, your indicator effectively publishes multiple output series.
A Practical Example: RSIMovingAverage
Let's revisit the RSIMovingAverage indicator we created. It naturally produces two distinct data series: the RSI line itself, and the moving average of that RSI line.
In the calculateBatch() method, we stored them with unique keys:
// In src/Indicator/RSIMovingAverage.php
public function calculateBatch(Map $dataframes): void
{
// ... (calculations for $rsiPadded and $maPadded)
// Store the final, padded data as Series objects.
// The keys used here are critical for accessing the data later.
$this->resultSeries['rsi'] = new Series($rsiPadded);
$this->resultSeries['rsi_ma'] = new Series($maPadded);
}Accessing Multi-Value Series in a Strategy
When you want to use this indicator in a strategy, you access each series by providing the specific key as the second argument to the $this->getIndicatorSeries() method.
// In your strategy's onBar() method:
// Get the indicator instance we defined earlier.
$indicatorKey = 'my_custom_rsi';
// To get the raw RSI line, we use the 'rsi' key.
$rsiLine = $this->getIndicatorSeries($indicatorKey, 'rsi');
// To get the moving average line, we use the 'rsi_ma' key.
$rsiMaLine = $this->getIndicatorSeries($indicatorKey, 'rsi_ma');
// Now we can use both series in our logic.
if ($rsiLine->crossesOver($rsiMaLine)) {
// A bullish signal has occurred.
// ...
}Important
If you do not provide the second argument to $this->getIndicatorSeries(), it will default to requesting a series with the key 'value'. In the case of our RSIMovingAverage indicator, this would cause an error because we did not define a series with the key 'value'. You must always use the explicit keys you defined in your indicator's calculateBatch() method.