Today, give a try to Techtonique web app, a tool designed to help you make informed, data-driven decisions using Mathematics, Statistics, Machine Learning, and Data Visualization. Here is a tutorial with audio, video, code, and slides: https://moudiki2.gumroad.com/l/nrhgb
This is the Python and JavaScript version of the Stock price forecasting with Deep Learning: throwing power at the problem (and why it won’t make you rich) post. Read the post for more details.
Contents:
Interactive dashboard
Stock price forecasting with Deep Learning: throwing power at the problem (and why it won't make you rich)
Observed and Forecast Values
Observed vs Forecast
Forecasting Residuals
Correct Guesses Distribution
Python code
!pip install nnetsauce
import matplotlib.pyplot as plt
import nnetsauce as ns
import pandas as pd
tscv = ns.utils.model_selection.TimeSeriesSplit()
stocks = pd.read_csv("https://raw.githubusercontent.com/Techtonique/datasets/refs/heads/main/time_series/multivariate/EuStockMarkets.csv")
stocks.head()
DAX | SMI | CAC | FTSE | |
---|---|---|---|---|
0 | 1628.75 | 1678.10 | 1772.80 | 2443.60 |
1 | 1613.63 | 1688.50 | 1750.50 | 2460.20 |
2 | 1606.51 | 1678.60 | 1718.00 | 2448.20 |
3 | 1621.04 | 1684.10 | 1708.10 | 2470.40 |
4 | 1618.16 | 1686.60 | 1723.10 | 2484.70 |
from tqdm import tqdm
n = stocks.shape[0]
half_n = n//2
for stock_index in range(stocks.shape[1]):
tscv_obj = tscv.split(stocks,
initial_window=half_n,
horizon=1,
fixed_window=False)
iterator = tqdm(tscv_obj, total=tscv.n_splits)
observed = [] # observed stock prices for the next day
forecasts = [] # random walk forecasts
correct_guesses = [] # correctly guessing the direction of stock price?
for i, (train_index, test_index) in enumerate(iterator):
observed.append(stocks.iloc[test_index[0], stock_index]) # observed stock price for the next day
forecasts.append(stocks.iloc[train_index[-1], stock_index]) # random walk forecast
if i == 0:
continue
correct_guesses.append(1 if ((observed[-1]-observed[-2])*(forecasts[-1]-forecasts[-2]) > 0) else 0)
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# Plot 1: Observed vs. Forecast Line Plot
axes[0, 0].plot(observed, label='Observed')
axes[0, 0].plot(forecasts, label='Forecast')
axes[0, 0].set_xlabel('Time')
axes[0, 0].set_ylabel('Stock Price')
axes[0, 0].set_title('Observed vs. Forecast')
axes[0, 0].legend()
# Plot 2: Observed vs. Forecast Scatter Plot
axes[0, 1].scatter(observed, forecasts, alpha=0.5)
axes[0, 1].plot([min(observed), max(observed)], [min(observed), max(observed)], color='red', linestyle='--', label='x=y')
axes[0, 1].set_xlabel('Observed Values')
axes[0, 1].set_ylabel('Forecast Values')
axes[0, 1].set_title('Observed vs. Forecast Scatterplot')
axes[0, 1].legend()
# Plot 3: Residuals Plot
residuals = [observed[i] - forecasts[i] for i in range(len(observed))]
axes[1, 0].plot(residuals)
axes[1, 0].axhline(y=0, color='r', linestyle='--')
axes[1, 0].set_xlabel('Time')
axes[1, 0].set_ylabel('Residuals (Observed - Forecast)')
axes[1, 0].set_title('Observed - Forecast Residuals')
# Plot 4: Percentage of Correct/Incorrect Direction Guesses
percentage_1 = (sum(correct_guesses) / len(correct_guesses)) * 100 if correct_guesses else 0
percentage_0 = 100 - percentage_1
categories = ['Correct Direction', 'Incorrect Direction']
percentages = [percentage_1, percentage_0]
axes[1, 1].bar(categories, percentages, color=['green', 'red'])
axes[1, 1].set_xlabel('Prediction Accuracy')
axes[1, 1].set_ylabel('Percentage')
axes[1, 1].set_title('Percentage of Correct and Incorrect Direction Guesses')
axes[1, 1].set_ylim(0, 100)
for i, v in enumerate(percentages):
axes[1, 1].text(i, v + 2, f'{v:.1f}%', ha='center', va='bottom')
plt.tight_layout() # Adjust layout to prevent overlapping
plt.show()
930it [00:00, 10694.50it/s]
100%|██████████| 930/930 [00:00<00:00, 12536.57it/s]
100%|██████████| 930/930 [00:00<00:00, 6134.14it/s]
100%|██████████| 930/930 [00:00<00:00, 8359.88it/s]
Comments powered by Talkyard.