溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何用Python實現(xiàn)一個基于EG協(xié)整法的跨周期套利策略

發(fā)布時間:2021-12-17 17:25:37 來源:億速云 閱讀:270 作者:柒染 欄目:互聯(lián)網(wǎng)科技

如何用Python實現(xiàn)一個基于EG協(xié)整法的跨周期套利策略,針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

一些金融學(xué)與數(shù)學(xué)背景

眾所周知,套利交易的大前提是兩個有相同屬性交易標(biāo)的價格的均值回歸,是一種賺取這種均值回歸的利差交易。經(jīng)典回歸模型是建立在平穩(wěn)數(shù)據(jù)變量的基礎(chǔ)之上的,對于非平穩(wěn)變量,不能使用經(jīng)典回歸模型,否則會出現(xiàn)虛假回歸等諸多問題。

由于許多關(guān)聯(lián)交易標(biāo)的價格相關(guān)性是非平穩(wěn)的,這就給經(jīng)典的回歸分析方法帶來了很大限制。實際應(yīng)用中大多數(shù)時間序列其實都是非平穩(wěn)的,通常采用差分方法消除序列中含有的非平穩(wěn)趨勢,使得序列平穩(wěn)化后建立模型,比如使用ARIMA模型。但是變換后的序列限制了交易標(biāo)的價格的范圍,并且有時變換后的序列由于不具有直接的分析意義,使得化為平穩(wěn)序列后所建立的時間序列模型不便于解釋。

1987年Engle和Granger提出的協(xié)整理論及其方法,為非平穩(wěn)序列的建模提供了另一種途徑。雖然一些經(jīng)濟(jì)變量的本身是非平穩(wěn)序列,但是,它們的線性組合卻有可能是平穩(wěn)序列。這種平穩(wěn)的線性組合被稱為協(xié)整方程,且可解釋為變量之間的長期穩(wěn)定的均衡關(guān)系。

例如,消費和收入都是非平穩(wěn)時間序列,但是具有協(xié)整關(guān)系。假如它們不具有,那么長期消費就可能比收入高或低,于是消費者便會非理性地消費或累積儲蓄。

假定一些經(jīng)濟(jì)指標(biāo)被某經(jīng)濟(jì)系統(tǒng)聯(lián)系在一起,那么從長遠(yuǎn)看來這些變量應(yīng)該具有均衡關(guān)系,這是建立和檢驗?zāi)P偷幕境霭l(fā)點。在短期內(nèi),因為季節(jié)影響或隨機干擾,這些變量有可能偏離均值。如果這種偏離是暫時的,那么隨著時間推移將會回到均衡狀態(tài);如果這種偏離是持久的,就不能說這些變量之間存在均衡關(guān)系。協(xié)整(co-integration)可被看作這種均衡關(guān)系性質(zhì)的統(tǒng)計表示。
  
協(xié)整概念是一個強有力的概念。因為協(xié)整允許我們刻畫兩個或多個序列之間的平衡或平穩(wěn)關(guān)系。對于每一個序列單獨來說可能是非平穩(wěn)的,這些序列的矩,如均值、方差或協(xié)方差隨時間而變化,而這些時間序列的線性組合序列卻可能有不隨時間變化的性質(zhì)。

將以上概念運用到期貨交易中

在大宗商品的套利交易中,相同品種的跨期合約具有強烈的協(xié)整關(guān)系(這同時也包括現(xiàn)貨與期貨的套利),運用Engle和Granger提出的這種協(xié)整理論及其方法進(jìn)行量化分析是最好不過的了,這也是目前很多世界上的頂級量化團(tuán)隊在進(jìn)行大宗商品同品種跨期套利時的理論基石。

本文將運用這套理論在螺紋鋼期貨上進(jìn)行實踐,代碼實現(xiàn)方面,我們使用Python這個目前量化金融中最強大的語言來編碼。

在開始編碼前,我們需要了解一下將會用到的一個在世界范圍內(nèi),數(shù)據(jù)科學(xué)領(lǐng)域非常流行的Python庫,名叫:statsmodels

