# Indicator development (/features/indicators/indicator-development)

## Indicator search \[#indicator-search]

New in 1.11.1

✅ VBT implements or integrates more than 500 indicators, making it hard to keep track
of them all. To make indicators easier to find, several new methods are available for globally searching
for indicators.

```python title="List all moving average indicators"
>>> vbt.IF.list_indicators("*ma")
[
    'vbt:MA',
    'talib:DEMA',
    'talib:EMA',
    'talib:KAMA',
    'talib:MA',
    ...
    'technical:ZEMA',
    'technical:ZLEMA',
    'technical:ZLHMA',
    'technical:ZLMA'
]

>>> vbt.indicator("technical:ZLMA")  # (1)
vectorbtpro.indicators.factory.technical.ZLMA
```

1.  Same as `vbt.IF.get_indicator`.

## Indicators for ML \[#indicators-for-ml]

New in 1.8.2

✅ Want to feed indicators as features to a machine-learning model? There is no need to run
them individually: you can tell VBT to run all indicators from an indicator package on
the given data instance. The data instance will recognize the input names of each indicator and supply
the required data. You can also easily change the defaults for each indicator.

```python title="Run all talib indicators on entire BTC-USD history"
>>> data = vbt.YFData.pull("BTC-USD")
>>> features = data.run("talib", mavp=vbt.run_arg_dict(periods=14))
>>> features.shape
(3046, 175)
```

## 1D-native indicators \[#1d-native-indicators]

New in 1.0.10

✅ Previously, custom indicators could only be created by accepting two-dimensional input arrays, which
forced users to adapt all functions accordingly. Now, the indicator factory can split each input array
along columns and pass one column at a time, making it much easier to design indicators that are meant
to be run natively on one-dimensional data (such as TA-Lib!).

```python title="Create a TA-Lib powered STOCHRSI indicator"
>>> import talib

>>> params = dict(
...     rsi_period=14,
...     fastk_period=5,
...     slowk_period=3,
...     slowk_matype=0,
...     slowd_period=3,
...     slowd_matype=0
... )

>>> def stochrsi_1d(close, *args):
...     rsi = talib.RSI(close, args[0])
...     k, d = talib.STOCH(rsi, rsi, rsi, *args[1:])
...     return rsi, k, d

>>> STOCHRSI = vbt.IF(
...     input_names=["close"],
...     param_names=list(params.keys()),
...     output_names=["rsi", "k", "d"]
... ).with_apply_func(stochrsi_1d, takes_1d=True, **params)

>>> data = vbt.YFData.pull("BTC-USD", start="2022-01", end="2022-06")
>>> stochrsi = STOCHRSI.run(data.close)
>>> fig = stochrsi.k.rename("%K").vbt.plot()
>>> stochrsi.d.rename("%D").vbt.plot(fig=fig)
>>> fig.show()
```

TA-Lib-powered stochastic RSI percent K and percent D for BTC-USD. [Figure data (JSON)](/assets/figures/features/indicators/stochastic-rsi.73211844ad8e.json)

## Parallelizable indicators \[#parallelizable-indicators]

New in 1.0.10

✅ Processing parameter combinations with the indicator factory can be distributed across multiple threads,
processes, or even in the cloud. This is a huge help when working with slow indicators 🐌

```python title="Benchmark a serial and multithreaded rolling min-max indicator"
>>> @njit
... def minmax_nb(close, window):
...     return (
...         vbt.nb.rolling_min_nb(close, window),
...         vbt.nb.rolling_max_nb(close, window)
...     )

>>> MINMAX = vbt.IF(
...     class_name="MINMAX",
...     input_names=["close"],
...     param_names=["window"],
...     output_names=["min", "max"]
... ).with_apply_func(minmax_nb, window=14)

>>> data = vbt.YFData.pull("BTC-USD")
```

```python
>>> %%timeit
>>> minmax = MINMAX.run(
...     data.close,
...     np.arange(2, 200),
...     jitted_loop=True
... )
420 ms ± 2.05 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
```

```python
>>> %%timeit
>>> minmax = MINMAX.run(
...     data.close,
...     np.arange(2, 200),
...     jitted_loop=True,
...     jitted_warmup=True,  # (1)
...     execute_kwargs=dict(engine="threadpool", n_chunks="auto")  # (2)
... )
120 ms ± 355 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
```

1.  Run one parameter combination to compile the indicator before running others
    in a multithreaded fashion.
2.  One Numba loop per thread, with the same number of threads as there are cores.

## Indicator expressions \[#indicator-expressions]

New in 1.0.8

✅ Indicators can now be created from expressions. An indicator expression is a regular string representing
Python code enhanced with various extensions. The indicator factory automatically derives all required
information, such as inputs, parameters, outputs, NumPy, VBT, and TA-Lib functions, and even
complex indicators, thanks to a unique format and built-in matching mechanism. Designing indicators
has never been easier!

```python title="Build a MACD indicator from an expression"
>>> data = vbt.YFData.pull("BTC-USD", start="2020", end="2021")

>>> expr = """
... MACD:
... fast_ema = @talib_ema(close, @p_fast_w)
... slow_ema = @talib_ema(close, @p_slow_w)
... macd = fast_ema - slow_ema
... signal = @talib_ema(macd, @p_signal_w)
... macd, signal
... """
>>> MACD = vbt.IF.from_expr(expr, fast_w=12, slow_w=26, signal_w=9)  # (1)
>>> macd = MACD.run(data.close)
>>> fig = macd.macd.rename("MACD").vbt.plot()
>>> macd.signal.rename("Signal").vbt.plot(fig=fig)
>>> fig.show()
```

1.  No need to manually set `input_names`, `param_names`, or other information.

Expression-built MACD and signal lines for BTC-USD during 2020. [Figure data (JSON)](/assets/figures/features/indicators/indicator-expressions.6bbc8e453580.json)
