Main function that does everything
(self)
| 187 | return total_sum_percentage_change, future_volatility |
| 188 | |
| 189 | def find_anomalies(self): |
| 190 | """ |
| 191 | Main function that does everything |
| 192 | """ |
| 193 | |
| 194 | # Gather data for all stocks |
| 195 | if self.IS_LOAD_FROM_DICTIONARY == 0: |
| 196 | features, historical_price_info, future_prices, symbol_names = self.dataEngine.collect_data_for_all_tickers() |
| 197 | else: |
| 198 | # Load data from dictionary |
| 199 | features, historical_price_info, future_prices, symbol_names = self.dataEngine.load_data_from_dictionary() |
| 200 | |
| 201 | # Find anomalous stocks using the Isolation Forest model. Read more about the model at -> https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html |
| 202 | detector = IsolationForest(n_estimators = 100, random_state = 0) |
| 203 | detector.fit(features) |
| 204 | predictions = detector.decision_function(features) |
| 205 | |
| 206 | # Print top predictions with some statistics |
| 207 | predictions_with_output_data = [[predictions[i], symbol_names[i], historical_price_info[i], future_prices[i]] for i in range(0, len(predictions))] |
| 208 | predictions_with_output_data = list(sorted(predictions_with_output_data)) |
| 209 | |
| 210 | #Results object for storing results in JSON format |
| 211 | results = [] |
| 212 | |
| 213 | for item in predictions_with_output_data[:self.TOP_PREDICTIONS_TO_PRINT]: |
| 214 | # Get some stats to print |
| 215 | prediction, symbol, historical_price, future_price = item |
| 216 | |
| 217 | # Check if future data is present or not |
| 218 | if self.IS_TEST == 1 and len(future_price) < 5: |
| 219 | print("No future data is present. Please make sure that you ran the prior command with is_test enabled or disable that command now. Exiting now...") |
| 220 | exit() |
| 221 | |
| 222 | latest_date, today_volume, average_vol_last_five_days, average_vol_last_twenty_days = self.calculate_volume_changes(historical_price) |
| 223 | volatility_vol_last_five_days, volatility_vol_last_twenty_days, _ = self.calculate_recent_volatility(historical_price) |
| 224 | if average_vol_last_five_days == None or volatility_vol_last_five_days == None: |
| 225 | continue |
| 226 | |
| 227 | if self.IS_TEST == 0: |
| 228 | # Not testing so just add/print the predictions |
| 229 | |
| 230 | if self.OUTPUT_FORMAT == "CLI": |
| 231 | print("Last Bar Time: %s\nSymbol: %s\nAnomaly Score: %.3f\nToday Volume: %s\nAverage Volume 5d: %s\nAverage Volume 20d: %s\nVolatility 5bars: %.3f\nVolatility 20bars: %.3f\n----------------------" % |
| 232 | (latest_date, symbol, prediction, |
| 233 | today_volume, average_vol_last_five_days, average_vol_last_twenty_days, |
| 234 | volatility_vol_last_five_days, volatility_vol_last_twenty_days)) |
| 235 | results.append({ |
| 236 | 'latest_date' : latest_date, |
| 237 | 'Symbol' : symbol, |
| 238 | 'Anomaly Score' : prediction, |
| 239 | 'Today Volume' : today_volume, |
| 240 | 'Average Volume 5d' : average_vol_last_five_days, |
| 241 | 'Average Volume 20d' : average_vol_last_twenty_days, |
| 242 | 'Volatility 5bars' : volatility_vol_last_five_days, |
| 243 | 'Volatility 20bars' : volatility_vol_last_twenty_days |
| 244 | }) |
| 245 | |
| 246 | else: |
no test coverage detected