statsmodels(http://www.statsmodels.org)是一個Python庫,用于擬合多種統(tǒng)計模型,執(zhí)行統(tǒng)計測試以及數(shù)據(jù)探索和可視化,是目前計量經(jīng)濟(jì)學(xué)和數(shù)據(jù)科學(xué)研究中必不可少的神兵利器。它包含很多的經(jīng)典頻率學(xué)派統(tǒng)計方法,而且目前人工智能領(lǐng)域中炙手可熱的貝葉斯方法和機器學(xué)習(xí)模型也可在其中找到。

比如:

  • 線性模型,廣義線性模型和魯棒線性模型

  • 線性混合效應(yīng)模型

  • 方差分析(ANOVA)方法

  • 時間序列過程和狀態(tài)空間模型

  • 廣義的矩量法

配合這個庫,加上著名的科學(xué)計算NumPy庫,我們便可以用Python編碼出這套理論的基礎(chǔ)框架用于量化分析,且同時在發(fā)明者量化平臺實現(xiàn)自動化交易。

注意:

關(guān)于這個庫的安裝方法,以及NumPy庫的安裝方法,參見發(fā)明者量化網(wǎng)站文庫中托管者的安裝與部署,這兩個庫都不是Python的官方自帶庫,需要讀者自行安裝到托管者部署的本地電腦或者云計算服務(wù)器上,不明白的讀者可以去發(fā)明者量化網(wǎng)站搜索一下方法,很簡單的,部署完托管者后用pip進(jìn)行安裝即可,這里不在贅述。

策略邏輯

本策略根據(jù)EG兩步法

第一步:序列同階單整
第二步:OLS殘差平穩(wěn)

根據(jù)以上兩步判斷序列具有協(xié)整關(guān)系之后(若無協(xié)整關(guān)系則全平倉位不進(jìn)行操作)

通過計算兩個真實價格序列回歸殘差的0.9個標(biāo)準(zhǔn)差上下軌,并在價差突破上軌的時候做空價差,價差突破下軌的時候做多價差并在回歸至標(biāo)準(zhǔn)差水平內(nèi)的時候平倉

用Python進(jìn)行代碼實現(xiàn)

第一步,我們需要創(chuàng)建一個函數(shù)用來協(xié)整檢驗,以下代碼中需要用到關(guān)于statsmodels庫的知識。

# 創(chuàng)建一個函數(shù)用來協(xié)整檢驗
def cointegration_check(series01, series02):

    urt_rb2001 = ts.adfuller(np.array(series01), 1)[1]
    urt_rb2005 = ts.adfuller(np.array(series01), 1)[1]

    # 同時平穩(wěn)或不平穩(wěn)則差分再次檢驗
    if (urt_rb2001 > 0.1 and urt_rb2005 > 0.1) or (urt_rb2001 < 0.1 and urt_rb2005 < 0.1):
        urt_diff_rb2001 = ts.adfuller(np.diff(np.array(series01)), 1)[1]
        urt_diff_rb2005 = ts.adfuller(np.diff(np.array(series01), 1))[1]

        # 同時差分平穩(wěn)進(jìn)行OLS回歸的殘差平穩(wěn)檢驗
        if urt_diff_rb2001 < 0.1 and urt_diff_rb2005 < 0.1:
            matrix = np.vstack([series02, np.ones(len(series02))]).T
            beta, c = np.linalg.lstsq(matrix, series01)[0]
            resid = series01 - beta * series02 - c
            if ts.adfuller(np.array(resid), 1)[1] > 0.1:
                result = 0.0
            else:
                result = 1.0
            return beta, c, resid, result
        else:
            result = 0.0
            return 0.0, 0.0, 0.0, result

    else:
        result = 0.0
        return 0.0, 0.0, 0.0, result

第二步,我們需要計算協(xié)整的相關(guān)數(shù)據(jù),主要是為了得到殘差的標(biāo)準(zhǔn)差上下軌數(shù)值,代碼如下:

# 計算協(xié)整
def cointegration_calc():

    # 使用發(fā)明者量化交易類庫
    obj = ext.NewPositionManager()

    # 展示兩個價格序列的協(xié)整檢驗的結(jié)果
    beta, c, resid, result = cointegration_check(close_01, close_02)
    
    # 如果返回協(xié)整檢驗不通過的結(jié)果則全平倉位等待
    if not result:
        print('協(xié)整檢驗不通過,全平所有倉位')
        obj.CoverAll()
        return
    
    # 計算殘差的標(biāo)準(zhǔn)差上下軌
    mean = np.mean(resid)
    up = mean + 0.9 * np.std(resid)
    down = mean - 0.9 * np.std(resid)
    
    # 計算新殘差
    resid_new = close_01[-1] - beta * close_02[-1] - c

這里需要注意的是,我們需要用到發(fā)明者量化平臺的國內(nèi)商品期貨模版,模版地址為:https://www.fmz.com/strategy/24288 各位在發(fā)明者量化策略編寫頁面進(jìn)行編碼時,需要把此模版先復(fù)制到自己的策略庫,然后在回測時勾選上,這里請各位讀者注意

關(guān)于如何部署托管者和機器人,請參考我之前的文章:https://www.fmz.com/bbs-topic/4140

想購買自己云計算服務(wù)器部署托管者的讀者,可以參考這篇文章:https://www.fmz.com/bbs-topic/2848

完整的策略代碼:

import types
import numpy as np
import statsmodels.tsa.stattools as ts

# 我們首先創(chuàng)建一個函數(shù)用來協(xié)整檢驗
def cointegration_check(series01, series02):
    urt_rb2001 = ts.adfuller(np.array(series01), 1)[1]
    urt_rb2005 = ts.adfuller(np.array(series01), 1)[1]

    # 同時平穩(wěn)或不平穩(wěn)則差分再次檢驗
    if (urt_rb2001 > 0.1 and urt_rb2005 > 0.1) or (urt_rb2001 < 0.1 and urt_rb2005 < 0.1):
        urt_diff_rb2001 = ts.adfuller(np.diff(np.array(series01)), 1)[1]
        urt_diff_rb2005 = ts.adfuller(np.diff(np.array(series01), 1))[1]

        # 同時差分平穩(wěn)進(jìn)行OLS回歸的殘差平穩(wěn)檢驗
        if urt_diff_rb2001 < 0.1 and urt_diff_rb2005 < 0.1:
            matrix = np.vstack([series02, np.ones(len(series02))]).T
            beta, c = np.linalg.lstsq(matrix, series01)[0]
            resid = series01 - beta * series02 - c
            if ts.adfuller(np.array(resid), 1)[1] > 0.1:
                result = 0.0
            else:
                result = 1.0
            return beta, c, resid, result
        else:
            result = 0.0
            return 0.0, 0.0, 0.0, result

    else:
        result = 0.0
        return 0.0, 0.0, 0.0, result

# 初始化合約數(shù)據(jù)
def init():

    # 訂閱螺紋鋼的2001合約與2005合約,并且取得發(fā)明者量化平臺當(dāng)前周期的所有收盤價
    exchange.SetContractType("rb2001")
    records = exchange.GetRecords()
    close_01 = records.Close

    exchange.SetContractType("rb2005")
    records = exchange.GetRecords()
    close_02 = records.Close

# 計算協(xié)整
def cointegration_calc():

    # 使用發(fā)明者量化交易類庫
    obj = ext.NewPositionManager()

    # 展示兩個價格序列的協(xié)整檢驗的結(jié)果
    beta, c, resid, result = cointegration_check(close_01, close_02)
    
    # 如果返回協(xié)整檢驗不通過的結(jié)果則全平倉位等待
    if not result:
        print('協(xié)整檢驗不通過,全平所有倉位')
        obj.CoverAll()
        return
    
    # 計算殘差的標(biāo)準(zhǔn)差上下軌
    mean = np.mean(resid)
    up = mean + 0.9 * np.std(resid)
    down = mean - 0.9 * np.std(resid)
    
    # 計算新殘差
    resid_new = close_01[-1] - beta * close_02[-1] - c

def trade():
    obj = ext.NewPositionManager() # 使用發(fā)明者量化交易類庫    

    # 此處用來獲取持倉信息
    positions = exchange.GetPosition() # 獲取持倉數(shù)組
    if len(positions) == 0: # 如果持倉數(shù)組的長度是0
        return 0 # 證明是空倉,返回0
    for i in range(len(positions)): # 遍歷持倉數(shù)組
        if (positions[i]['Type'] == PD_LONG) or (positions[i]['Type'] == PD_LONG_YD):
            position_01_long = 1 # 將position_01_long標(biāo)記為1

        elif (positions[i]['Type'] == PD_SHORT) or (positions[i]['Type'] == PD_SHORT_YD):
            position_01_short = -1 # 將position_01_short標(biāo)記為-1

    if not position_01_long = 1 and not position_01_short = -1:

        # 上穿上軌時做空新殘差
        if resid_new > up:

            obj.OpenLong("rb2001", 1) # 買開
            obj.OpenShort("rb2005", 1) # 賣開
            
        # 下穿下軌時做多新殘差
        if resid_new < down:

            obj.OpenLong("rb2005", 1) # 買開            
            obj.OpenShort("rb2001", 1) # 賣開

    # 新殘差回歸時平倉
    elif position_01_short = -1:

        if resid_new <= up:
            obj.CoverAll()
            print('價格回歸,平掉所有倉位')

        # 突破下軌反向開倉
        if resid_new < down:
            obj.OpenLong("rb2001", 1) # 買開
            obj.OpenShort("rb2005", 1) # 賣開

    elif position_01_long = 1:
        if resid_new >= down:
            obj.CoverAll()
            print('價格回歸,平所有倉位')

        # 突破上軌反向開倉
        if resid_new > up:
            obj.OpenLong("rb2005", 1) # 買開            
            obj.OpenShort("rb2001", 1) # 賣開

def main():
    while True:
        trade()
        Sleep(1000)

關(guān)于如何用Python實現(xiàn)一個基于EG協(xié)整法的跨周期套利策略問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI