Spaces:
Paused
Paused
Tonic commited on
adds confidence bands back , removes line graph, fixes volume prediction and display
Browse files
app.py
CHANGED
|
@@ -1666,11 +1666,11 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
|
|
| 1666 |
else: # 15m
|
| 1667 |
pred_dates = pd.date_range(start=last_date + timedelta(minutes=15), periods=prediction_days * 96)
|
| 1668 |
|
| 1669 |
-
# Create enhanced visualization
|
| 1670 |
-
fig = make_subplots(rows=
|
| 1671 |
shared_xaxes=True,
|
| 1672 |
vertical_spacing=0.05,
|
| 1673 |
-
subplot_titles=('Price Prediction', 'Technical Indicators', 'Volume
|
| 1674 |
|
| 1675 |
# Add historical price
|
| 1676 |
fig.add_trace(
|
|
@@ -1679,38 +1679,98 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
|
|
| 1679 |
row=1, col=1
|
| 1680 |
)
|
| 1681 |
|
| 1682 |
-
# Add predicted price with uncertainty bands
|
| 1683 |
fig.add_trace(
|
| 1684 |
go.Scatter(x=pred_dates, y=final_pred, name='Predicted Price',
|
| 1685 |
-
line=dict(color='red', width=
|
| 1686 |
row=1, col=1
|
| 1687 |
)
|
| 1688 |
|
| 1689 |
-
# Add uncertainty bands
|
| 1690 |
-
|
| 1691 |
-
|
| 1692 |
-
|
| 1693 |
-
|
| 1694 |
-
|
| 1695 |
-
|
| 1696 |
-
|
| 1697 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1698 |
|
| 1699 |
-
|
| 1700 |
-
|
| 1701 |
-
|
| 1702 |
-
|
| 1703 |
-
|
| 1704 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1705 |
|
| 1706 |
-
# Add technical indicators
|
|
|
|
| 1707 |
fig.add_trace(
|
| 1708 |
go.Scatter(x=df.index, y=df['RSI'], name='RSI (Historical)',
|
| 1709 |
line=dict(color='purple', width=1)),
|
| 1710 |
row=2, col=1
|
| 1711 |
)
|
| 1712 |
|
| 1713 |
-
# Add predicted RSI if available
|
| 1714 |
if 'RSI' in technical_predictions:
|
| 1715 |
fig.add_trace(
|
| 1716 |
go.Scatter(x=pred_dates, y=technical_predictions['RSI'], name='RSI (Predicted)',
|
|
@@ -1736,13 +1796,13 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
|
|
| 1736 |
row=2, col=1
|
| 1737 |
)
|
| 1738 |
|
|
|
|
| 1739 |
fig.add_trace(
|
| 1740 |
go.Scatter(x=df.index, y=df['MACD'], name='MACD (Historical)',
|
| 1741 |
line=dict(color='orange', width=1)),
|
| 1742 |
row=2, col=1
|
| 1743 |
)
|
| 1744 |
|
| 1745 |
-
# Add predicted MACD if available
|
| 1746 |
if 'MACD' in technical_predictions:
|
| 1747 |
fig.add_trace(
|
| 1748 |
go.Scatter(x=pred_dates, y=technical_predictions['MACD'], name='MACD (Predicted)',
|
|
@@ -1776,49 +1836,8 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
|
|
| 1776 |
row=2, col=1
|
| 1777 |
)
|
| 1778 |
|
| 1779 |
-
# Add
|
| 1780 |
-
if 'BB_Upper' in df.columns and 'BB_Middle' in df.columns and 'BB_Lower' in df.columns:
|
| 1781 |
-
fig.add_trace(
|
| 1782 |
-
go.Scatter(x=df.index, y=df['BB_Upper'], name='BB Upper (Historical)',
|
| 1783 |
-
line=dict(color='gray', width=1, dash='dash')),
|
| 1784 |
-
row=1, col=1
|
| 1785 |
-
)
|
| 1786 |
-
|
| 1787 |
-
fig.add_trace(
|
| 1788 |
-
go.Scatter(x=df.index, y=df['BB_Middle'], name='BB Middle (Historical)',
|
| 1789 |
-
line=dict(color='gray', width=1)),
|
| 1790 |
-
row=1, col=1
|
| 1791 |
-
)
|
| 1792 |
-
|
| 1793 |
-
fig.add_trace(
|
| 1794 |
-
go.Scatter(x=df.index, y=df['BB_Lower'], name='BB Lower (Historical)',
|
| 1795 |
-
line=dict(color='gray', width=1, dash='dash')),
|
| 1796 |
-
row=1, col=1
|
| 1797 |
-
)
|
| 1798 |
-
|
| 1799 |
-
# Add predicted Bollinger Bands if available
|
| 1800 |
-
if 'BB_Upper' in technical_predictions:
|
| 1801 |
-
fig.add_trace(
|
| 1802 |
-
go.Scatter(x=pred_dates, y=technical_predictions['BB_Upper'], name='BB Upper (Predicted)',
|
| 1803 |
-
line=dict(color='darkgray', width=2, dash='dash')),
|
| 1804 |
-
row=1, col=1
|
| 1805 |
-
)
|
| 1806 |
-
|
| 1807 |
-
fig.add_trace(
|
| 1808 |
-
go.Scatter(x=pred_dates, y=technical_predictions['BB_Middle'], name='BB Middle (Predicted)',
|
| 1809 |
-
line=dict(color='darkgray', width=2)),
|
| 1810 |
-
row=1, col=1
|
| 1811 |
-
)
|
| 1812 |
-
|
| 1813 |
-
fig.add_trace(
|
| 1814 |
-
go.Scatter(x=pred_dates, y=technical_predictions['BB_Lower'], name='BB Lower (Predicted)',
|
| 1815 |
-
line=dict(color='darkgray', width=2, dash='dash')),
|
| 1816 |
-
row=1, col=1
|
| 1817 |
-
)
|
| 1818 |
-
|
| 1819 |
-
# Add volume with better data handling
|
| 1820 |
if 'Volume' in df.columns and not df['Volume'].isna().all():
|
| 1821 |
-
# Ensure volume data is numeric and handle any NaN values
|
| 1822 |
volume_data = pd.to_numeric(df['Volume'], errors='coerce').fillna(0)
|
| 1823 |
|
| 1824 |
fig.add_trace(
|
|
@@ -1862,64 +1881,27 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
|
|
| 1862 |
row=3, col=1
|
| 1863 |
)
|
| 1864 |
|
| 1865 |
-
#
|
| 1866 |
-
|
| 1867 |
-
|
| 1868 |
-
|
| 1869 |
-
|
| 1870 |
-
|
| 1871 |
-
|
| 1872 |
-
|
| 1873 |
-
|
| 1874 |
-
|
| 1875 |
-
|
| 1876 |
-
|
| 1877 |
-
|
| 1878 |
-
|
| 1879 |
-
|
| 1880 |
-
|
| 1881 |
-
)
|
| 1882 |
-
|
| 1883 |
-
fig.add_trace(
|
| 1884 |
-
go.Scatter(x=pred_dates, y=final_pred - confidence_95, name='95% Confidence Lower',
|
| 1885 |
-
line=dict(color='green', width=1, dash='dash'), fill='tonexty',
|
| 1886 |
-
fillcolor='rgba(0,255,0,0.1)', showlegend=False),
|
| 1887 |
-
row=4, col=1
|
| 1888 |
-
)
|
| 1889 |
-
|
| 1890 |
-
fig.add_trace(
|
| 1891 |
-
go.Scatter(x=pred_dates, y=final_pred + confidence_68, name='68% Confidence Upper',
|
| 1892 |
-
line=dict(color='darkgreen', width=1, dash='dot'), showlegend=False),
|
| 1893 |
-
row=4, col=1
|
| 1894 |
-
)
|
| 1895 |
-
|
| 1896 |
-
fig.add_trace(
|
| 1897 |
-
go.Scatter(x=pred_dates, y=final_pred - confidence_68, name='68% Confidence Lower',
|
| 1898 |
-
line=dict(color='darkgreen', width=1, dash='dot'), fill='tonexty',
|
| 1899 |
-
fillcolor='rgba(0,128,0,0.1)', showlegend=False),
|
| 1900 |
-
row=4, col=1
|
| 1901 |
-
)
|
| 1902 |
-
|
| 1903 |
-
# Add the main prediction line on top
|
| 1904 |
-
fig.add_trace(
|
| 1905 |
-
go.Scatter(x=pred_dates, y=final_pred, name='Prediction with Uncertainty',
|
| 1906 |
-
line=dict(color='darkgreen', width=3)),
|
| 1907 |
-
row=4, col=1
|
| 1908 |
-
)
|
| 1909 |
-
|
| 1910 |
-
# Add uncertainty magnitude as a separate line
|
| 1911 |
-
fig.add_trace(
|
| 1912 |
-
go.Scatter(x=pred_dates, y=uncertainty_clean, name='Uncertainty Magnitude',
|
| 1913 |
-
line=dict(color='orange', width=2)),
|
| 1914 |
-
row=4, col=1
|
| 1915 |
-
)
|
| 1916 |
-
else:
|
| 1917 |
-
print("Warning: No valid uncertainty data available for plotting")
|
| 1918 |
|
| 1919 |
# Update layout with better titles and axis labels
|
| 1920 |
fig.update_layout(
|
| 1921 |
title=f'Enhanced Stock Prediction for {symbol}',
|
| 1922 |
-
height=
|
| 1923 |
showlegend=True,
|
| 1924 |
legend=dict(
|
| 1925 |
orientation="h",
|
|
@@ -1931,16 +1913,15 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
|
|
| 1931 |
)
|
| 1932 |
|
| 1933 |
# Update subplot titles and axis labels
|
| 1934 |
-
fig.update_xaxes(title_text="Date", row=
|
| 1935 |
fig.update_yaxes(title_text="Price ($)", row=1, col=1)
|
| 1936 |
fig.update_yaxes(title_text="Technical Indicators", row=2, col=1)
|
| 1937 |
fig.update_yaxes(title_text="Volume", row=3, col=1)
|
| 1938 |
-
fig.update_yaxes(title_text="Price with Uncertainty ($)", row=4, col=1)
|
| 1939 |
|
| 1940 |
# Update subplot titles
|
| 1941 |
fig.update_annotations(
|
| 1942 |
dict(
|
| 1943 |
-
text="Price Prediction with
|
| 1944 |
x=0.5,
|
| 1945 |
y=0.95,
|
| 1946 |
xref="paper",
|
|
|
|
| 1666 |
else: # 15m
|
| 1667 |
pred_dates = pd.date_range(start=last_date + timedelta(minutes=15), periods=prediction_days * 96)
|
| 1668 |
|
| 1669 |
+
# Create enhanced visualization with uncertainties integrated
|
| 1670 |
+
fig = make_subplots(rows=3, cols=1,
|
| 1671 |
shared_xaxes=True,
|
| 1672 |
vertical_spacing=0.05,
|
| 1673 |
+
subplot_titles=('Price Prediction with Uncertainty', 'Technical Indicators with Uncertainty', 'Volume with Uncertainty'))
|
| 1674 |
|
| 1675 |
# Add historical price
|
| 1676 |
fig.add_trace(
|
|
|
|
| 1679 |
row=1, col=1
|
| 1680 |
)
|
| 1681 |
|
| 1682 |
+
# Add predicted price with integrated uncertainty bands
|
| 1683 |
fig.add_trace(
|
| 1684 |
go.Scatter(x=pred_dates, y=final_pred, name='Predicted Price',
|
| 1685 |
+
line=dict(color='red', width=3)),
|
| 1686 |
row=1, col=1
|
| 1687 |
)
|
| 1688 |
|
| 1689 |
+
# Add price uncertainty bands on the same subplot
|
| 1690 |
+
if final_uncertainty is not None and len(final_uncertainty) > 0:
|
| 1691 |
+
uncertainty_clean = np.array(final_uncertainty)
|
| 1692 |
+
uncertainty_clean = np.where(np.isnan(uncertainty_clean), 0, uncertainty_clean)
|
| 1693 |
+
|
| 1694 |
+
# Create confidence bands
|
| 1695 |
+
confidence_68 = uncertainty_clean # 1 standard deviation (68% confidence)
|
| 1696 |
+
confidence_95 = 2 * uncertainty_clean # 2 standard deviations (95% confidence)
|
| 1697 |
+
|
| 1698 |
+
# Plot 95% confidence bands
|
| 1699 |
+
fig.add_trace(
|
| 1700 |
+
go.Scatter(x=pred_dates, y=final_pred + confidence_95, name='95% Confidence Upper',
|
| 1701 |
+
line=dict(color='red', width=1, dash='dash'), showlegend=False),
|
| 1702 |
+
row=1, col=1
|
| 1703 |
+
)
|
| 1704 |
+
|
| 1705 |
+
fig.add_trace(
|
| 1706 |
+
go.Scatter(x=pred_dates, y=final_pred - confidence_95, name='95% Confidence Lower',
|
| 1707 |
+
line=dict(color='red', width=1, dash='dash'), fill='tonexty',
|
| 1708 |
+
fillcolor='rgba(255,0,0,0.1)', showlegend=False),
|
| 1709 |
+
row=1, col=1
|
| 1710 |
+
)
|
| 1711 |
+
|
| 1712 |
+
# Plot 68% confidence bands
|
| 1713 |
+
fig.add_trace(
|
| 1714 |
+
go.Scatter(x=pred_dates, y=final_pred + confidence_68, name='68% Confidence Upper',
|
| 1715 |
+
line=dict(color='darkred', width=1, dash='dot'), showlegend=False),
|
| 1716 |
+
row=1, col=1
|
| 1717 |
+
)
|
| 1718 |
+
|
| 1719 |
+
fig.add_trace(
|
| 1720 |
+
go.Scatter(x=pred_dates, y=final_pred - confidence_68, name='68% Confidence Lower',
|
| 1721 |
+
line=dict(color='darkred', width=1, dash='dot'), fill='tonexty',
|
| 1722 |
+
fillcolor='rgba(139,0,0,0.1)', showlegend=False),
|
| 1723 |
+
row=1, col=1
|
| 1724 |
+
)
|
| 1725 |
|
| 1726 |
+
# Add Bollinger Bands if available (on price subplot)
|
| 1727 |
+
if 'BB_Upper' in df.columns and 'BB_Middle' in df.columns and 'BB_Lower' in df.columns:
|
| 1728 |
+
fig.add_trace(
|
| 1729 |
+
go.Scatter(x=df.index, y=df['BB_Upper'], name='BB Upper (Historical)',
|
| 1730 |
+
line=dict(color='gray', width=1, dash='dash')),
|
| 1731 |
+
row=1, col=1
|
| 1732 |
+
)
|
| 1733 |
+
|
| 1734 |
+
fig.add_trace(
|
| 1735 |
+
go.Scatter(x=df.index, y=df['BB_Middle'], name='BB Middle (Historical)',
|
| 1736 |
+
line=dict(color='gray', width=1)),
|
| 1737 |
+
row=1, col=1
|
| 1738 |
+
)
|
| 1739 |
+
|
| 1740 |
+
fig.add_trace(
|
| 1741 |
+
go.Scatter(x=df.index, y=df['BB_Lower'], name='BB Lower (Historical)',
|
| 1742 |
+
line=dict(color='gray', width=1, dash='dash')),
|
| 1743 |
+
row=1, col=1
|
| 1744 |
+
)
|
| 1745 |
+
|
| 1746 |
+
# Add predicted Bollinger Bands if available
|
| 1747 |
+
if 'BB_Upper' in technical_predictions:
|
| 1748 |
+
fig.add_trace(
|
| 1749 |
+
go.Scatter(x=pred_dates, y=technical_predictions['BB_Upper'], name='BB Upper (Predicted)',
|
| 1750 |
+
line=dict(color='darkgray', width=2, dash='dash')),
|
| 1751 |
+
row=1, col=1
|
| 1752 |
+
)
|
| 1753 |
+
|
| 1754 |
+
fig.add_trace(
|
| 1755 |
+
go.Scatter(x=pred_dates, y=technical_predictions['BB_Middle'], name='BB Middle (Predicted)',
|
| 1756 |
+
line=dict(color='darkgray', width=2)),
|
| 1757 |
+
row=1, col=1
|
| 1758 |
+
)
|
| 1759 |
+
|
| 1760 |
+
fig.add_trace(
|
| 1761 |
+
go.Scatter(x=pred_dates, y=technical_predictions['BB_Lower'], name='BB Lower (Predicted)',
|
| 1762 |
+
line=dict(color='darkgray', width=2, dash='dash')),
|
| 1763 |
+
row=1, col=1
|
| 1764 |
+
)
|
| 1765 |
|
| 1766 |
+
# Add technical indicators with their uncertainties on the same subplot
|
| 1767 |
+
# RSI with uncertainty
|
| 1768 |
fig.add_trace(
|
| 1769 |
go.Scatter(x=df.index, y=df['RSI'], name='RSI (Historical)',
|
| 1770 |
line=dict(color='purple', width=1)),
|
| 1771 |
row=2, col=1
|
| 1772 |
)
|
| 1773 |
|
|
|
|
| 1774 |
if 'RSI' in technical_predictions:
|
| 1775 |
fig.add_trace(
|
| 1776 |
go.Scatter(x=pred_dates, y=technical_predictions['RSI'], name='RSI (Predicted)',
|
|
|
|
| 1796 |
row=2, col=1
|
| 1797 |
)
|
| 1798 |
|
| 1799 |
+
# MACD with uncertainty
|
| 1800 |
fig.add_trace(
|
| 1801 |
go.Scatter(x=df.index, y=df['MACD'], name='MACD (Historical)',
|
| 1802 |
line=dict(color='orange', width=1)),
|
| 1803 |
row=2, col=1
|
| 1804 |
)
|
| 1805 |
|
|
|
|
| 1806 |
if 'MACD' in technical_predictions:
|
| 1807 |
fig.add_trace(
|
| 1808 |
go.Scatter(x=pred_dates, y=technical_predictions['MACD'], name='MACD (Predicted)',
|
|
|
|
| 1836 |
row=2, col=1
|
| 1837 |
)
|
| 1838 |
|
| 1839 |
+
# Add volume with uncertainty on the same subplot
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1840 |
if 'Volume' in df.columns and not df['Volume'].isna().all():
|
|
|
|
| 1841 |
volume_data = pd.to_numeric(df['Volume'], errors='coerce').fillna(0)
|
| 1842 |
|
| 1843 |
fig.add_trace(
|
|
|
|
| 1881 |
row=3, col=1
|
| 1882 |
)
|
| 1883 |
|
| 1884 |
+
# Add reference lines for technical indicators
|
| 1885 |
+
# RSI overbought/oversold lines
|
| 1886 |
+
fig.add_hline(y=70, line_dash="dash", line_color="red",
|
| 1887 |
+
annotation_text="Overbought (70)", row=2, col=1)
|
| 1888 |
+
fig.add_hline(y=30, line_dash="dash", line_color="green",
|
| 1889 |
+
annotation_text="Oversold (30)", row=2, col=1)
|
| 1890 |
+
|
| 1891 |
+
# MACD zero line
|
| 1892 |
+
fig.add_hline(y=0, line_dash="dash", line_color="black",
|
| 1893 |
+
annotation_text="MACD Zero", row=2, col=1)
|
| 1894 |
+
|
| 1895 |
+
# Add volume reference line (average volume)
|
| 1896 |
+
if 'Volume' in df.columns and not df['Volume'].isna().all():
|
| 1897 |
+
avg_volume = df['Volume'].mean()
|
| 1898 |
+
fig.add_hline(y=avg_volume, line_dash="dash", line_color="blue",
|
| 1899 |
+
annotation_text=f"Avg Volume: {avg_volume:,.0f}", row=3, col=1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1900 |
|
| 1901 |
# Update layout with better titles and axis labels
|
| 1902 |
fig.update_layout(
|
| 1903 |
title=f'Enhanced Stock Prediction for {symbol}',
|
| 1904 |
+
height=900, # Adjusted height for 3 subplots
|
| 1905 |
showlegend=True,
|
| 1906 |
legend=dict(
|
| 1907 |
orientation="h",
|
|
|
|
| 1913 |
)
|
| 1914 |
|
| 1915 |
# Update subplot titles and axis labels
|
| 1916 |
+
fig.update_xaxes(title_text="Date", row=3, col=1)
|
| 1917 |
fig.update_yaxes(title_text="Price ($)", row=1, col=1)
|
| 1918 |
fig.update_yaxes(title_text="Technical Indicators", row=2, col=1)
|
| 1919 |
fig.update_yaxes(title_text="Volume", row=3, col=1)
|
|
|
|
| 1920 |
|
| 1921 |
# Update subplot titles
|
| 1922 |
fig.update_annotations(
|
| 1923 |
dict(
|
| 1924 |
+
text="Price Prediction with Uncertainty",
|
| 1925 |
x=0.5,
|
| 1926 |
y=0.95,
|
| 1927 |
xref="paper",
|