比特币市场表现如何? 加密货币价格突然上涨和下跌的原因是什么? 在山寨币市场之间存在紧密不可分割的联系,还是它们彼此之间基本独立? 我们如何预测未来会发生什么?
加密货币推理的信息分析方法
推理和理论中充斥着有关比特币和以太坊等加密货币的文章。 数以百计的自封为专家而论的趋势,他们相信很快就会显示出来。 许多此类分析肯定缺乏可以支持某些陈述的数据和统计形式的坚实基础。
本文的目的是提供使用Python进行加密货币分析的简单介绍。 在其中,我们将逐步介绍一个简单的Python脚本,用于接收,分析和可视化各种加密货币上的数据。 在工作过程中,我们将发现动荡市场行为的有趣趋势,并找出其中发生了什么变化。

这篇文章不会专门解释什么是加密货币(如果您需要这样的解释,我会建议您进行出色的
评论 )。 不会讨论哪种特定货币的价值会上升或下降。 取而代之的是,该指南将重点关注获得粗略原始数据并查找隐藏在数字层下的历史记录。
阶段1.我们装备了实验室
本指南适用于各种爱好者,工程师和数据处理专业人员,无论其专业水平如何。 从这些技能中,您将只需要基本的Python理解和配置项目所需的最低命令行技能。
已完成工作的完整版本及其所有结果都可
在此处获得 。
1.1安装Anaconda
从头开始安装此项目的依赖关系的最简单方法是使用Anaconda,这是一个python生态系统和依赖关系管理器,其中包含用于处理数据和分析它们的所有必要软件包。
要安装Anaconda,建议您使用
此处的官方说明。
如果您是高级用户,而Anaconda不符合您的喜好,则无需安装它。 在这种情况下,我认为您在安装必要的依赖项时不需要帮助,您可以直接进入第二阶段。1.2在Anaconda中设置项目环境
一旦安装了Anaconda,我们将希望创建一个新的环境来组织依赖项的工作。
输入命令
conda create --name cryptocurrency-analysis python=3
为我们的项目创建一个新的Anaconda环境。
接下来,输入
source activate cryptocurrency-analysis
和(在Linux / macOS上)或
activate cryptocurrency-analysis
(在Windows上)以激活环境。
最后,
conda install numpy pandas nb_conda jupyter plotly quandl
在环境中安装必要的依赖项。 此过程可能需要几分钟。
我们为什么要使用环境? 如果计划同时使用计算机上的许多Python项目,则将依赖项(软件库和软件包)分开放置以避免冲突是很有用的。 在每个项目中,Anaconda都会为环境中的依赖项创建一个特殊的目录,使您可以将它们与其他项目的依赖项分开,并组织与之的工作。1.3启动Jupyter Notebook交互式笔记本
安装环境和依赖项后,在控制台中键入
jupyter notebook
以启动iPython内核,并在浏览器中打开
http:// localhost:8888 /链接。 创建一个新的Python笔记本,确认其使用
Python [conda env:cryptocurrency-analysis]
内核
Python [conda env:cryptocurrency-analysis]
。

1.4将依赖项导入笔记本的顶部
看到干净的Jupyter日志后,您首先需要导入必要的依赖项。
import os import numpy as np import pandas as pd import pickle import quandl from datetime import datetime
此外,您必须导入Plotly并为其启用离线模式。
import plotly.offline as py import plotly.graph_objs as go import plotly.figure_factory as ff py.init_notebook_mode(connected=True)
第二阶段。获取比特币价格数据
现在,所有设置均已完成,我们准备开始接收信息以进行分析。 首先,我们需要使用免费的
比特币API Quandl请求比特币价格数据。
2.1定义Quandl辅助函数
为了帮助数据采集,我们将定义一个从Quandl下载和缓存数据集的函数。
def get_quandl_data(quandl_id): '''Download and cache Quandl dataseries''' cache_path = '{}.pkl'.format(quandl_id).replace('/','-') try: f = open(cache_path, 'rb') df = pickle.load(f) print('Loaded {} from cache'.format(quandl_id)) except (OSError, IOError) as e: print('Downloading {} from Quandl'.format(quandl_id)) df = quandl.get(quandl_id, returns="pandas") df.to_pickle(cache_path) print('Cached {} at {}'.format(quandl_id, cache_path)) return df
为了转换下载的数据并将其保存到文件中,我们将使用
pickle
。 这将防止每次我们运行脚本时再次下载相同的数据。 该函数将返回数据作为
熊猫数据框。 如果您不熟悉数据框,则可以以功能非常强大的电子表格的形式显示它们。
2.2我们从Kraken交易所获取价格数据
首先,让我们从
Kraken交易所获取有关比特币汇率的历史数据。
# Pull Kraken BTC price exchange data btc_usd_price_kraken = get_quandl_data('BCHARTS/KRAKENUSD')
我们可以使用
head()
方法检查数据帧的前5行。
btc_usd_price_kraken.head()

