Predicting Cryptocurrency Prices using Machine Learning


 

by Nicholas Resendez 

I have a Deep Neural Network Machine Learning algorithm to predict the price of Cryptocurrencies.

Want to see?

Here are the results.

Picture 1

Predicting the Price of Litecoin using Machine Learning (LSTM)

Creating Long Term Short Term Memory (LSTM) neural networks to predict stock prices has been done for quite some time.

While typically used for time series, these algorithms have become popular when predicting market conditions in relation to price, marketcap, etc.

This algorithm utilizes Python and Keras.

Find the Data

Let’s fetch the Litecoin price over a series of 1000 days. We can use cryptocompare API to fetch the data.


endpoint = 'https://min-api.cryptocompare.com/data/histoday'
res = requests.get(endpoint + '?fsym=LTC&tsym=USD&limit=1000')
hist = pd.DataFrame(json.loads(res.content)['Data'])
hist = hist.set_index('time')
hist.index = pd.to_datetime(hist.index, unit='s')
hist.head()
//code used from n3ocortex

Picture 2 Past Litecoin price data.

Train the Data-set

We can then split our data and use it to train our dataset. We will use 33% of our previous data. The close column of the DataFrame will be the daily closing price for which we will predict.

def train_test_split(df, test_size=0.33):
    split_row = len(df) - int(test_size * len(df))
    train_data = df.iloc[:split_row]
    test_data = df.iloc[split_row:]
    return train_data, test_data
def line_plot(line1, line2, label1=None, label2=None, title=''):
    fig, ax = plt.subplots(1, figsize=(16, 9))
    ax.plot(line1, label=label1, linewidth=2)
    ax.plot(line2, label=label2, linewidth=2)
    ax.set_ylabel('price [USD]', fontsize=14)
    ax.set_title(title, fontsize=18)
    ax.legend(loc='best', fontsize=18)
train, test = train_test_split(hist, test_size=0.33)
line_plot(train.close, test.close, 'training', 'test', 'LTC')
//code used from n3ocortex

Picture 3

Normalize, Prepare, Build the Model

The LSTM will utilize a 5 day window. The normalized data will have a zero base and the other values will show us the change in respect to the first value. This means we will predict the price changes.

def normalise_zero_base(df):
    return df / df.iloc[0] - 1

def normalise_min_max(df):
    return (df - df.min()) / (data.max() - df.min())

def extract_window_data(df, window_len=10, zero_base=True):
    
    window_data = []
    for idx in range(len(df) - window_len):
        tmp = df[idx: (idx + window_len)].copy()
        if zero_base:
            tmp = normalise_zero_base(tmp)
        window_data.append(tmp.values)
    return np.array(window_data)

def prepare_data(df, target_col, window_len=10, zero_base=True, test_size=0.2):
    train_data, test_data = train_test_split(df, test_size=test_size)
    
    X_train = extract_window_data(train_data, window_len, zero_base)
    X_test = extract_window_data(test_data, window_len, zero_base)
    
    y_train = train_data[target_col][window_len:].values
    y_test = test_data[target_col][window_len:].values
    if zero_base:
        y_train = y_train / train_data[target_col][:-window_len].values - 1
        y_test = y_test / test_data[target_col][:-window_len].values - 1

    return train_data, test_data, X_train, X_test, y_train, y_test

def build_lstm_model(input_data, output_size, neurons=20, activ_func='linear',
                     dropout=0.25, loss='mae', optimizer='adam'):
    model = Sequential()

    model.add(LSTM(neurons, input_shape=(input_data.shape[1], input_data.shape[2])))
    model.add(Dropout(dropout))
    model.add(Dense(units=output_size))
    model.add(Activation(activ_func))

    model.compile(loss=loss, optimizer=optimizer)
    return model

np.random.seed(42)

# data params
window_len = 5
test_size = 0.3
zero_base = True

# model params
lstm_neurons = 20
epochs = 50
batch_size = 4
loss = 'mae'
dropout = 0.25
optimizer = 'adam'

The neural network consists of 20 neurons with a dopout factor of 0.25. 


train, test, X_train, X_test, y_train, y_test = prepare_data(
    hist, target_col, window_len=window_len, zero_base=zero_base, test_size=test_size)



model = build_lstm_model(
    X_train, output_size=1, neurons=lstm_neurons, dropout=dropout, loss=loss,
    optimizer=optimizer)
history = model.fit(
    X_train, y_train, epochs=epochs, batch_size=batch_size, verbose=1, shuffle=True)
    //code used from n3ocortex

Results

The trained model shows us a graph of actual and prediction of Litecoin price.

Picture 1

Compare Returns

Setting actual returns and predicted returns, we can get a better understanding of our data.

actual_returns = targets.pct_change()[1:]
predicted_returns = preds.pct_change()[1:]

def dual_line_plot(line1, line2, line3, line4, label1=None, label2=None, title='', lw=2):
    import matplotlib.dates as mdates
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(21, 9))
    ax1.plot(line1, label=label1, linewidth=lw)
    ax1.plot(line2, label=label2, linewidth=lw)
    ax2.plot(line3, label=label1, linewidth=lw)
    ax2.plot(line4, label=label2, linewidth=lw)
    ax2.set_xticks(ax1.get_xticks())
    ax2.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
    ax1.set_ylabel('daily returns', fontsize=14)
    ax2.legend(loc='best', fontsize=18);

dual_line_plot(actual_returns[-n_points:],
          predicted_returns[-n_points:],
          actual_returns[-n_points:][:-1],
          predicted_returns[-n_points:].shift(-1),
          'actual returns', 'predicted returns', lw=3)
	  //code used from n3ocortex

Picture 4

Conclusion

We have successfully setup a predictive model which uses machine learning algorithm (LSTM) to train/split test data to predict the price of Litecoin.

The network we built successfully learned but ultimately bases data off past performance, which we know is not a clear indication of cryptocurrency price.

Disclaimer: These models should not be used for personal or commercial trading, they should be seen as an educational model to learn more about market conditions.

Future work

Utilizing social media and news data for a better prediction of market conditions. We all know how fear, uncertainty, and doubt (FUD) can play a part in cryptocurrency price, and it would be interesting to see how price correlates with media coverage.

Thanks to n3ocortex for a great explanation of the algorithm and code.

Back to blog