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

  1. Add your custom indicator class to the custom_modules/indicators/ directory:

    custom_modules/indicators/<name_of_your_indicator>.py
  2. Implement your indicator class in a Python file named after your indicator.

Implementing a Custom Indicator

  1. 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
  2. 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.

  3. 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.

  4. Configuration:

    • Indicators must be initialized with a config dictionary containing all required parameters (e.g., the window size N).

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