我最近面临一项挑战,即使用 -1、1 的值来表示牛市/熊市的存在情况。
使用 for 循环来完成此操作非常简单,但我知道这是执行这些操作的最糟糕方法,如果可能的话最好使用 numpy/pandas 方法。但是,我没有找到一种简单的方法来做到这一点。如何做到这一点的任何方法,也许使用当前位置 +/- 20% 的变化来确定您所处的状态。
这是一个示例数据框:
dates = pd.date_range(start='1950-01-01', periods=25000)
rand = np.random.RandomState(42)
vals = np.zeros(25000)
vals[0] = 15
for i in range(1, 25000):
vals[i] = vals[i-1] + rand.normal(0, 1)
df = pd.DataFrame(vals, columns=['Price'], index=dates)
这些价格的图如下所示:
有人有任何建议来计算当前点所处的状态吗?
如果您必须使用 for 循环,那没问题。
最佳答案
这是使用 Yahoo! 的 S&P 500 指数的解决方案财务(股票代码 ^GSPC):
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import yfinance as yf
import requests_cache
session = requests_cache.CachedSession()
df = yf.download('^GSPC', session=session)
df = df[['Adj Close']].copy()
df['dd'] = df['Adj Close'].div(df['Adj Close'].cummax()).sub(1)
df['ddn'] = ((df['dd'] < 0.) & (df['dd'].shift() == 0.)).cumsum()
df['ddmax'] = df.groupby('ddn')['dd'].transform('min')
df['bear'] = (df['ddmax'] < -0.2) & (df['ddmax'] < df.groupby('ddn')['dd'].transform('cummin'))
df['bearn'] = ((df['bear'] == True) & (df['bear'].shift() == False)).cumsum()
bears = df.reset_index().query('bear == True').groupby('bearn')['Date'].agg(['min', 'max'])
print(bears)
df['Adj Close'].plot()
for i, row in bears.iterrows():
plt.fill_between(row, df['Adj Close'].max(), alpha=0.25, color='r')
plt.gca().yaxis.set_major_formatter(plt.matplotlib.ticker.StrMethodFormatter('{x:,.0f}'))
plt.ylabel('S&P 500 Index (^GSPC)')
plt.title('S&P 500 Index with Bear Markets (> 20% Declines)')
plt.savefig('bears.png')
plt.show()
以下是数据框架bears
中的熊市:
min max
bearn
1 1956-08-06 1957-10-21
2 1961-12-13 1962-06-25
3 1966-02-10 1966-10-06
4 1968-12-02 1970-05-25
5 1973-01-12 1974-10-02
6 1980-12-01 1982-08-11
7 1987-08-26 1987-12-03
8 2000-03-27 2002-10-08
9 2007-10-10 2009-03-06
10 2020-02-20 2020-03-20
11 2022-01-04 2022-06-15
这是一个情节:
编辑:我认为这是对我的第一个解决方案的改进,因为 ^GSPC 提供了更长的时间序列,并且熊市通常不进行股息调整。
关于python - 计算 Pandas 的牛市/熊市,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64830383/