接下来,让我们生成一个简单的图形,以便快速直观地验证数据的正确性。
# Chart the BTC pricing data btc_trace = go.Scatter(x=btc_usd_price_kraken.index, y=btc_usd_price_kraken['Weighted Price']) py.iplot([btc_trace])

为了可视化,
此处使用
Plotly 。 与更权威的python可视化库(例如
Matplotlib)相比,这是一种不太传统的方法,但是在我看来,Plotly是一个绝佳的选择,因为它允许您通过使用
D3.js创建完全交互式的图形
。 结果,您无需任何设置即可在输出端获得漂亮的可视化图表。 此外,Plotly易于学习,其结果也易于插入网页中。
当然,您应该始终记住需要将生成的可视化结果与公开可用的加密货币价格图表(例如,在Coinbase上)进行比较,以对下载数据的可靠性进行基本验证。2.3向其他BTC交易所索取价格数据
您可能已经注意到此组中的差异:该图在多个位置下垂到零,尤其是在2014年底和2016年初。这些跌幅在Kraken数据集中可以找到,我们显然不希望它们反映在最终价格分析中。
比特币交易所的性质是,价格由供求关系决定,因此,现有的交易所都不能声称其报价反映了比特币唯一真实的“参考”价格。 为了考虑到此缺点,并消除图表上的价格跌落(很可能是由于技术或数据集错误),我们将另外从其他三个大型比特币交易所收集数据,以计算比特币的总价格指数。
首先,让我们将每个交易所的数据下载到数据帧字典中。
# Pull pricing data for 3 more BTC exchanges exchanges = ['COINBASE','BITSTAMP','ITBIT'] exchange_data = {} exchange_data['KRAKEN'] = btc_usd_price_kraken for exchange in exchanges: exchange_code = 'BCHARTS/{}USD'.format(exchange) btc_exchange_df = get_quandl_data(exchange_code) exchange_data[exchange] = btc_exchange_df
2.4将所有价格数据合并到一个数据框中
接下来,我们将定义一个简单的函数,将每个数据帧的相似列合并为一个新的合并帧。
def merge_dfs_on_column(dataframes, labels, col): '''Merge a single column of each dataframe into a new combined dataframe''' series_dict = {} for index in range(len(dataframes)): series_dict[labels[index]] = dataframes[index][col] return pd.DataFrame(series_dict)
现在,让我们根据“加权价格”列组合所有数据框。
# Merge the BTC price dataseries' into a single dataframe btc_usd_datasets = merge_dfs_on_column(list(exchange_data.values()), list(exchange_data.keys()), 'Weighted Price')
最后,使用
tail()
方法查看最后五行,以确保我们的工作结果看起来正常。
btc_usd_datasets.tail()

价格看起来像预期的那样:处于相似的限制范围内,但是根据每个交易所的供求比率存在细微差异。
2.5可视化价格数据集
下一步的逻辑步骤是可视化结果数据集的比较。 为此,我们定义了一个辅助功能,该功能提供了使用单行命令基于数据框生成图形的功能。
def df_scatter(df, title, seperate_y_axis=False, y_axis_label='', scale='linear', initial_hide=False): '''Generate a scatter plot of the entire dataframe''' label_arr = list(df) series_arr = list(map(lambda col: df[col], label_arr)) layout = go.Layout( title=title, legend=dict(orientation="h"), xaxis=dict(type='date'), yaxis=dict( title=y_axis_label, showticklabels= not seperate_y_axis, type=scale ) ) y_axis_config = dict( overlaying='y', showticklabels=False, type=scale ) visibility = 'visible' if initial_hide: visibility = 'legendonly' # Form Trace For Each Series trace_arr = [] for index, series in enumerate(series_arr): trace = go.Scatter( x=series.index, y=series, name=label_arr[index], visible=visibility ) # Add seperate axis for the series if seperate_y_axis: trace['yaxis'] = 'y{}'.format(index + 1) layout['yaxis{}'.format(index + 1)] = y_axis_config trace_arr.append(trace) fig = go.Figure(data=trace_arr, layout=layout) py.iplot(fig)
为了简洁起见,我将不详细介绍辅助功能的操作。 如果您有兴趣了解更多有关它的信息,请参阅《
熊猫与
阴谋》文档 。
我们可以轻松地生成比特币价格数据图。
# Plot all of the BTC exchange prices df_scatter(btc_usd_datasets, 'Bitcoin Price (USD) By Exchange')

2.6整理并合并价格数据
我们可以看到,尽管所有4个系列的数据的行为都大致相同,但是仍需要消除其中一些与规范的偏差。
让我们从帧中删除所有零值,因为我们知道比特币的价格在我们所考虑的时间段内从未为零。
# Remove "0" values btc_usd_datasets.replace(0, np.nan, inplace=True)
再次构建图表后,我们得到了更整洁的曲线,没有任何急剧的下降。
# Plot the revised dataframe df_scatter(btc_usd_datasets, 'Bitcoin Price (USD) By Exchange')

现在,我们可以根据所有交易所的数据来计算一个包含平均每日比特币价格的新列。
# Calculate the average BTC price as a new column btc_usd_datasets['avg_btc_price_usd'] = btc_usd_datasets.mean(axis=1)
此新列是我们的比特币价格指数! 让我们绘制它以确保它看起来正常。
# Plot the average BTC price btc_trace = go.Scatter(x=btc_usd_datasets.index, y=btc_usd_datasets['avg_btc_price_usd']) py.iplot([btc_trace])

是的,看起来不错。 将来,我们将使用合并的价格序列将其他加密货币的汇率转换为美元。
第三阶段。获取山寨币价格数据
现在我们有了一个可靠的比特币价格时间序列,让我们请求一些非比特币加密货币的数据,这些数据通常被称为山寨币。
3.1定义用于Poloniex API的辅助功能
要获取山寨币数据,我们将使用
Poloniex API 。 两个辅助功能可以下载和缓存传递给此API的JSON数据,这将对我们有帮助。
首先,我们定义
get_json_data
,它将在提供的URL上下载并缓存JSON数据。
def get_json_data(json_url, cache_path): '''Download and cache JSON data, return as a dataframe.''' try: f = open(cache_path, 'rb') df = pickle.load(f) print('Loaded {} from cache'.format(json_url)) except (OSError, IOError) as e: print('Downloading {}'.format(json_url)) df = pd.read_json(json_url) df.to_pickle(cache_path) print('Cached {} at {}'.format(json_url, cache_path)) return df
接下来,我们定义一个函数,该函数生成对Poloniex API的HTTP请求,然后调用
get_json_data
,后者依次存储请求的数据。
base_polo_url = 'https://poloniex.com/public?command=returnChartData¤cyPair={}&start={}&end={}&period={}' start_date = datetime.strptime('2015-01-01', '%Y-%m-%d') # get data from the start of 2015 end_date = datetime.now() # up until today pediod = 86400 # pull daily data (86,400 seconds per day) def get_crypto_data(poloniex_pair): '''Retrieve cryptocurrency data from poloniex''' json_url = base_polo_url.format(poloniex_pair, start_date.timestamp(), end_date.timestamp(), pediod) data_df = get_json_data(json_url, poloniex_pair) data_df = data_df.set_index('date') return data_df
她采用一个指示加密货币对的字符串(例如BTC_ETH),并以其汇率返回包含历史数据的数据帧。
3.2使用Poloniex下载贸易数据
大多数山寨币不能直接用美元购买。 为了获得它们,人们经常购买比特币,并在交易所中将其交换为山寨币。 因此,我们下载每种硬币的BTC汇率,并使用BTC价格中的数据来计算以美元计算的山寨币的成本。
我们下载9种最受欢迎的加密货币的股票数据-
以太坊 ,
莱特币 ,
Ripple ,
以太坊经典 ,
Stellar ,
Dashcoin ,
Siacoin ,
Monero和
NEM 。
altcoins = ['ETH','LTC','XRP','ETC','STR','DASH','SC','XMR','XEM'] altcoin_data = {} for altcoin in altcoins: coinpair = 'BTC_{}'.format(altcoin) crypto_price_df = get_crypto_data(coinpair) altcoin_data[altcoin] = crypto_price_df
现在,我们有一个包含9个数据框的字典,每个字典都包含有关山寨币和比特币的平均每日交易价格对的历史数据。
再次,我们将检查以太坊价格表的最后五行,以确保一切正常。
altcoin_data['ETH'].tail()

