# 加密貨幣數據分析
## 芝加哥商業交易所-大戶持倉
### 介紹
[芝加哥商業交易所(CME)](https://www.cmegroup.com/markets/cryptocurrencies.html) 可以查詢比特幣期貨數據,透過 [商品期貨交易委員會(CFTC)](https://www.cmegroup.com/tools-information/quikstrike/commitment-of-traders.html) 可以清楚了解 CME 紀錄的各種型態的交易者其持倉報告:
先在圖表的左上角找到 SELECT PRODUCT 選單下拉,選擇:
Cryptocurrency $\to$ Indexes $\to$ Bitcoin(BTC)
![](https://i.imgur.com/VkleVm7.png)
![](https://i.imgur.com/SkOGQXk.png)
這張圖表記錄著各種型態的交易者包含:Dealer, Assert Manager, Leveraged ...,其中我們要關注的是 Largest Traders。
點選左側的 Supplemental $\to$ Largest Traders。
![](https://i.imgur.com/FZzcUdn.png)
可以看到大戶的持倉報告如上圖。
每週統計一次,觀察到近一個月來多方部位 (Long) 持續增加,是否意味著大戶在這段時間內不斷地抄底呢,後續會有一波行情嗎?
我們來把歷史數據爬取下來回測一下。
### 爬蟲
CFTC 與 CME 並沒有提供 API 方便我們直接抓取歷史數據(其實是 CME 要付費)。
幸運的是,[Nasdaq](https://data.nasdaq.com/) 交易所也有追蹤 CME 的期貨數據,且 Nasdaq 有提供 API 方便我們抓取。
參考:[Commitment of Traders - BITCOIN (CME)](https://data.nasdaq.com/data/CFTC/133741_F_ALL_CR-concentration-ratios-bitcoin-cme-futures-only-133741)
點選右側 Libraries $\to$ Python,可以得到程式碼:
```python
quandl.get("CFTC/133741_F_ALL_CR")
```
當然運行程式碼之前,需安裝套件:
```python
!pip install quandl
```
於是就可以輕鬆的將大戶持倉數據抓取下來:
```python
import quandl
large = quandl.get("CFTC/133741_F_ALL_CR")
large
```
其中 `CFTC/133741_F_ALL_CR` 為取得 CME 前四大帳戶的多空比代號。
![](https://i.imgur.com/0gilWdQ.png)
表中可以觀察到 Index 是時間,從 `2018-04-10` 開始記錄,算蠻久的,做回測應該足夠。
Columns 分別是 `Largest 4 Longs; Gross` 與 `Largest 4 Shorts; Gross`,字面上推測應該是前 4 大作多與做空的帳戶,單位是佔 CME 記錄的 [Open Interest](https://en.wikipedia.org/wiki/Open_interest) 百分比。將數列畫出來:
```python
large['Largest 4 Longs; Gross'].plot(figsize=[20,10], ylabel='Position(%)', legend=True)
large['Largest 4 Shorts; Gross'].plot(figsize=[20,10], legend=True)
```
![](https://i.imgur.com/tn5sUoi.png)
可以觀察到長期以來,空方的部位都是大於多方的。
將多空消長的情況與價格一起繪製來觀察:
```python
ohlcv = quandl.get("BCHAIN/MKPRU")
ohlcv.reindex(large.index).plot(legend=True)
delta = (large['Largest 4 Shorts; Gross']-large['Largest 4 Longs; Gross']).rename('Delta', axis=1)
delta.plot(figsize=[20,10], legend=True, secondary_y=True)
```
![](https://i.imgur.com/bU3Qlrz.png)
上圖將空方與多方的差值 **Delta**`(Delta = Shorts - Longs)` 與價格一起繪製。
可以看到,當 Delta 低於某個值(或急遽下降),看得出來是價格的低點,大戶似乎正在抄底。
![](https://i.imgur.com/kZYxzS1.png)
因此可以製作一個策略:當 Delta 低於某個值時買入,當 Shorts 值大於某個值時賣出。經過最佳化。
:::info
Delta 低於 5.5 進場做多, Shorts 大於 71.5 出場,可得最佳報酬
:::
將進出場訊號繪製如下:
![](https://i.imgur.com/4MFq6uZ.png)
其中的方波從 0 到 1 表示買入訊號,從 1 到 0 表示賣出訊號,可以看到進出次數非常少。優點是適於長期持有且無法長時間關注市場的投資者,缺點是失去 2021 年大牛市的許多坡段獲利。
考慮到更頻繁且有效的籌碼面策略,實作了下述的資金費率策略。
## 資金費率
### 介紹
各大期貨交易所設計一套機制稱為**資金費率** **(Funding Rate)**,用來防止合約價格與現貨價格差距過大。通常每 8 小時結算一次資金費率,若這區間內的合約價格大於現貨價格,則資金費率為正,多方須支付空方資金費率。反之資金費率為負,空方支付多方資金費率。
參考:[幣安合約資金費率簡介](https://www.binance.com/zh-TW/support/faq/360033525031)
常見的計算公式為:
```Position x TWAP((Perp_Price - Index_Price) / Index_Price) / 3```
其中:
:::info
```Position```:倉位大小
```TWAP```:[時間加權平均價格](https://zhuanlan.zhihu.com/p/165240689)
```Perp_Price```:永續合約價格
```Index_Price```:現貨價格
:::
由於 FTX 交易所是每小時結算一次資金費率,公式需修改成:
```Position x TWAP((Perp_Price - Index_Price) / Index_Price) / 24```
參考:[Funding](https://help.ftx.com/hc/en-us/articles/360027946571-Funding)
方便的是各大期貨交易所有提供 API 讓我們直接爬取資金費率數據,不需要分別爬取合約與現貨的價格再自己計算。因此可以透過觀察資金費率的變化,得知市場的情緒。
### 爬蟲
透過 FTX 提供的 REST API,撰寫爬取資金費率的程式碼可以參考:
[Bitcoin Market Analyze](https://colab.research.google.com/drive/1AfGz9UTLxyrXARnha6cwudtGmOs6QYwS?usp=sharing) 內的**抓取 FTX 交易所,資金費率歷史數據**
### 分析
下圖是 FTX 交易所的資金費率在 2019 年 9 月大跌時的情形,橘色是 BTC 價格,藍色是資金費率。可以看出大跌時,資金費率驟降且普遍為負數,市場情緒恐慌,是入場抄底的時機。
10 月底的急升也出現了資金費率飆高的情形,可做逃頂的依據。
![](https://i.imgur.com/krypNyg.png)
資金費率在 2020 年初持續維持在高檔,亦可作為逃頂的參考。來到 2020 年 3 月的大跌,資金費率驟降,可做進場抄底的參考。
![](https://i.imgur.com/bOu5Zad.png)
今年 4 月中和 5 月中的大跌之前,資金費率也出現急速飆高的情況,適合出場。5 月中的大跌之後,可以參考相對低點的資金費率進場抄底。
![](https://i.imgur.com/bvem8ER.png)
因此就以 BTC 在 FTX 交易所的資金費率為範例,設計一個進出場的策略:
:::info
* 若 FTX 的資金費率低於某個值,表示市場情緒恐慌,進場抄底。
* 若 FTX 的資金費率高於某個值,表示市場情緒貪婪,逃頂出場。
:::
透過開源的模組進行歷史數據回測與最佳化,得出結果為:
:::success
* 若 FTX 的資金費率低於 -0.015,表示市場情緒恐慌,進場抄底。
* 若 FTX 的資金費率高於 0.065,表示市場情緒貪婪,逃頂出場。
這裡的值是原始數據乘以 1000
:::
使用訊號圖表示如下:
![](https://i.imgur.com/j6amUiJ.png)
其中方波由 -1 轉為 +1 為買入訊號,由 +1 轉為 -1 為賣出訊號。
可以看出其實交易次數不多,尤其在今年 5 月大跌之後買入,一直持有到 11 月才出場。
績效圖如下:
![](https://i.imgur.com/HFk8fmI.png)
橘色是這個策略的績效,藍色是比特幣走勢。是一個不錯的打贏大盤的策略。
這裡只參考 FTX 交易所的數據,之後可以納入 Binance 以及 Bybit 這些較有規模的期貨交易所的數據一同參考,期待做出更精準的策略。
## Glassnode 鏈上數據
### 介紹
[Glassnode](https://studio.glassnode.com/dashboards/btc-core-on-chain) 鏈上數據 (On-chain data),提供了大量的加密貨幣在區塊鏈的活動情況,包含活躍地址 (Active address),交易數量 (Transaction count),比特幣算力 (Hash rate),持有者盈虧 (holder realized/unrealized profit/loss),以及各交易所的合約持倉量 (Open interest)。可以說是分析加密貨幣**基本面**的資料來源。
這小節將介紹 Glassnode 提供的指標:[SOPR](https://academy.glassnode.com/indicators/sopr/sopr-spent-output-profit-ratio) (Spend Output Profit Ratio)。使用 Python 將數據爬取下來繪製成時間序列,並透過長短期的移動平均 (Moving average) 消長製作進出場策略。
### 爬蟲
利用 Glassnode 提供的 [API](https://docs.glassnode.com/basic-api/api),撰寫 Python script 將欲取得的資料爬取下來:
```python
import json
def get_glassnode_help(url, api_key, index, asset='BTC', res='24h', currency='native'):
p = dict()
p['a'] = asset
p['i'] = res
p['c'] = currency
p['api_key'] = api_key
r = requests.get(url, params=p)
try:
r.raise_for_status()
except Exception as e:
print(e)
print(r.text)
try:
df = pd.DataFrame(json.loads(r.text))
df = df.set_index('t')
df.index = pd.to_datetime(df.index, unit='s')
df = df.sort_index()
s = df.v
s.name = '_'.join(url.split('/')[-2:])
return s
except Exception as e:
print(e)
def get_glassnode(url, api_key, index, asset='BTC', res='24h', currency='native'):
ret = get_glassnode_help(url, api_key, index, asset, res, currency)
ret.index = ret.index + datetime.timedelta(days=1)
ret.index = ret.index.tz_localize(timezone.utc)
ret = ret.reindex(index, method='ffill').ffill()
return ret.astype(float)
```
這裡將 SOPR 的 url 代入,觀察的幣種為 BTC,時匡為 4h:
```python
api_key = 'c2792d3c-6ccd-4bda-a09e-69964bade0f4'
url = 'https://api.glassnode.com/v1/metrics/indicators/sopr'
sopr = get_glassnode(url, api_key, index=ohlcv.index, asset='BTC')
# 前一章節的爬蟲,爬取 BTC 在 幣安的價格並繪製
ohlcv['close'].plot(legend=True)
sopr.plot(figsize=[20, 10], secondary_y=True, legend=True)
```
![](https://i.imgur.com/hUz39Z3.png)
上圖可以觀察到,SOPR 的值在 1 附近上下震盪。根據 SOPR 計算公式:
$$SOPR = \dfrac{Price_{spend}}{Price_{create}}$$
當 SOPR 大於 1 時,表示這時間賣出比特幣都是賺錢的,反之則是賠錢。若長期在 1 以上且越來越高,可以預期後市看漲。反之若長期在 1 以下且越來越低,則後市看壞。
![](https://i.imgur.com/m791WBS.png)
### 分析
考慮一個進出策略,以 SOPR 的長短期移動平均的交叉為依據:
:::success
若短期移動平均上穿長期移動平均,則進場
$$SMA_{fast} > SMA_{slow}$$
若短期移動平均下穿長期移動平均,則出場
$$SMA_{fast} < SMA_{slow}$$
:::
經過最佳化,短期移動平均以 **84** 根 k 棒的收盤價計算,長期移動平均以 **92** 根 k 棒的收盤價計算,每 4 小時繪製一根 k 棒。且以 [ASOPR](https://academy.glassnode.com/indicators/sopr/asopr-adjusted-sopr) (Adjusted Spend Output Profit Ratio) 取代原本的 SOPR,繪製進出場訊號圖如下:
![](https://i.imgur.com/pFeMyk0.png)
看起來進出非常頻繁,績效如何呢?
![](https://i.imgur.com/ZGlc7y9.png)
橘色是使用策略的回報,藍色是 BTC 走勢,看起來是有擊敗大盤的,不過回擋也相當巨大。
希望進場條件更加嚴苛,因此考慮加上 SOPR 的值大於 1,觀察進出場訊號:
![](https://i.imgur.com/fgkVsml.png)
看起來進出場次數減少,績效如下:
![](https://i.imgur.com/WvVMmJN.png)
看起來更勝於前者的策略。
以上的程式碼整理在 Google Colab:
[Bitcoin Data Analyze](https://colab.research.google.com/drive/1AfGz9UTLxyrXARnha6cwudtGmOs6QYwS?usp=sharing)