有一个带有一些股票数据的Pandas DataFrame对象。 SMA是从之前45/15天计算的移动平均线。
Date Price SMA_45 SMA_15
20150127 102.75 113 106
20150128 103.05 100 106
20150129 105.10 112 105
20150130 105.35 111 105
20150202 107.15 111 105
20150203 111.95 110 105
20150204 111.90 110 106
我希望找到所有日期,当SMA_15和SMA_45相交时。
使用Pandas或Numpy可以有效地完成吗?怎么样?
编辑:
我的意思是'十字路口':
数据行,时间:
答案 0 :(得分:14)
我正在采用交叉来表示何时SMA线 - 作为时间的函数 - 相交,如this investopedia page所示。
由于SMA表示连续功能,因此存在交叉时, 对于给定的行,(SMA_15小于SMA_45)和(之前的SMA_15是 大于之前的SMA_45) - 反之亦然。
在代码中,可以表示为
previous_15 = df['SMA_15'].shift(1)
previous_45 = df['SMA_45'].shift(1)
crossing = (((df['SMA_15'] <= df['SMA_45']) & (previous_15 >= previous_45))
| ((df['SMA_15'] >= df['SMA_45']) & (previous_15 <= previous_45)))
如果我们将您的数据更改为
Date Price SMA_45 SMA_15
20150127 102.75 113 106
20150128 103.05 100 106
20150129 105.10 112 105
20150130 105.35 111 105
20150202 107.15 111 105
20150203 111.95 110 105
20150204 111.90 110 106
以便有交叉点,
然后
import pandas as pd
df = pd.read_table('data', sep='\s+')
previous_15 = df['SMA_15'].shift(1)
previous_45 = df['SMA_45'].shift(1)
crossing = (((df['SMA_15'] <= df['SMA_45']) & (previous_15 >= previous_45))
| ((df['SMA_15'] >= df['SMA_45']) & (previous_15 <= previous_45)))
crossing_dates = df.loc[crossing, 'Date']
print(crossing_dates)
产量
1 20150128
2 20150129
Name: Date, dtype: int64
答案 1 :(得分:0)
作为unutbu答案的替代方法,也可以执行以下操作来查找SMA_15
跨越SMA_45
的索引。
diff = df['SMA_15'] < df['SMA_45']
diff_forward = diff.shift(1)
crossing = np.where(abs(diff - diff_forward) == 1)[0]
print(crossing)
>>> [1,2]
print(df.iloc[crossing])
>>>
Date Price SMA_15 SMA_45
1 20150128 103.05 100 106
2 20150129 105.10 112 105
答案 2 :(得分:0)
以下方法可获得相似的结果,但所需时间少于以前的方法:
df['position'] = df['SMA_15'] > df['SMA_45']
df['pre_position'] = df['position'].shift(1)
df.dropna(inplace=True) # dropping the NaN values
df['crossover'] = np.where(df['position'] == df['pre_position'], False, True)
此方法花费的时间:
2.7 ms ± 310 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
previous approach花费的时间:
3.46 ms ± 307 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)