LoginSignup
1
1

More than 5 years have passed since last update.

QuantXでROCを実装してみた

Posted at

今回やったこと

投資アルゴリズム開発プラットフォーム「QuantX」で、ROCを実装してみました。

ROCとは

ROCとは、モメンタムを改良したオシレーター系のテクニカル指標であり、一定の周期で値動きするレンジ相場を分析することで、相場の強弱や勢い、転換を見極めるために使われます。

モメンタムは単純に値動きの幅を取ったものなので、株価の高低によって値が大きく変わってしまいます。ROCはこの点を改良したもので、株価の高低にかかわらず使うことができます。

$$ROC = \frac{現在の株価 - 過去の株価}{過去の株価} × 100$$
ROCは上式で表され、過去の株価から見た現在の株価の値上がりを意味します。
一般的には、15日、20日、25日などが計算期間として使われるそうです。

アルゴリズム

今回書いたアルゴリズムはこちら

import pandas as pd
import numpy as np 
import talib as ta

def initialize(ctx):
    # 設定
    ctx.logger.debug("initialize() called")
    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": [
            #"open_price_adj",    # 始値(株式分割調整後)
            #"high_price_adj",    # 高値(株式分割調整後)
            #"low_price_adj",     # 安値(株式分割調整後)
            #"volume_adj",         # 出来高
            #"txn_volume",         # 売買代金
            "close_price",        # 終値
            "close_price_adj",    # 終値(株式分割調整後) 
          ]
        }
      }
    )

    def _my_signal(data):
      cp = data['close_price_adj'].fillna(method ='ffill')
      roc = pd.DataFrame(0, index = cp.index, columns = cp.columns)
      for (sym,val) in cp.items():
        roc[sym] = ta.ROC(cp[sym], 10)

      buy_sig = roc[(roc > 0) & (roc.shift(1) < 0) ]
      sell_sig = roc[(roc < 0) & (roc.shift(1) > 0)]

      return {
        'buy:sig':buy_sig,
        'sell:sig':sell_sig,
        'roc:g2':roc
      }

    # シグナル登録
    ctx.regist_signal("my_signal", _my_signal)

def handle_signals(ctx, date, current):
    '''
    current: pd.DataFrame
    '''

    done_syms = set([])
    for (sym,val) in ctx.portfolio.positions.items():
        returns = val["returns"]
        if returns < -0.03:
          sec = ctx.getSecurity(sym)
          sec.order(-val["amount"], comment="損切り(%f)" % returns)
          done_syms.add(sym)
        elif returns > 0.05:
          sec = ctx.getSecurity(sym)
          sec.order(-val["amount"], comment="利益確定売(%f)" % returns)
          done_syms.add(sym)


    buy = current["buy:sig"].dropna()
    for (sym,val) in buy.items():
        if sym in done_syms:
          continue

        sec = ctx.getSecurity(sym)
        sec.order(sec.unit() * 1, comment="SIGNAL BUY")
        ctx.logger.debug("BUY: %s,  %f" % (sec.code(), val))
        pass

    sell = current["sell:sig"].dropna()
    for (sym,val) in sell.items():
        if sym in done_syms:
          continue

        sec = ctx.getSecurity(sym)
        sec.order(sec.unit() * -1, comment="SIGNAL SELL")
        ctx.logger.debug("SELL: %s,  %f" % (sec.code(), val))
        pass

ROCの算出はta-libに関数が用意されているので簡単ですね。
今回は、ROCがゼロラインを上抜けしたら買い、下抜けしたら売りとしてシグナルを出しています。

1
1
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
1
1