update
This commit is contained in:
@@ -0,0 +1,619 @@
|
||||
from scipy.stats import rankdata
|
||||
from dateutil import parser
|
||||
import numpy as np
|
||||
import numpy.linalg as la
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
import scipy.stats as stats
|
||||
import matplotlib.pyplot as plt
|
||||
from WindPy import * # 万矿数据接口
|
||||
w.start()
|
||||
|
||||
## 内置函数
|
||||
# 行业中性化
|
||||
def neutral(data,ind):
|
||||
stocks = list(data.index)
|
||||
data_ = pd.DataFrame(ind.Data,index=['INDUSTRY'],columns=ind.Codes).T
|
||||
data_med = pd.get_dummies(data_,columns=['INDUSTRY'])
|
||||
X= np.array(data_med)
|
||||
y = data.values
|
||||
beta_ols = la.inv(X.T.dot(X)).dot(X.T).dot(y)
|
||||
residual = y - X.dot(beta_ols)
|
||||
return residual
|
||||
def IndNeutralize(vwap,ind):
|
||||
vwap_ = vwap.fillna(value = 0)
|
||||
ind = w.wss(stocks, "industry_citic","unit=1;tradeDate="+ind.Times[0].strftime("%Y%m%d")+";industryType=1")
|
||||
for i in range(len(vwap_)):
|
||||
vwap_.iloc[i] = neutral(vwap_.iloc[i],ind)
|
||||
return vwap_
|
||||
# 移动求和
|
||||
def ts_sum(df, window):
|
||||
return df.rolling(window).sum()
|
||||
# 移动平均
|
||||
def sma(df, window):
|
||||
return df.rolling(window).mean()
|
||||
# 移动标准差
|
||||
def stddev(df, window):
|
||||
return df.rolling(window).std()
|
||||
# 移动相关系数
|
||||
def correlation(x, y, window):
|
||||
return x.rolling(window).corr(y)
|
||||
# 移动协方差
|
||||
def covariance(x, y, window):
|
||||
return x.rolling(window).cov(y)
|
||||
# 在过去d天的时序排名
|
||||
def rolling_rank(na):
|
||||
return rankdata(na)[-1]
|
||||
def ts_rank(df,window):
|
||||
return df.rolling(window).apply(rolling_rank)
|
||||
# 过去d天的时序乘积
|
||||
def rolling_prod(na):
|
||||
return np.prod(na)
|
||||
def product(df, window):
|
||||
return df.rolling(window).apply(rolling_prod)
|
||||
# 过去d天最小值
|
||||
def ts_min(df, window):
|
||||
return df.rolling(window).min()
|
||||
# 过去d天最大值
|
||||
def ts_max(df, window):
|
||||
return df.rolling(window).max()
|
||||
# 当天取值减去d天前的值
|
||||
def delta(df, period):
|
||||
return df.diff(period)
|
||||
# d天前的值,滞后值
|
||||
def delay(df, period):
|
||||
return df.shift(period)
|
||||
# 截面数据排序,输出boolean值
|
||||
def rank(df):
|
||||
return df.rank(pct=True,axis=1)
|
||||
# 缩放时间序列,使其和为1
|
||||
def scale(df, k=1):
|
||||
return df.mul(k).div(np.abs(df).sum())
|
||||
# 过去d天最大值的位置
|
||||
def ts_argmax(df, window):
|
||||
return df.rolling(window).apply(np.argmax) + 1
|
||||
# 过去d天最小值的位置
|
||||
def ts_argmin(df, window):
|
||||
return df.rolling(window).apply(np.argmin) + 1
|
||||
# 线性衰减的移动平均加权
|
||||
def decay_linear(df, period):
|
||||
if df.isnull().values.any():
|
||||
df.fillna(method='ffill', inplace=True)
|
||||
df.fillna(method='bfill', inplace=True)
|
||||
df.fillna(value=0, inplace=True)
|
||||
na_lwma = np.zeros_like(df) # 生成与df大小相同的零数组
|
||||
na_lwma[:period, :] = df.iloc[:period, :] # 赋前period项的值
|
||||
na_series = df.as_matrix()
|
||||
# 计算加权系数
|
||||
divisor = period * (period + 1) / 2
|
||||
y = (np.arange(period) + 1) * 1.0 / divisor
|
||||
# 从第period项开始计算数值
|
||||
for row in range(period - 1, df.shape[0]):
|
||||
x = na_series[row - period + 1: row + 1, :]
|
||||
na_lwma[row, :] = (np.dot(x.T, y))
|
||||
return pd.DataFrame(na_lwma,index = df.index,columns = df.columns)
|
||||
|
||||
## 因子函数
|
||||
def alpha1(close,returns):
|
||||
x = close
|
||||
x[returns < 0] = stddev(returns,20)
|
||||
alpha = rank(ts_argmax(x ** 2, 5))-0.5
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha2(Open,close,volume):
|
||||
r1 = rank(delta(np.log(volume), 2))
|
||||
r2 = rank((close - Open) / Open)
|
||||
alpha = -1 * correlation(r1,r2,6)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha3(Open,volume):
|
||||
r1 = rank(Open)
|
||||
r2 = rank(volume)
|
||||
alpha = -1 * correlation(r1,r2,10)
|
||||
return alpha.replace([-np.inf, np.inf], 0).fillna(value = 0)
|
||||
def alpha4(low):
|
||||
r = rank(low)
|
||||
alpha = -1 * ts_rank(r,9)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha5(Open,vwap,close):
|
||||
alpha = (rank((Open - (ts_sum(vwap, 10) / 10))) * (-1 * abs(rank((close - vwap)))))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha6(Open, volume):
|
||||
alpha = -1 * correlation(Open, volume, 10)
|
||||
return alpha.replace([-np.inf, np.inf], 0).fillna(value = 0)
|
||||
def alpha7(volume,close):
|
||||
adv20 = sma(volume, 20)
|
||||
alpha = -1 * ts_rank(abs(delta(close, 7)), 60) * np.sign(delta(close, 7))
|
||||
alpha[adv20 >= volume] = -1
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha8(Open,returns):
|
||||
x1 = (ts_sum(Open, 5) * ts_sum(returns, 5))
|
||||
x2 = delay((ts_sum(Open, 5) * ts_sum(returns, 5)), 10)
|
||||
alpha = -1 * rank(x1-x2)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha9(close):
|
||||
delta_close = delta(close, 1)
|
||||
x1 = ts_min(delta_close, 5) > 0
|
||||
x2 = ts_max(delta_close, 5) < 0
|
||||
alpha = -1 * delta_close
|
||||
alpha[x1 | x2] = delta_close
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha10(close):
|
||||
delta_close = delta(close, 1)
|
||||
x1 = ts_min(delta_close, 4) > 0
|
||||
x2 = ts_max(delta_close, 4) < 0
|
||||
x = -1 * delta_close
|
||||
x[x1 | x2] = delta_close
|
||||
alpha = rank(x)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha11(vwap,close,volume):
|
||||
x1 = rank(ts_max((vwap - close), 3))
|
||||
x2 = rank(ts_min((vwap - close), 3))
|
||||
x3 = rank(delta(volume, 3))
|
||||
alpha = (x1 + x2) * x3
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha12(volume,close):
|
||||
alpha = np.sign(delta(volume, 1)) * (-1 * delta(close, 1))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha13(volume,close):
|
||||
alpha = -1 * rank(covariance(rank(close), rank(volume), 5))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha14(Open,volume,returns):
|
||||
x1 = correlation(Open, volume, 10).replace([-np.inf, np.inf], 0).fillna(value=0)
|
||||
x2 = -1 * rank(delta(returns, 3))
|
||||
alpha = x1 * x2
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha15(high,volume):
|
||||
x1 = correlation(rank(high), rank(volume), 3).replace([-np.inf, np.inf], 0).fillna(value=0)
|
||||
alpha = -1 * ts_sum(rank(x1), 3)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha16(high,volume):
|
||||
alpha = -1 * rank(covariance(rank(high), rank(volume), 5))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha17(volume,close):
|
||||
adv20 = sma(volume, 20)
|
||||
x1 = rank(ts_rank(close, 10))
|
||||
x2 = rank(delta(delta(close, 1), 1))
|
||||
x3 = rank(ts_rank((volume / adv20), 5))
|
||||
alpha = -1 * (x1 * x2 * x3)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha18(close,Open):
|
||||
x = correlation(close, Open, 10).replace([-np.inf, np.inf], 0).fillna(value=0)
|
||||
alpha = -1 * (rank((stddev(abs((close - Open)), 5) + (close - Open)) + x))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha19(close,returns):
|
||||
x1 = (-1 * np.sign((close - delay(close, 7)) + delta(close, 7)))
|
||||
x2 = (1 + rank(1 + ts_sum(returns, 250)))
|
||||
alpha = x1 * x2
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha20(Open,high,close,low):
|
||||
alpha = -1 * (rank(Open - delay(high, 1)) * rank(Open - delay(close, 1)) * rank(Open - delay(low, 1)))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha21(volume,close):
|
||||
x1 = sma(close, 8) + stddev(close, 8) < sma(close, 2)
|
||||
x2 = sma(close, 8) - stddev(close, 8) > sma(close, 2)
|
||||
x3 = sma(volume, 20) / volume < 1
|
||||
alpha = pd.DataFrame(np.ones_like(close), index = close.index,columns = close.columns)
|
||||
alpha[x1 | x3] = -1 * alpha
|
||||
return alpha
|
||||
def alpha22(high,volume,close):
|
||||
x = correlation(high, volume, 5).replace([-np.inf, np.inf], 0).fillna(value=0)
|
||||
alpha = -1 * delta(x, 5) * rank(stddev(close, 20))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha23(high,close):
|
||||
x = sma(high, 20) < high
|
||||
alpha = pd.DataFrame(np.zeros_like(close),index = close.index,columns = close.columns)
|
||||
alpha[x] = -1 * delta(high, 2).fillna(value = 0)
|
||||
return alpha
|
||||
def alpha24(close):
|
||||
x = delta(sma(close, 100), 100) / delay(close, 100) <= 0.05
|
||||
alpha = -1 * delta(close, 3)
|
||||
alpha[x] = -1 * (close - ts_min(close, 100))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha25(volume,returns,vwap,high,close):
|
||||
adv20 = sma(volume, 20)
|
||||
alpha = rank((((-1 * returns) * adv20) * vwap) * (high - close))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha26(volume,high):
|
||||
x = correlation(ts_rank(volume, 5), ts_rank(high, 5), 5).replace([-np.inf, np.inf], 0).fillna(value=0)
|
||||
alpha = -1 * ts_max(x, 3)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha27(volume,vwap):
|
||||
alpha = rank((sma(correlation(rank(volume), rank(vwap), 6), 2) / 2.0))
|
||||
alpha[alpha > 0.5] = -1
|
||||
alpha[alpha <= 0.5] = 1
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha28(volume,high,low,close):
|
||||
adv20 = sma(volume, 20)
|
||||
x = correlation(adv20, low, 5).replace([-np.inf, np.inf], 0).fillna(value=0)
|
||||
alpha = scale(((x + ((high + low) / 2)) - close))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha29(close,returns):
|
||||
x1 = ts_min(rank(rank(scale(np.log(ts_sum(rank(rank(-1 * rank(delta((close - 1), 5)))), 2))))), 5)
|
||||
x2 = ts_rank(delay((-1 * returns), 6), 5)
|
||||
alpha = x1 + x2
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha30(close,volume):
|
||||
delta_close = delta(close, 1)
|
||||
x = np.sign(delta_close) + np.sign(delay(delta_close, 1)) + np.sign(delay(delta_close, 2))
|
||||
alpha = ((1.0 - rank(x)) * ts_sum(volume, 5)) / ts_sum(volume, 20)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha31(close,low,volume):
|
||||
adv20 = sma(volume,20)
|
||||
x1 = rank(rank(rank(decay_linear((-1 * rank(rank(delta(close, 10)))), 10))))
|
||||
x2 = rank((-1 * delta(close, 3)))
|
||||
x3 = np.sign(scale(correlation(adv20, low, 12).replace([-np.inf, np.inf], 0).fillna(value=0)))
|
||||
alpha = x1 + x2 + x3
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha32(close,vwap):
|
||||
x = correlation(vwap, delay(close, 5),230).replace([-np.inf, np.inf], 0).fillna(value=0)
|
||||
alpha = scale(((sma(close, 7)) - close)) + 20 * scale(x)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha33(Open,close):
|
||||
alpha = rank(-1 + (Open / close))
|
||||
return alpha
|
||||
def alpha34(close,returns):
|
||||
x = (stddev(returns, 2) / stddev(returns, 5)).fillna(value = 0)
|
||||
alpha = rank(2 - rank(x) - rank(delta(close, 1)))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha35(volume,close,high,low,returns):
|
||||
x1 = ts_rank(volume, 32)
|
||||
x2 = 1 - ts_rank(close + high - low, 16)
|
||||
x3 = 1 - ts_rank(returns, 32)
|
||||
alpha = (x1 * x2 * x3).fillna(value = 0)
|
||||
return alpha
|
||||
def alpha36(Open,close,volume,returns,vwap):
|
||||
adv20 = sma(volume, 20)
|
||||
x1 = 2.21 * rank(correlation((close - Open), delay(volume, 1), 15))
|
||||
x2 = 0.7 * rank((Open- close))
|
||||
x3 = 0.73 * rank(ts_rank(delay((-1 * returns), 6), 5))
|
||||
x4 = rank(abs(correlation(vwap,adv20, 6)))
|
||||
x5 = 0.6 * rank((sma(close, 200) - Open) * (close - Open))
|
||||
alpha = x1 + x2 + x3 + x4 + x5
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha37(Open,close):
|
||||
alpha = rank(correlation(delay(Open - close, 1), close, 200)) + rank(Open - close)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha38(close,Open):
|
||||
x = (close / Open).replace([-np.inf, np.inf], 0).fillna(value=0)
|
||||
alpha = -1 * rank(ts_rank(Open, 10)) * rank(x)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha39(volume,close,returns):
|
||||
adv20 = sma(volume, 20)
|
||||
x = -1 * rank(delta(close, 7)) * (1 - rank(decay_linear((volume / adv20), 9)))
|
||||
alpha = x *(1 + rank(ts_sum(returns, 250)))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha40(high,volume):
|
||||
alpha = -1 * rank(stddev(high, 10)) * correlation(high, volume, 10)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha41(high,low,vwap):
|
||||
alpha = pow((high * low),0.5) - vwap
|
||||
return alpha
|
||||
def alpha42(vwap,close):
|
||||
alpha = rank((vwap - close)) / rank((vwap + close))
|
||||
return alpha
|
||||
def alpha43(volume,close):
|
||||
adv20 = sma(volume, 20)
|
||||
alpha = ts_rank(volume / adv20, 20) * ts_rank((-1 * delta(close, 7)), 8)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha44(high,volume):
|
||||
alpha = -1 *correlation(high, rank(volume), 5).replace([-np.inf, np.inf], 0).fillna(value=0)
|
||||
return alpha
|
||||
def alpha45(close,volume):
|
||||
x = correlation(close, volume, 2).replace([-np.inf, np.inf], 0).fillna(value=0)
|
||||
alpha = -1 * (rank(sma(delay(close, 5), 20)) * x * rank(correlation(ts_sum(close, 5), ts_sum(close, 20), 2)))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha46(close):
|
||||
x = ((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10)
|
||||
alpha = (-1 * (close - delay(close, 1)))
|
||||
alpha[x < 0] = 1
|
||||
alpha[x > 0.25] = -1
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha47(volume,close,high,vwap):
|
||||
adv20 = sma(volume, 20)
|
||||
alpha = ((rank((1 / close)) * volume) / adv20) * ((high * rank((high - close))) / sma(high, 5)) - rank((vwap - delay(vwap, 5)))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha49(close):
|
||||
x = (((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10))
|
||||
alpha = (-1 * delta(close,1))
|
||||
alpha[x < -0.1] = 1
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha50(volume,vwap):
|
||||
alpha = -1 * ts_max(rank(correlation(rank(volume), rank(vwap), 5)), 5)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha51(close):
|
||||
inner = (((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10))
|
||||
alpha = (-1 * delta(close,1))
|
||||
alpha[inner < -0.05] = 1
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha52(returns,volume,low):
|
||||
x = rank(((ts_sum(returns, 240) - ts_sum(returns, 20)) / 220))
|
||||
alpha = -1 * delta(ts_min(low, 5), 5) * x * ts_rank(volume, 5)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha53(close,high,low):
|
||||
alpha = -1 * delta((((close - low) - (high - close)) / (close - low).replace(0, 0.0001)), 9)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha54(Open,close,high,low):
|
||||
x = (low - high).replace(0, -0.0001)
|
||||
alpha = -1 * (low - close) * (Open ** 5) / (x * (close ** 5))
|
||||
return alpha
|
||||
def alpha55(high,low,close,volume):
|
||||
x = (close - ts_min(low, 12)) / (ts_max(high, 12) - ts_min(low, 12)).replace(0, 0.0001)
|
||||
alpha = -1 * correlation(rank(x), rank(volume), 6).replace([-np.inf, np.inf], 0).fillna(value=0)
|
||||
return alpha
|
||||
def alpha56(returns,cap):
|
||||
alpha = 0 - (1 * (rank((sma(returns, 10) / sma(sma(returns, 2), 3))) * rank((returns * cap))))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha57(close,vwap):
|
||||
alpha = 0 - 1 * ((close - vwap) / decay_linear(rank(ts_argmax(close, 30)), 2))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha60(close,high,low,volume):
|
||||
x = ((close - low) - (high - close)) * volume / (high - low).replace(0, 0.0001)
|
||||
alpha = - ((2 * scale(rank(x))) - scale(rank(ts_argmax(close, 10))))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha61(volume,vwap):
|
||||
adv180 = sma(volume, 180)
|
||||
alpha = rank((vwap - ts_min(vwap, 16))) < rank(correlation(vwap, adv180, 18))
|
||||
return alpha
|
||||
def alpha62(volume,high,low,Open,vwap):
|
||||
adv20 = sma(volume, 20)
|
||||
x1 = rank(correlation(vwap, ts_sum(adv20, 22), 10))
|
||||
x2 = rank(((rank(Open) + rank(Open)) < (rank(((high + low) / 2)) + rank(high))))
|
||||
alpha = x1 < x2
|
||||
return alpha*-1
|
||||
def alpha64(high,low,Open,volume,vwap):
|
||||
adv120 = sma(volume, 120)
|
||||
x1 = rank(correlation(ts_sum(((Open * 0.178404) + (low * (1 - 0.178404))), 13),ts_sum(adv120, 13), 17))
|
||||
x2 = rank(delta(((((high + low) / 2) * 0.178404) + (vwap * (1 -0.178404))), 3.69741))
|
||||
alpha = x1 < x2
|
||||
return alpha*-1
|
||||
def alpha65(volume,vwap,Open):
|
||||
adv60 = sma(volume, 60)
|
||||
x1 = rank(correlation(((Open * 0.00817205) + (vwap * (1 - 0.00817205))), ts_sum(adv60,9), 6))
|
||||
x2 = rank((Open - ts_min(Open, 14)))
|
||||
alpha = x1 < x2
|
||||
return alpha*-1
|
||||
def alpha66(vwap,low,Open,high):
|
||||
x1 = rank(decay_linear(delta(vwap, 4), 7))
|
||||
x2 = (((low* 0.96633) + (low * (1 - 0.96633))) - vwap) / (Open - ((high + low) / 2))
|
||||
alpha = (x1 + ts_rank(decay_linear(x2, 11), 7)) * -1
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha68(volume,high,close,low):
|
||||
adv15 = sma(volume, 15)
|
||||
x1 = ts_rank(correlation(rank(high), rank(adv15), 9), 14)
|
||||
x2 = rank(delta(((close * 0.518371) + (low * (1 - 0.518371))), 1.06157))
|
||||
alpha = x1 < x2
|
||||
return alpha*-1
|
||||
def alpha71(volume,close,low,Open,vwap):
|
||||
adv180 = sma(volume, 180)
|
||||
x1 = ts_rank(decay_linear(correlation(ts_rank(close, 3), ts_rank(adv180,12), 18), 4), 16)
|
||||
x2 = ts_rank(decay_linear((rank(((low + Open) - (vwap + vwap))).pow(2)), 16), 4)
|
||||
alpha = x1
|
||||
alpha[x1 < x2] = x2
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha72(volume,high,low,vwap):
|
||||
adv40 = sma(volume, 40)
|
||||
x1 = rank(decay_linear(correlation(((high + low) / 2), adv40, 9), 10))
|
||||
x2 = rank(decay_linear(correlation(ts_rank(vwap, 4), ts_rank(volume, 19), 7), 3))
|
||||
alpha = (x1 / x2.replace(0, 0.0001)).fillna(value = 0)
|
||||
return alpha
|
||||
def alpha73(vwap,Open,low):
|
||||
x1 = rank(decay_linear(delta(vwap, 5), 3))
|
||||
x2 = delta(((Open * 0.147155) + (low * (1 - 0.147155))), 2) / ((Open *0.147155) + (low * (1 - 0.147155)))
|
||||
x3 = ts_rank(decay_linear((x2 * -1), 3), 17)
|
||||
alpha = x1
|
||||
alpha[x1 < x3] = x3
|
||||
return -1 * alpha.fillna(value = 0)
|
||||
def alpha74(volume,close,high,vwap):
|
||||
adv30 = sma(volume, 30)
|
||||
x1 = rank(correlation(close, ts_sum(adv30, 37), 15))
|
||||
x2 = rank(correlation(rank(((high * 0.0261661) + (vwap * (1 - 0.0261661)))), rank(volume), 11))
|
||||
alpha = x1 < x2
|
||||
return alpha*-1
|
||||
def alpha75(volume,vwap,low):
|
||||
adv50 = sma(volume, 50)
|
||||
alpha = rank(correlation(vwap, volume, 4)) < rank(correlation(rank(low), rank(adv50), 12))
|
||||
return alpha
|
||||
def alpha77(volume,high,low,vwap):
|
||||
adv40 = sma(volume, 40)
|
||||
x1 = rank(decay_linear(((((high + low) / 2) + high) - (vwap + high)), 20))
|
||||
x2 = rank(decay_linear(correlation(((high + low) / 2), adv40, 3), 6))
|
||||
alpha = x1
|
||||
alpha[x1 > x2] = x2
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha78(volume,low,vwap):
|
||||
adv40 = sma(volume, 40)
|
||||
x1 = rank(correlation(ts_sum(((low * 0.352233) + (vwap * (1 - 0.352233))), 20), ts_sum(adv40, 20),7))
|
||||
x2 = rank(correlation(rank(vwap), rank(volume), 6))
|
||||
alpha = x1.pow(x2)
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha81(volume,vwap):
|
||||
adv10 = sma(volume, 10)
|
||||
x1 = rank(np.log(product(rank((rank(correlation(vwap, ts_sum(adv10, 50), 8)).pow(4))), 15)))
|
||||
x2 = rank(correlation(rank(vwap), rank(volume), 5))
|
||||
alpha = x1 < x2
|
||||
return alpha*-1
|
||||
def alpha83(high,low,close,volume):
|
||||
x = rank(delay(((high - low) / (ts_sum(close, 5) / 5)), 2)) * rank(rank(volume))
|
||||
alpha = x / (((high - low) / (ts_sum(close, 5) / 5)) / (vwap - close))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha84(vwap,close):
|
||||
alpha = pow(ts_rank((vwap - ts_max(vwap, 15)), 21), delta(close,5))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha85(volume,high,close,low):
|
||||
adv30 = sma(volume, 30)
|
||||
x1 = rank(correlation(((high * 0.876703) + (close * (1 - 0.876703))), adv30,10))
|
||||
alpha = x1.pow(rank(correlation(ts_rank(((high + low) / 2), 4), ts_rank(volume, 10), 7)))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha86(volume,close,Open,vwap):
|
||||
adv20 = sma(volume, 20)
|
||||
x1 = ts_rank(correlation(close, sma(adv20, 15), 6), 20)
|
||||
x2 = rank(((Open+ close) - (vwap + Open)))
|
||||
alpha = x1 < x2
|
||||
return alpha*-1
|
||||
def alpha88(volume,Open,low,high,close):
|
||||
adv60 = sma(volume, 60)
|
||||
x1 = rank(decay_linear(((rank(Open) + rank(low)) - (rank(high) + rank(close))),8))
|
||||
x2 = ts_rank(decay_linear(correlation(ts_rank(close, 8), ts_rank(adv60,21), 8), 7), 3)
|
||||
alpha = x1
|
||||
alpha[x1 > x2] = x2
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha92(volume,high,low,close,Open):
|
||||
adv30 = sma(volume, 30)
|
||||
x1 = ts_rank(decay_linear(((((high + low) / 2) + close) < (low + Open)), 15), 19)
|
||||
x2 = ts_rank(decay_linear(correlation(rank(low), rank(adv30), 8), 7),7)
|
||||
alpha = x1
|
||||
alpha[x1 > x2] = x2
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha94(volume,vwap):
|
||||
adv60 = sma(volume, 60)
|
||||
x = rank((vwap - ts_min(vwap, 12)))
|
||||
alpha = x.pow(ts_rank(correlation(ts_rank(vwap,20), ts_rank(adv60, 4), 18), 3))* -1
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha95(volume,high,low,Open):
|
||||
adv40 = sma(volume, 40)
|
||||
x = ts_rank((rank(correlation(sma(((high + low)/ 2), 19), sma(adv40, 19), 13)).pow(5)), 12)
|
||||
alpha = rank((Open - ts_min(Open, 12))) < x
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha96(volume,vwap,close):
|
||||
adv60 = sma(volume, 60)
|
||||
x1 = ts_rank(decay_linear(correlation(rank(vwap), rank(volume), 4),4), 8)
|
||||
x2 = ts_rank(decay_linear(ts_argmax(correlation(ts_rank(close, 7),ts_rank(adv60, 4), 4), 13), 14), 13)
|
||||
alpha = x1
|
||||
alpha[x1 < x2] = x2
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha98(volume,Open,vwap):
|
||||
adv5 = sma(volume, 5)
|
||||
adv15 = sma(volume, 15)
|
||||
x1 = rank(decay_linear(correlation(vwap, sma(adv5, 26), 5), 7))
|
||||
alpha = x1 - rank(decay_linear(ts_rank(ts_argmin(correlation(rank(Open), rank(adv15), 21), 9),7), 8))
|
||||
return alpha.fillna(value = 0)
|
||||
def alpha99(volume,high,low):
|
||||
adv60 = sma(volume, 60)
|
||||
x1 = rank(correlation(ts_sum(((high + low) / 2), 20), ts_sum(adv60,20), 9))
|
||||
x2 = rank(correlation(low, volume, 6))
|
||||
alpha = x1 < x2
|
||||
return alpha*-1
|
||||
def alpha101(close,Open,high,low):
|
||||
alpha = (close - Open) / ((high - low) + 0.001)
|
||||
return alpha
|
||||
|
||||
def alpha48(close,ind):
|
||||
r1 = (correlation(delta(close, 1), delta(delay(close, 1), 1), 250) * delta(close, 1)) / close
|
||||
r2 = ts_sum((pow((delta(close, 1) / delay(close, 1)),2)), 250)
|
||||
alpha = IndNeutralize(r1, ind) / r2
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha58(vwap,volume,ind):
|
||||
x = IndNeutralize(vwap, ind)
|
||||
alpha = -1 * ts_rank(decay_linear(correlation(x, volume, 4), 8), 6)
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha59(vwap,volume,ind):
|
||||
x = IndNeutralize(((vwap * 0.728317) + (vwap * (1 - 0.728317))), ind)
|
||||
alpha = -1 * ts_rank(decay_linear(correlation(x, volume, 4), 16), 8)
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha63(volume,close,vwap,Open,ind):
|
||||
adv180 = sma(volume, 180).fillna(value = 0)
|
||||
r1 = rank(decay_linear(delta(IndNeutralize(close, ind), 2), 8))
|
||||
r2 = rank(decay_linear(correlation(((vwap * 0.318108) + (Open * (1 - 0.318108))), ts_sum(adv180, 37), 14), 12))
|
||||
alpha = -1 * (r1 - r2)
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha67(volume,vwap,high,ind):
|
||||
adv20 = sma(volume, 20)
|
||||
r = rank(correlation(IndNeutralize(vwap, ind), IndNeutralize(adv20, ind), 6))
|
||||
alpha = pow(rank(high - ts_min(high, 2)),r) * -1
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha69(volume,vwap,ind,close):
|
||||
adv20 = sma(volume, 20)
|
||||
r1 = rank(ts_max(delta(IndNeutralize(vwap, ind), 3), 5))
|
||||
r2 = ts_rank(correlation(((close * 0.490655) + (vwap * (1 - 0.490655))), adv20, 5), 9)
|
||||
alpha = pow(r1,r2) * -1
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha70(close,ind,vwap):
|
||||
adv50 = sma(volume, 50).fillna(value = 0)
|
||||
r = ts_rank(correlation(IndNeutralize(close, ind), adv50, 18), 18)
|
||||
alpha = pow(rank(delta(vwap, 1)),r) * -1
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha76(volume,vwap,low,ind):
|
||||
adv81 = sma(volume, 81).fillna(value = 0)
|
||||
r1 = rank(decay_linear(delta(vwap, 1), 12))
|
||||
r2 = ts_rank(decay_linear(ts_rank(correlation(IndNeutralize(low, ind), adv81, 8), 20), 17), 19)
|
||||
alpha = r1
|
||||
alpha[r1 < r2] = r2
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha79(volume,close,Open,ind,vwap):
|
||||
adv150 = sma(volume, 150).fillna(value = 0)
|
||||
r1 = rank(delta(IndNeutralize(((close * 0.60733) + (Open * (1 - 0.60733))), ind), 1))
|
||||
r2 = rank(correlation(ts_rank(vwap, 4), ts_rank(adv150, 9), 15))
|
||||
alpha = (r1 < r2) * -1
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha80(Open,high,ind):
|
||||
adv10 = sma(volume, 10)
|
||||
r1 = rank(np.sign(delta(IndNeutralize(((Open * 0.868128) + (high * (1 - 0.868128))), ind), 4)))
|
||||
r2 = ts_rank(correlation(high, adv10, 5), 6)
|
||||
alpha = pow(r1,r2) * -1
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha82(Open,volume,ind):
|
||||
r1 = rank(decay_linear(delta(Open, 1), 15))
|
||||
r2 = ts_rank(decay_linear(correlation(IndNeutralize(volume, ind), ((Open * 0.634196) + (Open * (1 - 0.634196))), 17), 7), 13)
|
||||
alpha = r1
|
||||
alpha[r1 > r2] = r2
|
||||
return -1 * alpha.fillna(value = 0)
|
||||
|
||||
def alpha87(volume,close,vwap):
|
||||
adv81 = sma(volume, 81).fillna(value = 0)
|
||||
r1 = rank(decay_linear(delta(((close * 0.369701) + (vwap * (1 - 0.369701))), 2), 3))
|
||||
r2 = ts_rank(decay_linear(abs(correlation(IndNeutralize(adv81, ind), close, 13)), 5), 14)
|
||||
alpha = r1
|
||||
alpha[r1 < r2] = r2
|
||||
return -1 * alpha.fillna(value = 0)
|
||||
|
||||
def alpha89(low,vwap,ind):
|
||||
adv10 = sma(volume, 10)
|
||||
r1 = ts_rank(decay_linear(correlation(((low * 0.967285) + (low * (1 - 0.967285))), adv10, 7), 6), 4)
|
||||
r2 = ts_rank(decay_linear(delta(IndNeutralize(vwap, ind), 3), 10), 15)
|
||||
alpha = r1 - r2
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha90(volume,close,ind,low):
|
||||
adv40 = sma(volume, 40).fillna(value = 0)
|
||||
r1 = rank((close - ts_max(close, 5)))
|
||||
r2 = ts_rank(correlation(IndNeutralize(adv40, ind), low, 5), 3)
|
||||
alpha = pow(r1,r2) * -1
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha91(close,ind,volume,vwap):
|
||||
adv30 = sma(volume, 30)
|
||||
r1 = ts_rank(decay_linear(decay_linear(correlation(IndNeutralize(close, ind), volume, 10), 16), 4), 5)
|
||||
r2 = rank(decay_linear(correlation(vwap, adv30, 4), 3))
|
||||
alpha = (r1 - r2) * -1
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha93(vwap,ind,volume,close):
|
||||
adv81 = sma(volume, 81).fillna(value = 0)
|
||||
r1 = ts_rank(decay_linear(correlation(IndNeutralize(vwap, ind), adv81, 17), 20), 8)
|
||||
r2 = rank(decay_linear(delta(((close * 0.524434) + (vwap * (1 - 0.524434))), 3), 16))
|
||||
alpha = r1 / r2
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha97(volume,low,vwap,ind):
|
||||
adv60 = sma(volume, 60).fillna(value = 0)
|
||||
r1 = rank(decay_linear(delta(IndNeutralize(((low * 0.721001) + (vwap * (1 - 0.721001))), ind), 3), 20))
|
||||
r2 = ts_rank(decay_linear(ts_rank(correlation(ts_rank(low, 8), ts_rank(adv60, 17), 5), 19), 16), 7)
|
||||
alpha = (r1 - r2) * -1
|
||||
return alpha.fillna(value = 0)
|
||||
|
||||
def alpha100(volume,close,low,high,ind):
|
||||
adv20 = sma(volume, 20)
|
||||
r1 = IndNeutralize(rank(((((close - low) - (high - close)) / (high - low)) * volume)), ind)
|
||||
r2 = 1.5 * scale(IndNeutralize(r1, ind))
|
||||
r3 = scale(IndNeutralize((correlation(close, rank(adv20), 5) - rank(ts_argmin(close, 30))), ind))
|
||||
alpha = -1 * (r2 - r3) * (volume / adv20)
|
||||
return alpha.fillna(value = 0)
|
||||
@@ -0,0 +1,184 @@
|
||||
from WindPy import *
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
import matplotlib.pyplot as plt
|
||||
w.start()
|
||||
|
||||
## 获取股票池
|
||||
s_date = '2014-01-01'
|
||||
e_date = '2016-01-01'
|
||||
date = w.tdays(s_date, e_date, "preiod = D").Data[0] # 日期函数
|
||||
stocks = w.wset("sectorconstituent", "date="+e_date+";windcode=000906.SH").Data[1] # 中证800股票池
|
||||
|
||||
## 获取日频量价原始数据
|
||||
close = w.wsd(stocks,'close',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index'])
|
||||
# 改日期索引为数字,考虑后文rolling函数应用的便捷性
|
||||
returns = w.wsd(stocks,'pct_chg',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index'])
|
||||
Open = w.wsd(stocks,'open',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index'])
|
||||
low = w.wsd(stocks,'low',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index'])
|
||||
vwap = w.wsd(stocks,'vwap',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index'])
|
||||
high = w.wsd(stocks,'high',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index'])
|
||||
cap = w.wsd(stocks,'mkt_cap_ashare',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index'])
|
||||
volume = w.wsd(stocks,'volume',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index'])
|
||||
ind = w.wss(stocks, "industry_citic","unit=1;tradeDate="+date[0].strftime("%Y%m%d")+";industryType=1")
|
||||
|
||||
## 计算因子值
|
||||
start_1 = datetime.now() # 记录计算用时
|
||||
|
||||
alpha_1 = alpha1(close,returns)
|
||||
alpha_2 = alpha2(Open,close,volume)
|
||||
alpha_3 = alpha3(Open,volume)
|
||||
alpha_4 = alpha4(low)
|
||||
alpha_5 = alpha5(Open,vwap,close)
|
||||
alpha_6 = alpha6(Open, volume)
|
||||
alpha_7 = alpha7(volume,close)
|
||||
alpha_8 = alpha8(Open,returns)
|
||||
alpha_9 = alpha9(close)
|
||||
alpha_10 = alpha10(close)
|
||||
alpha_11 = alpha11(vwap,close,volume)
|
||||
alpha_12 = alpha12(volume,close)
|
||||
alpha_13 = alpha13(volume,close)
|
||||
alpha_14 = alpha14(Open,volume,returns)
|
||||
alpha_15 = alpha15(high,volume)
|
||||
alpha_16 = alpha16(high,volume)
|
||||
alpha_17 = alpha17(volume,close)
|
||||
alpha_18 = alpha18(close,Open)
|
||||
alpha_19 = alpha19(close,returns)
|
||||
alpha_20 = alpha20(Open,high,close,low)
|
||||
alpha_21 = alpha21(volume,close)
|
||||
alpha_22 = alpha22(high,volume,close)
|
||||
alpha_23 = alpha23(high,close)
|
||||
alpha_24 = alpha24(close)
|
||||
alpha_25 = alpha25(volume,returns,vwap,high,close)
|
||||
alpha_26 = alpha26(volume,high)
|
||||
alpha_27 = alpha27(volume,vwap)
|
||||
alpha_28 = alpha28(volume,high,low,close)
|
||||
alpha_29 = alpha29(close,returns)
|
||||
alpha_30 = alpha30(close,volume)
|
||||
alpha_31 = alpha31(close,low,volume)
|
||||
alpha_32 = alpha32(close,vwap)
|
||||
alpha_33 = alpha33(Open,close)
|
||||
alpha_34 = alpha34(close,returns)
|
||||
alpha_35 = alpha35(volume,close,high,low,returns)
|
||||
alpha_36 = alpha36(Open,close,volume,returns,vwap)
|
||||
alpha_37 = alpha37(Open,close)
|
||||
alpha_38 = alpha38(close,Open)
|
||||
alpha_39 = alpha39(volume,close,returns)
|
||||
alpha_40 = alpha40(high,volume)
|
||||
alpha_41 = alpha41(high,low,vwap)
|
||||
alpha_42 = alpha42(vwap,close)
|
||||
alpha_43 = alpha43(volume,close)
|
||||
alpha_44 = alpha44(high,volume)
|
||||
alpha_45 = alpha45(close,volume)
|
||||
alpha_46 = alpha46(close)
|
||||
alpha_47 = alpha47(volume,close,high,vwap)
|
||||
alpha_49 = alpha49(close)
|
||||
alpha_50 = alpha50(volume,vwap)
|
||||
alpha_51 = alpha51(close)
|
||||
alpha_52 = alpha52(returns,volume,low)
|
||||
alpha_53 = alpha53(close,high,low)
|
||||
alpha_54 = alpha54(Open,close,high,low)
|
||||
alpha_55 = alpha55(high,low,close,volume)
|
||||
alpha_56 = alpha56(returns,cap)
|
||||
alpha_57 = alpha57(close,vwap)
|
||||
alpha_60 = alpha60(close,high,low,volume)
|
||||
alpha_61 = alpha61(volume,vwap)
|
||||
alpha_62 = alpha62(volume,high,low,Open,vwap)
|
||||
alpha_64 = alpha64(high,low,Open,volume,vwap)
|
||||
alpha_65 = alpha65(volume,vwap,Open)
|
||||
alpha_66 = alpha66(vwap,low,Open,high)
|
||||
alpha_68 = alpha41(high,low,vwap)
|
||||
alpha_71 = alpha71(volume,close,low,Open,vwap)
|
||||
alpha_72 = alpha72(volume,high,low,vwap)
|
||||
alpha_73 = alpha73(vwap,Open,low)
|
||||
alpha_74 = alpha74(volume,close,high,vwap)
|
||||
alpha_75 = alpha75(volume,vwap,low)
|
||||
alpha_77 = alpha77(volume,high,low,vwap)
|
||||
alpha_78 = alpha78(volume,low,vwap)
|
||||
alpha_81 = alpha81(volume,vwap)
|
||||
alpha_83 = alpha83(high,low,close,volume)
|
||||
alpha_84 = alpha84(vwap,close)
|
||||
alpha_85 = alpha85(volume,high,close,low)
|
||||
alpha_86 = alpha41(high,low,vwap)
|
||||
alpha_88 = alpha88(volume,Open,low,high,close)
|
||||
alpha_92 = alpha92(volume,high,low,close,Open)
|
||||
alpha_94 = alpha94(volume,vwap)
|
||||
alpha_95 = alpha95(volume,high,low,Open)
|
||||
alpha_96 = alpha96(volume,vwap,close)
|
||||
alpha_98 = alpha98(volume,Open,vwap)
|
||||
alpha_99 = alpha99(volume,high,low)
|
||||
alpha_100 = alpha41(high,low,vwap)
|
||||
alpha_101 = alpha101(close,Open,high,low)
|
||||
|
||||
alpha_48 = alpha48(close,ind) # 这些因子涉及行业中性化,计算时间较长
|
||||
alpha_58 = alpha58(vwap,volume,ind)
|
||||
alpha_59 = alpha59(vwap,volume,ind)
|
||||
alpha_63 = alpha63(volume,close,vwap,Open,ind)
|
||||
alpha_67 = alpha67(volume,vwap,high,ind)
|
||||
alpha_69 = alpha69(volume,vwap,ind,close)
|
||||
alpha_70 = alpha70(close,ind,vwap)
|
||||
alpha_76 = alpha76(volume,vwap,low,ind)
|
||||
alpha_79 = alpha79(volume,close,Open,ind,vwap)
|
||||
alpha_80 = alpha80(Open,high,ind)
|
||||
alpha_82 = alpha82(Open,volume,ind)
|
||||
alpha_87 = alpha87(volume,close,vwap)
|
||||
alpha_89 = alpha89(low,vwap,ind)
|
||||
alpha_90 = alpha90(volume,close,ind,low)
|
||||
alpha_91 = alpha91(close,ind,volume,vwap)
|
||||
alpha_93 = alpha93(vwap,ind,volume,close)
|
||||
alpha_97 = alpha97(volume,low,vwap,ind)
|
||||
alpha_100 = alpha100(volume,close,low,high,ind)
|
||||
|
||||
# 因子放入列表
|
||||
data_alpha = [alpha_1,alpha_2,alpha_3,alpha_4,alpha_5,alpha_6,alpha_7,alpha_8,alpha_9,alpha_10,
|
||||
alpha_11,alpha_12,alpha_13,alpha_14,alpha_15,alpha_16,alpha_17,alpha_18,alpha_19,alpha_20,
|
||||
alpha_21,alpha_22,alpha_23,alpha_24,alpha_25,alpha_26,alpha_27,alpha_28,alpha_29,alpha_30,
|
||||
alpha_31,alpha_32,alpha_33,alpha_34,alpha_35,alpha_36,alpha_37,alpha_38,alpha_39,alpha_40,
|
||||
alpha_41,alpha_42,alpha_43,alpha_44,alpha_45,alpha_46,alpha_47,alpha_48,alpha_49,alpha_50,
|
||||
alpha_51,alpha_52,alpha_53,alpha_54,alpha_55,alpha_56,alpha_57,alpha_58,alpha_59,alpha_60,
|
||||
alpha_61,alpha_62,alpha_63,alpha_64,alpha_65,alpha_66,alpha_67,alpha_68,alpha_69,alpha_70,
|
||||
alpha_71,alpha_72,alpha_73,alpha_74,alpha_75,alpha_76,alpha_77,alpha_78,alpha_79,alpha_80,
|
||||
alpha_81,alpha_82,alpha_83,alpha_84,alpha_85,alpha_86,alpha_87,alpha_88,alpha_89,alpha_90,
|
||||
alpha_91,alpha_92,alpha_93,alpha_94,alpha_95,alpha_96,alpha_97,alpha_98,alpha_99,alpha_100,alpha_101]
|
||||
|
||||
# 由于一些因子应用前几个月的数据进行计算,因此初始时期因子为错误值,所以取两年保留一年
|
||||
for i in range(len(data_alpha)):
|
||||
data_alpha[i] = data_alpha[i].iloc[245:] # 243,245,244,244,244/这些数字为某年交易日数量
|
||||
df_101 = pd.concat(data_alpha) # 合并各因子的数据
|
||||
df_101.to_csv('data/alpha.csv') # 储存数据至csv文件
|
||||
|
||||
## 提取数据并转换数据结构
|
||||
# 因子数据转化为时间+股票的双重索引格式
|
||||
def zhuanhuan(alpha_1,date,stocks,columns = ['alpha']):
|
||||
alpha_year = alpha_1.fillna(value = 0)
|
||||
alpha_year.set_index(date,inplace = True)
|
||||
index = pd.MultiIndex.from_product([date,stocks],names = ['date', 'codes'])
|
||||
df = pd.DataFrame(alpha_year.stack(),columns = columns)
|
||||
alpha = pd.DataFrame(df.values,columns = columns,index = index)
|
||||
return alpha
|
||||
|
||||
date_list = ['2014-01-01','2015-01-01','2016-01-01','2017-01-01','2018-01-01','2019-05-30'] # 测试区间,每年更换一次股票池
|
||||
data_alpha = []
|
||||
div = 101
|
||||
# 从csv文件取出因子数据存进列表
|
||||
for i in range(5):
|
||||
data_ = pd.read_csv('data/data_alpha_re'+str(i+1)+'.csv')
|
||||
data_.drop(data_.columns[0], axis=1, inplace=True)
|
||||
data_alpha.append(data_)
|
||||
# 将之前合并的因子进行分割,并转换数据结构为双重索引,存进二维列表
|
||||
for i in range(5):
|
||||
data = []
|
||||
df = data_alpha[i]
|
||||
n = int(len(df)/div)
|
||||
date = w.wsd('000001.SZ','close',date_list[i],date_list[i+1],period = 'D',usedf = True)[1].index
|
||||
stocks = w.wset("sectorconstituent", "date="+date_list[i+1]+";windcode=000906.SH").Data[1]
|
||||
for j in range(div):
|
||||
d = zhuanhuan(df.iloc[n*j:n*(j+1)],date,stocks,columns = ['alpha'+str(j+1)])
|
||||
data.append(d)
|
||||
data_alpha[i] = data
|
||||
# 将各因子不同时期的数据进行合并,得到一维列表data存放各因子的双重索引可用数据
|
||||
data = []
|
||||
for j in range(div):
|
||||
d = pd.concat([data_alpha[0][j],data_alpha[1][j],data_alpha[2][j],data_alpha[3][j],data_alpha[4][j]])
|
||||
data.append(d)
|
||||
@@ -0,0 +1,61 @@
|
||||
## 股票池筛选,可交易,非新股,非PT,ST,涨跌停的股票
|
||||
def get_stocks(trDate):
|
||||
trDate = trDate.strftime('%Y-%m-%d')
|
||||
stocks_800 = w.wset("sectorconstituent", "date="+trDate+";windcode=000906.SH").Data[1]
|
||||
status = w.wss(stocks_800, "trade_status,maxupordown,riskwarning,ipo_date", tradeDate=trDate, usedf=True)[1]
|
||||
date_least=w.tdaysoffset(-6,trDate,'Period=M').Data[0][0]
|
||||
trade_codes=list(status[(status['TRADE_STATUS']=='交易')&(status['IPO_DATE']<=date_least)&(status['MAXUPORDOWN']==0)&(status['RISKWARNING']=='否')].index)
|
||||
return trade_codes
|
||||
trade_d = w.tdays("2014-01-02", "2019-05-30", Period='M',usedf=True).Data[0]
|
||||
stock_valid = []
|
||||
for i in range(len(trade_d)):
|
||||
stock_valid.append(get_stocks(trade_d[i]))
|
||||
stock_valid_df = pd.DataFrame(stock_valid,index = trade_d)
|
||||
|
||||
## 获取下期收益数据
|
||||
Period = 'M'
|
||||
# 时间列表设置避免取到重复数据
|
||||
date_list = ['2014-01-02','2015-01-09','2016-01-08','2017-01-06','2018-01-05','2019-05-30']
|
||||
date_listd = ['2015-01-08','2016-01-07','2017-01-05','2018-01-04','2019-04-30']
|
||||
date_listw = ['2015-01-02','2016-01-01','2016-12-30','2017-12-29','2019-05-30']
|
||||
date_listm = ['2015-01-01','2016-01-01','2017-01-01','2018-01-01','2019-04-30']
|
||||
next_ret = []
|
||||
bench_date = [] # 之后分层测试可视化需要用到
|
||||
for i in range(5):
|
||||
date = w.wsd('000001.SZ','close',date_list[i],date_listm[i],period = Period,usedf = True)[1].index
|
||||
stocks = w.wset("sectorconstituent", "date="+date_listm[i]+";windcode=000906.SH").Data[1]
|
||||
d1 = w.tdaysoffset(1, date[0], Period = Period,usedf=True).Data[0][0].strftime('%Y-%m-%d') # 时间往后推一个周期,并且格式转化为字符串
|
||||
d2 = w.tdaysoffset(1, date[-1],Period = Period, usedf=True).Data[0][0].strftime('%Y-%m-%d')
|
||||
bench_date.append(d1)
|
||||
bench_date.append(d2)
|
||||
next_ret_ = w.wsd(stocks, "pct_chg", d1, d2, usedf=True, Period = Period)[1].fillna(value = 0)
|
||||
f = lambda x: x/100 # 万矿收益率数据单位为100%,这里换算成小数
|
||||
next_ret_ = next_ret_.applymap(f)
|
||||
next_ret.append(zhuanhuan(next_ret_,date,stocks,columns = ['NEXT_RET'])) # 转化下期收益数据为双重索引
|
||||
next_ret = pd.concat(next_ret) # 合并5年的下期收益数据
|
||||
|
||||
## IC测试
|
||||
def ic_fenxi(df,next_ret,alpha = ['alpha']):
|
||||
d = list(next_ret.index.levels[0]) # 获取双索引中的日期索引
|
||||
ic_s = []
|
||||
df = df.fillna(value = 0) # 异常值填充为0
|
||||
for i in range(len(date_)):
|
||||
stock_v = stock_valid_df.loc[d[i]].dropna().values # 获取当期有效股票池
|
||||
stock_v = list(set(stock_v) & set(df.loc[d[i]].index))
|
||||
dff = df.loc[d[i]].loc[stock_v] # 提取当期可用因子值和下期收益数据
|
||||
# dff = dff.sort_values(alpha,ascending=False).iloc[:round(len(dff)/10)] # 提取top组的数据分析
|
||||
ic_s.append(dff['NEXT_RET'].corr(dff[alpha],method='spearman')) # 计算因子值与下期收益的秩相关系数,并存进ic值列表
|
||||
ic_s = pd.Series(ic_s) # 列表转化为Series,从而能够计算各统计量
|
||||
rate = len(ic_s[ic_s>=0])/len(ic_s) # ic值大于0的比例
|
||||
IC_mean = ic_s.mean() # ic均值
|
||||
IC_std = ic_s.std() # ic标准差
|
||||
IC_IR = ic_s.mean()/ic_s.std() # ic_IR用来衡量因子有效性
|
||||
stats = [IC_mean,IC_std,IC_IR,rate]
|
||||
return stats
|
||||
|
||||
for i in range(len(data)):
|
||||
d = list(next_ret.index.levels[0])
|
||||
lc = data[i].loc[d] # 根据调仓频率筛选数据
|
||||
lc['NEXT_RET'] = next_ret.NEXT_RET
|
||||
list_ic = ic_fenxi(lc,next_ret,alpha = ['alpha'+str(i+1)]) # 计算IC统计量
|
||||
print(list_ic)
|
||||
@@ -0,0 +1,66 @@
|
||||
## 分层测试
|
||||
def return_fenxi(df,d,num,alpha = 'alpha'):
|
||||
df.fillna(value = 0,inplace = True)
|
||||
date_ = d
|
||||
return_s = []
|
||||
for i in range(len(date_)):
|
||||
stock_v = stock_valid_df.loc[d[i]].dropna().values
|
||||
stock_v = list(set(stock_v) & set(df.loc[d[i]].index))
|
||||
dff = df.loc[d[i]].loc[stock_v]
|
||||
x = dff[alpha]
|
||||
if x.sum() != 0: # 筛选掉因子值异常期
|
||||
df_i = dff.sort_values(alpha)
|
||||
return_list = []
|
||||
for j in range(num):
|
||||
n1 = round(len(df_i)*j/num)
|
||||
n2 = round(len(df_i)*(j+1)/num)
|
||||
df_j = df_i.iloc[n1:n2]
|
||||
return_j = df_j['NEXT_RET'].mean()+1
|
||||
return_list.append(return_j)
|
||||
return_s.append(return_list)
|
||||
x = np.array(return_s).T # 二维列表转化为二维数组转置
|
||||
return_s = [list(i) for i in x]
|
||||
for i in range(num):
|
||||
x = return_s[i]
|
||||
for j in range(1,len(x)):
|
||||
x[j] = x[j]*x[j-1]
|
||||
return_s[i] = x
|
||||
culmu = [re[-1] for re in return_s]
|
||||
return culmu,return_s
|
||||
|
||||
def fencengceshi(data,next_ret,num):
|
||||
data_re = []
|
||||
data_re1 = []
|
||||
for i in range(len(data)):
|
||||
lc = data[i]
|
||||
#lc.fillna(value = 0,inplace = True)
|
||||
d = list(next_ret.index.levels[0])
|
||||
lc = data[i].loc[d]
|
||||
lc['NEXT_RET'] = next_ret.NEXT_RET
|
||||
list_re1,list_re = return_fenxi(lc,d,num,alpha = data[i].columns[0])
|
||||
data_re.append(list_re)
|
||||
data_re1.append(list_re1)
|
||||
print(data_re1[i]) # 各因子最终各组累计收益
|
||||
return data_re
|
||||
|
||||
df = fencengceshi(data,next_ret,num=20) # 各因子分组累计收益序列
|
||||
dff = fencengceshi(data,next_ret,num=1) # 计算等权基准线
|
||||
|
||||
## 各组收益时序图,top/middle/bottom
|
||||
n = 1
|
||||
x = df[n-1]
|
||||
y1 = x[0]
|
||||
y2 = x[num/2]
|
||||
y3 = x[-1]
|
||||
d = list(next_ret.index.levels[0])[-len(y1):]
|
||||
bench = dff[1][0][-len(y1):]
|
||||
|
||||
plt.subplots(figsize=(15,5)) # 图的长宽设置
|
||||
plt.plot(d,y1,label='Group1')
|
||||
plt.plot(d,y2,label='Group2')
|
||||
plt.plot(d,y3,label='Group3')
|
||||
plt.plot(d,bench,label='ZZ800')
|
||||
plt.legend()
|
||||
plt.title('alpha'+str(n)+' 分层测试(月)')
|
||||
plt.xlabel('回测区间')
|
||||
plt.ylabel("净值")
|
||||
@@ -0,0 +1,135 @@
|
||||
from WindPy import *
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import numpy.linalg as la
|
||||
import seaborn as sns
|
||||
w.start()
|
||||
|
||||
## 组合多因子
|
||||
lc = data.copy()
|
||||
num_list = [42,44,36,15,4]
|
||||
num_list = [i-1 for i in num_list]
|
||||
m = []
|
||||
alpha_m = lc[num_list[0]].copy()
|
||||
for i in num_list[1:]:
|
||||
alpha_m['alpha'+str(i+1)] = lc[i]['alpha'+str(i+1)]
|
||||
|
||||
## 因子数据预处理
|
||||
# 因子相关系数热力图
|
||||
fig=plt.figure(figsize=(10,6))
|
||||
relations= alpha_m.corr()
|
||||
sns.heatmap(relations,annot=True,linewidths=0.05,linecolor='white',annot_kws={'size':8,'weight':'bold'})
|
||||
|
||||
# 中位数去极值
|
||||
def extreme_process_MAD(sample): # 输入的sample为时间截面的股票因子df数据
|
||||
factor_name = list(sample.columns)
|
||||
for name in factor_name:
|
||||
x = sample[name]
|
||||
median = x.median()
|
||||
MAD = abs(x - median).median()
|
||||
x[x>(median+3*1.4826*MAD)] = median+3*1.4826*MAD
|
||||
x[x<(median-3*1.4826*MAD)] = median-3*1.4826*MAD
|
||||
sample[name] = x
|
||||
return sample
|
||||
|
||||
# 行业市值中性化
|
||||
def data_scale_neutral(sample,date):
|
||||
stocks = list(sample.index)
|
||||
ind=w.wss(stocks, "industry_citic","unit=1;tradeDate="+date+";industryType=1", usedf=True)[1]
|
||||
Incap=w.wss(stocks, "val_lnmv","unit=1;tradeDate="+date+";industryType=1", usedf=True)[1]
|
||||
data_med = pd.get_dummies(ind,columns=['INDUSTRY_CITIC']) # 生成0-1变量矩阵
|
||||
x = pd.concat([data_med,Incap],axis=1).dropna()
|
||||
X= np.array(x)
|
||||
sample = sample.loc[list(x.index)]
|
||||
factor_name = list(sample.columns)
|
||||
for name in factor_name:
|
||||
y = np.array(sample[name])
|
||||
if la.matrix_rank(X.T.dot(X)) == X.shape[1]:
|
||||
beta_ols = la.inv(X.T.dot(X)).dot(X.T).dot(y) # 最小二乘法计算拟合值
|
||||
residual = y - X.dot(beta_ols) # 取残差为中性化后的因子值
|
||||
else:
|
||||
residual = y
|
||||
sample[name] = residual
|
||||
return sample
|
||||
|
||||
# 标准化
|
||||
def standardize(sample):
|
||||
factor_name = list(sample.columns)
|
||||
for name in factor_name:
|
||||
x = sample[name]
|
||||
sample[name] = (x - np.mean(x))/(np.std(x))
|
||||
return sample
|
||||
|
||||
# 数据预处理
|
||||
def data_process(sample,date):
|
||||
sample = extreme_process_MAD(sample)
|
||||
sample = data_scale_neutral(sample,date)
|
||||
sample = standardize(sample)
|
||||
return sample
|
||||
|
||||
# 回测筛选股票池
|
||||
def get_stocks(trDate,A_stocks):
|
||||
status = w.wss(A_stocks, "trade_status,maxupordown,riskwarning,ipo_date", tradeDate=trDate, usedf=True)[1]
|
||||
date_least=w.tdaysoffset(-6,trDate,'Period=M').Data[0][0]
|
||||
trade_codes=list(status[(status['TRADE_STATUS']=='交易')&(status['IPO_DATE']<=date_least)&(status['MAXUPORDOWN']==0)&(status['RISKWARNING']=='否')].index)
|
||||
return trade_codes
|
||||
|
||||
# 最大化历史ICIR加权/历史IC均值加权
|
||||
def IR_weight(bar_datetime_str,stocks,alpha_data):
|
||||
Period="W"
|
||||
begin_time = w.tdaysoffset(-12, bar_datetime_str, Period=Period, usedf=True).Data[0][0].strftime('%Y-%m-%d')
|
||||
time_list = w.tdays(begin_time,bar_datetime_str,Period=Period, usedf=True).Data[0]
|
||||
time_list = [time.strftime('%Y-%m-%d') for time in time_list]
|
||||
IC_s = []
|
||||
IC = []
|
||||
next_ret = w.wsd(stocks, "pct_chg", begin_time, bar_datetime_str, usedf=True, Period = Period)[1].fillna(value = 0).iloc[1:]
|
||||
for i in range(12):
|
||||
factor = alpha_data.loc[time_list[i]].reset_index().set_index(['codes']).drop(columns = ['date']).loc[stocks] # 转化为股票单层索引
|
||||
factor_name = list(factor.columns)
|
||||
ic_s = []
|
||||
for name in factor_name:
|
||||
try:
|
||||
ic_s.append(factor[name].corr(next_ret.iloc[i],method='spearman'))
|
||||
except:
|
||||
ic_s.append(factor[name].corr(next_ret.iloc[i-1],method='spearman'))
|
||||
IC_s.append(ic_s)
|
||||
IC_s = np.array(IC_s).T
|
||||
W = np.cov(IC_s)
|
||||
for i in range(len(IC_s)):
|
||||
IC.append(IC_s[i].mean())
|
||||
IC_IR = np.dot(W,np.array(IC))
|
||||
return IC_IR # np.array(IC)
|
||||
|
||||
# 最大化历史收益率加权
|
||||
def rate_weight(bar_datetime_str,stocks,alpha_data,num=10):
|
||||
Period="W"
|
||||
begin_time = w.tdaysoffset(-12, bar_datetime_str, Period=Period, usedf=True).Data[0][0].strftime('%Y-%m-%d')
|
||||
time_list = w.tdays(begin_time,bar_datetime_str,Period=Period, usedf=True).Data[0]
|
||||
time_list = [time.strftime('%Y-%m-%d') for time in time_list]
|
||||
IC_s = []
|
||||
IC = []
|
||||
next_ret = w.wsd(stocks, "pct_chg", begin_time, bar_datetime_str, usedf=True, Period = Period)[1].fillna(value = 0).iloc[1:]
|
||||
for i in range(12):
|
||||
factor = alpha_data.loc[time_list[i]].reset_index().set_index(['codes']).drop(columns = ['date']).loc[stocks]
|
||||
factor_name = list(factor.columns)
|
||||
ic_s = []
|
||||
for name in factor_name:
|
||||
g10 = list(factor.sort_values([name],ascending=False).iloc[:round(len(factor)/num)].index)
|
||||
try:
|
||||
ic_s = (next_ret.T.loc[g10]).T.iloc[i].mean()
|
||||
except:
|
||||
ic_s = (next_ret.T.loc[g10]).T.iloc[i-1].mean()
|
||||
IC_s.append(ic_s)
|
||||
IC_s = np.array(IC_s).T
|
||||
for i in range(len(IC_s)):
|
||||
IC.append(IC_s[i].mean())
|
||||
rate = np.array(IC)
|
||||
return rate
|
||||
|
||||
# 因子打分
|
||||
def factor_sum(sample,weight_list):
|
||||
factor_name = list(sample.columns)
|
||||
sample['alpha_sum'] = sample[factor_name[0]] * 0
|
||||
for i in range(len(factor_name)):
|
||||
sample['alpha_sum'] = sample['alpha_sum'] + sample[factor_name[i]] * weight_list[i]
|
||||
return sample
|
||||
@@ -0,0 +1,68 @@
|
||||
from WindPy import *
|
||||
from datetime import *
|
||||
from WindAlgo import *
|
||||
from scipy.stats import rankdata
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
import scipy.stats as stats
|
||||
import numpy.linalg as la
|
||||
w.start()
|
||||
|
||||
alpha_data = alpha_m
|
||||
|
||||
def initialize(context):
|
||||
context.capital = 10000000 # 回测的初始资金
|
||||
context.securities = w.wset("sectorconstituent", "date=20140101;windcode=000906.SH").Data[1]
|
||||
context.start_date = "20140104" # 回测开始时间
|
||||
context.end_date = "20190530" # 回测结束时间
|
||||
context.commission = 0.0003 # 手续费
|
||||
context.alpha_data = alpha_data
|
||||
context.benchmark = '000906.SH' # 设置回测基准
|
||||
|
||||
def handle_data(bar_datetime, context, bar_data):
|
||||
pass
|
||||
|
||||
def my_schedule1(bar_datetime, context, bar_data):
|
||||
bar_datetime_str = bar_datetime.strftime('%Y-%m-%d')
|
||||
stock800 = w.wset("sectorconstituent", "date="+bar_datetime_str+";windcode=000906.SH").Data[1]
|
||||
stocks = get_stocks(bar_datetime_str,stock800) # 获取筛选后的股票池
|
||||
## 提取因子数据法
|
||||
data = context.alpha_data.loc[bar_datetime_str].reset_index().set_index(['codes']).drop(columns = ['date']) #提取因子数据并调整结构
|
||||
stock_v = list(set(stocks) & set(data.index))
|
||||
data = data.loc[stock_v].dropna(axis=0) # 筛选出有效股票池对应数据
|
||||
profit = w.wss(stock_v, "fa_oigr_ttm,pe_ttm", tradeDate=bar_datetime_str, usedf=True)[1] # 加入财务因子
|
||||
profit.index = data.index
|
||||
data['1/PEG'] = profit['FA_OIGR_TTM']/profit['PE_TTM']
|
||||
data = data_process(data,bar_datetime_str) # 数据预处理
|
||||
weight = [] # 因子加权权重
|
||||
data = factor_sum(data,weight) # 因子打分
|
||||
## 回测中计算法
|
||||
# start_time = w.tdaysoffset(-5, bar_datetime_str,usedf=True).Data[0][0].strftime('%Y-%m-%d')
|
||||
# close = w.wsd(stocks,'close',start_time,bar_datetime_str,usedf = True)[1].reset_index().drop(columns = ['index'])
|
||||
# vwap = w.wsd(stocks,'vwap',start_time,bar_datetime_str,usedf = True)[1].reset_index().drop(columns = ['index'])
|
||||
# alpha = {'alpha':alpha42(vwap,close).iloc[-1]}
|
||||
# data = pd.DataFrame(alpha,index=stocks)
|
||||
|
||||
data = data.sort_values([data.columns.values[-1]],ascending=False) # 按打分大小排序
|
||||
code_list = list(data[:round(len(stocks)/5)].index) # 选出top组股票
|
||||
wa.change_securities(code_list) # 改变证券池
|
||||
context.securities = code_list
|
||||
list_sell = list(wa.query_position().get_field('code')) # 获取当前仓位股票池
|
||||
for code in list_sell:
|
||||
if code not in code_list:
|
||||
volumn = wa.query_position()[code]['volume'] # 找到每个股票的持仓量
|
||||
res = wa.order(code,volumn,'sell',price='close', volume_check=False)
|
||||
|
||||
def my_schedule2(bar_datetime, context,bar_data):
|
||||
buy_code_list=list(set(context.securities)-(set(context.securities)-set(list(bar_data.get_field('code')))))
|
||||
list_now = list(wa.query_position().get_field('code')) # 获取当前仓位股票池
|
||||
for code in buy_code_list:
|
||||
if code not in list_now:
|
||||
res = wa.order_percent(code,1/len(buy_code_list),'buy',price='close', volume_check=False) # 等权买入
|
||||
|
||||
wa = BackTest(init_func = initialize, handle_data_func=handle_data) # 实例化回测对象
|
||||
wa.schedule(my_schedule1, "w", 0) # w表示在每周执行一次策略,0表示偏移,表示月初第一个交易日往后0天
|
||||
wa.schedule(my_schedule2, "w", 0)
|
||||
res = wa.run(show_progress=True) # 调用run()函数开始回测,show_progress可用于指定是否显示回测净值曲线图
|
||||
nav_df = wa.summary('nav') # 获取回测结果,回测周期内每一天的组合净值
|
||||
@@ -0,0 +1,2 @@
|
||||
# alpha101
|
||||
基于万矿平台对alpha101因子进行测试并构造多因子策略
|
||||
Reference in New Issue
Block a user