您的位置:首页 > 区块链 >

Keras和Tensorflow可作为主要clarvoyance工具 可估计加密货币价格

2019-11-22 11:27:57 来源: 区块网

介 绍在本教程中,我们将介绍神经网络的原型,该模型将使我们能够使用Keras和Tensorflow作为我们的主要clarvoyance工具来估计未来的加密货币

介 绍

在本教程中,我们将介绍神经网络的原型,该模型将使我们能够使用Keras和Tensorflow作为我们的主要clarvoyance工具来估计未来的加密货币价格(作为二进制分类问题)。

然这很可能不是解决问题的最佳方法(毕竟投资银行在开发这种算法上投入了数十亿美元),但如果我们能够在55%以上的时间里把问题解决好,我们就有钱了!

我们要做什么

1. 使用Binance API下载数据

2. 预处理数据

3. 训练我们的模型

4. 特征工程

5. 评估性能最佳的模型

使用Binance API下载数据

对于此示例,我们将下载单个调用中可获取的最大数据量。如果您想训练更多更好的东西并在现实世界中使用它(不建议这样做,那么您可能会浪费真钱),我建议您使用多次调用收集更多数据。

import requests

import json

import pandas as pd

import datetime as dt

START_DATE = '2019-01-01'

END_DATE = '2019-10-01'

INTERVAL = '15m'

def parse_date(x):

return str(int(dt.datetime.fromisoformat(x).timestamp()))

def get_bars(symbol, interval):

root_url = 'https://api.binance.com/api/v1/klines'

url = root_url + '?symbol=' + symbol + '&interval=' + interval + '&startTime=' + parse_date(START_DATE) + '&limit=1000'

data = json.loads(requests.get(url).text)

df = pd.DataFrame(data)

df.columns = ['open_time',

'o', 'h', 'l', 'c', 'v',

'close_time', 'qav', 'num_trades',

'taker_base_vol', 'taker_quote_vol', 'ignore']

df.drop(['ignore', 'close_time'], axis=1, inplace=True)

return df

ethusdt = get_bars('ETHUSDT', INTERVAL)

ethusdt.to_csv('./data.csv', index=False)

在这段简单的代码中,我们需要必要的程序包,设置几个参数(我选择了15分钟的时间间隔,但是您可以选择更精细的时间间隔以进行更高频率的交易)并设置一些方便的函数,然后将数据保存到csv以供将来重用。这应该是不言而喻的,但如果有什么事情让你困惑,请随时留下评论,要求澄清:)

数据预处理

由于价格是顺序数据的一种形式,因此我们将使用LSTM层(长期短期记忆)作为我们网络中的第一层。我们希望将数据提供为一系列事件,这些事件将预测时间t + n处的价格,其中t是当前时间,n定义我们要预测的未来时间,为此,我们将数据作为 w长度的时间窗口。查看代码后,一切将变得更加清晰,让我们开始导入所需的软件包。

import pandas as pd

import numpy as np

import seaborn as sns

import random

from tensorflow.keras.models import Sequential

from tensorflow.keras.layers import Dense, LSTM, Dropout

from tensorflow.keras.callbacks import TensorBoard

import time

import matplotlib.pyplot as plt

这将导入Pandas,Numpy,我们训练模型所需的所有Tensorflow函数以及其他一些有用的软件包。

