Edited at

RSIのアルゴリズム #QuantX


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)


結果

2018-08-02_19.jpg


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上でも全く同じ構造です.(ただしコラム名は文字列ではなく銘柄オブジェクト)

2018-08-02_16.jpg

このデータフレームの各コラム,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 は,このようなデータになります.

2018-08-02_17.jpg


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 のサンプルコードとして掲載しているだけです.