3.3价格转换为美元
现在,我们可以将价格对的数据与我们的比特币价格指数进行比较,以直接获取有关以美元表示的山寨币价值的历史数据。
# Calculate USD Price as a new column in each altcoin dataframe for altcoin in altcoin_data.keys(): altcoin_data[altcoin]['price_usd'] = altcoin_data[altcoin]['weightedAverage'] * btc_usd_datasets['avg_btc_price_usd']
使用此代码,我们在每个山寨币的数据框中使用美元硬币价格创建了一个新列。
此外,我们可以重用先前定义的功能
merge_dfs_on_column
来创建一个数据框,其中包含每种加密货币的美元价格。
# Merge USD price of each altcoin into single dataframe combined_df = merge_dfs_on_column(list(altcoin_data.values()), list(altcoin_data.keys()), 'price_usd')
就这样 现在,让我们还将比特币价格添加到组合数据框的最后一列。
# Add BTC price to the dataframe combined_df['BTC'] = btc_usd_datasets['avg_btc_price_usd']
现在我们有了一个框架,其中包含我们正在研究的十种加密货币的每日美元价格。
让我们重用先前设置的
df_scatter
函数以绘制加密货币价格变化的比较图。
# Chart all of the altocoin prices df_scatter(combined_df, 'Cryptocurrency Prices (USD)', seperate_y_axis=False, y_axis_label='Coin Value (USD)', scale='log')

太好了! 该图表使您可以非常清楚地评估过去几年中每种加密货币的汇率动态。
请注意,我们使用对数纵坐标刻度,因为它使我们能够在一张图表上拟合所有货币。 但是,如果您愿意,可以尝试使用不同的参数值(例如scale='linear'
)从不同的角度查看数据。3.4相关分析
您可能已经注意到,尽管加密货币汇率的价值和波动性完全不同,但它们之间似乎存在一定的相关性。 尤其是当您查看八月暴涨之后的时间间隔时,即使不同的代币也会出现微小的波动,就像同步发生一样。
但是,在我们可以使用统计数据进行备份之前,基于外部相似性的预示并不比简单的猜测更好。
我们可以使用Pandas集合中的
corr()
方法来检验我们的相关假设,并使用它来计算帧中所有列相对于彼此的Pearson相关系数。
更正日期为8/22/2017-这部分工作已被修改。 现在,要计算相关系数,而不是使用绝对价格值,而是使用其每日变化的百分比值。直接在非平稳时间序列(例如原始价格数据)之间进行相关性计算可能会导致结果有偏差。 我们将通过应用
pct_change()
方法来纠正此缺陷,该方法会将每个帧单元的值从绝对值转换为其每日变化的百分比。
首先,我们计算2016年的相关性。
# Calculate the pearson correlation coefficients for cryptocurrencies in 2016 combined_df_2016 = combined_df[combined_df.index.year == 2016] combined_df_2016.pct_change().corr(method='pearson')

