Vai al contenuto

Applicazioni pratiche di machine learning/Previsioni su azioni, criptovalute, derivati

Wikibooks, manuali e libri di testo liberi.
Indice del libro

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)

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.