天天看點

自己做量化交易軟體(40)小白量化實戰13--Alpha101及自編因子公式

自己做量化交易軟體(40)小白量化實戰13–Alpha101及自編因子公式

2015年底World Quant發表了論文《101 Formulaic Alpha》。論文中給出了101個現實中的alpha。初期因子資料挖掘量化投資取得了不錯的收益,後來實戰效果并不理想。不過我們可以根據因子公式原理來設計自己的自編因子公式。

首先我們要實作Alpha101因子公式的計算。

Alpha101因子公式的函數的定義和解釋:

rank(x) 排名函數

abs(x) ,log(x) 取絕對值,對數

sign(x) 信号函數

delay(x,d) 在d天前的x值

delta(x,d) 今天的x值減去d天前的x值

correlation(x,y,d) 在過去d天,x和y的相關性

covariance(x,y,d) 在過去d天,x和y的協方差

ts_min(x,d),ts_max(x,d) 時間序列函數,d天内的最小值和最大值

ts_argmax(x,d),ts_argmin(x,d) 計算ts_min(x,d)和ts_max(x,d)發生在哪一天

Alpha101因子公式需要輸入的資料:

returns 每日收盤後的收益

open,close,high,low,volume 開收高低成交量

vwap 成交量權重平均價

我們下面給出一些Alpha101因子公式:

因子名稱 因子公式 發明者量化注釋

Alpha#1 (rank(tsargmax(signedpower(((returns < 0) ? stddev(returns, 20) : close), 2.), 5)) - 0.5) 趨勢

Alpha#4 (-1 * ts_rank(rank(low), 9)) 反轉

Alpha#5 (rank((open - (sum(vwap, 10) / 10))) * (-1 _ abs(rank((close - vwap))))) 反轉

Alpha#8 (-1 _ rank(((sum(open, 5) _ sum(returns, 5)) - delay((sum(open, 5) * sum(returns, 5)), 10)))) 反轉

Alpha#9 ((0 < tsmin(delta(close, 1), 5)) ? delta(close, 1) : ((ts_max(delta(close, 1), 5) < 0) ? delta(close, 1) : (-1 * delta(close, 1)))) 反轉或趨勢

Alpha#41 (((high * low)^0.5) - vwap) 反轉

Alpha#42 (rank((vwap - close)) / rank((vwap + close))) 反轉

從上面介紹,我們可以看出這些因子公式的數學算法。

我們利用小白量化因子公式庫HP_formula2,可以友善實作這些公式算法以及實作自編因子公式。

前面部落客要介紹仿通達信和大智慧等軟體公式計算,我們利用類似手段來實作因子計算。

import numpy as np
import pandas as pd
from scipy.stats import rankdata
import HP_tdx as htdx  #小白量化通達信行情庫
from HP_formula2 import *  #小白量化仿通達信公式及因子公式函數庫

# 小白量化仿通達信公式資料格式化
mydf=stock.reset_index(level=None, drop=True ,col_level=0, col_fill='')  
CLOSE=mydf['close']
LOW=mydf['low']
HIGH=mydf['high']
OPEN=mydf['open']
VOL=mydf['volume']
C=mydf['close']
L=mydf['low']
H=mydf['high']
O=mydf['open']
V=mydf['volume']    

mydf['rtn']=100*(C-REF(C,1))/C   #收益率,又稱回報率
mydf['vwap']=SUM(C*V, 10)/SUM(V, 10)  #成交量權重平均價

#仿通達信公式計算
mydf['rsi']=RSI()   #rsi名額
#計算單個股票的alpha因子值
#Alpha#41	(((high * low)^0.5) - vwap)	反轉
mydf['alpha041']=(((HIGH * LOW)**0.5) - mydf['vwap'])

           

上面程式alpha041因子值就可以計算出來。結果不顯示了,看後面綜合代碼輸出結果。

我們建立因子公式的原理,就采用仿通達信公式的原理實作。不過要使用更新版的公式庫子產品,除了支援原先仿通達信公式庫外,增加了因子公式函數計算。

仿通達信公式計算,是對單隻股票計算。因子公式是對一組股票進行計算,HP_formula2.py子產品,相容網上因子公式,可以直接複制來計算,例如alpha002的計算公式。

print('alpha002')
#  alpha002:(-1 * correlation(rank(delta(log(volume), 2)), rank(((close - open) / open)), 6))
def alpha002():
    alpha = -1 * correlation(rank(delta(np.log(mVOL), 2)), rank((mCLOSE - mOPEN) / mOPEN), 6)
    return alpha.replace([-np.inf, np.inf], np.nan)

print(alpha002())
           

也可以利用仿通達信公式模式設計新的因子公式。我們以RSI名額為例。資料處理流程如下:

