LoginSignup
7
4

More than 5 years have passed since last update.

新高値更新のアルゴリズム #QuantX

Last updated at Posted at 2018-07-27

新高値更新

ある株の銘柄の本日の高値が、過去の一定期間における最高値を更新した場合、相場の一段高を暗示し、買いシグナルになるそうです.これを新高値更新と呼ぶそうです。
今回は、これを使ってQuantXでシミュレーションをしてみます。

シグナル

ここでは本日の高値と過去10日間の最高値を見て、新高値更新の判定をし、取引シグナルとすることにします.株価の比較には、株式分割調整後のものを用います。
ただし,本日の高値が過去10日間の最高値になっていても、過去5日間(=ホールド期間)に既にも同じことが起きていた場合にはシグナルとはしません。

手仕舞い

シグナルが出てから5日間ホールドして、クローズすることにします。

コード


def initialize(ctx):
    # 設定
    ctx.logger.debug("initialize() called")

    # 過去何日間を観察するか
    ctx.high_term = 10
    # ポジションに対して何%持つか 
    ctx.target = 0.5 
    # ポジションを何日ホールドするか
    ctx.holding_days = 5 

    ctx.configure(
      channels={          # 利用チャンネル
        "jp.stock": {
          "symbols": [
            "jp.stock.1305",
            "jp.stock.9984",
            "jp.stock.9983",
            "jp.stock.7201",
            "jp.stock.9201",
            "jp.stock.9202",
            "jp.stock.7203"
          ],
          "columns": [
            "high_price_adj",]}})    # 高値(株式分割調整後)

    def _BREAK_NEW_HIGH(data):

      # 欠損値を埋める
      hp = data["high_price_adj"].fillna(method="ffill")
      # 過去10日間における最高値を取得
      new_max = hp.rolling(window=ctx.high_term, center=False).max()
      # その最高値が今日の高値と同じかどうかの真偽値
      today_is_new_high = new_max == hp
      # 今日が過去10日間における最高値であり,かつ,過去5日間において最高値が発生していないという真偽値
      buy_signal = (today_is_new_high) & (today_is_new_high.rolling(window=ctx.holding_days, center=False).sum() == 1)

      # pd.Serieseの shift 関数を使って5日前のbuy_signalのシグナルを取得.
      # ここがTrueであれば5日前に取引したという事なので,この日にポジションを閉じる
      # (memo 参照)
      close_signal = buy_signal.shift(ctx.holding_days)


      return {
        "New High":new_max, 
        "buy:sig": buy_signal,
        "close:sig": close_signal,
        }

    # シグナル登録
    ctx.regist_signal("BREAK_NEW_HIGH", _BREAK_NEW_HIGH)

def handle_signals(ctx, date, current):

    df = current.copy()

    # 買いシグナル
    df_long = df[df["buy:sig"]]

    if not df_long.empty:
      for (sym, val) in df_long.iterrows(): 
        #ctx.logger.info(val)
        sec = ctx.getSecurity(sym)
        # New High と 過去10日間の High が本当に同じかどうか確認したかったのでコメントに入れた.
        msg = "買いシグナル: Today's High {0}, Rolling High {1}".format(val["high_price_adj"], val["New High"],)
        sec.order_target_percent(ctx.target, comment= msg)


    # # ポジションクローズ
    df_close = df[df["close:sig"]]
    if not df_close.empty:
      for (sym, val) in df_close.iterrows(): 
        sec = ctx.getSecurity(sym)
        sec.order_target_percent(0, comment= "position close")

memo

shift について

shiftは,データをn行ずらすときに使います.コードでは,buy_signalを5シフトした pd.Serise データを close_signal とすることで,5日間ホールドして手仕舞うというシグナルを作っています.

イメージはこんな感じです.

2018-07-27-18:00:25.jpg

結果

2018-07-27-18:11:51.jpg

感想など

  • 銘柄選定はQuantXプロジェクトを新規作成すると自動生成されるサンプルコードに使われている銘柄をそのまま使っています.
  • 高値で見るのではなく,終値で見たほうがいいのでは?と思いました.
  • shift とは仲良くしていきたい.
  • 台風12号が心配

免責注意事項

  • このコードに基づき投資した結果、損害が発生しても,一切責任を持ちません.
  • このコードが正しく機能する保証は一切致しません.
  • このアルゴリズムを勧めているわけではありません.あくまで python のサンプルコードとして掲載しているだけです.
7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4