def ols_analysis(df, t, i):
"""
回归分析
"""
df_ols = pd.DataFrame()
# df_ols['y'] = df[''] # 缺的第一个问题里的数据
for a in range(5):
df_ols['x%s' % a] = df[''] # 缺的第二个问题里的数据
y = df_ols.iloc[:, 0] # 因变量取值
x = df_ols.iloc[:, 1:6] # 自变量取值
x = sm.add_constant(x) # 截距项
model = sm.OLS(y, x).fit() # OLS 回归
return model
def w_volume(model):
"""
残差项及周特质收益率
"""
df_resid = pd.DataFrame()
df_resid['re'] = model.resid # 残差项
df_resid['w'] = [math.log(re + 1, math.e)
for re in df_resid['re']] # w 值,周特质收益率
return df_resid
def duweek(df_resid):
"""
DUVOL ,用到上升周和下降周,上升周是残差大于平均残差的,下降周反之
"""
w_down, w_up = [], []
for _w in df_resid['w']: # 历遍各周中的每一项 w 值
if _w < df_resid['w'].mean(): # 如果 w 值小于平均
w_down.append(_w) # 记一个下降周
w_up.append(0) # 上升周对齐
else: # 否则
w_up.append(_w) # 记一个上升周
w_down.append(0) # 下降周对齐
df_duweek = pd.DataFrame()
df_duweek['w_down'] = w_down
df_duweek['w_up'] = w_up
return df_duweek
def duvol_cal(duvol, df_duweek):
"""
变量部分
"""
w_down_num = list(df_duweek['w_up']).count(0) # 下降周的数量等于上升周列表里的 0 的个数
w_up_num = list(df_duweek['w_down']).count(0) # 外汇跟单gendan5.com 反之亦然
w_down_sum = sum(w ** 2 for w in df_duweek['w_down']) # 下降周 w 平方和
w_up_sum = sum(w ** 2 for w in df_duweek['w_up']) # 下降周 w 平方和
"""
计算部分
"""
if ((w_down_num - 1) * w_up_sum) > 0 and ((w_up_num - 1) * w_down_sum) > 0: # 分母不能为 0
before_log = ((w_up_num - 1) * w_down_sum) / ((w_down_num - 1) * w_up_sum) # 取对数前 DUVOL
duvol.append(math.log(before_log, math.e)) # 取对数后 DUVOL
else:
duvol.append(' 全年涨或跌 ')
return duvol
def ncskew_cal(ncskew, df_resid, i):
w_lifanghe = sum(w**3 for w in df_resid)
w_pingfanghe = sum(w ** 2 for w in df_resid)
if ((i - 1) * (i - 2) * w_pingfanghe ** (3 / 2)) != 0: # 分母不能为 0
jisuan = -((i * (i - 1) ** (3 / 2)) * w_lifanghe) / ((i - 1) * (i - 2) * w_pingfanghe ** (3 / 2)) # 计算公式
ncskew.append(jisuan)
else:
ncskew.append(' 数据异常 ')
return ncskew
def main():
"""
用扩展指数模型做回归分析
得到残差,可以刻画上市公司的股价崩盘事件
"""
n = pd.read_csv(path1+files1) # 每年交易周数
# k_data = pd.read_csv(path2+files1) # k 线数据,解决问题一和二之后才可用
"""
跳过一些空的文件
"""
if n.empty or k_data.empty:
pass
else:
df_duvol = pd.DataFrame() # 用来装 DUVOL
df_ncskew = pd.DataFrame() # 用来装 NCSKEW
t = 0
df_all = pd.DataFrame()
for i in n['week_num']:
duvol, ncskew = [], []
df_du = pd.DataFrame()
df_nc = pd.DataFrame()
if i > 10: # 一年的交易周低于 10 周的话没法回归
# model = ols_analysis(k_data[''], t, i) # 缺数据
df_resid = w_volume(model)
df_duweek = duweek(df_resid)
duvol = duvol_cal(duvol, df_duweek)
ncskew = ncskew_cal(ncskew, df_resid['w'], i)
else:
duvol.append(' 数据异常 ')
ncskew.append(' 数据异常 ')
t += i
df_du['duvol'] = duvol
df_duvol = df_duvol.append(df_du)
df_nc['ncskew'] = ncskew
df_ncskew = df_ncskew.append(df_nc)
"""
以下就是对齐表格的索引,然后输出的过程
"""
df_duvol['year'] = list(n['year']) # 这个表格里面加一个年份的一列,直接用 n['year'] 的话有索引,得先 list
df_duvol.set_index(['year'], inplace=True) # 把 year 这列设置成索引
df_ncskew['year'] = list(n['year']) # 同上
df_ncskew.set_index(['year'], inplace=True) # 同上
df_all['duvol'] = df_duvol['DUVOL'] # 第一次存进来会生成索引
df_all['ncskew'] = df_ncskew['NCSKEW'] # 这个索引和上面是对齐的
df_all.to_csv(r'mypath\%s' % files1) # 输出到文件, index 默认 True
if __name__ == '__main__':
path1 = '' # 上一个函数导出来的交易周数据
path2 = '' # 上一个函数里还缺的数据
for files1 in tqdm(os.listdir(path1)):
main()