1、首先要建立股票池或闆塊。

2、擷取行情資料。

3、建立小白量化資料池。

4、小白量化因子資料初始化。

5、因子公式計算。

為了區分仿通達信公式資料,我們對因子資料和因子函數前加上小寫“m”,例如:mCLOSE,mMA()等等。

下面比較個股計算與因子計算RSI名額值的計算程式。RSI()是個股計算公式,mRSI()是因子計算公式。

#購買<零基礎搭建量化投資系統>正版書,送小白量化軟體源代碼。
# https://item.jd.com/61567375505.html
#獨狼荷蒲qq:2775205
#通通python量化群:524949939
#電話微信:18578755056
#微信公衆号:獨狼股票分析
import numpy as np
import pandas as pd
from scipy.stats import rankdata
import HP_tdx as htdx  #小白量化通達信行情庫
from HP_formula2 import *  #小白量化仿通達信公式函數庫
    
#連接配接行情主站
htdx.TdxInit(ip='183.60.224.178',port=7709)

#股票池或闆塊
codes = ['000001', '000519', '600029', '000089', '000402']

#RSI名額,隻能個股計算
def RSI(N1=5):
    LC = REF(CLOSE, 1)
    RSI1 = SMA(MAX(CLOSE - LC, 0), N1, 1) / SMA(ABS(CLOSE - LC), N1, 1) * 100.00
    return RSI1

#小白量化資料池
stocks_dict = {}  #小白量化資料池
for c in codes:
    #nCategory -> K 線種類 
    #0 5 分鐘K 線 
    #1 15 分鐘K 線 
    #2 30 分鐘K 線 
    #3 1 小時K 線 
    #4 日K 線 
    #5 周K 線 
    #6 月K 線 
    #7 1 分鐘 
    #8 1 分鐘K 線 
    #9 日K 線 
    #10 季K 線 
    #11 年K 線 
    #擷取行情
    stock =htdx. get_security_bars(nCategory=5,nMarket = 0,code=c,nCount=800)

    # 小白量化仿通達信公式資料格式化
    mydf=stock.reset_index(level=None, drop=True ,col_level=0, col_fill='')  
    CLOSE=mydf['close']
    LOW=mydf['low']
    HIGH=mydf['high']
    OPEN=mydf['open']
    VOL=mydf['volume']
    C=mydf['close']
    L=mydf['low']
    H=mydf['high']
    O=mydf['open']
    V=mydf['volume']    
    
    mydf['rtn']=100*(C-REF(C,1))/C   #收益率,又稱回報率
    mydf['vwap']=SUM(C*V, 10)/SUM(V, 10)  #成交量權重平均價
    
    #仿通達信公式計算
    mydf['rsi']=RSI()   #rsi名額
    #計算單個股票的alpha因子值
    mydf['alpha041']=(((HIGH * LOW)**0.5) - mydf['vwap'])

    #加入小白量化資料池
    stocks_dict[c] = mydf


#建立小白量化股票資料池,以股票代碼為key的字典
mdf=MDF(stocks_dict)
#小白量化因子資料初始化
mCLOSE=mdf.to_df('close')
mLOW=mdf.to_df('low')
mHIGH=mdf.to_df('high')
mOPEN=mdf.to_df('open')
mVOL=mdf.to_df('volume')
mVOL=mdf.to_df('volume')
mRTN=mdf.to_df('rtn')
mVWAP=mdf.to_df('vwap')
alpha041=mdf.to_df('alpha041')

#mRSI名額
def mRSI(N1=5):
    LC = mREF(mCLOSE, 1)
    RSI1 = mdf.mSMA(mdf.mMAX(mCLOSE - LC, 0), N1, 1) / mdf.mSMA(mABS(mCLOSE - LC), N1, 1) * 100.00
    return RSI1

#mRSI因子公式
mR=mRSI()
print('mR',mR)

#RSI個股仿通達信公式計算結果
mR2=mdf.to_df('rsi')
print('mR2',mR2)
           

程式運作結果如下:

因子公式mRSI計算結果mR :
          000001      000519     600029      000089      000402
0    100.000000  100.000000  -0.000000  100.000000  100.000000
1    100.000000  100.000000  -0.000000  100.000000  100.000000
2    100.000000   25.531915  20.987654   70.000000   34.567901
3    100.000000   13.793103  17.708333   52.913386   22.903885
4     80.181200   10.865874  15.019326   70.935601   67.784661
..          ...         ...        ...         ...         ...
795   80.769225   65.814169  32.217581   30.173070   15.959343
796   85.634577   71.838955  28.265217   24.833588   13.536974
797   89.161924   33.311967  49.085419   30.591114    9.442198
798   92.929160   28.064610  56.903150   17.972153    6.736044
799   73.629923   35.498982  67.739026   44.151432    6.335506

