def computerBondFactor(obj, startDate, momwindow=20, window=20):
# 储存固定周期的涨跌幅数据并计算动量,以及后续我们因子构建是按照市值加权的
startDate = pd.to_datetime(startDate).strftime('%Y/%#m/%#d')
ret = obj.DB['CLOSE'].pct_change(window).loc[startDate::window]
wgt = obj.DB['AMT'].loc[startDate::window]
obj.DB['1Mmom'] = obj.DB['CLOSE'].pct_change(momwindow).shift(window + 1)
dictRawdf = {
'ptm': {'dfRank': obj.DB['MATURITY'].loc[startDate::window].rank(pct=True, axis=1), 'mat': [None, None, None]},
'credit': {'dfRank': obj.DB['DIVIDEND'].loc[startDate::window].rank(pct=True, axis=1),
'mat': [None, None, None]},
'mom': {'dfRank': obj.DB['1Mmom'].loc[startDate::window].rank(pct=True, axis=1), 'mat': [None, None, None]}}
# 将每个周期依照期限、信用和动量进行三分(以30%与70%为界)
for k, v in dictRawdf.items():
dfRaw = v['dfRank']
v['mat'][0] = dfRaw.applymap(lambda x: 1 if x > 0.7 else np.nan)
v['mat'][1] = dfRaw.applymap(lambda x: 1 if (x <= 0.7) & (x >= 0.3) else np.nan)
v['mat'][2] = dfRaw.applymap(lambda x: 1 if x < 0.3 else np.nan)
dictFactors = {'LMS': {'keydf': 'ptm', 'comdf': ['credit', 'mom'], 'values': None},
'GMP': {'keydf': 'credit', 'comdf': ['ptm', 'mom'], 'values': None},
'HMW': {'keydf': 'mom', 'comdf': ['ptm'
, 'credit'], 'values': None}}
# 依据类似Carhart四因子方式构建期限、信用和动量三大因子(市值加权计算因子)
for k, v in dictFactors.items():
factorValue = None
for num, com in enumerate(v['comdf']):
pctDiff = None
for i in [0, 2]:
pct = None
for j in [0, 1, 2]:
mat = dictRawdf[v['keydf']]['mat'][i] * dictRawdf[com]['mat'][j]
pctwgtMean = (ret * mat * wgt).sum(axis=1) / (wgt * mat).sum(axis=1)
pct = pctwgtMean if j == 0 else pct + pctwgtMean
pct.fillna(0, inplace=True)
pctDiff = pct if i == 0 else pctDiff - pct
pctDiff.fillna(0, inplace=True)
factorValue = pctDiff if num == 0 else factorValue + pctDiff
v['values'] = factorValue / 6.
dfRet = pd.DataFrame(columns=dictFactors.keys())
for k in dfRet.columns:
dfRet[k] = dictFactors[k]['values']
dfRet.index = [pd.to_datetime(d) for d in dfRet.index]
return dfRet