1
2

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でMACDを用いたシステムトレード

Posted at

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

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

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

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


日経平均寄与率上位10位の銘柄(2018年12月25日)を用いて、MACDのゴールデンクロスとデッドクロスで売買するアルゴリズムを作る!!!

とりあえず動けば良い。

イメージはこんな感じ
スクリーンショット 2018-12-27 11.37.20.png

引用 https://www.gaitame.com/products/plus/jisseki.html

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

############################################################################
# 日経225 MACD

  #ライブラリーの設定
import pandas as pd
import talib as ta
import numpy as np


def initialize(ctx):
    # 設定
    ctx.logger.debug("initialize() called")
    ctx.configure(
      target="jp.stock.daily",
      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",     # 安値(株式分割調整後)
            "close_price",        # 終値
            "close_price_adj",    # 終値(株式分割調整後) 
            "volume_adj",         # 出来高
            "txn_volume",         # 売買代金
          ]
        }
      }
    )

 #売買シグナル生成部分
    def _my_MACD(data):

      #各銘柄の終値(株式分割調整後)を取得、欠損データの補完 
      df_close = data["close_price_adj"].fillna(method='ffill')

      #MACDの設定
      d_macd = dict() 
      d_macdsignal = dict()
      d_macdhist = dict() 

      for symbol in data.minor_axis:
        macd, macdsignal, macdhist = ta.MACD(df_close[symbol].values.astype(np.double), 
                                          fastperiod=12 , slowperiod=26, signalperiod=9)
        d_macd[symbol] = macd
        d_macdsignal[symbol] = macdsignal
        d_macdhist[symbol] = macdhist

      df_macd = pd.DataFrame(d_macd, index=data.major_axis)        
      df_macdsignal = pd.DataFrame(d_macdsignal, index=data.major_axis)        
      df_macdhist = pd.DataFrame(d_macdhist, index=data.major_axis)

      #macdの売り買いのサインを定義
      df_goldencross = (df_macd > df_macdsignal) &  (df_macd.shift(1) < df_macdsignal.shift(1))
      df_deadcross = (df_macd < df_macdsignal) &  (df_macd.shift(1) > df_macdsignal.shift(1))

      # 売買シグナルの設定
      buy_sig = df_goldencross 
      sell_sig = df_deadcross 

      return{
          "MACD": df_macd, 
          "MACDSignal": df_macdsignal, 
          "MACDHist": df_macdhist,
          "buy:sig": buy_sig,
          "sell:sig": sell_sig,
        }


    # シグナル登録
    ctx.regist_signal("my_MACD", _my_MACD)

def handle_signals(ctx, date, current):

    df = current.copy()

    # 買いシグナル
    df_buy = df[df["buy:sig"]]
    if not df_buy.empty:
      for (sym, val) in df_buy.iterrows(): 
        #ctx.logger.info(val)
        sec = ctx.getSecurity(sym)
        msg = "買いシグナル"
        sec.order_target_percent(0.10, 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-12-27 11.13.17.png


三年間で5%のプラスですね。とりあえずプラスで嬉しいって感じ。
アルファが低すぎ。

ちなみに、

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


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

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

#ライブラリーの設定

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

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

##日本株式の選択

def initialize(ctx):
    # 設定
    ctx.logger.debug("initialize() called")
    ctx.configure(
      target="jp.stock.daily",
      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",     # 安値(株式分割調整後)
            #"close_price",        # 終値
            "close_price_adj",    # 終値(株式分割調整後) 
            #"volume_adj",         # 出来高
            #"txn_volume",         # 売買代金
          ]
        }
      }
    )

    

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

##取引手法

#売買シグナル生成部分
    def _my_MACD(data):

      #各銘柄の終値(株式分割調整後)を取得、欠損データの補完 
      df_close = data["close_price_adj"].fillna(method='ffill')

      #MACDの設定
      d_macd = dict() 
      d_macdsignal = dict()
      d_macdhist = dict() 

      for symbol in data.minor_axis:
        macd, macdsignal, macdhist = ta.MACD(df_close[symbol].values.astype(np.double), 
                                          fastperiod=12 , slowperiod=26, signalperiod=9)
        d_macd[symbol] = macd
        d_macdsignal[symbol] = macdsignal
        d_macdhist[symbol] = macdhist

      df_macd = pd.DataFrame(d_macd, index=data.major_axis)        
      df_macdsignal = pd.DataFrame(d_macdsignal, index=data.major_axis)        
      df_macdhist = pd.DataFrame(d_macdhist, index=data.major_axis)

      #macdの売り買いのサインを定義
      df_goldencross = (df_macd > df_macdsignal) &  (df_macd.shift(1) < df_macdsignal.shift(1))
      df_deadcross = (df_macd < df_macdsignal) &  (df_macd.shift(1) > df_macdsignal.shift(1))

      # 売買シグナルの設定
      buy_sig = df_goldencross 
      sell_sig = df_deadcross 

      return{
          "MACD": df_macd, 
          "MACDSignal": df_macdsignal, 
          "MACDHist": df_macdhist,
          "buy:sig": buy_sig,
          "sell:sig": sell_sig,
        }


    # シグナル登録
    ctx.regist_signal("my_MACD", _my_MACD)

今回使用する値をcpに代入して 、fastperiod=12 , slowperiod=26, signalperiod=9でMACDを求めています。

ちなみにMACDとは、2本の移動平均線(MACDとそれを単純移動平均化したシグナルの2本のライン)を用いることで、相場の周期とタイミングを捉える指標です

計算式は、
MACD(マックディ線)=12日EMA-26日EMA
シグナル=MACDの9日EMA

指数平滑移動平均線(EMA)は、従来の移動平均線(SMA)の欠点を補正するために生み出された移動平均線で、直近のデータにより比重を置いて算出・描画したものです。


売り買いの仕方は、シグナルをMACDを超えたら買い、シグナルがMACDを下げたら売りです。 shiftで1日ずらしたものも含めています。
返り値としてMACDのシグナルと買いシグナルと売りシグナルを設定します。
そしてシグナルを登録しておく。

##数量選択

def handle_signals(ctx, date, current):

    df = current.copy()

    # 買いシグナル
    df_buy = df[df["buy:sig"]]
    if not df_buy.empty:
      for (sym, val) in df_buy.iterrows(): 
        #ctx.logger.info(val)
        sec = ctx.getSecurity(sym)
        msg = "買いシグナル"
        sec.order_target_percent(0.10, 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)

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


  **order_target_percent(amount, comment): void**

この銘柄の総保有額が総資産評価額(現金+保有ポジション評価額)に対して指定の割合となるように注文を行ないます。 amountには割合(例:5%なら0.05)を指定します。


つまり、今回の場合は、総資産の10%の買いを入れていて、資金がなくなったらおしまいという感じで資金管理しています。

どうやらMACDは何かと組み合わせないとキツそうですな。

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

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?