[800 rows x 5 columns]
個股公式RSI計算結果mR2 :
          000001      000519     600029      000089      000402
0    100.000000  100.000000   0.000000  100.000000  100.000000
1    100.000000  100.000000   0.000000  100.000000  100.000000
2    100.000000   25.531915  20.987654   70.000000   34.567901
3    100.000000   13.793103  17.708333   52.913386   22.903885
4     80.181200   10.865874  15.019326   70.935601   67.784661
..          ...         ...        ...         ...         ...
795   80.769225   65.814169  32.217581   30.173070   15.959343
796   85.634577   71.838955  28.265217   24.833588   13.536974
797   89.161924   33.311967  49.085419   30.591114    9.442198
798   92.929160   28.064610  56.903150   17.972153    6.736044
799   73.629923   35.498982  67.739026   44.151432    6.335506
           

從上面比較結果來看,個股單獨計算與因子公式計算一緻。但是因子公式計算的速度更快,使用更簡單。

最後給出全部因子公式的示範程式。

#購買<零基礎搭建量化投資系統>正版書,送小白量化軟體源代碼。
# https://item.jd.com/61567375505.html
#獨狼荷蒲qq:2775205
#通通python量化群:524949939
#電話微信:18578755056
#微信公衆号:獨狼股票分析
import numpy as np
import pandas as pd
from scipy.stats import rankdata
import HP_tdx as htdx  #小白量化通達信行情庫
from HP_formula2 import *  #小白量化仿通達信公式函數庫
    
#連接配接行情主站
htdx.TdxInit(ip='183.60.224.178',port=7709)

#股票池或闆塊
codes = ['000001', '000519', '600029', '000089', '000402']

#RSI名額,隻能個股計算
def RSI(N1=5):
    LC = REF(CLOSE, 1)
    RSI1 = SMA(MAX(CLOSE - LC, 0), N1, 1) / SMA(ABS(CLOSE - LC), N1, 1) * 100.00
    return RSI1

#小白量化資料池
stocks_dict = {}  #小白量化資料池
for c in codes:
    #nCategory -> K 線種類 
    #0 5 分鐘K 線 
    #1 15 分鐘K 線 
    #2 30 分鐘K 線 
    #3 1 小時K 線 
    #4 日K 線 
    #5 周K 線 
    #6 月K 線 
    #7 1 分鐘 
    #8 1 分鐘K 線 
    #9 日K 線 
    #10 季K 線 
    #11 年K 線 
    #擷取行情
    stock =htdx. get_security_bars(nCategory=5,nMarket = 0,code=c,nCount=800)

    # 小白量化仿通達信公式資料格式化
    mydf=stock.reset_index(level=None, drop=True ,col_level=0, col_fill='')  
    CLOSE=mydf['close']
    LOW=mydf['low']
    HIGH=mydf['high']
    OPEN=mydf['open']
    VOL=mydf['volume']
    C=mydf['close']
    L=mydf['low']
    H=mydf['high']
    O=mydf['open']
    V=mydf['volume']    
    
    mydf['rtn']=100*(C-REF(C,1))/C   #收益率,又稱回報率
    mydf['vwap']=SUM(C*V, 10)/SUM(V, 10)  #成交量權重平均價
    
    #仿通達信公式計算
    mydf['rsi']=RSI()   #rsi名額
    #計算單個股票的alpha因子值
    mydf['alpha041']=(((HIGH * LOW)**0.5) - mydf['vwap'])

    #加入小白量化資料池
    stocks_dict[c] = mydf


#建立小白量化股票資料池,以股票代碼為key的字典
mdf=MDF(stocks_dict)
#小白量化因子資料初始化
mCLOSE=mdf.to_df('close')
mLOW=mdf.to_df('low')
mHIGH=mdf.to_df('high')
mOPEN=mdf.to_df('open')
mVOL=mdf.to_df('volume')
mVOL=mdf.to_df('volume')
mRTN=mdf.to_df('rtn')
mVWAP=mdf.to_df('vwap')
alpha041=mdf.to_df('alpha041')

#mRSI名額
def mRSI(N1=5):
    LC = mREF(mCLOSE, 1)
    RSI1 = mdf.mSMA(mdf.mMAX(mCLOSE - LC, 0), N1, 1) / mdf.mSMA(mABS(mCLOSE - LC), N1, 1) * 100.00
    return RSI1

#mRSI因子公式
mR=mRSI()
print('因子公式mRSI計算結果mR :\n',mR)

#RSI個股仿通達信公式計算結果
mR2=mdf.to_df('rsi')
print('個股公式RSI計算結果mR2 :\n',mR2)

##下面是Alpha101及自編因子公式的示範
def mKDJ(N=9, M1=3, M2=3):
    """
    KDJ 随機名額
    """
    RSV = (mCLOSE - mLLV(mLOW, N)) / (mHHV(mHIGH, N) - mLLV(mLOW, N)) * 100
    K = mEMA(RSV, (M1 * 2 - 1))
    D = mEMA(K, (M2 * 2 - 1))
    J = K * 3 - D * 2

    return K, D, J

mK,mD,mJ=mKDJ()

print(mK)

#mRSI名額
def mRSI(N1=5):
    LC = mREF(mCLOSE, 1)
    RSI1 = mdf.mSMA(mdf.mMAX(mCLOSE - LC, 0), N1, 1) / mdf.mSMA(mABS(mCLOSE - LC), N1, 1) * 100.00
    return RSI1

mR2=mdf.to_df('rsi')
print('mR2',mR2)

mR=mRSI()
print('mR',mR)

print('alpha001')
#   alpha001:(rank(Ts_ArgMax(SignedPower(((returns < 0) ? stddev(returns, 20) : close), 2.), 5)) -0.5)
def alpha001():
    inner = mCLOSE
    inner[mRTN < 0] = stddev(mRTN, 20)
    alpha = rank(ts_argmax(inner ** 2, 5))
    return alpha

print(alpha001())

print('alpha002')
#  alpha002:(-1 * correlation(rank(delta(log(volume), 2)), rank(((close - open) / open)), 6))
def alpha002():
    alpha = -1 * correlation(rank(delta(np.log(mVOL), 2)), rank((mCLOSE - mOPEN) / mOPEN), 6)
    return alpha.replace([-np.inf, np.inf], np.nan)

print(alpha002())

print('alpha003')
# alpha003:(-1 * correlation(rank(open), rank(volume), 10))
def alpha003():
    alpha = -1 * correlation(rank(mOPEN), rank(mVOL), 10)
    return alpha.replace([-np.inf, np.inf], np.nan)

print(alpha003())

print('alpha004')
# alpha004: (-1 * Ts_Rank(rank(low), 9))
def alpha004():
    alpha = -1 * ts_rank(rank(mLOW), 9)
    return alpha
print(alpha004())

print('alpha005')
# alpha005:(rank((open - (sum(vwap, 10) / 10))) * (-1 * abs(rank((close - vwap)))))
def alpha005():
    alpha = (rank((mOPEN - (ts_sum(mVWAP, 10) / 10))) * (-1 * np.abs(rank((mCLOSE - mVWAP)))))
    return alpha
print(alpha005())

print('alpha006')
# alpha006: (-1 * correlation(open, volume, 10))
def alpha006():
    alpha = -1 * correlation(mOPEN, mVOL, 10)
    return alpha
print(alpha006())

print('alpha008')
# alpha008: (-1 * rank(((sum(open, 5) * sum(returns, 5)) - delay((sum(open, 5) * sum(returns, 5)),10))))
def alpha008():
    alpha = -1 * (rank(((ts_sum(mOPEN, 5) * ts_sum(mRTN, 5)) -
                      delay((ts_sum(mOPEN, 5) * ts_sum(mRTN, 5)), 10))))
    return alpha
print(alpha008())

print('alpha009')
# alpha009:((0 < ts_min(delta(close, 1), 5)) ? delta(close, 1) : ((ts_max(delta(close, 1), 5) < 0) ?delta(close, 1) : (-1 * delta(close, 1))))
def alpha009():
    delta_close = delta(mCLOSE, 1)
    cond_1 = ts_min(delta_close, 5) > 0
    cond_2 = ts_max(delta_close, 5) < 0
    alpha = -1 * delta_close
    alpha[cond_1 | cond_2] = delta_close
    return alpha
print(alpha009())

print('alpha010')
# alpha010: rank(((0 < ts_min(delta(close, 1), 4)) ? delta(close, 1) : ((ts_max(delta(close, 1), 4) < 0)? delta(close, 1) : (-1 * delta(close, 1)))))
def alpha010():
    delta_close = delta(mCLOSE, 1)
    cond_1 = ts_min(delta_close, 4) > 0
    cond_2 = ts_max(delta_close, 4) < 0
    alpha = -1 * delta_close
    alpha[cond_1 | cond_2] = delta_close
    return alpha
print(alpha010())

print('alpha041,由仿通達信公式單獨計算的結果:')
print(alpha041)

           

上面程式給出一些Alpha101因子公式及代碼實作。輸出結果就省略了,自己去嘗試了。

後面文章将介紹因子量化投資及利用因子公式的神經網絡量化投資分析文章。

請持續關注我的部落格,我的進步,就是你的進步!