现在到处都是赔率。 接近1或-1的值表示时间序列之间分别存在很强的正向或反向相关性。 系数接近零意味着值不相关,并且彼此独立变化。
为了使结果可视化,我们需要创建另一个辅助可视化功能。
def correlation_heatmap(df, title, absolute_bounds=True): '''Plot a correlation heatmap for the entire dataframe''' heatmap = go.Heatmap( z=df.corr(method='pearson').as_matrix(), x=df.columns, y=df.columns, colorbar=dict(title='Pearson Coefficient'), ) layout = go.Layout(title=title) if absolute_bounds: heatmap['zmax'] = 1.0 heatmap['zmin'] = -1.0 fig = go.Figure(data=[heatmap], layout=layout) py.iplot(fig)
correlation_heatmap(combined_df_2016.pct_change(), "Cryptocurrency Correlations in 2016")

图表上的深红色单元格显示出很强的相关性(每种货币显然会尽可能地与其自身建立相关性),深蓝色表示强烈的反相关性。 它们之间所有的蓝色,橙色,灰色,沙色表示不同程度的弱相关性或不存在相关性。
这张图告诉我们什么? 实际上,这表明2016年各种加密货币的价格波动之间的统计显着性关系很小。
现在,为了检验我们的假设,即近几个月来加密货币之间的关联度越来越高,让我们使用2017年已经存在的数据重复进行同样的检验。
combined_df_2017 = combined_df[combined_df.index.year == 2017] combined_df_2017.pct_change().corr(method='pearson')

获得的系数表明存在更显着的相关性。 她足够强大,可以利用这一事实进行投资吗? 绝对不是。
但是,我们应该注意这样一个事实,即几乎所有的加密货币作为一个整体都变得越来越相互关联。
correlation_heatmap(combined_df_2017.pct_change(), "Cryptocurrency Correlations in 2017")

这是一个相当有趣的观察。
为什么会这样呢?
好问题。 我不能肯定地说。
首先想到的是:原因是对冲基金最近开始在加密货币市场公开交易。 [
1 ] [
2 ]这种基金的资金量比普通交易者大得多,并且如果它们通过将其资金分散到各种加密货币中并基于独立变量对它们中的每一种使用类似的交易策略来保护自己免受风险的影响, (例如在股票市场中),那么此方法的逻辑结果可能是相关性增加的趋势的出现。
深入分析:XRP和STR
例如,一种趋势间接证实了上述推理。 XRP(波纹令牌)与其他山寨币的关联最少。 但是有一个值得注意的例外-STR(Stellar代币,正式名称为“ Lumens”),其与XRP的相关系数为0.62。
有趣的是,Stellar和Ripple都是相当相似的金融科技平台,其活动旨在简化国际银行间支付的流程。
我看到一个非常现实的情况,其中一些富裕的参与者和对冲基金使用类似的策略来交易投资于Stellar和Ripple的资金,因为这些代币背后的两种服务本质上非常相似。 这个假设可以解释为什么XRP与STR的关联性比与其他加密货币的关联性大得多。
换你了
但是,这种解释很大程度上是推测性的结论。 但是也许您可以做得更好? 我们在这项工作中奠定的基础使我们能够继续在各个方向上研究数据。
这里有一些想法要检查:
- 将更多加密货币的数据添加到分析中。
- 更准确地考虑相关趋势,更正相关分析的时间范围和详细程度,反之亦然(更一般而言)。
- 搜索交易量和/或用于区块链挖掘的数据集的趋势。 销售/购买比率比原始价格数据更适合预测价格波动。
- 添加股票,商品和原材料,法定货币的价格数据,以找出其中哪些资产与加密货币相关。 (但请记住一句古老的谚语:“相关还不意味着因果关系。”)
- 使用Event Registry , GDELT和Google Trends量化围绕单个加密货币的炒作量。
- 使用机器学习,训练程序来分析数据以预测价格趋势。 如果有雄心壮志,您甚至可以尝试使用循环神经网络来实现。
- 使用您的分析,使用适当的API在Poloniex和Coinbase等网站上创建自动机器人交易者。 但请注意:优化不佳的交易机器人会迅速剥夺您所有可用资金。
- 分享您的发现! 一般来说,比特币和其他加密货币的最大特点是,与几乎任何其他资产相比,它们的去中心化性质使它们更加自由和民主。 , , , -.
HTML- python-
.
, , - , , , .
, , , - , . - ,
Github- .
, , , . , , , .
