Spaces:
Running
on
Zero
Running
on
Zero
attempt to predict technicals and volume
Browse files
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:
|