RSRS指標,相對阻力支撐指標的實現,qlib擴充套件自己的特徵表示式

光大證券有一個RSRS指標,回測看來效果很不錯,它也是基於突破的邏輯。與傳統布林帶這樣的通道不同,它對$high最高價,與$low最低價之間做一個線性迴歸,看它的趨勢。

只是RSRS指數要計算兩個序列的相對斜率,這個指標,qlib沒有實現。

——他們想到的,但還是todo。只能自己動手,豐衣足食。

# TODO:# support pair-wise rolling like `Slope(A, B, N)`class Slope(Rolling):

正好熟悉一下qlib的自定義指標。

其實過程不復雜,在初始化的時候,把自定義指標註冊進去即可。就是下面程式碼裡的“custom_ops”。

provider_uri = “~/。qlib/qlib_data/{}”。format(‘index_data’)qlib。init(provider_uri=provider_uri, region=REG_CN, **{“custom_ops”: [RSRS]})

指標的實現過程如下,兩個指標運算,繼承自PairOperator,只需要實現這個_load_internal即可。載入資料邏輯是一樣的,把se_left,se_right兩個序列載入,然後進行計算。

import numpy as npimport pandas as pdimport qlibfrom qlib。data import Dfrom qlib。data。ops import ElemOperator, PairOperatorfrom qlib。config import REG_CNimport statsmodels。api as smclass PairSlope(PairOperator): def __init__(self, feature_left, feature_right, N): self。N = N super(PairSlope, self)。__init__(feature_left,feature_right) def _load_internal(self, instrument, start_index, end_index, freq): series_left = self。feature_left。load(instrument, start_index, end_index, freq) series_right = self。feature_right。load(instrument, start_index, end_index, freq) slope = [] #R2 = [] # 計算斜率值 n = self。N for i in range(len(series_left)): if i < (self。N - 1): continue else: x = series_right[i - n + 1:i + 1] # iloc左閉右開 x = sm。add_constant(x) y = series_left。iloc[i - n + 1:i + 1] regr = sm。OLS(y, x) res = regr。fit() beta = round(res。params[1], 2) # 斜率指標 slope。append(beta) #R2。append(res。rsquared) #df = df。iloc[n - 1:] slope = pd。Series(slope) return slope if __name__ == ‘__main__’: provider_uri = “~/。qlib/qlib_data/{}”。format(‘index_data’) qlib。init(provider_uri=provider_uri, region=REG_CN, **{“custom_ops”: [PairSlope]}) instruments = [“sh000300”] fields = [“PairSlope($high, $close,18)”] print(D。features(instruments, fields, start_time=“2010-01-01”, end_time=“2017-12-31”, freq=“day”))

然後我們需要實現一下pair_slope即可。

qlib自身有一個slope的計算函式。

# TODO:# support pair-wise rolling like `Slope(A, B, N)`class Slope(Rolling): def __init__(self, feature, N): super(Slope, self)。__init__(feature, N, “slope”) def _load_internal(self, instrument, start_index, end_index, freq): series = self。feature。load(instrument, start_index, end_index, freq) if self。N == 0: series = pd。Series(expanding_slope(series。values), index=series。index) else: series = pd。Series(rolling_slope(series。values, self。N), index=series。index) return series

呼叫了rolling_slope這個函式。

from 。_libs。rolling import rolling_slope, rolling_rsquare, rolling_resifrom 。_libs。expanding import expanding_slope, expanding_rsquare, expanding_resi

我呼叫了statsmodels。api線性迴歸演算法計算了,效能可能差一點,後續可以最佳化。

有了指標,其實策略就很簡單了。

由於計算時間較長,我使用了hdf5來快取,hdf5可以原樣儲存dataframe的資料,而且效能很好,可以當離線的字典來用,csv大且慢,而且dataframe寫csv再讀出來,index,column資訊會丟失,資料格式float可能會變成str,都要自己去轉換。

store = pd。HDFStore(‘cache。h5’)if ‘cache’ in store。keys(): df = store。get(key=‘cache’)else: features = [“$high”, “$low”, “PairSlope($high, $close,18)”] features。append(‘$close / Ref($close,1) -1’) names = [‘high’, ‘low’, ‘RSRS’, ‘rate’] # ‘sh000905’, ‘sz399006’ df = logic。load_data(instruments=[‘sh000300’,], features=features, names=names)df = df[‘feature’]df[‘to_buy’] = df[‘RSRS’] > 1df[‘to_sell’] =df[‘RSRS’] < 0。8

明天正式來實證RSRS策略,復現光大證券研報。

RSRS指標,相對阻力支撐指標的實現,qlib擴充套件自己的特徵表示式

策略整合並模板化 | 從零實現AI量化回測平臺 #5

“積木式”的策略框架 | 從零搭建自己的AI量化平臺 #2

搭建回測系統主框架 | 從零搭建自己的AI量化平臺 #1