加密市場之間的協整
我很難理解協整是如何工作的。基本上我試圖在加密市場中找到協整對,所以我做了以下事情:
- 獲取兩個市場的 OHLC 數據(我在 5m 時間範圍內獲得 5k 根蠟燭)
- 獲取兩個市場的日誌回報
- 當我在日誌返回之間尋找協整時檢查 p 值
我的程式碼的問題是,無論我嘗試什麼市場,我總是得到非常低的 p 值,並且在某些市場上 p 值為 0。
這是我的程式碼:
import pandas as pd import json import numpy as np import requests import time import json import mplfinance as mpf import matplotlib.pyplot as plt import matplotlib.dates as mdates import statsmodels.tsa.stattools as ts import threading import scipy import pandas_ta as ta import ccxt from pykalman import KalmanFilter ftx = ccxt.ftx() def get_ohlc_ccxt(market, timeframe): data = ftx.fetch_ohlcv(market, timeframe, limit=5000) ohlcv = pd.DataFrame(data, columns=['time', 'open', 'high', 'low', 'close', 'volume']) ohlcv = ohlcv.drop_duplicates(subset=['time', 'open', 'high', 'low', 'close', 'volume'], keep='first') ohlcv['time'] = ohlcv['time'].astype('int64') ohlcv['time'] = ohlcv['time']/1000 ohlcv['date'] = pd.to_datetime(ohlcv['time'], unit='s') ohlcv = ohlcv.set_index(pd.DatetimeIndex(ohlcv['date'])) return ohlcv def check_pair(first_market, second_market, timeframe): first = get_ohlc_ccxt(first_market, timeframe) second = get_ohlc_ccxt(second_market, timeframe) if len(first) != len(second): length = min(len(first), len(second)) first = first.iloc[-length:] second = second.iloc[-length:] x = first['close'].to_numpy() y = second['close'].to_numpy() first['logret'] = first.ta.log_return() second['logret'] = second.ta.log_return() xr = first['logret'].fillna(0) yr = second['logret'].fillna(0) coint = ts.coint(xr.to_numpy(), yr.to_numpy()) p_value = coint[1] print('Cointegration:', first_market, second_market, p_value) spread = xr-yr return first, second data = check_pair('BTC-PERP', 'ETH-PERP', '5m')
在這種情況下,p 值為
8.94059749424772e-29
。如果我嘗試其他市場(如 BTC-LINK 或 BTC-LTC 等),p 值將總是非常低。誰能幫我找出我做錯了什麼?
您的數據中缺少蠟燭可能存在問題。雖然您已採取措施確保測試的數據長度相同,但這兩個系列的時間戳很可能沒有對齊,因此最終會覆蓋不同的時間段 - 數據不同步。
請允許我舉一個例子,假設你看一下
BTC-USD
和ETH-USD
市場。您已經設置了每隔 5 分鐘返回 5,000 根蠟燭的限制,您將所有參數提供給 CCXT 庫,它會返回您的時間序列。現在讓我將BTC-USD
時間序列表示為 $ X_{t} $ 和ETH-USD
系列為 $ Y_{t} $ ,對於每個系列,我們有 $ t $ 這樣 $ 0 \leq t < 5000 $ .5,000 個 5 分鐘的間隔讓我們回到不到 2.5 週。所以我們有兩個系列 $ X_{0} $ 和 $ Y_{0} $ 繼續,假設 2022 年 6 月 20 日 00:00:00。
但是,無論出於何種原因,讓我們說對於
ETH-USD
,有一些時期沒有發生交易。這可能是由於非流動性交易所的非流動性市場、交易所中斷、API 錯誤等……關鍵是,在特定的 5 分鐘間隔內完全有可能沒有交易發生。我可以看到您使用 FTX 作為您的範例,我無法評論他們的 API 文件,但我知道其他交易所 API 在發生 0 次交易的蠟燭間隔內不返回任何內容是很常見的。請參閱有關 Bitfinex API 的此範例,當由於沒有交易發生而沒有蠟燭數據時,它不會返回任何時間戳。這可能會導致您的系列長度小於 5,000 個間隔。雖然您的方法在確保兩個時間序列長度相等方面是正確的,但您需要確保它在正確的位置長度相等。您的程式碼任意截斷系列,但您需要做的只是使用兩個系列中都存在時間戳的數據!
回到我的範例,假設
ETH-USD
缺少 3 個間隔/蠟燭。假設在 $ x $ , $ y $ , 和 $ z $ 5 分鐘間隔,其中 ( $ x,y,z \leq 5000 $ ),沒有交易發生。但是您的BTC-USD
系列是完整的,那麼您只能使用數據 $ X_{t, \text{s.t.} 0 \leq t < 5000, t \notin {x,y,z}} $ . 這可以確保您的系列正確對齊並且您的協整測試正確完成。
當對大型數據集進行假設檢驗時,這是一個常見的觀察結果。
最常見的假設檢驗具有這樣的特性,即隨著樣本量的增加,檢驗變得越來越敏感,在極限內對任何與原假設的偏差都非常敏感。
因此,大樣本量使您的測試具有強大的能力來拒絕與零假設的微小偏差。我懷疑這就是發生在你身上的事情:至少有一個微小的偏差,而且大樣本量可以讓你檢測到它。
(請注意,當原假設真的為假時,就會出現這種敏感性。如果原假設為真,那麼敏感性應該在 $ \alpha $ , 意思是 $ \text{Uniform}(0, 1) $ 原假設下的 p 值分佈。)