LoginSignup
1
2

More than 3 years have passed since last update.

ローソク足を複数組み合わせたアルゴリズムを作る

Posted at

はじめに

QuantX Factoryでは、talibを用いて、ローソク足を用いた株売買アルゴリズムを作ることが出来ます。
こちらの記事では、ローソク足とテクニカル指標を組み合わせたアルゴリズムを紹介しています。
今回は、複数のローソク足を使って売買シグナルを出すアルゴリズムを紹介したいと思います。

アルゴリズム

このアルゴリズムでは、赤三兵、黒三兵をアレンジしたいと思います。

# 必要なライブラリーをimportする
import maron
import maron.signalfunc as sf
import maron.execfunc as ef
import pandas as pd
import talib as ta
import numpy as np

# オーダ方法を決定する
ot = maron.OrderType.MARKET_OPEN   # シグナルがでた翌日の始値のタイミングでオーダー

# 銘柄、columnsの取得を行う
# 初期化を行う
def initialize(ctx):
  ctx.configure(
    channels={               # 利用チャンネル
      "jp.stock": {
        "symbols": [
          "jp.stock.2914", #JT(日本たばこ産業)
          "jp.stock.8766", #東京海上ホールディングス
          "jp.stock.8031", #三井物産
          "jp.stock.8316", #三井住友フィナンシャルグループ
          "jp.stock.8411", #みずほフィナンシャルグループ
          "jp.stock.9437", #NTTドコモ
          "jp.stock.4502", #武田薬品工業
          "jp.stock.8058", #三菱商事
          "jp.stock.9433", #KDDI
          "jp.stock.9432", #日本電信電話
          "jp.stock.7267", #ホンダ(本田技研工業)
          "jp.stock.8306", #三菱UFJフィナンシャル・グループ
          "jp.stock.4503", #アステラス製薬
          "jp.stock.4063", #信越化学工業
          "jp.stock.7974", #任天堂
          "jp.stock.6981", #村田製作所
          "jp.stock.3382", #セブン&アイ・ホールディングス
          "jp.stock.9020", #東日本旅客鉄道
          "jp.stock.8802", #三菱地所
          "jp.stock.9022", #東海旅客鉄道
          "jp.stock.9984", #ソフトバンクグループ
          "jp.stock.6861", #キーエンス
          "jp.stock.6501", #日立製作所
          "jp.stock.6752", #パナソニック
          "jp.stock.6758", #ソニー
          "jp.stock.6954", #ファナック
          "jp.stock.7203", #トヨタ自動車
          "jp.stock.7751", #キヤノン
          "jp.stock.4452", #花王
          "jp.stock.6098", #リクルートホールディングス
        ],
        "columns": [
          "open_price_adj",    # 始値(株式分割調整後)
          "high_price_adj",    # 高値(株式分割調整後)
          "low_price_adj",     # 安値(株式分割調整後)
          "close_price",     # 終値
          "close_price_adj", # 終値(株式分割調整後)
          #"volume_adj",     # 出来高
          #"txn_volume",     # 売買代金
        ]
      }
    }
  )

  # シグナル定義
  def _my_signal(data):
    # 終値等の取得を行い、欠損値補完を行う。
    cp =  data["close_price_adj"].fillna(method='ffill')
    op =  data["open_price_adj"].fillna(method= 'ffill')
    hp = data["high_price_adj"].fillna(method="ffill")
    lp = data["low_price_adj"].fillna(method="ffill")

    # ローソク足についてを計算
    candle_1 = pd.DataFrame(data=0,columns=[], index=cp.index)
    for(sym,val) in cp.items():
      candle_1[sym] = ta.CDLMARUBOZU(op[sym],hp[sym],lp[sym],cp[sym])

    # true,falseのbool型にする
    candle_1_buy = candle_1[(candle_1 == 100)]
    candle_1_sell = candle_1[(candle_1 == -100)]
    candle_1_buy[(candle_1 == 100)] = True
    candle_1_sell[(candle_1 == -100)] = False

    # 売買シグナルを定義(bool値で返す)
    buy_sig = candle_1_buy & candle_1_buy.shift(1)
    sell_sig = candle_1_sell 

    # market_sigという全て0が格納されているデータフレームを作成
    market_sig = pd.DataFrame(data=0.0, columns=cp.columns, index=cp.index)

    # buy_sigがTrueのとき1.0、sell_sigがTrueのとき-1.0とおく
    market_sig[buy_sig == True] = 1.0
    market_sig[sell_sig == True] = -1.0
    market_sig[(buy_sig == True) & (sell_sig == True)] = 0.0

    return {
      "market:sig": market_sig,
      "candle:1":candle_1
    }

  # シグナル登録
  ctx.regist_signal("my_signal", _my_signal)

def handle_signals(ctx, date, current):
  '''
  current: pd.DataFrame
  '''
  market_sig = current["market:sig"]

  done_syms = set([])

  # 損切り、利確の設定
  for (sym, val) in ctx.portfolio.positions.items():
    returns = val["returns"]
    if returns < -0.03:
      sec = ctx.getSecurity(sym)
      sec.order(-val["amount"], comment="損切り(%f)" % returns)
      done_syms.add(sym)
    elif returns > 0.05:
      sec = ctx.getSecurity(sym)
      sec.order(-val["amount"], comment="利益確定売(%f)" % returns)
      done_syms.add(sym)


  # 買シグナルについて注文方法を設定する
  buy = market_sig[market_sig > 0.0]
  for (sym, val) in buy.items():
    if sym in done_syms:
      continue

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

  # 売シグナルも同様に行う
  sell = market_sig[market_sig < 0.0]
  for (sym, val) in sell.items():
    if sym in done_syms:
      continue
    sec = ctx.getSecurity(sym)
    sec.order(sec.unit() * -1,orderType=ot, comment="SIGNAL SELL")
    #ctx.logger.debug("SELL: %s,  %f" % (sec.code(), val))
    pass

アルゴリズムの解説

基本的なアルゴリズムの仕組みは公式ドキュメント前回の記事と同じなので、今回はこのアルゴリズムの特徴的なところを紹介したいと思います。

今回作りたいのは、
赤三兵 (2).png
になります。(https://ottopilotmedia.com/chart/rousoku-pattern)

talib には、複数本のローソク足を組み合わせてセットになったものがいくつかありますが、今回は練習のためと、赤三兵はtalibには、用意されていなかったので、このセットを作ってみたいと思います。

使ったローソク足はこちらにて紹介されている、丸坊主のローソク足組み合わせました。

今回のアルゴリズムは基本的な形をしていますが、他のアルゴリズムと比べて特徴的なところは以下になります。

  def _my_signal(data):
    # 終値等の取得を行い、欠損値補完を行う。
    cp =  data["close_price_adj"].fillna(method='ffill')
    op =  data["open_price_adj"].fillna(method= 'ffill')
    hp = data["high_price_adj"].fillna(method="ffill")
    lp = data["low_price_adj"].fillna(method="ffill")

    # ローソク足についてを計算
    candle_1 = pd.DataFrame(data=0,columns=[], index=cp.index)
    for(sym,val) in cp.items():
      candle_1[sym] = ta.CDLMARUBOZU(op[sym],hp[sym],lp[sym],cp[sym])

    # true,falseのbool型にする
    candle_1_buy = candle_1[(candle_1 == 100)]
    candle_1_sell = candle_1[(candle_1 == -100)]
    candle_1_buy[(candle_1 == 100)] = True
    candle_1_sell[(candle_1 == -100)] = False

    # 売買シグナルを定義(bool値で返す)
    buy_sig = candle_1_buy & candle_1_buy.shift(1)
    sell_sig = candle_1_sell & candle_1_sell.shift(1)

赤三兵では買シグナルを出します。
今回は、使用しているローソク足の種類も同じなので、新たに candle_2 を定義することなく、candle_1を組み合わせて、buy_signalを出していきます。
実際には、

    # 売買シグナルを定義(bool値で返す)
    buy_sig = candle_1_buy & candle_1_buy.shift(1)
    sell_sig = candle_1_sell & candle_1_sell.shift(1)

というコードになります。
pandas のメソッドを使って、2日連続で、丸坊主が出ているときに買うというシグナル生成いたしました。
写真上では3つ連続の時になっていますが、3つにすると制約的に厳しくなり、シグナルが出にくくなるので、今回は2つにしました。

売シグナルも同様の操作を行います。

まとめ

このアルゴリズムをTOPIX Core 30で行ったものが以下になります。

赤三兵損益率 (2).png

あまりシグナルが出ず、取引が行われませんでした。
次回は色々な指標を組み合わせて、複数のものから判断できるアルゴリズムを検討してみたいと思います!

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