#今回やったこと
投資アルゴリズム開発プラットフォーム「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がゼロラインを上抜けしたら買い、下抜けしたら売りとしてシグナルを出しています。