株価から特定パターンを抽出する簡易プログラムをRubyで実装する

このエントリーをはてなブックマークに追加

やっぱシストレ本は読んでて本当に意味があるんかいなと懐疑的になってきますね。確かに評価方法を知れたのは収穫だったのですけども。

人が関わる以上過去のチャートの中に痕跡が残る、あるいはその痕跡をもとにトレードを行っているはずで、その中に優位な痕跡を見つけることができれば数打つことで優位を保証できるというのがシストレの大前提です。

問題なのは、そのパターンを移動平均やら、いくつかの指標を使って上手く抜けているかかどうか?ってところになると思います。

何とかしてパターンを特定しようとするわけですが、複数市場を対象にするだけでその特定が一気に困難になりました。

そこで一旦指標から離れて、もっと正確にパターンを抜くことを目標としていこうと思います。

パターン分類をしようとするとなると、クラスタ分析なんてのが良さげですが、今回はもっと単純に始めてみたいと思います。

テンプレートを作成し、それと規格化された株価との2乗距離を測定することでテンプレートに近いチャートの抜き出しを行いたいと思います。

では、さっそく参りましょう。

目次

実践

パターン抽出方法の説明

パターンの抽出は以下の方法で行います。

  1. テンプレートの作成
  2. 株価の規格化
  3. テンプレートと規格化された株価の二乗距離の測定
  4. 距離が規定値以下かどうかを判定

テンプレートの作成

テンプレートは0から1の間の50日分の点で作成します。例えば急落局面のテンプレートを作成しようとした場合は、次のようなグラフで書ける50個の点を用意することになります。

profit_histgram

株価の規格化

テンプレートは0〜1の値ですので、それに合わせて株価も0〜1の値を取るように弄くります。単純に50日間の株価の中で最小となる値を0、最大となる値を1として規格化を行います。式で書けば以下のようになります。

(株価t - 株価.MIN) / (株価.MAX - 株価.MIN)

テンプレートと規格化された株価の二乗距離の測定

あとはテンプレートと、株価との距離を測定します。各日において求めた二乗誤差の集計が二乗距離となります。つまり、

Σt50(テンプレートt - 規格化株価t)2

最後にこの距離が規定値以下の場合はテンプレートと同じ株価だと判定して終わりです。

コードにすると下記のようになります。

class Pattern
    attr_accessor :pattern, :thr

    def initialize(pattern)
      @thr = 1.5
      @pattern = Soks[*pattern]
    end

    def correspond?(target)
      size = @pattern.length
      min = target[-size..-1].min
      reg = target[-size..-1].max - min
      ts = target[-size..-1].map {|t| (t-min).to_f / reg}
      di = 0
      ts.zip(pattern).each do |t,p|
        di += (t - p) ** 2
      end
      di = Math.sqrt(di)
      @thr > di
    end
  end

実際にどういった株価が抽出されるのかを確認してみます。☓までがパターン一致部分でそれから20日ぶん表示してあります。

profit_histgram

N日検定

これで抜き出された株価は、指標を用いたシグナル判定に比べ、より似た値動きをしているはずです。

N日検定を用いて、その優位性を確認してみましょう。データは2007年から2017年の33業種別株価指数を用います。

ルールは次のようになります。

  • パターン判定されるかつ10日安値をつける。
  • 翌日の初値で売り。
  • N日経過で仕切り。

用いたパターンは上記のものです。コードにすれば下記のようになります。

      Pattern.new(40.times.map {|i| i.to_f/39} +
                  10.times.map {|i| 1.0 - i.to_f/9})
