Adding an Indicator
To add a custom indicator to the project, follow these guidelines. Every custom indicator must extend the BaseIndicator
class and adhere to the specified directory and file structure.
Directory Structure
Add your custom indicator class to the
custom_modules/indicators/
directory:custom_modules/indicators/<name_of_your_indicator>.py
Implement your indicator class in a Python file named after your indicator.
Implementing a Custom Indicator
Class Definition:
Your indicator class must extend the
BaseIndicator
class.Here's an example of a custom indicator implementation:
from ats.indicators.base_indicator import BaseIndicator class CustomIndicator(BaseIndicator): def running_calc(self, popped_data_point, new_data_point) -> float: """ Calculates the indicator in a running window. Args: popped_data_point: The data point removed from the time series (if window size is reached). new_data_point: The new data point being added. Returns: The new calculated data point. """ # Example logic for a moving average indicator if popped_data_point is not None: self.sums -= popped_data_point else: self.sums = 0 self.sums += new_data_point self.result = self.sums / self.N return new_data_point
Requirements:
Implement the
running_calc(popped_data_point, new_data_point)
method to define the indicator's calculation logic.Use the
self.time_series
to maintain the data points within the indicator's rolling window (N
size specified in the config).Update
self.result
with the calculated result of the indicator in each window.
State Management:
The
BaseIndicator
class maintains an internal time series and state. You can extend this state or use additional internal variables for more complex calculations.
Configuration:
Indicators must be initialized with a
config
dictionary containing all required parameters (e.g., the window sizeN
).
Accessing and Using Indicators
Custom indicators can be used in strategies or other components by importing and instantiating them:
from ats.utils.general import helpers as general_helpers
config = {"N": 5} # Configuration of the sliding window size
indicator_class = general_helpers.get_class_from_namespace("indicators:custom_indicator")
indicator = indicator_class(config)
# Add data points to the indicator
indicator.add(1.0)
indicator.add(2.0)
# Check if the indicator is ready
if indicator.is_ready():
print(f"Indicator result: {indicator.result}")
Example Directory Structure
Assuming the indicator is named custom_indicator
:
custom_modules/
├── indicators/
│ ├── custom_indicator.py
Notes on Indicator Logic
Rolling Window Calculations: The
running_calc()
method provides a streamlined way to perform calculations within a rolling window. When a new data point is added, the oldest data point is removed (if the window size is reached).State Handling: Use the
self.states
attribute if you need to maintain additional state data across calculations.Thread Safety: The
BaseIndicator
class is not thread-safe. If your use case requires thread safety, you should implement appropriate synchronization mechanisms.
By following these guidelines, your custom indicator will integrate seamlessly with the project, ensuring compatibility and adherence to project conventions. This modular structure allows for easy addition, management, and testing of new indicators.
Last updated