Pandas数据帧:列值低于指定行的下一行的向量函数?

时间:2013-07-20 15:26:51

标签: python pandas vectorization

我在带有日期时间指数的Pandas Dataframe中有OHLC价格数据,并且正在回溯测试交易进入信号。

其中一个是标记买入进入模式,其中先前的重要低点被打破。我已经编写了下面的代码,它可以正常工作,但是我想将它向量化以返回“FooBuy”列的向量函数,如果可能的话。

我计划最终在实时系统中使用此代码,因此使用自动响应变化数据的向量将是一个很大的好处。

有人可以提出任何建议吗?

class FooBuy(PricePattern):

  def df_apply(self, df):

    if not ("SigLow" in df.columns):
       df["SigLow"] = SigLow().df_apply(df)  # correct pattern

    df["SigLowBrokenAt"] = None
    df["FooBuy"] = False

    for date, row in df[df.SigLow].iterrows():
        df_sorted_lows = df[date:].sort("Low", ascending=False)
        df_later_and_lower = df_sorted_lows[df_sorted_lows.Low < row["Low"]]
        if len(df_later_and_lower) > 0:
           df["SigLowBrokenAt"].ix[date] = df_later_and_lower.ix[0].name

    for date in df.SigLowBrokenAt.dropna():
        df["FooBuy"].ix[date] = True

以下是SigLow的代码:

class PricePattern(object):

  def __init__(self, shift=0, **kwargs):
    self.shift = shift

  def __repr__(self):
    return "{0}({1})".format(self.__class__.__name__, "" if self.shift == 0 else "shift=\"{0}\"".format(self.shift))

  def df_apply(self, df):
    raise NotImplementedError()


class SigLow(PricePattern):

  def __init__(self, **kwargs):
    super(SigLow, self).__init__(**kwargs)

  def df_apply(self, df):
    return (df.Low.shift(self.shift) < df.Low.shift(self.shift + 1)) & \
        (df.Low.shift(self.shift) < df.Low.shift(self.shift - 1))

这是一些通过的测试代码:

class TestBase(unittest.TestCase):
  def _create_df(self, data):
    return 1 + pd.DataFrame(data, columns=['Open', 'High', 'Low', 'Close'],
                            index=pd.date_range('2/25/2013 06:00', periods=len(data),
                                                freq='H')) / 100

  def _assert_true_alone(self, series, index):
    for i in arange(len(series)):
        self.assertTrue(series[i] or (i not in index))

  def _assert_all_false(self, series):
    for i in arange(len(series)):
        self.assertFalse(series[i])


class TestFooBuy(TestBase):

  def test_matches(self):
    data1 = [[48, 49, 34, 48],
             [48, 50, 46, 48],
             [47, 49, 38, 48],  # SL
             [48, 59, 48, 58],
             [57, 57, 50, 54],
             [53, 53, 36, 40],  # FB
             [39, 39, 29, 32]]

    df = self._create_df(data1)
    #df["FooBuy"] = FooBuy().df_apply(df)  # correct pattern
    FooBuy().df_apply(df)
    self._assert_true_alone(df.SigLow, [2])
    self._assert_true_alone(df.FooBuy, [5])

  def test_does_not_match(self):
    data1 = [[48, 49, 34, 48],
             [48, 50, 46, 48],
             [47, 49, 38, 48],  # SL
             [48, 59, 48, 58],
             [57, 57, 42, 48],  # SL
             [48, 50, 43, 44],
             [45, 52, 45, 51]]

    df = self._create_df(data1)
    #df["FooBuy"] = FooBuy().df_apply(df, config_defaults)  # correct pattern
    FooBuy().df_apply(df, config_defaults)
    #print df
    self._assert_true_alone(df.SigLow, [2, 4])
    self._assert_all_false(df.FooBuy)

0 个答案:

没有答案