Code 5 10 15 20 30 50
I201 0.47 0.50 0.58 0.33 0.45 0.50
I202 0.58 0.45 0.45 0.36 0.18 0.36
I203 0.60 0.67 0.58 0.50 0.25 0.58
I204 0.33 0.44 0.33 0.33 0.29 0.33
I205 0.73 0.60 0.70 0.70 0.70 0.78
I206 0.43 0.44 0.53 0.47 0.35 0.43
I207 0.64 0.58 0.58 0.75 0.58 0.50
I208 0.57 0.67 0.50 0.58 0.50 0.50
I209 0.44 0.50 0.62 0.46 0.62 0.64
I210 0.38 0.33 0.43 0.43 0.43 0.50
I211 0.53 0.54 0.62 0.54 0.46 0.55
I212 0.72 0.64 0.69 0.62 0.54 0.58
I213 0.50 0.59 0.59 0.59 0.47 0.56
I214 0.50 0.50 0.54 0.54 0.54 0.77
I215 0.63 0.67 0.67 0.53 0.67 0.67
I216 0.54 0.80 0.70 0.50 0.60 0.67
I217 0.53 0.62 0.69 0.62 0.54 0.54
I218 0.38 0.43 0.38 0.46 0.42 0.50
I219 0.40 0.33 0.33 0.25 0.18 0.27
I220 0.73 0.43 0.36 0.43 0.29 0.55
I221 0.38 0.42 0.50 0.67 0.42 0.58
I222 0.56 0.50 0.50 0.50 0.43 0.55
I223 0.50 0.50 0.58 0.42 0.36 0.78
I224 0.46 0.58 0.42 0.42 0.50 0.70
I225 0.64 0.60 0.60 0.40 0.40 0.56
I226 0.39 0.63 0.56 0.56 0.44 0.54
I227 0.63 0.67 0.67 0.64 0.57 0.62
I228 0.43 0.60 0.50 0.50 0.50 0.60
I229 0.73 0.55 0.64 0.55 0.45 0.60
I230 0.61 0.57 0.43 0.50 0.57 0.54
I231 0.90 0.75 0.63 0.75 0.50 0.75
I232 0.58 0.36 0.45 0.64 0.64 0.36
I233 0.43 0.33 0.33 0.25 0.36 0.36
平均 0.53 0.53 0.53 0.50 0.45 0.54

N日検定はN日によらず勝率55%を超えることで、その仕掛けの優位を確認する検定です。この結果はそれに到底及びませんが、私が行ってきた今までの結果からすればましな結果になっています。

少しは期待できるかもしれません。

検証

仕切りを10日安値をつけたら買い戻しとして、バックテストを行ってみます。データは同じものを使います。

Code Income Trades Win PF Average DD
I201 10.13 12 50.0 1.51 0.84 -10.63
I202 5.17 11 27.27 1.14 0.47 -23.81
I203 1.58 12 41.67 1.09 0.13 -5.87
I204 -15.23 17 29.41 0.53 -0.9 -11.25
I205 14.61 10 60.0 2.54 1.46 -8.33
I206 -12.98 17 35.29 0.73 -0.76 -32.12
I207 24.36 12 50.0 2.63 2.03 -12.35
I208 -0.73 12 41.67 0.96 -0.06 -12.62
I209 -4.36 13 38.46 0.89 -0.34 -16.95
I210 -45.29 15 13.33 0.26 -3.02 -28.76
I211 -9.7 13 38.46 0.69 -0.75 -13.08
I212 51.82 13 61.54 3.18 3.99 -9.09
I213 -4.72 17 52.94 0.89 -0.28 -12.28
I214 6.66 14 50.0 1.27 0.48 -9.3
I215 19.62 16 43.75 1.76 1.23 -14.1
I216 30.7 10 60.0 4.22 3.07 -7.03
I217 7.52 13 46.15 1.37 0.58 -15.51
I218 -5.7 13 23.08 0.78 -0.44 -14.66
I219 -14.37 12 25.0 0.61 -1.2 -19.33
I220 -19.41 14 42.86 0.41 -1.39 -20.21
I221 -5.18 12 33.33 0.72 -0.43 -15.04
I222 -1.14 14 28.57 0.97 -0.08 -35.81
I223 -13.51 12 33.33 0.44 -1.13 -19.11
I224 -11.08 12 25.0 0.61 -0.92 -12.59
I225 4.46 10 60.0 1.41 0.45 -4.56
I226 23.56 16 50.0 1.73 1.47 -18.2
I227 20.65 15 53.33 2.24 1.38 -4.71
I228 27.83 10 40.0 2.09 2.78 -10.95
I229 34.16 11 63.64 2.38 3.11 -9.03
I230 1.31 14 50.0 1.05 0.09 -9.38
I231 24.53 8 75.0 4.97 3.07 -4.31
I232 -7.56 11 45.45 0.78 -0.69 -20.24
I233 -6.93 12 33.33 0.61 -0.58 -6.78
平均 4.0 12.0 43.1 1.4 0.4 -14.2
分散 18.85 2.24 13.58 1.08 1.54 7.55

トレード数が少ないのでなんとも言い難いですが、期待していたほどではありませんね。

まとめ

二乗距離を用いて、テンプレートに一致するかの判定を行い、仕掛けのルールに組み込んでみました。ものは試しに程度のことしか行っていませんが、いじり方によっては期待ができそうな気はします。

Recent Entries
Categories
    Tags
    Archives
    Search