【问题标题】:How to set triggers based on observed values如何根据观察值设置触发器
【发布时间】:2018-08-22 10:25:55
【问题描述】:

我是使用 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

【问题讨论】:

    标签: python python-3.x pandas


    【解决方案1】:

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

    从简化版的 Dataframe 开始:

             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
    

    【讨论】:

      【解决方案2】:

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

      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()
      

      这假设所有连续的日子都存在并且您的时间序列中没有漏洞。如果不是这样,你需要使用更多的诡计。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-17
        • 1970-01-01
        • 2011-03-29
        • 1970-01-01
        相关资源
        最近更新 更多