docstr: Calculate different stats for future data to show whether the anomalous stocks found were actually better than non-anomalous ones
docstr_tok: ["Calculate","different","stats","for","future","data","to","show","whether","the","anomalous","stocks","found","were","actually","better","than","non-anomalous","ones"]
code: def calculate_future_stats(self, predictions_with_output_data):
      """
      Calculate different stats for future data to show whether the anomalous stocks found were actually better than non-anomalous ones
      """
      future_change = []
      anomalous_score = []
      historical_volatilities = []
      future_volatilities = []
  
      for item in predictions_with_output_data:
          prediction, symbol, historical_price, future_price = item
          (
              future_sum_percentage_change,
              future_volatility,
          ) = self.calculate_future_performance(future_price)
          (
              _,
              _,
              historical_volatility,
          ) = self.calculate_recent_volatility(historical_price)
  
          # Skip for when there is a reverse split, the yfinance package does not handle that well so percentages get weirdly large
          if (
              abs(future_sum_percentage_change) > 250
              or self.is_nan(future_sum_percentage_change) == True
              or self.is_nan(prediction) == True
          ):
              continue
  
          future_change.append(future_sum_percentage_change)
          anomalous_score.append(prediction)
          future_volatilities.append(future_volatility)
          historical_volatilities.append(historical_volatility)
  
      # Calculate correlation and stats
      correlation = np.corrcoef(anomalous_score, future_change)[0, 1]
      anomalous_future_changes = np.mean(
          [
              future_change[x]
              for x in range(0, len(future_change))
              if anomalous_score[x] < 0
          ]
      )  # Anything less than 0 is considered anomalous
      normal_future_changes = np.mean(
          [
              future_change[x]
              for x in range(0, len(future_change))
              if anomalous_score[x] >= 0
          ]
      )
      anomalous_future_volatilities = np.mean(
          [
              future_volatilities[x]
              for x in range(0, len(future_volatilities))
              if anomalous_score[x] < 0
          ]
      )  # Anything less than 0 is considered anomalous
      normal_future_volatilities = np.mean(
          [
              future_volatilities[x]
              for x in range(0, len(future_volatilities))
              if anomalous_score[x] >= 0
          ]
      )
      anomalous_historical_volatilities = np.mean(
          [
              historical_volatilities[x]
              for x in range(0, len(historical_volatilities))
              if anomalous_score[x] < 0
          ]
      )  # Anything less than 0 is considered anomalous
      normal_historical_volatilities = np.mean(
          [
              historical_volatilities[x]
              for x in range(0, len(historical_volatilities))
              if anomalous_score[x] >= 0
          ]
      )
  
      print("\n*************** Future Performance ***************")
      print(
          "Correlation between future absolute change vs anomalous score (lower is better, range = (-1, 1)): **%.2f**\nTotal absolute change in future for Anomalous Stocks: **%.3f**\nTotal absolute change in future for Normal Stocks: **%.3f**\nAverage future volatility of Anomalous Stocks: **%.3f**\nAverage future volatility of Normal Stocks: **%.3f**\nHistorical volatility for Anomalous Stocks: **%.3f**\nHistorical volatility for Normal Stocks: **%.3f**\n"
          % (
              correlation,
              anomalous_future_changes,
              normal_future_changes,
              anomalous_future_volatilities,
              normal_future_volatilities,
              anomalous_historical_volatilities,
              normal_historical_volatilities,
          )
      )
  
      # Plot
      FONT_SIZE = 14
      colors = [
          "#c91414" if anomalous_score[x] < 0 else "#035AA6"
          for x in range(0, len(anomalous_score))
      ]
      anomalous_vs_normal = np.array(
          [
              1 if anomalous_score[x] < 0 else 0
              for x in range(0, len(anomalous_score))
          ]
      )
      plt.scatter(
          np.array(anomalous_score)[anomalous_vs_normal == 1],
          np.array(future_change)[anomalous_vs_normal == 1],
          marker="v",
          color="#c91414",
      )
      plt.scatter(
          np.array(anomalous_score)[anomalous_vs_normal == 0],
          np.array(future_change)[anomalous_vs_normal == 0],
          marker="P",
          color="#035AA6",
      )
      plt.axvline(x=0, linestyle="--", color="#848484")
      plt.xlabel("Anomaly Score", fontsize=FONT_SIZE)
      plt.ylabel("Absolute Future Change", fontsize=FONT_SIZE)
      plt.xticks(fontsize=FONT_SIZE)
      plt.yticks(fontsize=FONT_SIZE)
      plt.legend(["Anomalous", "Normal"], fontsize=FONT_SIZE)
      plt.title("Absolute Future Change", fontsize=FONT_SIZE)
      plt.tight_layout()
      plt.grid()
      plt.show()
  
imports: import os
  import ta
  import sys
  import json
  import math
  import pickle
  import random
  import requests
  import collections
  import numpy
  from os import walk, path
  import pandas
  import yfinance
  import datetime
  from scipy.stats import linregress
  from datetime import datetime, timedelta
  import matplotlib.pyplot
  from sklearn.ensemble import IsolationForest
  from data_loader import DataEngine
  import warnings
  import argparse
label_desc: Use image node_id 11 for calling the Surpriver obj's underlying member method code with example usage: obj.calculate_future_stats(predictions_with_output_data) without return types