Posted at
FinTechDay 6

QuantXで一目均衡表を作ってみた(Python)


QuantXとは

株式会社SmartTradeが提供しているアルゴリズム開発プラットフォーム

QuantX Factoryの公式ホームページ

無料でアルゴリズムを作成してバックテストすることができるほか、アルゴリズムを販売したり、購入したりすることができる。ちなみに、ロイター社からデータの提供を受けており、センチメントデータを用いたアルゴリズムの作成を無料で行うこともできます。

詳しくはQuantXの公式ドキュメントのページ


一目均衡表とは

使う指標は、、、

基準線=(26日最高値+26日最安値)

転換線=(9日最高値+9日最安値)

先行スパン1本目=基準線と転換線の平均を26日先行させたもの

先行スパン2本目=52日間の最高値と最安値の平均を26日先行させたもの

遅行線=当日の終値を26日先行させたもの

という感じです。

売買シグナルは、

基準線と転換線のクロス2本の先行スパン間を指す雲を上抜けあるいは下抜けするかなど様々ありますが、今回は基準線と転換線のクロスを使いたいと思います.


早速実装してミマーーース‼️


qiita1.py

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.1333",#マルハニチロ(水産)
"jp.stock.1605",#国際石開帝石(鉱業)
"jp.stock.1925",#ハウス(建設)
"jp.stock.2914",#JT(食品)
"jp.stock.3402",#東レ (繊維)
"jp.stock.3861",#王子HD(パルプ・紙)
"jp.stock.4519",#中外薬(医薬品)
"jp.stock.4452",#花王(化学)
"jp.stock.5020",#JXTG(石油)
"jp.stock.5108",#ブリヂストン(ゴム)
"jp.stock.5201",#AGC(窯業)
"jp.stock.5401",#新日鉄住金(鉄鋼)
"jp.stock.5802",#住友電(非鉄金属製品)
"jp.stock.6367",#ダイキン(機械)
"jp.stock.6758",#ソニー(電気機器)
"jp.stock.7012",#川重(造船)
"jp.stock.7203",#トヨタ(自動車)
"jp.stock.4543",#テルモ(精密機器)
"jp.stock.7951",#ヤマハ(その他製造)
"jp.stock.8058",#三菱商(商社)
"jp.stock.9983",#ファストリ(小売業)
"jp.stock.8306",#三菱UFJ(銀行)
"jp.stock.8604",#野村(証券)
"jp.stock.8766",#東京海上(保険)
"jp.stock.8253",#クレゾン(その他金融)
"jp.stock.8801",#三井不動産(不動産)
"jp.stock.9022",#JR東海(鉄道)
"jp.stock.9062",#日通(陸運)
"jp.stock.9104",#商船三井(海運)
"jp.stock.9202",#ANAHD(空運)
"jp.stock.9301",#三菱倉(倉庫)
"jp.stock.9437",#NTTドコモ(通信)
"jp.stock.9503",#関西電(電力)
"jp.stock.9531",#東ガス(ガス)
"jp.stock.6178",#日本郵政(サービス)
],
"columns": [
#"open_price_adj", # 始値(株式分割調整後)
"high_price_adj", # 高値(株式分割調整後)
"low_price_adj", # 安値(株式分割調整後)
#"volume_adj", # 出来高
#"txn_volume", # 売買代金
"close_price", # 終値
"close_price_adj", # 終値(株式分割調整後)
]
}
}
)

def _my_signal(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)
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)

buy_sig=index13[(index13>0)&(index14<0)]
sell_sig=index13[(index13<0)&(index14>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_signal", _my_signal)

def handle_signals(ctx, date, current):
'''
current: pd.DataFrame
'''

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


株式銘柄は参考までに、日経平均採用銘柄の中で各セクターで時価総額トップのものを採用しました。

転換線と基準線のゴールデンクロスで買い、デッドクロスで売りとしました。

1年でバックテストしてみましたーーーーー

結果は⁉️⁉️⁉️

スクリーンショット 2018-12-07 18.27.10.png

一目均衡表が無事実装できたみたいです:joy_cat::joy_cat:

ところで収益率はどうでしょうか⁉️

スクリーンショット 2018-12-07 18.28.55.png

これはイマイチですねーーーー:weary::confounded:

日経平均の動きを表した赤色のベンチマークとあまりかわらない結果になってしまいましたねーーー。

やっぱり、転換線と基準線のクロスだけではものたりないようです。

ただ、一目均衡表の動きを見るに、終値が雲を上抜け、下抜けするときに注目した手法をとると大きく改善しそうな気がします‼️‼️‼️

改良してみるので、続編をお待ちください:pray::pray_tone1::pray_tone2::pray_tone3::pray_tone4::pray_tone5: