|
| 1 | +# Using Indicators |
| 2 | + |
| 3 | +Indicators are the cornerstone of technical analysis, transforming raw price data into actionable insights. Stochastix is designed to make using a vast library of common indicators simple and efficient. |
| 4 | + |
| 5 | +## The `TALibIndicator` Wrapper |
| 6 | + |
| 7 | +The primary way to use technical indicators in Stochastix is through the `TALibIndicator` class. This class is a powerful and convenient wrapper around the standard **PHP `trader` PECL extension**, which itself is a binding for the widely-used **TA-Lib (Technical Analysis Library)** written in C. |
| 8 | + |
| 9 | +This approach gives you access to dozens of battle-tested, high-performance indicators out of the box. |
| 10 | + |
| 11 | +::: tip Learn More |
| 12 | +For a complete list of all available functions and their required parameters, the official PHP documentation for the `trader` extension is the definitive resource. |
| 13 | +**[PHP Trader Documentation](https://www.php.net/manual/en/book.trader.php)** |
| 14 | +::: |
| 15 | + |
| 16 | +## Defining an Indicator |
| 17 | + |
| 18 | +All indicators must be defined within the `defineIndicators()` method of your strategy. This method is called once at the start of a backtest, before the bar-by-bar processing begins. |
| 19 | + |
| 20 | +To add an indicator, you use the `$this->addIndicator()` helper method from the `AbstractStrategy` class. |
| 21 | + |
| 22 | +```php |
| 23 | +// In src/Strategy/MyEmaStrategy.php |
| 24 | + |
| 25 | +use Stochastix\Domain\Common\Enum\TALibFunctionEnum; |
| 26 | +use Stochastix\Domain\Indicator\Model\TALibIndicator; |
| 27 | + |
| 28 | +// ... inside your strategy class |
| 29 | + |
| 30 | +protected function defineIndicators(): void |
| 31 | +{ |
| 32 | + $this->addIndicator( |
| 33 | + 'ema_fast', // A unique key to identify this indicator instance |
| 34 | + new TALibIndicator( |
| 35 | + TALibFunctionEnum::Ema, // The trader function to call |
| 36 | + ['timePeriod' => $this->emaFastPeriod] // Parameters for the function |
| 37 | + ) |
| 38 | + ); |
| 39 | +} |
| 40 | +``` |
| 41 | +In this example: |
| 42 | +1. We give our indicator a unique key, `'ema_fast'`, so we can access it later. |
| 43 | +2. We instantiate `TALibIndicator`. |
| 44 | +3. The first argument is an enum case from `TALibFunctionEnum`, which corresponds to a `trader_*` function (e.g., `trader_ema`). |
| 45 | +4. The second argument is an associative array of parameters that will be passed to the `trader_ema` function. The key, `timePeriod`, matches the parameter name required by the underlying C library. |
| 46 | + |
| 47 | +## Accessing Indicator Values |
| 48 | + |
| 49 | +Once an indicator is defined, the backtesting engine automatically calculates its value for every bar. You can access these values in the `onBar()` method through the `$this->getIndicatorSeries()` helper. This method returns a [`Series`](/core-concepts.html#the-series) object. |
| 50 | + |
| 51 | +```php |
| 52 | +public function onBar(MultiTimeframeOhlcvSeries $bars): void |
| 53 | +{ |
| 54 | + // Get the entire series object for our indicator |
| 55 | + $fastEmaSeries = $this->getIndicatorSeries('ema_fast'); |
| 56 | + |
| 57 | + // Access the current value (for the current bar) |
| 58 | + $currentEmaValue = $fastEmaSeries[0]; |
| 59 | + |
| 60 | + // Access the previous bar's value |
| 61 | + $previousEmaValue = $fastEmaSeries[1]; |
| 62 | + |
| 63 | + if ($currentEmaValue === null || $previousEmaValue === null) { |
| 64 | + // The indicator might not have enough data to calculate a value yet |
| 65 | + // (e.g., an EMA(20) needs at least 20 bars of data). |
| 66 | + return; |
| 67 | + } |
| 68 | + |
| 69 | + // Now you can use the values in your logic |
| 70 | + if ($bars->close[0] > $currentEmaValue) { |
| 71 | + // ... Price is above the fast EMA |
| 72 | + } |
| 73 | +} |
| 74 | +``` |
| 75 | + |
| 76 | +## Multi-Value Indicators (e.g., MACD, BBANDS) |
| 77 | + |
| 78 | +Some indicators, like MACD or Bollinger Bands, don't just return a single line; they return multiple arrays of data (e.g., MACD line, signal line, and histogram). The `TALibIndicator` class handles this automatically. |
| 79 | + |
| 80 | +For these indicators, the framework assigns a default key to each returned data series. For example, the `trader_macd` function returns three arrays, which Stochastix maps to the keys: `macd`, `signal`, and `hist`. |
| 81 | + |
| 82 | +To access these individual series, you simply pass the specific series key as the second argument to `getIndicatorSeries()`. |
| 83 | + |
| 84 | +```php |
| 85 | +// In defineIndicators(): |
| 86 | +$this->addIndicator( |
| 87 | + 'macd_main', // The key for the indicator group |
| 88 | + new TALibIndicator(TALibFunctionEnum::Macd, [ |
| 89 | + 'fastPeriod' => 12, |
| 90 | + 'slowPeriod' => 26, |
| 91 | + 'signalPeriod' => 9, |
| 92 | + ]) |
| 93 | +); |
| 94 | + |
| 95 | + |
| 96 | +// In onBar(): |
| 97 | +// Get the individual series objects |
| 98 | +$macdLine = $this->getIndicatorSeries('macd_main', 'macd'); |
| 99 | +$signalLine = $this->getIndicatorSeries('macd_main', 'signal'); |
| 100 | +$macdHist = $this->getIndicatorSeries('macd_main', 'hist'); |
| 101 | + |
| 102 | +// Now you can use their current and previous values |
| 103 | +$isMacdCrossUp = $macdLine->crossesOver($signalLine); |
| 104 | +$isHistogramPositive = $macdHist[0] > 0; |
| 105 | + |
| 106 | +if ($isMacdCrossUp && $isHistogramPositive) { |
| 107 | + // ... A bullish MACD crossover occurred |
| 108 | +} |
| 109 | +``` |
0 commit comments