4
7

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.

移動平均線乖離を利用したアルゴリズム

Posted at

#今回のアルゴリズム
小型成長株メインで、移動平均線MA25とMA5を利用した順張りアルゴリズムを作成し実装してみました。

#移動平均線とは
移動平均線は、一定期間の平均価格を日々計算して算出した値を、単純平均したものです。
例えば5日移動平均値は5日分の平均価格となります。そして、日々の平均価格を線でつないだものが5日移動平均線となります。
平均価格(ここでは終値の平均)を使用することで日中の大きな変動に惑わされることなく、現在の相場の方向性(トレンド)がどちらを向いているのか(上がっているのか、下がっているのか)を見ることができます。
####よく利用される移動平均線の種類
・短期線 … 5日、10日
・中期線 … 20日、25日、75日
・長期線 … 100日、200日

#アルゴリズム
###銘柄
東証1部・2部・マザーズに上場している売上高成長率30%以上の銘柄をスクリーニングしました。
また、小型成長株がメインのポートフォリオなため、どうしてもダウントレンドの際にパフォーマンスが安定しないと考え、緩和するためにダブルインバースを組み込みました。

###シグナル
買い:MA25 +2%
売り:MA5 -2%

損切:なし
利確:なし
##コード

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.1360', #  ダブルインバース
'jp.stock.4571', #   ナノキャリア
'jp.stock.4586', #   メドレックス
'jp.stock.4597', #   ソレイジア
'jp.stock.4598', #   DELTA-P
'jp.stock.6027', #   弁護士コム
'jp.stock.6030', #   アドベンチャ
'jp.stock.6033', #   エクストリーム
'jp.stock.6034', #   MRT
'jp.stock.6086', #   シンメンテHD
'jp.stock.6090', #   HMT
'jp.stock.6095', #   メドピア
'jp.stock.6172', #   メタップス
'jp.stock.6190', #   PXB
'jp.stock.6192', #   HyAS&Co.
'jp.stock.6195', #   ホープ
'jp.stock.6232', #   ACSL
'jp.stock.6537', #   WASHハウス
'jp.stock.6553', #   ソウルドアウト
'jp.stock.6561', #   HANATOUR
'jp.stock.6572', #   RPA
'jp.stock.6577', #   ベストワン
'jp.stock.7033', #   MSOL
'jp.stock.7034', #   プロレド
'jp.stock.7035', #   anfac
'jp.stock.7046', #   TDSE
'jp.stock.7047', #   ポート
'jp.stock.7172', #   JIA
'jp.stock.8789', #   フィンテック
'jp.stock.9271', #   和 心
          ],
          "columns": [
            #"open_price_adj",    # 始値(株式分割調整後)
            #"high_price_adj",    # 高値(株式分割調整後)
            #"low_price_adj",     # 安値(株式分割調整後)
            "close_price",        # 終値
            "close_price_adj",    # 終値(株式分割調整後) 
            "volume_adj",         # 出来高
            "txn_volume",         # 売買代金
          ]
        }
      }
    )

    def _mavg_signal(data):
        #ns_sentiment = data["ns_sentiment"].fillna(method="ffill")
        # ctx.logger.debug(ns_sentiment)
        m25 = data["close_price_adj"].fillna(method='ffill').ewm(span=25).mean()
        dfma25 = (data["close_price_adj"] -  m25) / m25 * 100
        m5 = data["close_price_adj"].fillna(method='ffill').ewm(span=5).mean()
        dfma5 = (data["close_price_adj"] -  m5) / m5 * 100

        buy_sig = dfma25[(dfma25 > 2.0)]
        sell_sig = dfma5[(dfma5 < -2.0)]
        return {
            "mavg_25:price": m25,
            "mavg_5:price": m5,
            #"mavg_ratio:ratio": ratio,
            "buy:sig": buy_sig,
            "sell:sig": sell_sig,
        }

    # シグナル登録
    ctx.regist_signal("mavg_signal", _mavg_signal)

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

    done_syms = set([])
    for (sym,val) in ctx.portfolio.positions.items():
        returns = val["returns"]
        ctx.logger.debug("%s %f" % (sym, 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 = current["buy:sig"].dropna()
    for (sym,val) in buy.items():
        if sym in done_syms:
          continue

        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():
        if sym in done_syms:
          continue

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

#バックテスト結果
スクリーンショット 2019-02-21 18.01.43.jpg

昨年の暴落期間を含めても+18.9%とまずまずの成果ではないでしょうか。

#まとめ
色々な期間でバックテストを試みたものの、やはりダウントレンドになると、パフォーマンスがいまいちでしたので、下落相場であってもハイパフォーマンスを発揮できるよう、他のシグナルを追加するなど、引き続き改善を図っていきたいと思います。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?