# Python-使用 PYTHON 分析加密货币市场 **Repository Path**: adam-lu/python1 ## Basic Information - **Project Name**: Python-使用 PYTHON 分析加密货币市场 - **Description**: 你一定听说过比特币,但你知道比特币的价格是怎么突然飞起由跌落的吗?除了比特币,市场上还有许多的加密货币,这些货币和比特币的价格之间的关系,是绑定的还是独立的呢?我们如何才能预测接下来的加密货币市场会发生什么呢? 如今,已经有成千上万篇的文章围绕比特币、以太坊等加密货币的价格展开讨论和预测,这些文章都自称是专家观点,但很多文章却仅仅建立在个人观点上,而缺乏足够的数据和统计学背景支持。 此次分析目的,就是使用python为加密货币的市场情况进行一次通俗易懂的分析。仅仅用很简单的python代码,完成对市场主流的加密货币数据的数据采集、数据分析及可视化。在过程中,可以看到这些货币的完整演变趋势。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: https://blog.csdn.net/adamlay/article/details/115960257 - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-04-21 - **Last Updated**: 2023-02-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 使用PYTHON分析加密货币市场 ## 背景 你一定听说过比特币,但你知道比特币的价格是怎么突然飞起由跌落的吗?除了比特币,市场上还有许多的加密货币,这些货币和比特币的价格之间的关系,是绑定的还是独立的呢?我们如何才能预测接下来的加密货币市场会发生什么呢? 如今,已经有成千上万篇的文章围绕比特币、以太坊等加密货币的价格展开讨论和预测,这些文章都自称是专家观点,但很多文章却仅仅建立在个人观点上,而缺乏足够的数据和统计学背景支持。 此次分析目的,就是使用python为加密货币的市场情况进行一次通俗易懂的分析。仅仅用很简单的python代码,完成对市场主流的加密货币数据的数据采集、数据分析及可视化。在过程中,可以看到这些货币的完整演变趋势。 ![输入图片说明](https://gitee.com/adam-lu/python1/raw/master/Img/plot5.png "在这里输入图片标题") > 注:这篇分析不是对加密货币的专业讲解,也不对未来市场的走向构成预测建议,而旨在展现市场表现的源数据,并发现这些数据背后的事实。 ## 使用工具 Jupyter Notebook、Python、Microsoft Edge ## 分析过程 ### 1. 导入包 ```python import os import numpy as np import pandas as pd import pickle import quandl #调取quandl数据 quandl.ApiConfig.api_key = "CsyAyPx338JrXsbdfiJy" #设置quandl个人账号API密匙 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) ``` ### 2. 获取比特币价格数据 获取数据源使用的是[Quandl的免费比特币API](https://blog.quandl.com/api-for-bitcoin-data) #### 2.1 **定义函数以获取Quandl数据** ```python def get_quandl_data(quandl_id): 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 ``` #### 2.2 **Kraken比特币交易所数据** ```python btc_usd_price_kraken = get_quandl_data('BCHARTS/KRAKENUSD') btc_usd_price_kraken.tail() ``` ![输入图片说明](https://gitee.com/adam-lu/python1/raw/master/Img/1.png "在这里输入图片标题") ```python # 作图 btc_trace = go.Scatter(x=btc_usd_price_kraken.index,y=btc_usd_price_kraken['Weighted Price']) py.iplot([btc_trace]) ``` ![输入图片说明](https://gitee.com/adam-lu/python1/raw/master/Img/plot1.png "在这里输入图片标题") 放大后,可以看到折线图在2014年、2016年和2018年的某个时间段内,都有明显的数据缺口,这是受制于Kraken比特币交易所的数据缺陷,它对于接下来的分析可能会造成不便。 #### 2.3 因此,我们应该**获取多个交易所的数据** 第一步,将交易所数据下载打包到一个二维数组组成的字典中 ```python 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 ``` 第二步,将所有交易所数据合并成一个二维数组 ```python def merge_dfs_on_column(dataframes,labels,col): series_dict = {} for index in range(len(dataframes)): series_dict[labels[index]] = dataframes[index][col] return pd.DataFrame(series_dict) btc_usd_datasets = merge_dfs_on_column(list(exchange_data.values()),list(exchange_data.keys()),'Weighted Price') btc_usd_datasets.tail() ``` ![输入图片说明](https://gitee.com/adam-lu/python1/raw/master/Img/2.png "在这里输入图片标题") 第三步,plot作图 ```python def df_scatter(df, title, seperate_y_axis=False, y_axis_label='', scale='linear', initial_hide=False): 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=True ) # 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) df_scatter(btc_usd_datasets, '各交易所比特币价格(USD)') ``` ![输入图片说明](https://gitee.com/adam-lu/python1/raw/master/Img/plot2.png "在这里输入图片标题") 第四步,将零值替换为空值 ```python btc_usd_datasets.replace(0, np.nan, inplace=True) df_scatter(btc_usd_datasets, '各交易所比特币价格(USD)') ``` ![输入图片说明](https://gitee.com/adam-lu/python1/raw/master/Img/plot3.png "在这里输入图片标题") 第五步,将数据合并为一条线 ```python #在数组中生成一个列新的字段,计算所有交易所数据的平均值 btc_usd_datasets['avg_btc_price_usd'] = btc_usd_datasets.mean(axis=1) #plotly作图 btc_trace = go.Scatter(x=btc_usd_datasets.index, y=btc_usd_datasets['avg_btc_price_usd']) py.iplot({"data": [btc_trace],"layout":go.Layout(title='各交易所比特币价格(USD)')}) ``` ![输入图片说明](https://gitee.com/adam-lu/python1/raw/master/Img/plot4.png "在这里输入图片标题") ### 3. 嵌入其他加密货币 获取数据源使用的是[Poloniex(一站式数字货币交易所)的API](https://poloniex.com/) #### 3.1 创建获取json数据的函数 ```python 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 ``` 生成PoloniexAPI获取器 ```python base_polo_url = 'https://poloniex.com/public?command=returnChartData¤cyPair={}&start={}&end={}&period={}' start_date = datetime.strptime('2015-01-01', '%Y-%m-%d') end_date = datetime.now() pediod = 86400 # 1天=86400秒 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 ``` #### 3.2 从Poloniex下载数据 此次获取的比特币数据包括:以太坊、莱特币(Litecoin)、瑞波币(Ripple/XRP)、以太经典、恒星币(Stellar)、达世币(DASH)、云储币(Siacoin)、门罗币(Monero)、新经币( NEM) ```python 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 ``` ![输入图片说明](https://gitee.com/adam-lu/python1/raw/master/Img/3.png "在这里输入图片标题") #### 3.3 货币价值转换单位为美元 > 注:多数加密货币无法直接使用美元购买,因此我们将以比特币定位各类货币的价值,然后再通过以上获得的比特币价值,等价转换成以美元为单位 第一步,币值转换 ```python for altcoin in altcoin_data.keys(): altcoin_data[altcoin]['price_usd'] = altcoin_data[altcoin]['weightedAverage'] * btc_usd_datasets['avg_btc_price_usd'] ``` 第二步,将所有货币数据合并成一个二维数组 ```python combined_df = merge_dfs_on_column(list(altcoin_data.values()), list(altcoin_data.keys()), 'price_usd') ``` 第三步,添加比特币数值到数组中 ```python combined_df['BTC'] = btc_usd_datasets['avg_btc_price_usd'] ``` 第四步,作图 ```python df_scatter(combined_df, '加密货币市场价格 (USD)', seperate_y_axis=False, y_axis_label='市场价格 (USD)', scale='log') ``` ![输入图片说明](https://gitee.com/adam-lu/python1/raw/master/Img/plot5.png "在这里输入图片标题") ### 4. 使用皮尔森相关系数进行分析 从上图我们可以看出,随着市场不断发展,各类货币走势开始渐渐绑定在一起,呈现出一荣俱荣、一损俱损的情况,如果仔细查看的话,会发现这种趋势在2017年开始变得越为明显。 能够发现这一规律,是此次分析的重要收获,但只是肉眼去判定当然不够,任何主观判断在经过科学验证之前都只能算是猜想,因此需要使用统计学相关知识去辅证这个猜想。 这里,就可以使用皮尔森相关系数来达到目的 > 皮尔森相关系数(Pearson correlation coefficient) ,也称皮尔森积矩相关系数,是一种线性相关系数,是最常用的一种相关系数。记为r,用来反映两个变量X和Y的线性相关程度,r值介于-1到1之间,绝对值越大表明相关性越强。 首先,计算2016年各类货币价值的数据相关性 ```python combined_df_2016 = combined_df[combined_df.index.year == 2016] combined_df_2016.pct_change().corr(method='pearson') ``` ![输入图片说明](https://gitee.com/adam-lu/python1/raw/master/Img/4.png "在这里输入图片标题") 从结果来看,需要设置一个可视化效果图辅助发现各数值代表的意义,这里使用plotly的热力图 ```python def correlation_heatmap(df, title, absolute_bounds=True): '''Plot a correlation heatmap for the entire dataframe''' heatmap = go.Heatmap( z=df.corr(method='pearson').values, x=df.columns, y=df.columns, colorbar=dict(title='皮尔森相关系数'), ) 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(), "2016年加密货币相关系数") ``` ![plot6](https://gitee.com/adam-lu/python1/raw/master/Img/plot6.png) 在上图中由紫色→黄色,代表货币之间相关性,由负相关到不相关到强相关 这张图中,基本可以认为在2016年,货币之间是没有明确的相关性的 同样的方法,我们再来看看2017年 ```python combined_df_2017 = combined_df[combined_df.index.year == 2017] combined_df_2017.pct_change().corr(method='pearson') #plotly作图 correlation_heatmap(combined_df_2017.pct_change(), "2017年加密货币相关系数") ``` ![plot7](https://gitee.com/adam-lu/python1/raw/master/Img/plot7.png) 2017年对比2016年,可以看到大部分货币关系之间表现出了较高的相关性 ```python combined_df_2020 = combined_df[combined_df.index.year == 2020] combined_df_2020.pct_change().corr(method='pearson') #plotly作图 correlation_heatmap(combined_df_2020.pct_change(), "2020年加密货币相关系数") ``` ![plot8](https://gitee.com/adam-lu/python1/raw/master/Img/plot8.png) 进一步,将去年的数据相关性计算后,可以看到这种趋势更加明显了 这个结果基本可以验证之前的猜测,即“自2017年起,加密货币价格产生了紧密的相关性” ### 5. 结果分析 回到现实中,我们需要为辛苦得到的结论找到依据,为什么会出现这种现象呢? 所谓“反常必有妖”,果不其然,在有关2017年的加密货币新闻中,找到了原因——大量的对冲基金于这一年涌入了这个市场。 [摩根士丹利的一份报告《比特币解码》中指出,在过去6年里,出现了100多家与加密货币相关的对冲基金,其中有84只基金是在2017年发起的](http://www.jpm.cn/article-48278-1.html) 热钱的涌入,使得整个加密货币市场的发展骤然加速,作为附带效应,这些对冲基金在各类货币上进行投资并使用了相似的投资策略,最终使得各类货币之间产生了强相关性。