簡易バックテストツールの実装

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

週明け早々物騒ですね。ロフテッド軌道って迎撃出来るのでしょうか?迎撃してる訓練なんかが公開されると安心なのですが。

さて、このサイトはRubyでバックテストツールを作成し、様々なストラテジーを検証することを目的としています。前回はgnuplotを利用したチャートの出力について説明しました。

今回からバックテストツールの実装に入りたいと思います。ここで作成するのは単一銘柄を対象とした単利での売買システムとなります。

まず、バックテストの評価に当たってどのような指標を出力しなければならないかを一覧し、その後プログラムを動かしましょう。

目次

実践

バックテストの評価{#item1}

バックテストの結果として表示する指標は下記のものとします。

  • 純利益
  • 総利益
  • 総損失
  • 含み損益
  • 総利益÷総損失
  • 最大利益
  • 最大損失

  • 総トレード数
  • 勝ちトレード数
  • 負けトレード数
  • 勝率

  • 勝ちトレードの平均利益
  • 負けトレードの平均損失
  • トレードの平均損益

  • 最大連勝数
  • 最大連敗数
  • 勝ちトレードの平均保有期間
  • 負けトレードの平均保有期間
  • 最大ドローダウン

グラフで下記の表示も行えるようにします。

  • 損益曲線
  • 損益ヒストグラム
  • 月次損益

動作確認

特にインストールするものはありませんので、Sok配下でgit pullしてソースを更新してください。

コマンドを叩き、結果をターミナルに出力するプログラムが追加されています。プログラムの流れはざっとこんな感じです。

Strategyは株価やTraderからのPositionを材料に、Actionを決定します。ActionにはNone(何もしない)Buy、Sellがあります。このActionをTraderは受取って、取引の損益を記録し、Positionの変化を行います。Positionは各々の銘柄に対して、何時からいくらで何枚、BuyまたはSellで持っているという情報です。記録した結果を最後に上記の形式で出力します。

今回使うStrategyは、ほぼほぼ何もしないけども時々適当に売ったり買ったりするという適当なロジックです。

これを用いて実際にバックテストを行ってみます。Sok配下で次のコマンドを叩きます。

bundle exec ruby example/back_test/random_strategy.rb

次のような出力がされます。先にリストした指標が表示されているはずです。

======================================================
net income:               624.0
profit | loss:            2026.0    | -1402.0
pf:                       1.4
max profit | max loss:    173.0     | -220.0
trades | wins | looses:   74     | 38     | 36
wins{%}                   51.4
max series of wins:       6
max series of looses:     8
average span{win}:        25
average span{loose}:      16
max drow down:            -274.0
======================================================

また、Sok配下にdata/sample1というディレクトリが作成され、そこに3つのJPEGとrecordが作成されます。recordは後に各々の取引結果を調査したいときのためのダンプです。今回は使いません。

それぞれのJPEGを開きます。

  • 損益曲線 profit_curve

  • ヒストグラム profit_histgram

  • 月次損益 monthly_profit

ランダムで売買している割にはなかなかな結果ですが、月次で見ると結構忍耐が必要かもしれませんね。最も何回か動かせばマイナスの収益になったりもするのですが。

プログラムはここで確認できます。裏ではワヤクチャやってますが、表面的にはこんなコードです。

require File.expand_path '../../lib/sok', File.dirname(__FILE__)
include Kabu

trader = Trader.new
strategy = Kabu::Strategy::Random.new

code = 1305
soks = Sok.joins(:company).where('companies.code=?',code).order('date')
position = nil

soks.each do |sok|
  action = strategy.decide(code: code, date: sok.date, 
                    close: sok.close, position: position)
  trader.receive [action]
  position = trader.positions.any? ? trader.positions[0] : nil
end

trader.summary
trader.save File.expand_path('../../data/sample1', File.dirname(__FILE__))

まとめ

ツールを作成して実際にバックテストを行ってみました。

ただ、実際この結果がほんまもんかいな?ってところが有るので次回はダンプしていおいたrecordを使って、取引が行われていたときのチャートを確認して行きたいと思います。

Recent Entries
Categories
    Tags
    Archives
    Search