code: def add_technical_indicator(
      self,
      df,
      tech_indicator_list=[
          "macd",
          "boll_ub",
          "boll_lb",
          "rsi_30",
          "dx_30",
          "close_30_sma",
          "close_60_sma",
      ],
  ):
      print("Started adding Indicators")
  
      # Store the original data type of the 'timestamp' column
      original_timestamp_dtype = df["timestamp"].dtype
  
      # Convert df to stock data format just once
      stock = Sdf.retype(df)
      unique_ticker = stock.tic.unique()
  
      # Convert timestamp to a consistent datatype (timezone-naive) before entering the loop
      df["timestamp"] = df["timestamp"].dt.tz_convert(None)
  
      print("Running Loop")
      for indicator in tech_indicator_list:
          indicator_dfs = []
          for tic in unique_ticker:
              tic_data = stock[stock.tic == tic]
              indicator_series = tic_data[indicator]
  
              tic_timestamps = df.loc[df.tic == tic, "timestamp"]
  
              indicator_df = pd.DataFrame(
                  {
                      "tic": tic,
                      "date": tic_timestamps.values,
                      indicator: indicator_series.values,
                  }
              )
              indicator_dfs.append(indicator_df)
  
          # Concatenate all intermediate dataframes at once
          indicator_df = pd.concat(indicator_dfs, ignore_index=True)
  
          # Merge the indicator data frame
          df = df.merge(
              indicator_df[["tic", "date", indicator]],
              left_on=["tic", "timestamp"],
              right_on=["tic", "date"],
              how="left",
          ).drop(columns="date")
  
      print("Restore Timestamps")
      # Restore the original data type of the 'timestamp' column
      if isinstance(original_timestamp_dtype, pd.DatetimeTZDtype):
          if df["timestamp"].dt.tz is None:
              df["timestamp"] = df["timestamp"].dt.tz_localize("UTC")
          df["timestamp"] = df["timestamp"].dt.tz_convert(
              original_timestamp_dtype.tz
          )
      else:
          df["timestamp"] = df["timestamp"].astype(
              original_timestamp_dtype
          )
  
      print("Finished adding Indicators")
      return df
  
imports: from __future__ import annotations
  from concurrent.futures import ProcessPoolExecutor
  from concurrent.futures import ThreadPoolExecutor
  import alpaca_trade_api
  import exchange_calendars
  import numpy
  import pandas
  import pytz
  from stockstats import StockDataFrame
label_desc: Use image node_id 6 for calling the AlpacaProcessor obj's underlying member method code with example usage: obj.add_technical_indicator(df, tech_indicator_list) and returns: df