2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

QuantXで一目均衡表を用いたシステムトレードその2(雲)

Last updated at Posted at 2018-12-27

#自己紹介
この度Smart Tradeでインターンすることになったゴンです。

ゴンについて、知りたい方はこちら。

初めての記事はこちら(QuantXを初めてみて)
https://qiita.com/investor-gon/items/2b1952ae5c2c88334c74

#何を作るのか(完成目標)


日経平均寄与率上位10位の銘柄(2018年12月25日)を用いて、一目均衡表の雲のクロスを用いた売買をするアルゴリズムを作る!!!

とりあえず動けば良い。

数式で書くとこんな感じ




買い(buy)= 株価>先行スパン1・2の値
\\

\\
売り(sell) =株価<先行スパン1・2の値


#まずは完成コード(コピペ、どうぞ)

############################################################################
############################################################################
# 日経一目均衡表その2
import numpy as np
import pandas as pd
import talib as ta


def initialize(ctx):
    # 設定
    ctx.logger.debug("initialize() called")
    ctx.configure(
      channels={          # 利用チャンネル
        "jp.stock": {
          "symbols": [
             "jp.stock.9983", #ファーストリテイリング
            "jp.stock.9984", #ソフトバンク
            "jp.stock.6954", #ファナック
            "jp.stock.9433", #KDDI
            "jp.stock.8028", #ファミリーマート
            "jp.stock.8035", #東京エレクトロン
            "jp.stock.4543", #テルモ
            "jp.stock.6367", #ダイキン
            "jp.stock.6971", #京セラ
            "jp.stock.9735", #セコム
          ],
          "columns": [
           #"open_price_adj",    # 始値(株式分割調整後)
            "high_price_adj",    # 高値(株式分割調整後)
            "low_price_adj",     # 安値(株式分割調整後)
            #"volume_adj",         # 出来高
            #"txn_volume",         # 売買代金
            "close_price",        # 終値
            "close_price_adj",    # 終値(株式分割調整後) 
          ]
        }
      }
    )
    
    def _my_ichimoku(data):
      
      cp=data["close_price_adj"].fillna(method="ffill")
      hp=data["high_price_adj"].fillna(method="ffill")
      
      result1=pd.DataFrame(data=0,columns=[],index=cp.index)
      sample1=pd.DataFrame(data=0,columns=[],index=cp.index)
      result1=pd.DataFrame(data=0,columns=[],index=cp.index)
      sample3=pd.DataFrame(data=0,columns=[],index=cp.index)
      index3=pd.DataFrame(data=0,columns=[],index=cp.index)
      index6=pd.DataFrame(data=0,columns=[],index=cp.index)
      index7=pd.DataFrame(data=0,columns=[],index=cp.index)
      index8=pd.DataFrame(data=0,columns=[],index=cp.index)
      index12=pd.DataFrame(data=0,columns=[],index=cp.index)
      index13=pd.DataFrame(data=0,columns=[],index=cp.index)
      index14=pd.DataFrame(data=0,columns=[],index=cp.index)
      index15=pd.DataFrame(data=0,columns=[],index=cp.index)
      index16=pd.DataFrame(data=0,columns=[],index=cp.index)
      index17=pd.DataFrame(data=0,columns=[],index=cp.index)
      index18=pd.DataFrame(data=0,columns=[],index=cp.index)
      index19=pd.DataFrame(data=0,columns=[],index=cp.index)
      index20=pd.DataFrame(data=0,columns=[],index=cp.index)
      index21=pd.DataFrame(data=0,columns=[],index=cp.index)
      
      
      index1=data["high_price_adj"].fillna(method='ffill').rolling(window=9,center=False).max()
      index2=data["low_price_adj"].fillna(method="ffill").rolling(window=9,center=False).min()
      index3=(index1+index2)/2 #転換線
      index4=data["high_price_adj"].fillna(method='ffill').rolling(window=26,center=False).max()
      index5=data["low_price_adj"].fillna(method='ffill').rolling(window=26,center=False).min()
      index6=(index4+index5)/2 #基準線
      index7=(index3+index6)/2 
      index8=index7.shift(26) #先行スパン1
      index9=data["high_price_adj"].fillna(method='ffill').rolling(window=52,center=False).max()
      index10=data["low_price_adj"].fillna(method='ffill').rolling(window=52,center=False).min()
      index11=(index8+index9)/2 
      index12=index11.shift(26) #先行スパン2
      index13=index3-index6
      index14=index13.shift(1)
      index15=data["close_price_adj"].fillna(method='ffill').shift(26)
      index16=np.maximum(index8,index12)
      index17=np.minimum(index8,index12)
      index18=cp-index17
      index19=index18.shift()
      index20=cp-index16
      index21=index20.shift()
      
      buy_sig=index18[(index18>0)&(index19<0)]
      sell_sig=index20[(index20<0)&(index21>0)]
     
      return {
          "buy:sig":buy_sig,
          "sell:sig":sell_sig,
          "転換線:g2":index3,
          "基準線:g2":index6,
          "先行スパン1:g2":index8,
          "先行スパン2:g2":index12,
          "遅行線:g2":index15
        }

    # シグナル登録
    ctx.regist_signal("my_ichimoku", _my_ichimoku)

def handle_signals(ctx, date, current):
    
    buy = current["buy:sig"].dropna()
    for (sym,val) in buy.items():

        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():

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

#結果はこちら
スクリーンショット 2018-12-27 13.41.36.png


三年間で25%のプラスですね。とりま、プラス。

ちなみに、

アルファ値は、アルゴリズムの収益率から市場全体の動き(ベンチマーク)に連動したリターンを差し引いたもので、本数値が高いほど、ベンチマークの収益率を上回り、それだけリターンが高いことを意味します。


ベータ値とは、アルゴリズムの収益が証券市場全体の動きに対してどの程度敏感に反応して変動するかを示す数値です。この数値が高いほど、証券市場全体の動きに連動した変動幅(増減幅)が大きいことを意味します。

#解説
##ライブラリーの選択

#ライブラリーの設定

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

使うライブラリーをあらかじめ設定しておきます。

##日本株式の選択

def initialize(ctx):
    # 設定
    ctx.logger.debug("initialize() called")
    ctx.configure(
      channels={          # 利用チャンネル
        "jp.stock": {
          "symbols": [
             "jp.stock.9983", #ファーストリテイリング
            "jp.stock.9984", #ソフトバンク
            "jp.stock.6954", #ファナック
            "jp.stock.9433", #KDDI
            "jp.stock.8028", #ファミリーマート
            "jp.stock.8035", #東京エレクトロン
            "jp.stock.4543", #テルモ
            "jp.stock.6367", #ダイキン
            "jp.stock.6971", #京セラ
            "jp.stock.9735", #セコム
          ],
          "columns": [
           #"open_price_adj",    # 始値(株式分割調整後)
            "high_price_adj",    # 高値(株式分割調整後)
            "low_price_adj",     # 安値(株式分割調整後)
            #"volume_adj",         # 出来高
            #"txn_volume",         # 売買代金
            "close_price",        # 終値
            "close_price_adj",    # 終値(株式分割調整後) 
          ]
        }
      }
    )
    

今回使用する日経平均寄与率上位10銘柄を持ってきます。
また、使う値は、日足の終値・高値・安値(株式分割調整後) です。

##取引手法

