主页 > imtoken > 如何在技术上成功预测比特币价格?

如何在技术上成功预测比特币价格?

imtoken 2023-03-27 07:39:19

点击上方“CSDN”,选择“知鼎公众号”

关键时刻第一时间送达!

许多论点声称可以通过深度学习网络准确预测加密货币的价格走势。本文用实际数据打脸:别上当了!这种所谓的“准确预测”有很多陷阱。

640?wx_fmt=jpeg

以下为译文:

我尝试建立一个深度神经网络来预测比特币的价格,结果令人难以置信。

想知道发生了什么吗?先来看看我的预测吧。

640?wx_fmt=png

看起来很准确,不是吗?

你不用问,我直接告诉你答案:是的,上面的测试是在之前没有遇到过的数据上做的,模型训练时只使用之前的数据(详情会稍后解释)。

看来这是发财的摇钱树啊!对?其实我可以把上面模型的代码给你,然后你就可以自己用了……

好吧,别这样!请勿在交易中使用此模型,虽然这些看似准确的结果具有相当的欺骗性,但请不要上当。

比特币技术

让我详细解释一下。

出了点问题。

在过去的几周甚至几个月前,我阅读了太多与上图类似的方式显示加密货币价格预测的文章。

但是,这些极其准确的价格预测应该会立即提醒您。 “如果某件事好得令人难以置信,那通常是假的。——艾美·罗森”

现在我想说明为什么会这样。

但不要误会我的意思——我并不是要否认这些文章的努力。这些文章真的很好,值得鼓掌。事实上,许多方法在理论上确实非常准确。本文的主要目的是揭示为什么这些模型在实践中是不合理的?为什么他们的预测不一定适合实际交易?

使用 LSTM 预测比特币价格

为了便于说明,先引入多维LSTM(Long Short-Term Memory)神经网络来预测比特币价格,并生成上述预测结果示例。

LSTM 是一种特殊的 RNN(循环神经网络),非常适用于时间序列问题。因此,LSTM 在预测加密货币价格和股票市场方面非常受欢迎。

如果你想进一步了解 LSTM,可以阅读这两篇文章:

以下 LSTM 实现使用 Python 和 Keras()。

查看我的 Github 以获取相应的 Jupyter Notebook:

比特币技术

获取数据

首先,我下载了比特币的历史价格数据(你也可以下载其他任何加密数据)。这可以使用 cryptocompare() API 来完成:

import json
import requests
import pandas as pd
endpoint = 'https://min-api.cryptocompare.com/data/histoday'
res = requests.get(endpoint + '?fsym=BTC&tsym=USD&limit=2000')
hist = pd.DataFrame(json.loads(res.content)['Data'])
hist = hist.set_index('time')
hist.index = pd.to_datetime(hist.index, unit='s')
hist.head()

640?wx_fmt=png

传奇:比特币历史部分价格数据

这样我们就有了过去 2000 天的 BTC 数据,从 2012/10/10 到 2018/4/4。

拆分训练集和测试集

接下来比特币技术,我将数据分成训练集和测试集。使用最后 10% 的数据作为测试,使分界线在 2017/9/14。此日期之前的所有数据都用于训练,此日期之后的数据用于测试训练好的模型。下面,我绘制了 DataFrame 的收盘列,这是我们要预测的每日收盘价。

def train_test_split(df, test_size=0.1):
   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.1)
line_plot(train.close, test.close, 'training', 'test', 'BTC')

640?wx_fmt=png

图例:比特币历史价格数据分为训练集和测试集

构建模型

比特币技术

为了训练LSTM,我们把数据分成7天的时间段(时间长短可以选择,我简单用一周作为时间段),每个时间段都归零数据归一化基于零基,即每个时间段内的第一个数据为0,其他值代表相对于第一个数据的相对变化。因此,这里预测的是价格变动,而不是绝对价格。

def normalise_zero_base(df):
   """ Normalise dataframe column-wise to reflect changes with
       respect to first entry.
   """

   return df / df.iloc[0] - 1
def extract_window_data(df, window=7, zero_base=True):
   """ Convert dataframe to overlapping sequences/windows of
       length `window`.
   """

   window_data = []
   for idx in range(len(df) - window):
       tmp = df[idx: (idx + window)].copy()
       if zero_base:
           tmp = normalise_zero_base(tmp)
       window_data.append(tmp.values)
   return np.array(window_data)
def prepare_data(df, window=7, zero_base=True, test_size=0.1):
   """ Prepare data for LSTM. """
   # train test split
   train_data, test_data = train_test_split(df, test_size)
   # extract window data
   X_train = extract_window_data(train_data, window, zero_base)
   X_test = extract_window_data(test_data, window, zero_base)
   # extract targets
   y_train = train_data.close[window:].values
   y_test = test_data.close[window:].values
   if zero_base:
       y_train = y_train / train_data.close[:-window].values - 1
       y_test = y_test / test_data.close[:-window].values - 1
   return train_data, test_data, X_train, X_test, y_train, y_test
train, test, X_train, X_test, y_train, y_test = prepare_data(hist)

这里使用一个简单的神经网络,包括一个由20个神经元组成的LSTM层,dropout率为0.25,还有一个密集层(Dense),激活函数是一个简单的线性函数另外,损失函数使用MAE(Mean Absolute Error,平均绝对误差),优化器使用Adam。

我对网络进行了 50 个 epoch 的训练,批量大小为 4。

注意:网络架构和所有参数可以任意选择,我这里没有做任何优化,因为这不是本文的中心点。

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
model = build_lstm_model(X_train, output_size=1)
history = model.fit(X_train, y_train, epochs=50, batch_size=4)

结果

使用训练好的模型预测剩余的测试集得到本文开头的图片。

640?wx_fmt=png

那么这些结果有什么问题呢?仔细查看并放大最近 30 天的图像。

targets = test[target_col][window:]
preds = model.predict(X_test).squeeze()
# convert change predictions back to actual price
preds = test.close.values[:-window] * (preds + 1)
preds = pd.Series(index=targets.index, data=preds)
n = 30
line_plot(targets[-n:], preds[-n:], 'actual', 'prediction')

640?wx_fmt=png

比特币技术

看到了吗?

正如您可能已经猜到的那样,这个模型的根本问题是,对于给定日期的预测,它与前一天的实际结果几乎相同。

预测曲线似乎只是将实际曲线移动了一天。

实际上,如果预测曲线移动一天,这个结论会更加明显。

line_plot(targets[-n:][:-1], preds[-n:].shift(-1))

640?wx_fmt=png

如上图,预测曲线和实际曲线完美匹配,说明模型实际学习了前一天的价格。

结果与我在许多使用 LSTM 进行单点预测的示例中看到的结果相同。

为了更明确,让我们计算预测回报和实际回报:

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

观察 实际和预测的返回结果,一个是原始形式,一个是偏移一天的形式,可以得出相同的结论。

640?wx_fmt=png

比特币技术

实际和预测的返回结果,左图中预测结果调整了一天。

实际上,如果我们计算实际结果和预测结果的相关性,可以得出以下结论:

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(18, 9))
# actual correlation
corr = np.corrcoef(actual_returns, predicted_returns)[0][1]
ax1.scatter(actual_returns, predicted_returns, color='k')
ax1.set_title('r = {:.2f}'.format(corr), fontsize=18)
# shifted correlation
shifted_actual = actual_returns[:-1]
shifted_predicted = predicted_returns.shift(-1).dropna()
corr = np.corrcoef(shifted_actual, shifted_predicted)[0][1]
ax2.scatter(shifted_actual, shifted_predicted, color='k')
ax2.set_title('r = {:.2f}'.format(corr));

640?wx_fmt=png

从上图中可以看出比特币技术,实际回报和预测回报实际上并不相关。然而,在将预测收益偏移一天后,观察到强相关性,表明预测结果与实际比特币数据重复。

总结

本文的目的是讨论我在过去几个月中看到的许多使用深度神经网络预测加密货币和股票市场价格的示例。这些文章在这里使用了类似的方法:使用历史价格数据来实现 LSTM 并预测未来的走势。

这篇文章说明了为什么这些模型不能用于真实交易。

是的,互联网在学习方面非常有效。然而,学习的策略是预测一个尽可能接近前一天的值,因为这将产生最小的平均绝对误差。但是,无论这种预测结果对损失函数的预测有多准确,在实践中,仅基于历史价格数据的单点预测模型的结果仍然难以准确,在实际交易中几乎没有用处。

当然,在价格预测方面,可能有更复杂的方法来实现更有用的 LSTM。您可以从使用更多数据开始,同时优化网络结构和超参数。但我认为它更有可能使用历史价格数据以外的数据和特征。毕竟,投资界的共识是“过去的表现并不代表未来的产出”。

同样的结论也适用于加密货币。

免责声明:本文不是投资建议。本文和提供的模型仅用于教育目的。请不要用于交易或市场投资决策。

原文: