RSI
今回はRSIを使ったアルゴリズムを QuantXで書いてみたいと思います.
RSI(相対力指数)は最も有名なオシレーター系の指標と言えるのではないでしょうか.
計算式は簡単で,
RSI = \frac{過去n日間で上昇した値幅}{過去n日間で上昇した値幅+過去n日間で下落した値幅} \times 100 \\
です.
過去何日分を見るか,というのがキモになりますが,よく使われるのは14日間のようです.
今回は短めに5日間にしてみます.
シグナル
RSIが30%以下になったら買い,70%以上で売り
手仕舞い
売りシグナルがでたタイミング
コード
import numpy as np
import talib as ta
import pandas as pd
def initialize(ctx):
# 設定
ctx.target = 0.10
ctx.period = 5
ctx.codes = [1605, 1925, 2503, 4519, 4911, 6301, 6752, 7741, 8001 ]
ctx.symbol_list = ["jp.stock.{}".format(code) for code in ctx.codes]
ctx.configure(
channels={ # 利用チャンネル
"jp.stock": {
"symbols":ctx.symbol_list,
"columns": ["close_price_adj", # 終値(株式分割調整後)
]}})
def _RSI(data):
df_close = data["close_price_adj"].fillna(method='ffill')
# memo 参照
df_rsi = df_close.apply(lambda s: ta.RSI(s.values.astype(np.double), timeperiod=ctx.period),axis=0)
buy_sig = df_rsi < 30.0
sell_sig = df_rsi > 70.0
return {
"rsi": df_rsi,
"buy:sig": buy_sig,
"sell:sig": sell_sig,
}
# シグナル登録
ctx.regist_signal("RSI", _RSI)
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():
sec = ctx.getSecurity(sym)
msg = "買いシグナル"
sec.order_target_percent(ctx.target, comment= msg)
# 売り(ポジションクローズ)シグナル
df_sell = df[df["sell:sig"]]
if not df_sell.empty:
for (sym, val) in df_sell.iterrows():
sec = ctx.getSecurity(sym)
msg = "売りシグナル"
sec.order_target_percent(0, comment= msg)
結果
memo
apply
今回は,pandas.DataFrame.applyを使って各銘柄のRSIを算出しました.
どういう仕組みか,簡単に説明します.
まずは説明のために、いくつかの銘柄について、乱数で過去100日分の株価を作ります.
import pandas as pd
import numpy as np
import talib as ta
inputs = {
'Toyota': np.random.randint(80, 100, size=100),
'Nissan': np.random.randint(50, 100, size=100),
'JAL': np.random.randint(40, 60, size=100),
'ANA': np.random.randint(50, 100, size=100),
'JT': np.random.randint(150, 200, size=100),
}
df_close = pd.DataFrame(inputs)
df_close
のデータはこのような構造になります.QuantX上でも全く同じ構造です.(ただしコラム名は文字列ではなく銘柄オブジェクト)
このデータフレームの各コラム,ANA
, JAL
, JT
, Nissan
, Toyota
それぞれの Series
データに ta.RSI
を適用させて,その結果をDataFrameで返すのが apply です.
df_rsi = df_close.apply(lambda s: ta.RSI(s.values.astype(np.double), timeperiod=5))
df_rsi
は,このようなデータになります.
lambda
apply の引数に無名関数 lambda
を使いました.
上記の lambda s: ta.RSI(s.values.astype(np.double), timeperiod=5)
は
def hoge (s)
return ta.RSI(s.values.astype(np.double), timeperiod=5)
と全く同じ意味になります.
apply を使用しない
apply
を使わずに書くとすると,このようなコードが考えられます.
d =dict()
for s in df_close.columns:
d[s] = ta.RSI(df_close[s].values.astype(np.double), timeperiod=5)
# df_rsi = pd.DataFrame(d)
df_rsi = pd.DataFrame(d, index = df_close.index)
個人的な趣味ですが,1行で終わるところを4行も書くのは好みではないので, apply
を使いました.
感想
- 銘柄は ストキャスティクスアルゴリズムで使用したものをそのまま使いました.
免責注意事項
- このコードに基づき投資した結果、損害が発生しても,一切責任を持ちません.
- このコードが正しく機能する保証は一切致しません.
- このアルゴリズムを勧めているわけではありません.あくまで QuantX / Python のサンプルコードとして掲載しているだけです.