18号 【有料】connors_rsi.py
今回はconnors_rsi.pyをアップします。
※注意事項
作者はPythonのプログラムを自学自習で書いています。他の人が書いたものはネットのサンプル程度しか見たことがないため、一般的な書き方ではないかもしれません。
とりあえず動けばよしという姿勢で作っています。システムトレードのプログラムを作る際の参考程度にお考え下さい。
connors_rsi.pyは以下の場所に置いてください。
解説
ConnorsRsiクラスは売買ルール「コナーズRSI」に基づいてシグナルを発生させるクラスです。
仕掛け(買い)のシグナルはsignal.txtに書き込みます。手仕舞い(売り)のシグナルはprofit_taking.txtに書き込みます。
例)2024年1月31日にシグナル発生処理を実行した場合
デスクトップに日付のフォルダが作成され、フォルダ内に4つのファイルが作成されます。
★フォルダ名
2024-01-31
★ファイル名
error.txt
profit_taking.txt
signal.txt
start_end_time.txt
実装方法について
バックテストで良い結果が出た売買ルールをシグナル発生で実装します。
バックテスト側のTradeクラスのis_buy_signal()の内容をシグナル発生側のbuy_signal()に実装します。バックテスト側のTradeクラスのis_sell_signal()の内容をシグナル発生側のprofit_taking()に実装します。
バックテスト側とシグナル発生側では以下の箇所が異なっています。
①株価取得
シグナル発生側では処理で使用する株価を、マーケットスピード2RSS(プログラム内のコメントでは楽天RSS)で取得した値を保持しているデータフレームから取得します。
②売買シグナル判定
シグナル発生側では売買シグナルの判定結果をファイルに書き込みます。
実装の具体例
売買ルール「コナーズRSI」の場合
①定数定義
■バックテスト側
RSI_DAYS = 3
RISE_FALLS_DAYS = 2
PERCENT_RANK_DAYS = 50
BUY_THRESHOLD = 10
SELL_RSI_DAYS = 5
SELL_RISE_FALLS_DAYS = 3
SELL_THRESHOLD = 70
EXIT_DAYS = 10
LOSS_CUT_RATE = 0.90
■シグナル発生側
RSI_DAYS = 3
RISE_FALLS_DAYS = 2
PERCENT_RANK_DAYS = 50
BUY_THRESHOLD = 10
SELL_RSI_DAYS = 5
SELL_RISE_FALLS_DAYS = 3
SELL_THRESHOLD = 70
SIGNAL = 'ConnorsRsi'
シグナル発生側では時限による手仕舞いは対応していません。ロスカットについても対応していません。なのでEXIT_DAYS、LOSS_CUT_RATEについてはシグナル発生側には不要です。
※私が対応していないだけですので必要であれば処理を追加してください。
複数のシグナルを発生させる場合にどのシグナルか判別する必要があります。そのためSIGNALに売買ルールのクラス名を設定しています。
②買い判定
異なっている箇所だけを抜粋します。
■バックテスト側 is_buy_signal()
close_list = self.price.close_list
price_days = self.price.days
・・・
if connors_rsi < self.BUY_THRESHOLD:
can_buy = True
■シグナル発生側 buy_signal()
close_list = self.stock_df['Close'].values
price_days = len(close_list)
・・・
if connors_rsi < self.BUY_THRESHOLD:
if not self.ignore_signal():
# シグナルファイルに出力
FileUtil.output(self.signal_file, 'a', ' '.join([self.code, self.get_signal()]))
# 新規無視リストに追加
ignore_line = ' '.join([str(self.today), self.code, self.get_signal()])
self.ignore_new_list.append(ignore_line)
シグナル発生側では株価を楽天RSSのデータフレームから取得します。
price_daysは8号の末尾に注釈で書いたとおり、株価リストの要素数と同じ値です。
判定結果をsignal.txtに出力し、新規無視リストに追加します。signal.txtには証券コードと定数SIGNALの値を書き込みます。新規無視リストはシグナルが発生しても指定日数の間はsignal.txtに書き込まないようにするためのものです。シグナルが連日発生してややこしいと思い追加しました。
③利食い判定
異なっている箇所だけを抜粋します。
■バックテスト側 is_sell_signal()
close_list = self.price.close_list
price_days = self.price.days
・・・
if connors_rsi > self.SELL_THRESHOLD:
can_sell = True
■シグナル発生側 profit_taking()
close_list = self.stock_df['Close'].values
price_days = len(close_list)
・・・
if connors_rsi > self.SELL_THRESHOLD:
# 利食いファイルに出力
FileUtil.output(self.profit_file, 'a', ' '.join([self.code, self.get_signal()]))
判定結果をprofit_taking.txtに出力します。証券コードと定数SIGNALの値を書き込みます。
※get_signal()でself.codeとself.SIGNALを連結して返せばいいのにと思いますが、そのうち人類はイルカに滅ぼされてしまうので直していません。
ここから先は
¥ 100
この記事が気に入ったらサポートをしてみませんか?