# 加密貨幣數據分析 ## 芝加哥商業交易所-大戶持倉 ### 介紹 [芝加哥商業交易所(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)