如何根据观察值设置触发器

时间:2018-08-21 20:33:38

标签: python python-3.x pandas

我不熟悉使用熊猫,所以请指出我在代码中可能遗漏的所有最佳做法。我编写了以下python代码,下面的代码从Yahoo Finance下载股票行情收录器数据,仅保留AAPL和MSFT的每日调整后收盘价。然后,我在数据框中创建了一个新列,其中包含AAPL的每日调整后收盘价除以MSFT的每日调整后收盘价(A),以及另一列,即同一计算的100天移动平均线(B)。后第二列是(A)/(B),最后一列是倒数第二天的每日变化百分比。

import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_like
from pandas_datareader import data as pdr
import fix_yahoo_finance as yf
yf.pdr_override()
import matplotlib.pyplot as plt
import pandas as pd

# Define the instruments to download. We would like to see Apple, and Microsoft
tickers = ['AAPL', 'MSFT']

# We would like all available data from 01/01/2000 until 12/31/2016.
start_date = '2010-01-01'
end_date = '2016-12-31'

# User pandas_reader.data.DataReader to load the desired data. As simple as that.
df = pdr.get_data_yahoo(tickers, start_date, end_date)['Adj Close']

df["AAPL/MSFT"] = df['AAPL']/df['MSFT']
df["100Day-MA APPL/MSFT"] = (df['AAPL']/df['MSFT']).rolling(window=100).mean()
df["AAPL/MSFT / MA"] = df["AAPL/MSFT"]/df["100Day-MA APPL/MSFT"]
df["% change AAPL/MSFT / MA"] = df["AAPL/MSFT / MA"].pct_change()

print(df.tail(9))

输出如下。我的问题是我该如何设置条件声明,以查看每日价格趋势,并根据这些信号发出买/卖信号。例如,df的最后一栏表示%的变化已连续5天增加。或者,倒数第二列已连续增加5天,但仍低于1。任何见解将不胜感激:)

                  AAPL       MSFT           ...             AAPL/MSFT / MA  % change AAPL/MSFT / MA
Date                                        ...
2016-12-19  113.490685  61.435783           ...                   0.965480                -0.014949
2016-12-20  113.792313  61.358532           ...                   0.969278                 0.003933
2016-12-21  113.899338  61.358532           ...                   0.970376                 0.001133
2016-12-22  113.150139  61.368191           ...                   0.963949                -0.006623
2016-12-23  113.373917  61.068832           ...                   0.970687                 0.006990
2016-12-27  114.093948  61.107452           ...                   0.976266                 0.005748
2016-12-28  113.607445  60.827412           ...                   0.976658                 0.000401
2016-12-29  113.578247  60.740505           ...                   0.977934                 0.001307
2016-12-30  112.692825  60.006588           ...                   0.982284                 0.004448

2 个答案:

答案 0 :(得分:1)

您的问题要问很多。我将向您展示如何找到连续的增长。

从数据框的简化版本开始:

         Date        AAPL       MSFT    change        MA
0  2016-12-19  113.490685  61.435783  0.965480 -0.014949
1  2016-12-20  113.792313  61.358532  0.969278  0.003933
2  2016-12-21  113.899338  61.358532  0.970376  0.001133
3  2016-12-22  113.150139  61.368191  0.963949 -0.006623
4  2016-12-23  113.373917  61.068832  0.970687  0.006990
5  2016-12-27  114.093948  61.107452  0.976266  0.005748
6  2016-12-28  113.607445  60.827412  0.976658  0.000401
7  2016-12-29  113.578247  60.740505  0.977934  0.001307
8  2016-12-30  112.692825  60.006588  0.982284  0.004448

我们将询问change列是否比前一天有所增加:

df['inc'] = df['change'] > df['change'].shift()

这给我们留下了

         Date        AAPL       MSFT    change        MA    inc
0  2016-12-19  113.490685  61.435783  0.965480 -0.014949  False
1  2016-12-20  113.792313  61.358532  0.969278  0.003933   True
2  2016-12-21  113.899338  61.358532  0.970376  0.001133   True
3  2016-12-22  113.150139  61.368191  0.963949 -0.006623  False
4  2016-12-23  113.373917  61.068832  0.970687  0.006990   True
5  2016-12-27  114.093948  61.107452  0.976266  0.005748   True
6  2016-12-28  113.607445  60.827412  0.976658  0.000401   True
7  2016-12-29  113.578247  60.740505  0.977934  0.001307   True
8  2016-12-30  112.692825  60.006588  0.982284  0.004448   True

然后,我们要求在为期5天的跟踪窗口中选择最小值;仅当所有5天均为True时,该值将为True

df['inc5'] = df['inc'].rolling(5).min().fillna(0).astype('bool')

因此我们有:

         Date        AAPL       MSFT    change        MA    inc   inc5
0  2016-12-19  113.490685  61.435783  0.965480 -0.014949  False  False
1  2016-12-20  113.792313  61.358532  0.969278  0.003933   True  False
2  2016-12-21  113.899338  61.358532  0.970376  0.001133   True  False
3  2016-12-22  113.150139  61.368191  0.963949 -0.006623  False  False
4  2016-12-23  113.373917  61.068832  0.970687  0.006990   True  False
5  2016-12-27  114.093948  61.107452  0.976266  0.005748   True  False
6  2016-12-28  113.607445  60.827412  0.976658  0.000401   True  False
7  2016-12-29  113.578247  60.740505  0.977934  0.001307   True  False
8  2016-12-30  112.692825  60.006588  0.982284  0.004448   True   True

答案 1 :(得分:0)

一种方法是计算差异,如果差异大于0,则创建一个列,否则为0。然后对最后一列进行滚动总和,如果得到5,则执行某项操作。 / p>

df['diff'] = df["AAPL/MSFT / MA"].diff()
df.loc[df['diff'] > 0, 'sign'] = 1
df.loc[df['diff'] <= 0, 'sign'] = 0
df['sum'] = df['sign'].rolling(5).sum()
if len(df.loc[df['sum'] == 5, 'sum']) > 0:
    all_your_stocks_are_belong_to_us()

这假定所有连续的天都存在并且时间序列中没有空洞。如果不是这种情况,则需要使用更多的技巧。