Tonic commited on
Commit
65bf228
·
1 Parent(s): a65d91d

attempt to predict technicals and volume

Browse files
Files changed (1) hide show
  1. app.py +153 -0
app.py CHANGED
@@ -620,6 +620,128 @@ def make_prediction(symbol: str, timeframe: str = "1d", prediction_days: int = 5
620
  mean_pred = extended_mean_pred[:prediction_days * 96]
621
  std_pred = extended_std_pred[:prediction_days * 96]
622
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
623
  except Exception as e:
624
  print(f"Chronos prediction error: {str(e)}")
625
  print(f"Error type: {type(e)}")
@@ -701,6 +823,21 @@ def make_prediction(symbol: str, timeframe: str = "1d", prediction_days: int = 5
701
  row=2, col=1
702
  )
703
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
704
  # Add volume
705
  fig.add_trace(
706
  go.Bar(x=df.index, y=df['Volume'], name='Volume',
@@ -708,6 +845,14 @@ def make_prediction(symbol: str, timeframe: str = "1d", prediction_days: int = 5
708
  row=3, col=1
709
  )
710
 
 
 
 
 
 
 
 
 
711
  # Update layout with timeframe-specific settings
712
  fig.update_layout(
713
  title=f'{symbol} {timeframe} Analysis and Prediction',
@@ -730,6 +875,14 @@ def make_prediction(symbol: str, timeframe: str = "1d", prediction_days: int = 5
730
  "strategy_used": strategy
731
  })
732
 
 
 
 
 
 
 
 
 
733
  return signals, fig
734
 
735
  except Exception as e:
 
620
  mean_pred = extended_mean_pred[:prediction_days * 96]
621
  std_pred = extended_std_pred[:prediction_days * 96]
622
 
623
+ # Extend Chronos forecasting to volume and technical indicators
624
+ volume_pred = None
625
+ rsi_pred = None
626
+ macd_pred = None
627
+
628
+ try:
629
+ # Prepare volume data for Chronos
630
+ volume_data = df['Volume'].values
631
+ if len(volume_data) >= 64:
632
+ # Normalize volume data
633
+ volume_scaler = MinMaxScaler(feature_range=(-1, 1))
634
+ normalized_volume = volume_scaler.fit_transform(volume_data.reshape(-1, 1)).flatten()
635
+
636
+ # Use last 64 points for volume prediction
637
+ volume_context = normalized_volume[-64:]
638
+ volume_context_tensor = torch.tensor(volume_context, dtype=dtype, device=device)
639
+ if len(volume_context_tensor.shape) == 1:
640
+ volume_context_tensor = volume_context_tensor.unsqueeze(0)
641
+
642
+ # Predict volume
643
+ with torch.amp.autocast('cuda'):
644
+ volume_quantiles, volume_mean = pipe.predict_quantiles(
645
+ context=volume_context_tensor,
646
+ prediction_length=min(actual_prediction_length, 64),
647
+ quantile_levels=[0.1, 0.5, 0.9]
648
+ )
649
+
650
+ # Convert and denormalize volume predictions
651
+ volume_mean = volume_mean.detach().cpu().numpy()
652
+ volume_pred = volume_scaler.inverse_transform(volume_mean.reshape(-1, 1)).flatten()
653
+
654
+ # Extend volume predictions if needed
655
+ if len(volume_pred) < len(mean_pred):
656
+ last_volume = volume_pred[-1]
657
+ extension_length = len(mean_pred) - len(volume_pred)
658
+ volume_extension = np.full(extension_length, last_volume)
659
+ volume_pred = np.concatenate([volume_pred, volume_extension])
660
+ except Exception as e:
661
+ print(f"Volume prediction error: {str(e)}")
662
+ # Fallback: use historical average
663
+ avg_volume = df['Volume'].mean()
664
+ volume_pred = np.full(len(mean_pred), avg_volume)
665
+
666
+ try:
667
+ # Prepare RSI data for Chronos
668
+ rsi_data = df['RSI'].values
669
+ if len(rsi_data) >= 64 and not np.any(np.isnan(rsi_data)):
670
+ # RSI is already normalized (0-100), but we'll scale it to (-1, 1)
671
+ rsi_scaler = MinMaxScaler(feature_range=(-1, 1))
672
+ normalized_rsi = rsi_scaler.fit_transform(rsi_data.reshape(-1, 1)).flatten()
673
+
674
+ # Use last 64 points for RSI prediction
675
+ rsi_context = normalized_rsi[-64:]
676
+ rsi_context_tensor = torch.tensor(rsi_context, dtype=dtype, device=device)
677
+ if len(rsi_context_tensor.shape) == 1:
678
+ rsi_context_tensor = rsi_context_tensor.unsqueeze(0)
679
+
680
+ # Predict RSI
681
+ with torch.amp.autocast('cuda'):
682
+ rsi_quantiles, rsi_mean = pipe.predict_quantiles(
683
+ context=rsi_context_tensor,
684
+ prediction_length=min(actual_prediction_length, 64),
685
+ quantile_levels=[0.1, 0.5, 0.9]
686
+ )
687
+
688
+ # Convert and denormalize RSI predictions
689
+ rsi_mean = rsi_mean.detach().cpu().numpy()
690
+ rsi_pred = rsi_scaler.inverse_transform(rsi_mean.reshape(-1, 1)).flatten()
691
+
692
+ # Clamp RSI to valid range (0-100)
693
+ rsi_pred = np.clip(rsi_pred, 0, 100)
694
+
695
+ # Extend RSI predictions if needed
696
+ if len(rsi_pred) < len(mean_pred):
697
+ last_rsi = rsi_pred[-1]
698
+ extension_length = len(mean_pred) - len(rsi_pred)
699
+ rsi_extension = np.full(extension_length, last_rsi)
700
+ rsi_pred = np.concatenate([rsi_pred, rsi_extension])
701
+ except Exception as e:
702
+ print(f"RSI prediction error: {str(e)}")
703
+ # Fallback: use last known RSI value
704
+ last_rsi = df['RSI'].iloc[-1]
705
+ rsi_pred = np.full(len(mean_pred), last_rsi)
706
+
707
+ try:
708
+ # Prepare MACD data for Chronos
709
+ macd_data = df['MACD'].values
710
+ if len(macd_data) >= 64 and not np.any(np.isnan(macd_data)):
711
+ # Normalize MACD data
712
+ macd_scaler = MinMaxScaler(feature_range=(-1, 1))
713
+ normalized_macd = macd_scaler.fit_transform(macd_data.reshape(-1, 1)).flatten()
714
+
715
+ # Use last 64 points for MACD prediction
716
+ macd_context = normalized_macd[-64:]
717
+ macd_context_tensor = torch.tensor(macd_context, dtype=dtype, device=device)
718
+ if len(macd_context_tensor.shape) == 1:
719
+ macd_context_tensor = macd_context_tensor.unsqueeze(0)
720
+
721
+ # Predict MACD
722
+ with torch.amp.autocast('cuda'):
723
+ macd_quantiles, macd_mean = pipe.predict_quantiles(
724
+ context=macd_context_tensor,
725
+ prediction_length=min(actual_prediction_length, 64),
726
+ quantile_levels=[0.1, 0.5, 0.9]
727
+ )
728
+
729
+ # Convert and denormalize MACD predictions
730
+ macd_mean = macd_mean.detach().cpu().numpy()
731
+ macd_pred = macd_scaler.inverse_transform(macd_mean.reshape(-1, 1)).flatten()
732
+
733
+ # Extend MACD predictions if needed
734
+ if len(macd_pred) < len(mean_pred):
735
+ last_macd = macd_pred[-1]
736
+ extension_length = len(mean_pred) - len(macd_pred)
737
+ macd_extension = np.full(extension_length, last_macd)
738
+ macd_pred = np.concatenate([macd_pred, macd_extension])
739
+ except Exception as e:
740
+ print(f"MACD prediction error: {str(e)}")
741
+ # Fallback: use last known MACD value
742
+ last_macd = df['MACD'].iloc[-1]
743
+ macd_pred = np.full(len(mean_pred), last_macd)
744
+
745
  except Exception as e:
746
  print(f"Chronos prediction error: {str(e)}")
747
  print(f"Error type: {type(e)}")
 
823
  row=2, col=1
824
  )
825
 
826
+ # Add predicted technical indicators if available
827
+ if rsi_pred is not None:
828
+ fig.add_trace(
829
+ go.Scatter(x=pred_dates, y=rsi_pred, name='Predicted RSI',
830
+ line=dict(color='purple', dash='dash')),
831
+ row=2, col=1
832
+ )
833
+
834
+ if macd_pred is not None:
835
+ fig.add_trace(
836
+ go.Scatter(x=pred_dates, y=macd_pred, name='Predicted MACD',
837
+ line=dict(color='orange', dash='dash')),
838
+ row=2, col=1
839
+ )
840
+
841
  # Add volume
842
  fig.add_trace(
843
  go.Bar(x=df.index, y=df['Volume'], name='Volume',
 
845
  row=3, col=1
846
  )
847
 
848
+ # Add predicted volume if available
849
+ if volume_pred is not None:
850
+ fig.add_trace(
851
+ go.Bar(x=pred_dates, y=volume_pred, name='Predicted Volume',
852
+ marker_color='red', opacity=0.7),
853
+ row=3, col=1
854
+ )
855
+
856
  # Update layout with timeframe-specific settings
857
  fig.update_layout(
858
  title=f'{symbol} {timeframe} Analysis and Prediction',
 
875
  "strategy_used": strategy
876
  })
877
 
878
+ # Add predicted indicators to signals if available
879
+ if volume_pred is not None:
880
+ signals["predicted_volume"] = volume_pred.tolist()
881
+ if rsi_pred is not None:
882
+ signals["predicted_rsi"] = rsi_pred.tolist()
883
+ if macd_pred is not None:
884
+ signals["predicted_macd"] = macd_pred.tolist()
885
+
886
  return signals, fig
887
 
888
  except Exception as e: