Applicazioni pratiche di machine learning/Previsioni su azioni, criptovalute, derivati
AZIONI
[modifica | modifica sorgente]Azioni, criptovalute e derivati sono caratterizzati da elevata volatilità, rumore nei dati e influenze esterne difficilmente modellabili, quindi i prezzi finanziari sono difficili da prevedere , pertanto modelli previsionali avanzati non garantiscono profitti. In questo articolo si faranno previsioni con Prophet, LinearRegression e RandomForestRegressor scegliendo quello che produce un errore previsionale minore.
Installazione librerie
[modifica | modifica sorgente]In un notebook Jupyter dopo avere creato un ambiente virtuale si scarica la libreria yfinance e le altre tramite:
pip install pandas
pip install matplotlib
pip install yfinance
pip install prophet
pip install scikit-learn
L'ambiente virtuale è necessario crearlo, per evitare conflitti tra le librerie scaricate rispettivamente con apt e pip . Per entrare nell'ambiente virtuale creato da Jupyter si seleziona Kernel --> Change Kernel .
Caricamento librerie
[modifica | modifica sorgente]import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import yfinance as yf
from prophet import Prophet
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error, root_mean_squared_error
Parte 1: Dati
[modifica | modifica sorgente]Collegarsi con Yahoo Finance da qui : https://it.finance.yahoo.com e cercare nell'apposita casella di ricerca l'azione TESLA. In corrispondenza del titolo dell'azione si legge : Tesla, Inc. (TSLA) quindi il simbolo dell'azione è TSLA . Scaricare i dati degli ultimi 5 anni di quote azionarie come pandas dataframe tramite la libreria yfinance passando il simbolo dell'azione. Si possono scaricare i dati per un periodo di tempo diverso, sostituendo il parametro period con uno dei seguenti valori:
1d: ultimo giorno 5d: ultimi 5 giorni 1mo: ultimo mese 3mo: ultimi 3 mesi 6mo: ultimi 6 mesi 1y: ultimo anno 2y: ultimi 2 anni 5y: ultimi 5 anni 10y: ultimi 10 anni ytd: da inizio anno a oggi max: tutti i dati disponibili
data = yf.download("TSLA", period='5Y')
Le variabili che interessano per la previsione sono Date e Close, quindi si crea un dataframe con tali variabili da fornire alla libreria Prophet:
data = data.reset_index()
data = data[['Date', 'Close']]
data.columns = ['ds', 'y']
# Print the output.
data.head()
Parte 2: Previsioni
[modifica | modifica sorgente]Si prevedono le quote azionarie di TESLA per i successivi 365 giorni a partire dall'ultima data disponibile nei dati scaricati e si traccia il grafico. La linea blu rappresenta la previsione, l'area ombreggiata celeste rappresenta l'intervallo di confidenza previsionale all'80%, mentre la linea nera rappresenta i dati reali:
m = Prophet(daily_seasonality = True) # the Prophet class (model)
m.fit(df) # fit the model using all data
future = m.make_future_dataframe(periods=365) #we need to specify the number of days in future
prediction = m.predict(future)
m.plot(prediction)
plt.title("Prediction of the Tesla Stock Price using the Prophet")
plt.xlabel("Date")
plt.ylabel("Close Stock Price")
plt.show()

Si prevedono le quote azionarie nei successivi 20 giorni e si visualizza la tabella delle previsioni con yhat previsione alla data ds e [yhat_lower, yhat_upper] intervallo di confidenza all'80%:
future = m.make_future_dataframe(periods=20) #we need to specify the number of days in future
prediction = m.predict(future)
prediction[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(20)
ds yhat yhat_lower yhat_upper 1256 2026-04-03 416.148699 371.716528 460.750515 1257 2026-04-04 417.746326 372.388732 464.770411 1258 2026-04-05 418.364354 373.579088 465.311336 1259 2026-04-06 419.955265 376.118794 467.335318 1260 2026-04-07 418.811049 370.591006 463.896723 1261 2026-04-08 419.087303 374.719526 463.456450 1262 2026-04-09 417.223413 372.379131 462.966878 1263 2026-04-10 418.478923 375.344127 469.486487 1264 2026-04-11 419.130260 373.078782 465.553853 1265 2026-04-12 418.869333 372.545574 463.567407 1266 2026-04-13 419.661288 376.807116 465.655037 1267 2026-04-14 417.808110 374.490678 464.735605 1268 2026-04-15 417.472613 370.688519 461.969838 1269 2026-04-16 415.098603 372.982666 461.005783 1270 2026-04-17 415.947298 371.930832 459.872842 1271 2026-04-18 416.294185 370.327939 460.597072 1272 2026-04-19 415.827800 367.497141 462.073262 1273 2026-04-20 416.507747 369.101295 463.302699 1274 2026-04-21 414.628583 366.432458 459.852383 1275 2026-04-22 414.344156 368.022605 458.613347
È fondamentale valutare le previsioni calcolando gli errori mae ed rmse sul testing set, costituito dagli ultimi 30 valori azionari nei dati scaricati, in modo da confrontare tali errori con quelli delle previsioni fatte con LinearRegression e RandomForestRegressor:
train = data[:-30]
test = data[-30:]
mae = mean_absolute_error(test['y'], prediction['yhat'][-30:])
rmse = root_mean_squared_error(test['y'], prediction['yhat'][-30:])
print("MAE=",mae)
print("RMSE=",rmse)
MAE= 114.52102529427317 RMSE= 116.883114345922
La previsione fatta con LinearRegression produce errori maggiori rispetto a quella fatta con Prophet, quindi si preferisce Prophet:
# dati
X = np.arange(len(data)).reshape(-1, 1)
y = data['y'].values
# split train/test
split = int(len(X) * 0.8)
X_train, X_test = X[:split], X[split:]
y_train, y_test = y[:split], y[split:]
# modello
model = LinearRegression()
model.fit(X_train, y_train)
# predizioni
y_pred = model.predict(X_test)
# metriche
mae = mean_absolute_error(y_test, y_pred)
rmse = root_mean_squared_error(y_test, y_pred)
print("MAE:", mae)
print("RMSE:", rmse)
MAE: 130.71524358030433 RMSE: 145.1068070164013
La previsione fatta con RandomForestRegressor produce errori maggiori rispetto a quella fatta con Prophet, quindi si preferisce Prophet:
model = RandomForestRegressor(n_estimators=100)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
mae = mean_absolute_error(y_test, y_pred)
rmse = root_mean_squared_error(y_test, y_pred)
print("MAE:", mae)
print("RMSE:", rmse)
MAE: 112.25284249441964 RMSE: 127.26623215841326
CRIPTOVALUTE
[modifica | modifica sorgente]Installazione librerie
[modifica | modifica sorgente]In un notebook Jupyter scaricare le seguenti librerie tramite:
pip install pandas
pip install matplotlib
pip install ccxt
pip install prophet
Caricamento librerie
[modifica | modifica sorgente]import pandas as pd
import ccxt
import matplotlib.pyplot as plt
from prophet import Prophet
Parte 1: Dati
[modifica | modifica sorgente]La libreria ccxt può gestire vari mercati di scambio di criptovalute elencati di seguito ma in questa analisi si utilizzerà Binance:
print(ccxt.exchanges)
['alpaca', 'ascendex', 'bequant', 'bigone', 'binance', 'binancecoinm', 'binanceus', 'binanceusdm', 'bit2c', 'bitbank', 'bitbay', 'bitbns', 'bitcoincom', 'bitfinex', 'bitfinex2', 'bitflyer', 'bitforex', 'bitget', 'bithumb', 'bitmart', 'bitmex', 'bitopro', 'bitpanda', 'bitrue', 'bitso', 'bitstamp', 'bitstamp1', 'bittrex', 'bitvavo', 'bkex', 'bl3p', 'blockchaincom', 'btcalpha', 'btcbox', 'btcex', 'btcmarkets', 'btctradeua', 'btcturk', 'buda', 'bybit', 'cex', 'coinbase', 'coinbaseprime', 'coinbasepro', 'coincheck', 'coinex', 'coinfalcon', 'coinmate', 'coinone', 'coinspot', 'cryptocom', 'currencycom', 'delta', 'deribit', 'digifinex', 'exmo', 'flowbtc', 'fmfwio', 'gate', 'gateio', 'gemini', 'hitbtc', 'hitbtc3', 'hollaex', 'huobi', 'huobijp', 'huobipro', 'idex', 'independentreserve', 'indodax', 'itbit', 'kraken', 'kucoin', 'kucoinfutures', 'kuna', 'latoken', 'lbank', 'lbank2', 'luno', 'lykke', 'mercado', 'mexc', 'mexc3', 'ndax', 'novadax', 'oceanex', 'okcoin', 'okex', 'okex5', 'okx', 'paymium', 'phemex', 'poloniex', 'poloniexfutures', 'probit', 'ripio', 'stex', 'therock', 'tidex', 'timex', 'tokocrypto', 'upbit', 'wavesexchange', 'wazirx', 'whitebit', 'woo', 'yobit', 'zaif', 'zb', 'zipmex', 'zonda']
# creare un'istanza di Binance
exchange = ccxt.binance()
# impostare il simbolo del bitcoin/euro su Binance
symbol ='BTC/EUR'
# impostare il periodo di tempo desiderato cioè giornaliero
timeframe = '1d'
# scaricare i dati del prezzo del bitcoin
ohlcv = exchange.fetch_ohlcv(symbol, timeframe)
# convertire i dati in un DataFrame di pandas
df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
# convertire la colonna timestamp in una colonna datetime
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
# visualizzare i dati
df.tail()
timestamp open high low close 495 2023-01-04 15803.30 16031.64 15771.00 15889.31 496 2023-01-05 15886.01 16034.95 15797.24 15993.84 497 2023-01-06 15993.84 16015.00 15809.07 15924.82 498 2023-01-07 15924.83 15954.45 15889.11 15917.02 499 2023-01-08 15916.00 15935.00 15888.88 15904.99
Le variabili che interessano per la previsione sono timestamp e close, quindi si crea un dataframe con tali variabili da fornire alla libreria Prophet:
data = df[["timestamp","close"]] # select Date and Price
# Rename the features: These names are NEEDED for the model fitting
data = data.rename(columns = {"timestamp":"ds","close":"y"}) #renaming the columns of the dataset
data.head()
Parte 2: Previsioni
[modifica | modifica sorgente]Si procede come nel caso delle azioni, prevedendo per i successivi 365 giorni a partire dall'ultima data disponibile nei dati scaricati il prezzo dei bitcoins e si traccia il grafico. La linea blu rappresenta la previsione, l'area ombreggiata celeste rappresenta l'intervallo di confidenza previsionale all'80%, mentre la linea nera rappresenta i dati reali:
m = Prophet(daily_seasonality = True) # the Prophet class (model)
m.fit(data) # fit the model using all data
future = m.make_future_dataframe(periods=365) #we need to specify the number of days in future
prediction = m.predict(future)
m.plot(prediction)
plt.title("Prediction of the Tesla Stock Price using the Prophet")
plt.xlabel("Date")
plt.ylabel("Close Stock Price")
plt.show()
Si prevede il prezzo dei bitcoin nei successivi 20 giorni e si visualizza la tabella delle previsioni con yhat previsione alla data ds e [yhat_lower, yhat_upper] intervallo di confidenza all'80%:
future = m.make_future_dataframe(periods=20) #we need to specify the number of days in future
prediction = m.predict(future)
prediction[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(20)
Conclusioni
[modifica | modifica sorgente]Uno dei vantaggi del machine learning è che può essere utilizzato per prevedere gli andamenti dei mercati in modo più preciso e tempestivo rispetto agli approcci basati sulla sola analisi umana. Inoltre, il machine learning può essere utilizzato per identificare pattern e trend nascosti che potrebbero non essere evidenti a un analista umano. Nonostante i vantaggi del machine learning, è importante notare che esso non è immune da errori e che le previsioni effettuate tramite questa tecnologia devono essere sempre prese con le dovute precauzioni.