计算股票市场的季节性指数:如何对市场关闭进行编码?

2024-03-29 07:47:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我写了一个计算股票季节指数的小程序。它使用一个简单的数据文件,如下所示:

2/17/1995,481.97
2/21/1995,482.74
2/22/1995,485.07
2/23/1995,486.91
2/24/1995,488.11
2/27/1995,483.81
2/28/1995,487.39

节目如下:

#-------------------------------------------------------------------------------
# Name:        newSeasonal
# Purpose:     calculate a seasonal index
#
# Author:      John Bollinger
#
# Created:     07/12/2020
# Copyright:   (c) John Bollinger 2020
# Licence:     MIT
#-------------------------------------------------------------------------------

# python 3.6.1+ required
# import the packages we will need
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime

def main(datapath, datafile, start, stop, nonTradeDays):
    # read file and store recent changes
    df = pd.read_csv(datapath + datafile, parse_dates=True, names = ["date","close"], index_col = 0)
    # correct for market closures
    for day in nonTradingDays:
         pass
    # create a dataframe to hold the results
    seasonal = pd.DataFrame(index = np.arange(1,253))
    for col in range(start, stop):
        seasonal[col] = np.nan
    # populate the dataframe
    for year in range(start, stop):
        date_ = datetime.date(year, 1, 2)
        j = 1
        while (date_.year == year):
            try:
                seasonal.loc[j, year] = df.loc[date_].close
                j += 1
                date_ += datetime.timedelta(days=1)
            except KeyError:
                date_ += datetime.timedelta(days=1)
    # index the years to 100
    for year in range(start, stop):
        seasonal[year] = seasonal[year]/seasonal.loc[1, year]*100
    # plot the results
    plotTitle = "S&P 500 Annual Seasonal Trading Pattern 2000 through 2019"
    ax = seasonal[1:252].mean(axis=1, skipna = True).plot(title = plotTitle)
    ax.set_xlabel("trading days")
    ax.set_ylabel("composite seasonal")
    ax.grid()
    plt.show()

if __name__ == '__main__':
    datapath = "c:\\Users\Public\\Portfolio\\Python Scripts\\newSeasonal\data\\"
    datafile = "spx.csv"
    start = 2000
    stop = 2020
    # special non-trading days 1990 through 2020
    # Nixon     4/27/1994
    # 9/11      9/11-14/2001
    # Reagan    6/11/2004
    # Ford      1/2/2007
    # Sandy     10/29-30/2012
    # HW Bush   12/5/2018
    nonTradeDays = ["1994-04-27", "2001-09-11", "2001-09-12", "2001-09-13", \
        "2001-09-14", "2004-06-11", "2007-01-02", "2012-10-29", \
        "2012-10-30", "2018-12-05"]
    main(datapath, datafile, start, stop, nonTradeDays)

#  That's all folks!

我的问题是,特殊的非交易日会导致列表问题,因此我想为每个特殊日插入一行,其中包含前一天的值。像这样

6/10/2004, aaaa.aa
6/12/2004, bbbb.bb

变成

6/10/2004, aaaa.aa
6/11/2004, aaaa.aa
6/12/2004, bbbb.bb

我有一个缺失日期的列表,并尝试了各种策略,如附加重新索引、concat和设置放大,但都没有成功。我的问题是:做这件事最好的方法是什么


Tags: theinimportfordatetimedateindexax
1条回答
网友
1楼 · 发布于 2024-03-29 07:47:43

在数据框上使用pandas DatetimeIndex(即,将数据框索引设置为日期列中的值),您可以将其与特殊非交易日组成的空数据框(作为另一个DatetimeIndex)连接起来,然后最终向前填充NAN:

# Example dataframe, df:

#                   Open        High         Low       Close    Volume
# Date                                                                
# 2020-11-16  118.919998  120.989998  118.150002  120.300003  91183000
# 2020-11-18  118.610001  119.820000  118.000000  118.029999  76322100
# 2020-11-20  118.639999  118.769997  117.290001  117.339996  73391400

# Special days:

special_days = ['2020-11-17', '2020-11-19']

special_days_df = pd.DataFrame(index=pd.to_datetime(special_days))

pd.concat([df,special_days_df],axis=0).sort_index().fillna(method='ffill')

#                   Open        High         Low       Close    Volume
# Date                                                                
# 2020-11-16  118.919998  120.989998  118.150002  120.300003  91183000
# 2020-11-17  118.919998  120.989998  118.150002  120.300003  91183000
# 2020-11-18  118.610001  119.820000  118.000000  118.029999  76322100
# 2020-11-19  118.610001  119.820000  118.000000  118.029999  76322100
# 2020-11-20  118.639999  118.769997  117.290001  117.339996  73391400

相关问题 更多 >