求助:Python 股價崩盤風險指標

專注的阿熊發表於2021-06-28

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()


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2778690/,如需轉載,請註明出處,否則將追究法律責任。

相關文章