Building Custom Indicators
Relevant source files
The following files were used as context for generating this wiki page:
Custom indicators in vectorbt are high-performance computational pipelines designed to backtest trading strategies at scale. By packing thousands of configurations into NumPy arrays and accelerating execution with Numba or Rust, the system allows for rapid grid search and multi-asset analysis. The core mechanism for creating these tools is the IndicatorFactory, which standardizes the transition from User-Defined Functions (UDFs) to complex, vectorized indicator classes.
Sources: README.md:32-34, vectorbt/indicators/factory.py:12-25
The Indicator Factory Architecture
The IndicatorFactory is the central component for constructing indicator classes. It acts as a skeleton builder that binds calculation functions to a standardized interface. Each generated class inherits from IndicatorBase, providing built-in support for broadcasting, indexing, caching, and integrated statistics/plotting capabilities.
Sources: vectorbt/indicators/factory.py:928-940, vectorbt/indicators/factory.py:836-840
Core Components of an Indicator
An indicator pipeline is structured around four primary data types:
- Inputs: Time-series arrays (e.g., OHLCV data).
- Parameters: Variables that define the calculation (e.g., window sizes).
- Outputs: Regular arrays returned by the function.
- In-place Outputs: Arrays modified in-place to save memory or maintain state.
The diagram shows the workflow from the Factory to the generation of a production-ready Indicator class.
Sources: vectorbt/indicators/factory.py:20-35, vectorbt/indicators/factory.py:950-965
Implementation Methods
Vectorbt provides two primary methods for binding logic to the factory: from_apply_func and from_custom_func.
Apply Function (Simple Logic)
from_apply_func is used when the calculation can be defined for a single parameter selection. The factory automatically handles the looping over parameter grids and the concatenation of results into a single vectorized output.
| Feature | Description |
|---|---|
| Numba Support | Highly compatible with @njit for performance. |
| Caching | Supports a cache_func to preprocess data once for all combinations. |
| Parallelization | Supports Ray for executing combinations in parallel. |
Sources: vectorbt/indicators/factory.py:1515-1530, vectorbt/indicators/factory.py:1560-1570
Custom Function (Full Control)
from_custom_func offers full flexibility. The user is responsible for handling the concatenation of columns for each parameter, often using utilities like apply_and_concat_one. This is required for logic that needs to view the entire parameter grid simultaneously.
Sources: vectorbt/indicators/factory.py:1305-1315, vectorbt/indicators/factory.py:1320-1330
Data Flow and Broadcasting
One of the most powerful features of custom indicators is the automatic broadcasting mechanism managed by run_pipeline.
This flowchart illustrates how disparate input shapes and parameter lists are unified before execution.
Sources: vectorbt/indicators/factory.py:530-550, vectorbt/indicators/factory.py:650-670
Parameter Settings
Parameters can be configured via param_settings to behave as scalars, 1D arrays, or 2D arrays that broadcast to the input shape.
| Setting | Effect |
|---|---|
is_array_like | Treats an array as a single value rather than a list of values. |
bc_to_input | Broadcasts the parameter to the input size or a specific axis (0 or 1). |
per_column | Applies parameter values per column of the input DataFrame. |
Sources: vectorbt/indicators/factory.py:270-285, vectorbt/indicators/factory.py:560-575
Integrated Analysis Tools
Generated indicators automatically gain access to vectorbt's statistical and plotting subsystems.
Statistics Integration
Through StatsBuilderMixin, indicators support a .stats() method. Users can define custom metrics in the factory using a metrics dictionary. Metrics can be associated with tags for filtered calculation.
Sources: vectorbt/generic/stats_builder.py:50-70, vectorbt/indicators/factory.py:500-515
Plotting Integration
Through PlotsBuilderMixin, indicators support a .plots() method. Custom subplots are defined via a subplots dictionary, allowing indicators to render complex visual representations (e.g., OHLC with overlays) using Plotly.
Sources: vectorbt/generic/plots_builder.py:45-60, vectorbt/indicators/factory.py:516-525
Caching and Optimization
Performance is optimized through several layers:
- Unique Running: When
run_uniqueis enabled, the pipeline only calculates unique parameter combinations, which is critical when input arrays are narrow but the parameter grid is large. - Flexible Broadcasting: Preserves original dimensions to minimize memory footprint during calculation.
- Raw Output Reuse: Users can return raw results (
return_raw=True) and reuse them in subsequent runs viause_rawto skip the calculation phase entirely.
Sources: vectorbt/indicators/factory.py:450-465, vectorbt/indicators/factory.py:755-770, vectorbt/indicators/factory.py:800-810
Conclusion
Building custom indicators in vectorbt transforms standard financial logic into scalable, high-performance backtesting engines. By utilizing the IndicatorFactory, developers can focus on the mathematical UDF while the framework manages the complexities of broadcasting, memory management, and data alignment. This architecture ensures that even complex strategies with thousands of parameter permutations can be analyzed with the same ease as a simple moving average.
Sources: vectorbt/indicators/factory.py:12-25, README.md:15-20