接下来,我们要定义一些常量,并从csv加载我们的数据(以防您在其他文件上编写训练代码:

WINDOW = 10 # how many time units we are going to use to evaluate

the future value, in our case each time unit is 15 minutes so we

are going to look at 15 * 10 = 150 minutes trading data

LOOKAHEAD = 5 # how far ahead we want to estimate if the future

prices is going to be higher or lower? In this case is 5 * 15 = 75

minutes in the future

VALIDATION_SAMPLES = 100 # We want to validate our model on data

that wasn't used for the training, we are establishing how many

data point we are going to use here.

data = pd.read_csv('./data.csv')

data['future_value'] = data['c'].shift(-LOOKAHEAD) # This allows us to

define a new column future_value with as the value of c 5 time units

in the future

data.drop([

'open_time'

], axis=1, inplace=True) # we don't care about the timestamp for

predicting future prices

让我们定义一个函数,该函数使我们可以定义将来的价格是高于还是低于当前收盘价:

def define_output(last, future):

if future > last:

return 1

else:

return 0

如果价格低于或等于当前收盘价,只需将目标设置为0,如果价格高于或高于当前收盘价,则将其设置为1。 现在让我们定义一个函数,该函数使我们能够创建需要输入神经网络的移动时间窗口:

def sequelize(x):

data = x.copy()

buys = []

sells = []

holds = []

data_length = len(data)

for index, row in data.iterrows():

if index <= data_length - WINDOW:

last_index = index + WINDOW -1

rowset = data[index : index + WINDOW]

row_stats = rowset.describe().transpose()

last_close = rowset['c'][last_index]

future_close = rowset['future_value'][last_index]

rowset = 2 * (rowset - row_stats['min']) / (row_stats['max'] - row_stats['min']) - 1

rowset.drop(['future_value'], axis=1, inplace=True)

rowset.fillna(0, inplace=True)

category = define_output(last_close, future_close)

if category == 1:

buys.append([rowset, category])

elif category == 0:

sells.append([rowset, category])

min_len = min(len(sells), len(buys))

results = sells[:min_len] + buys[:min_len]

return results

sequences = sequelize(data)

哦,好吧,这里有很多东西。让我们一点一点地看:

data = x.copy() # let's copy the dataframe, just in case

buys = []

sells = []

holds = []

data_length = len(data)

在这里,我们正在做一些初步的工作,复制数据框以确保我们不覆盖它(例如如果您使用Jupyter Notebook可能会很烦人),并设置用于买卖的数组,我们将使用它们来平衡数据。

for index, row in data.iterrows():

if index <= data_length - WINDOW:

last_index = index + WINDOW -1

rowset = data[index : index + WINDOW]

当我们迭代数据集中的每一行时,如果索引大于我们定义的窗口大小,我们可以创建一个新的数据块,即窗口大小。在将此数据存储到另一个数组中之前,我们需要使用以下代码对其进行规范化:

row_stats = rowset.describe().transpose()

last_close = rowset['c'][last_index]

future_close = rowset['future_value'][last_index] # we'll need to save this separately from the rest of the data

rowset = 2 * (rowset - row_stats['min']) / (row_stats['max'] - row_stats['min']) - 1

而且我们还想从数据集中删除future_value,并用0替换任何可能的NaN(对于我们的目的而言,理想情况还不够好):

rowset.drop(['future_value'], axis=1, inplace=True)

rowset.fillna(0, inplace=True)

最后我们要确保我们的买卖平衡,如果其中一种发生的频率比另一种发生的频率高,我们的网络将迅速偏向偏斜,并且无法为我们提供可靠的估计:

if category == 1:

buys.append([rowset, category])

elif category == 0:

sells.append([rowset, category])

# the following 2 lines will ensure that we have an equal amount of buys and sells

min_len = min(len(sells), len(buys))

results = sells[:min_len] + buys[:min_len]

return results

最后我们在数据序列上运行此函数= sequelize(data)

随机化我们的数据也是个好主意,这样我们的模型就不会受到数据集排序的精确顺序的影响,以下代码将对数据集进行随机化,将训练数据集与测试数据集进行拆分,并同时显示这两种数据中的买入与卖出分布数据集。随时重新运行此代码段,以确保更均衡地分配购买和出售:

random.shuffle(sequences)

def split_label_and_data(x):

length = len(x)

data_shape = x[0][0].shape

data = np.zeros(shape=(len(x),data_shape[0],data_shape[1]))

labels = np.zeros(shape=(length,))

for index in range(len(x)):

labels[index] = x[index][1]

data[index] = x[index][0]

return data, labels

x_train, y_train = split_label_and_data(sequences[: -VALIDATION_SAMPLES])

x_test, y_test = split_label_and_data(sequences[-VALIDATION_SAMPLES :])

sns.distplot(y_test)

sns.distplot(y_train)

len(y_train)

在运行了一段代码后,您应该得到类似的东西,两个数据集之间的买卖均分(左对右)。

训练模型

现在我们已经准备好训练模型,但是由于我们还没有探索哪种超参数最适合我们的模型和数据,因此我们将尝试一种稍微复杂一些的方法。 首先让我们定义四个超参数数组:

DROPOUTS = [

0.1,

0.2,

]

HIDDENS = [

32,

64,

128

]

OPTIMIZERS = [

'rmsprop',

'adam'

]

LOSSES = [

'mse',

'binary_crossentropy'

]

然后,我们将遍历每个数组以使用超参数组合来训练模型,以便以后可以使用TensorBoard比较它们:

for DROPOUT in DROPOUTS:

for HIDDEN in HIDDENS:

for OPTIMIZER in OPTIMIZERS:

for LOSS in LOSSES:

train_model(DROPOUT, HIDDEN, OPTIMIZER, LOSS)

现在我们需要定义train_model函数,该函数将实际创建和训练模型:

def train_model(DROPOUT, HIDDEN, OPTIMIZER, LOSS):

NAME = f"{HIDDEN} - Dropout {DROPOUT} - Optimizer {OPTIMIZER} - Loss {LOSS} - {int(time.time())}"

tensorboard = TensorBoard(log_dir=f"logs/{NAME}", histogram_freq=1)

model = Sequential([

LSTM(HIDDEN, activation='relu', input_shape=x_train[0].shape),

Dropout(DROPOUT),

Dense(HIDDEN, activation='relu'),

Dropout(DROPOUT),

Dense(1, activation='sigmoid')

])

model.compile(

optimizer=OPTIMIZER,

loss=LOSS,

metrics=['accuracy']

)

model.fit(

x_train,

y_train,

epochs=60,

batch_size=64,

verbose=1,

validation_data=(x_test, y_test),

callbacks=[

tensorboard

]

)

目前,这是一个非常简单的模型,其中的LSTM层为第一层,一个Dense中间层,一个Dense输出层,其大小为1,且为S型激活。该层将输出概率(从0到1),在LOOKAHEAD间隔之后,特定大小的WINDOW序列将跟随较高的收盘价,其中0是较低的收盘价的高概率,1是较高的更高的收盘价。

我们还添加了一个Tensorboard回调,这将使我们能够看到每种模型在每个训练周期(EPOCH)的表现。

随意运行此代码,然后在终端tensorboard --logdir = logs中运行Tensorboard

特征工程

最好的模型在验证数据上的准确性应该高于60%,这已经相当不错了。但是我们可以通过从现有数据集中提取更多数据来快速改进模型。从现有要素中提取新要素的过程称为要素工程。特征工程的示例是从数据中提取周末布尔值列,或从坐标对中提取国家/地区。在我们的案例中,我们将技术分析数据添加到我们的OHLC数据集中。

在笔记本或文件的顶部,添加ta包:from ta import *。

从csv加载数据后,添加以下行,它将以新列的形式将TA数据追加到我们现有的数据集中

data = pd.read_csv('./data.csv')

#add the following line

add_all_ta_features(data, "o", "h", "l", "c", "v", fillna=True)

data['future_value'] = data['c'].shift(-LOOKAHEAD)

就是这样,在几行中我们极大地丰富了我们的数据集。 现在我们可以运行模型生成器循环来弄清楚我们的模型如何使用新的数据集,这将花费更长的时间,但值得等待。

有意义的数据集应确保模型更准确,在上图中,我们可以清楚地看到丰富数据集的性能比简单数据集更好,验证准确性徘徊在80%左右!

评估性能最佳的模型

现在我们有了一些看起来在纸面上表现不错的模型,我们如何评估假设的交易系统中应该使用哪个模型?

这可能是非常主观的,但我认为一种好的方法是从已知的验证标签分别查看买卖,并绘制相应预测的分布。希望于所有购买,我们的模型都可以预测购买,而不是很多出售,反之亦然。

让我们定义一个显示每个模型的图表的函数:

def display_results(NAME, y_test, predictions):

plt.figure()

buys = []

sells = []

for index in range(len(y_test)):

if y_test[index] == 0:

sells.append(predictions[index])

elif y_test[index] == 1:

buys.append(predictions[index])

sns.distplot(buys, bins=10, color='green').set_title(NAME)

sns.distplot(sells, bins=10, color='red')

plt.show()

现在让我们在每次完成模型训练时都调用此函数:

model.fit(

x_train,

y_train,

epochs=60,

batch_size=64,

verbose=0,

validation_data=(x_test, y_test),

callbacks=[

tensorboard

]

)

# after the model.fit call, add the following 2 lines.

predictions = model.predict(x_test)

display_results(NAME, y_test, predictions)

随着不同模型的训练,我们现在应该看到类似于下图的图像,其中买入以绿色绘制(并且我们希望它们在右端,聚集在1值附近),卖出以红色绘制(聚集在 左侧为0个值)。这些应有助于我们确定哪种模型可以提供更可靠的未来价格估算。(链三丰)

就是这样,我们现在有一些原型可以使用,它们可以对未来的价格提供合理的估计。作为练习,请尝试以下操作:

1. 如果增加网络的隐藏层数会怎样?

2. 如果您的数据集不平衡会怎样?

3. 如果增加DROPOUT值会怎样?

4. 如果您在新数据上测试最佳模型会怎样?(例如通过从币安获取不同的时间戳记?)

关键词: Keras Tensorflow 加密货币价格

精选 导读

募资55亿港元万物云启动招股 预计9月29日登陆港交所主板

万科9月19日早间公告,万物云当日启动招股,预计发行价介乎每股47 1港元至52 7港元,预计9月29日登陆港交所主板。按发行1 167亿股计算,万

发布时间: 2022-09-20 10:39
管理   2022-09-20

公募基金二季度持股情况曝光 隐形重仓股多为高端制造业

随着半年报披露收官,公募基金二季度持股情况曝光。截至今年二季度末,公募基金全市场基金总数为9794只,资产净值为269454 75亿元,同比上

发布时间: 2022-09-02 10:45
资讯   2022-09-02

又有上市公司宣布变卖房产 上市公司粉饰财报动作不断

再有上市公司宣布变卖房产。四川长虹25日称,拟以1 66亿元的转让底价挂牌出售31套房产。今年以来,A股公司出售房产不断。根据记者不完全统

发布时间: 2022-08-26 09:44
资讯   2022-08-26

16天12连板大港股份回复深交所关注函 股份继续冲高

回复交易所关注函后,大港股份继续冲高。8月11日大港股份高开,随后震荡走高,接近收盘时触及涨停,报20 2元 股。值得一提的是,在7月21日

发布时间: 2022-08-12 09:56
资讯   2022-08-12

万家基金再添第二大股东 中泰证券拟受让11%基金股权

7月13日,中泰证券发布公告,拟受让齐河众鑫投资有限公司(以下简称齐河众鑫)所持有的万家基金11%的股权,交易双方共同确定本次交易的标的资

发布时间: 2022-07-14 09:39
管理   2022-07-14

央行连续7日每天30亿元逆回购 对债市影响如何?

央行12日再次开展了30亿元逆回购操作,中标利率2 10%。这已是央行连续7日每天仅进行30亿元的逆回购缩量投放,创下去年1月以来的最低操作规

发布时间: 2022-07-13 09:38
资讯   2022-07-13

美元指数创近20年新高 黄金期货创出逾9个月新低

由于对美联储激进加息的担忧,美元指数11日大涨近1%创出近20年新高。受此影响,欧美股市、大宗商品均走弱,而黄金期货创出逾9个月新低。美

发布时间: 2022-07-13 09:36
资讯   2022-07-13

美股三大股指全线下跌 纳斯达克跌幅创下记录以来最大跌幅

今年上半年,美股持续回落。数据显示,道琼斯指数上半年下跌15 3%,纳斯达克综合指数下跌29 5%,标普500指数下跌20 6%。其中,纳斯达克连续

发布时间: 2022-07-04 09:51
推荐   2022-07-04

融资客热情回升 两市融资余额月内增加超344亿元

近期A股走强,沪指6月以来上涨4%,融资客热情明显回升。数据显示,截至6月16日,两市融资余额1 479万亿元,月内增加344 67亿元,最近一个半

发布时间: 2022-06-20 09:41
资讯   2022-06-20

4个交易日净买入超百亿元 北向资金持续流入A股市场

北向资金净流入态势延续。继6月15日净买入133 59亿元后,北向资金6月16日净买入44 52亿元。自5月27日至今,除6月13日以外,北向资金累计净

发布时间: 2022-06-17 09:37
推荐   2022-06-17