簡體   English   中英

Python和Pandas - 移動平均線交叉

[英]Python and Pandas - Moving Average Crossover

有一個帶有一些股票數據的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有效地完成嗎? 怎么樣?

編輯:

我的意思是'十字路口':

數據行,時間:

  • 長SMA(45)值比短SMA(15)值大於短SMA周期(15)並且變小。
  • 長SMA(45)值比短SMA(15)值小於短SMA周期(15)並且變得更大。

我正在采用交叉來表示當SMA線 - 作為時間函數 - 相交時, 如此投資頁面上所示

在此輸入圖像描述

由於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

作為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

以下方法給出了類似的結果,但比以前的方法花費的時間更少:

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)

先前方法所需的時間: 3.46 ms ± 307 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM