docs: def get_forecast_errors(y_hat,
                          y_true,
                          window_size=5,
                          batch_size=30,
                          smoothing_percent=0.05,
                          smoothed=True):
      """
      Calculates the forecasting error for two arrays of data. If smoothed errors desired,
          runs EWMA.
      Args:
          y_hat (list): forecasted values. len(y_hat)==len(y_true).
          y_true (list): true values. len(y_hat)==len(y_true).
          window_size (int):
          batch_size (int):
          smoothing_percent (float):
          smoothed (bool): whether the returned errors should be smoothed with EWMA.
      Returns:
          (list): error residuals. Smoothed if specified by user.
      """
      errors = [abs(y_h - y_t) for y_h, y_t in zip(y_hat, y_true)]
  
      if not smoothed:
          return errors
  
      historical_error_window = int(window_size * batch_size * smoothing_percent)
      moving_avg = []
      for i in range(len(errors)):
          left_window = i - historical_error_window
          right_window = i + historical_error_window + 1
          if left_window < 0:
              left_window = 0
  
          if right_window > len(errors):
              right_window = len(errors)
  
          moving_avg.append(np.mean(errors[left_window:right_window]))
  
      return moving_avg