1

Pandas Dataframe に datetime インデックスを含む OHLC 価格データがあり、トレード エントリー シグナルをバックテストしています。

そのうちの 1 つは、以前の大幅な安値を破った買いエントリー パターンをマークすることです。正しく動作するコードを以下に記述しましたが、可能であれば、「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)
4

0 に答える 0