将每日股票价格变成每周/每月/每季度/学期/每年?

Posted

技术标签:

【中文标题】将每日股票价格变成每周/每月/每季度/学期/每年?【英文标题】:Turning daily stock prices into weekly/monthly/quarterly/semester/yearly? 【发布时间】:2021-10-08 21:31:54 【问题描述】:

我正在尝试将每日价格转换为每周、每月、每季度、每学期、每年,但该代码仅在我为一只股票运行时才有效。当我将另一只股票添加到列表中时,代码崩溃并出现两个错误。 “ValueError:名称长度必须与 MultiIndex 中的级别数匹配。”和 'T​​ypeError: other 必须是 MultiIndex 或元组列表。'我没有使用 MultiIndexing 的经验,并且到处搜索都没有成功。

这是代码:

import yfinance as yf
from pandas_datareader import data as pdr

symbols = ['AMZN', 'AAPL']

yf.pdr_override()

df = pdr.get_data_yahoo(symbols, start = '2014-12-01', end = '2021-01-01')
df = df.reset_index()
df.Date = pd.to_datetime(df.Date)
df.set_index('Date', inplace = True)

res = 'Open': 'first', 'Adj Close': 'last'

dfw = df.resample('W').agg(res)
dfw_ret = (dfw['Adj Close'] / dfw['Open'] - 1)

dfm = df.resample('BM').agg(res)
dfm_ret = (dfm['Adj Close'] / dfm['Open'] - 1)

dfq = df.resample('Q').agg(res)
dfq_ret = (dfq['Adj Close'] / dfq['Open'] - 1)

dfs = df.resample('6M').agg(res)
dfs_ret = (dfs['Adj Close'] / dfs['Open'] - 1)

dfy = df.resample('Y').agg(res)
dfy_ret = (dfy['Adj Close'] / dfy['Open'] - 1)

print(dfw_ret)
print(dfm_ret)
print(dfq_ret)
print(dfs_ret)
print(dfy_ret)```

This is what the original df prints:

```Adj Close                     Open             
                  AAPL         AMZN        AAPL         AMZN
Date                                                        
2014-12-01   26.122288   326.000000   29.702499   338.119995
2014-12-02   26.022408   326.309998   28.375000   327.500000
2014-12-03   26.317518   316.500000   28.937500   325.730011
2014-12-04   26.217640   316.929993   28.942499   315.529999
2014-12-05   26.106400   312.630005   28.997499   316.799988
...                ...          ...         ...          ...
2020-12-24  131.549637  3172.689941  131.320007  3193.899902
2020-12-28  136.254608  3283.959961  133.990005  3194.000000
2020-12-29  134.440399  3322.000000  138.050003  3309.939941
2020-12-30  133.294067  3285.850098  135.580002  3341.000000
2020-12-31  132.267349  3256.929932  134.080002  3275.000000


And this is what the different df_ret print when I go from daily 
to weekly/monthly/etc but it can only do it for one stock and 
the idea is to be able to do it for multiple stocks:


Date
2014-12-07   -0.075387
2014-12-14   -0.013641
2014-12-21   -0.029041
2014-12-28    0.023680
2015-01-04    0.002176
                ...   
2020-12-06   -0.014306
2020-12-13   -0.012691
2020-12-20    0.018660
2020-12-27   -0.008537
2021-01-03    0.019703
Freq: W-SUN, Length: 318, dtype: float64

Date
2014-12-31   -0.082131
2015-01-30    0.134206
2015-02-27    0.086016
2015-03-31   -0.022975
2015-04-30    0.133512
                ...   
2020-08-31    0.085034
2020-09-30   -0.097677
2020-10-30   -0.053569
2020-11-30    0.034719
2020-12-31    0.021461
Freq: BM, Length: 73, dtype: float64

Date
2014-12-31   -0.082131
2015-03-31    0.190415
2015-06-30    0.166595
2015-09-30    0.165108
2015-12-31    0.322681
2016-03-31   -0.095461
2016-06-30    0.211909
2016-09-30    0.167275
2016-12-31   -0.103026
2017-03-31    0.169701
2017-06-30    0.090090
2017-09-30   -0.011760
2017-12-31    0.213143
2018-03-31    0.234932
2018-06-30    0.199052
2018-09-30    0.190349
2018-12-31   -0.257182
2019-03-31    0.215363
2019-06-30    0.051952
2019-09-30   -0.097281
2019-12-31    0.058328
2020-03-31    0.039851
2020-06-30    0.427244
2020-09-30    0.141676
2020-12-31    0.015252
Freq: Q-DEC, dtype: float64

Date
2014-12-31   -0.082131
2015-06-30    0.388733
2015-12-31    0.538386
2016-06-30    0.090402
2016-12-31    0.045377
2017-06-30    0.277180
2017-12-31    0.202181
2018-06-30    0.450341
2018-12-31   -0.107405
2019-06-30    0.292404
2019-12-31   -0.039075
2020-06-30    0.471371
2020-12-31    0.180907
Freq: 6M, dtype: float64

Date
2014-12-31   -0.082131
2015-12-31    1.162295
2016-12-31    0.142589
2017-12-31    0.542999
2018-12-31    0.281544
2019-12-31    0.261152
2020-12-31    0.737029
Freq: A-DEC, dtype: float64```

【问题讨论】:

代码中的哪一行发生了错误? pdr.get_Data_yahoo() 是否接受符号列表?如果是这样,因为您将其保存到单个 DataFrame 中,它可能会返回一个 MultiIndex。有多种方法可以处理此问题,但我想了解一下您正在使用的 DataFrame。 当我重新采样数据时,错误发生在第 16 行。是的pdr.get_Data_yahoo()确实接受符号列表。 【参考方案1】:

在不知道您的 df DataFrame 是什么样子的情况下,我假设这是正确处理 MultiIndex 上的重采样的问题,类似于在此 question 中讨论的问题。

那里列出的解决方案是使用pd.Grouper 并正确填写freqlevel 参数。

# This is just from the listed solution so I am not sure if these is the correct level to choose
df.groupby(pd.Grouper(freq='W', level=-1))

如果这不起作用,我认为您需要提供更多细节或虚拟数据集来重现该问题。

【讨论】:

嗯 groupby 方法打印了我这个。 <pandas.core.groupby.generic.DataFrameGroupBy object at 0x7fce0d2f7dc0>。我更新了问题以显示原始 df 的样子。 :)

以上是关于将每日股票价格变成每周/每月/每季度/学期/每年?的主要内容,如果未能解决你的问题,请参考以下文章

每天、每周、每月和每年调用一个方法

cron和crontab命令详解 crontab 每分钟每小时每天每周每月每年定时执行 crontab每5分钟执行一次

消防供水设施 官网及阀门

AppEngine cron (python) 中的每一天、每周、每月、每年

请问JS如何实现这样一个时间选择联动效果

2022:股票程序化交易实战2022Q1