def _my_ichimoku(data):
      
      cp=data["close_price_adj"].fillna(method="ffill")
      hp=data["high_price_adj"].fillna(method="ffill")
      
      result1=pd.DataFrame(data=0,columns=[],index=cp.index)
      sample1=pd.DataFrame(data=0,columns=[],index=cp.index)
      result1=pd.DataFrame(data=0,columns=[],index=cp.index)
      sample3=pd.DataFrame(data=0,columns=[],index=cp.index)
      index3=pd.DataFrame(data=0,columns=[],index=cp.index)
      index6=pd.DataFrame(data=0,columns=[],index=cp.index)
      index7=pd.DataFrame(data=0,columns=[],index=cp.index)
      index8=pd.DataFrame(data=0,columns=[],index=cp.index)
      index12=pd.DataFrame(data=0,columns=[],index=cp.index)
      index13=pd.DataFrame(data=0,columns=[],index=cp.index)
      index14=pd.DataFrame(data=0,columns=[],index=cp.index)
      index15=pd.DataFrame(data=0,columns=[],index=cp.index)
      index16=pd.DataFrame(data=0,columns=[],index=cp.index)
      index17=pd.DataFrame(data=0,columns=[],index=cp.index)
      index18=pd.DataFrame(data=0,columns=[],index=cp.index)
      index19=pd.DataFrame(data=0,columns=[],index=cp.index)
      index20=pd.DataFrame(data=0,columns=[],index=cp.index)
      index21=pd.DataFrame(data=0,columns=[],index=cp.index)
      
      
      index1=data["high_price_adj"].fillna(method='ffill').rolling(window=9,center=False).max()
      index2=data["low_price_adj"].fillna(method="ffill").rolling(window=9,center=False).min()
      index3=(index1+index2)/2 #転換線
      index4=data["high_price_adj"].fillna(method='ffill').rolling(window=26,center=False).max()
      index5=data["low_price_adj"].fillna(method='ffill').rolling(window=26,center=False).min()
      index6=(index4+index5)/2 #基準線
      index7=(index3+index6)/2 
      index8=index7.shift(26) #先行スパン1
      index9=data["high_price_adj"].fillna(method='ffill').rolling(window=52,center=False).max()
      index10=data["low_price_adj"].fillna(method='ffill').rolling(window=52,center=False).min()
      index11=(index8+index9)/2 
      index12=index11.shift(26) #先行スパン2
      index13=index3-index6
      index14=index13.shift(1)
      index15=data["close_price_adj"].fillna(method='ffill').shift(26)
      index16=np.maximum(index8,index12)
      index17=np.minimum(index8,index12)
      index18=cp-index17
      index19=index18.shift()
      index20=cp-index16
      index21=index20.shift()
      
      buy_sig=index18[(index18>0)&(index19<0)]
      sell_sig=index20[(index20<0)&(index21>0)]
     
      return {
          "buy:sig":buy_sig,
          "sell:sig":sell_sig,
          "転換線:g2":index3,
          "基準線:g2":index6,
          "先行スパン1:g2":index8,
          "先行スパン2:g2":index12,
          "遅行線:g2":index15
        }

    # シグナル登録
    ctx.regist_signal("my_ichimoku", _my_ichimoku)

今回使用する値をcpに代入して、一目均衡表(基準線、転換線、先行スパン1・2、遅行線)に必要な値を求めます。

株価が先行スパン1・2の値がより大きい時に買い、小さい時に売りとなるシグナルです。

一目均衡表の値について

基準線 過去26日間の高値と安値の平均値
転換線 過去9日間の高値と安値の平均値
遅行スパン 当日の終値を26日さかのぼった値
先行スパン1 基準線と転換線の中間地を26日先に記入したもの
先行スパン2 52日間の高値と安値を26日先に記入したもの

返り値として一目均衡表の値と買いシグナルと売りシグナルを設定します。
そしてシグナルを登録しておく。

##数量選択

def handle_signals(ctx, date, current):
    
    buy = current["buy:sig"].dropna()
    for (sym,val) in buy.items():

        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():

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

あとは、さっき設定した買いシグナル売りシグナルで売買をするのですが、
詳しくはこちらなのですが、今回使用したやつだけ載せておきます。


 
order(amount, comment): void

数量を指定して注文を行ないます。

つまり、今回の場合は、1単元株で売り買いするという感じで資金管理しています。

それでは今回はこの辺で。

2
4
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
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?