株価チャートをRuby+Numo-gnuplotで作成する。

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

日本郵政、野村不動産買収を検討って、ぱっと聞くと大丈夫なん?と思うのですがどうなりますかね。あまり関係のない私は引き続き環境構築を行っていきます。

さて、このサイトはRubyで簡単なバックテストツールを作成して、広く知られているストラテジーの検証を行っていくことを目的としています。前回、株価の取得方法について説明しました。このままバックテストツールの作成に入ってもよいのですが、先にチャート周りの環境を整えていこうと思います。

ただRubyはRailsと共にあるため、チャート作成ライブラリはどちらかというとWeb周りのものが多いようです。このサイトでは特にそういったものを必要としているわけではないので、しばし検討を行い、Gnuplotで吐き出す方針で行くことに決めました。実際重要になるのは収益曲線で株価チャートはおまけなのですが、今回は株価チャートを書くための準備を整えていきます。

インストールを行ったら終わりではありますが、取り掛かっていきましょう。

目次

実践

インストール

gnuplotをインストールします。

sudo apt-get install gnuplot

前回のsokディレクトリにて次のコマンドを打ちます。

git pull
bundle install --path vendor/bunler

以上で終わりです。

株価のチャートをJPEG形式で出力するサンプルを幾つか上げておきます。このサンプルはgnuplot-numofinance.demoを参考に作ったものです。

サンプル1

sok/example/chartディレクトリにてbundle exec ruby sample1.rbを実行すると、sample1.jpegが出力されます。

sample1.rbの中はこのようになっています。必要に応じて、証券コードを変更してください。

Bundler.require

soks = Kabu::Company.find_by_code(1305).soks
dates, closes = Kabu::Soks.parse(soks, :date, :close)

Numo.gnuplot do
  set terminal: 'jpeg'
  set output:  'sample1.jpeg'
  set title: "Demo of plotting financial data"
  set yrange: closes.yrange
  set xtics: dates.xtics
  set lmargin: 9
  set rmargin: 2
  set grid: true
  plot dates.x, closes.y, with: :lines, notitle: true
end

出力結果はこのようになります。 sample1

このサイトはlokka+herokuを使って無料で運用しているのですが、lokkaは既に更新のとまっているCMSってこともあり、情報が少ない。画像を表示させるのにかなり手こずりました。ちなみに、gdriveからここの方法でいけました…そのうちlokkaで不親切だと感じたところを記事にできたらなと思います。

サンプル2

Bundler.require

soks = Kabu::Company.find_by_code(1305).soks
dates = Kabu::Soks.parse(soks,:date)
values = Kabu::Soks.parse(soks,:open,:high,:low,:close)

Numo.gnuplot do
  set terminal: 'jpeg'
  set output:  'sample2.jpeg'
  set title: "Demo of plotting financial data"
  set yrange: values.yrange
  set xtics: dates.xtics
  set lmargin: 9
  set rmargin: 2
  plot dates.x, *values.y, with: :financebars, lt: 8, notitle: true
end

sample2

ラインチャートからバーチャートに変えたものです。バーチャートには4本足が必要になります。100日分のデータを出力するとした場合valuesにはlengthが100の配列が4つ格納されています。それぞれ、初値高値安値終値となります。plotする際には配列を展開するために*が必要になります。

サンプル3

Bundler.require

soks = Kabu::Company.find_by_code(1305).soks
dates = Kabu::Soks.parse(soks,:date)
values = Kabu::Soks.parse(soks,:open,:high,:low,:close)
closes = values[3]
bols = closes.bol(25)
dates, values, bols = Kabu::Soks.adjust_length(dates, values, bols)

Numo.gnuplot do
  set terminal: 'jpeg'
  set output:  'sample3.jpeg'
  set title: "Demo of plotting financial data"
  set yrange: bols[1..2].yrange
  set xtics: dates.xtics
  set lmargin: 9
  set rmargin: 2
  set grid: true
  plot [dates.x, *values.y, with: :financebars, lt: 8, notitle: true],
    [dates.x, bols[0].y, with: :lines, notitle: true, lc: "'blue'"],
    [dates.x, bols[1].y, with: :lines, notitle: true, lc: "'blue'", lt: 0],
    [dates.x, bols[2].y, with: :lines, notitle: true, lc: "'blue'", lt: 0],
    [dates.x, bols[3].y, axes: :x1y2, with: :lines, notitle: true, lc: "'orange'"]
end

sample3

Sample2に対して、ボリンジャーバンドを追加しました。バンド幅は1です。ボリンジャーバンドの計算はKabu::Soksで行います。結果は平均、アッパーバンド、ボトムバンド、偏差がそれぞれ格納されている配列です。

サンプル4

Bundler.require

soks = Kabu::Company.find_by_code(1305).soks
dates = Kabu::Soks.parse(soks,:date)
values = Kabu::Soks.parse(soks,:open,:high,:low,:close)
volumes = Kabu::Soks.parse(soks,:volume)
v_aves = volumes.ave(25)
closes = values[3]
bols = closes.bol(25)
dates, values, bols, v_aves = Kabu::Soks.adjust_length(dates, values, bols, v_aves)

Numo.gnuplot do
  set terminal: 'jpeg'
  set output:  'sample4.jpeg'
  set multiplot: true
  set label: "Bolinger Band", at: [0.01, 0.03]
  set label: "http://gnuplot.sourceforge.net/demo/finance.html", at: [0.01, 0.07]
  set yrange: (values+bols[1..2]).yrange
  set lmargin: 8
  set rmargin: 2
  set bmargin: 0
  set xtics: dates.xtics(visible: false)
  set format_x: ""
  set grid: true
  set grid: true
  set origin: [0.0, 0.3]
  set size: [1.0, 0.7]
  plot [dates.x, *values.y, with: :financebars, lt: 8, notitle: true],
    [dates.x, bols[0].y, with: :lines, notitle: true, lc: "'blue'"],
    [dates.x, bols[1].y, with: :lines, notitle: true, lc: "'blue'", lt: 0],
    [dates.x, bols[2].y, with: :lines, notitle: true, lc: "'blue'", lt: 0],
    [dates.x, bols[3].y, axes: :x1y2, with: :lines, notitle: true, lc: "'orange'"]

  unset label: 1
  unset label: 2
  set :bmargin
  set tmargin: 0
  set format: :x
  set xtics: dates.xtics
  set ytics: volumes.ytics(count: 2)
  set grid: true
  set origin: [0.0, 0.0]
  set size: [1.0, 0.3]
  set yrange: volumes.yrange
  plot [dates.x, volumes.y, with: :impulses, notitle: true, lt: 3, lc: "'green'"],
    [dates.x, v_aves.y, with: :lines, notitle: true, lt: 3 ]
  unset multiplot: true
end

sample4

出来高を加えます。ようやくチャートらしくなりました。

サンプル5

最後にローソク足チャートを表示します。gnuplotのローソク足は色分けがかなりアナログな方法を用いているようで、上がったときと下がったときのplotを別々で描いています。

Bundler.require

soks = Kabu::Company.find_by_code(1305).soks
dates = Kabu::Soks.parse(soks,:date)
values = Kabu::Soks.parse(soks,:open,:high,:low,:close)
volumes = Kabu::Soks.parse(soks,:volume)
v_aves = volumes.ave(25)
closes = values[3]
bols = closes.bol(25)
dates, values, bols, v_aves = Kabu::Soks.adjust_length(dates, values, bols, v_aves)
up_stick, down_stick = values.split_up_and_down_sticks

Numo.gnuplot do
  set terminal: 'jpeg'
  set output:  'sample5.jpeg'
  set multiplot: true
  set label: "Bolinger Band", at: [0.01, 0.03]
  set label: "http://gnuplot.sourceforge.net/demo/finance.html", at: [0.01, 0.07]
  set yrange: (values+bols[1..2]).yrange
  set lmargin: 8
  set rmargin: 2
  set bmargin: 0
  set xtics: dates.xtics(visible: false)
  set format_x: ""
  set grid: true
  set grid: true
  set origin: [0.0, 0.3]
  set size: [1.0, 0.7]
  plot [dates.x, *up_stick.y, with: :candlesticks, lt: 6, notitle: true],
    [dates.x, *down_stick.y, with: :candlesticks, lt: 7, notitle: true],
    [dates.x, bols[0].y, with: :lines, notitle: true, lc: "'salmon'"],
    [dates.x, bols[1].y, with: :lines, notitle: true, lc: "'salmon'", lt: 0],
    [dates.x, bols[2].y, with: :lines, notitle: true, lc: "'salmon'", lt: 0],
    [dates.x, bols[3].y, axes: :x1y2, with: :lines, notitle: true, lc: "'orange'"]

  unset label: 1
  unset label: 2
  set :bmargin
  set tmargin: 0
  set format: :x
  set xtics: dates.xtics
  set ytics: volumes.ytics(count: 2)
  set grid: true
  set origin: [0.0, 0.0]
  set size: [1.0, 0.3]
  set yrange: volumes.yrange
  plot [dates.x, volumes.y, with: :impulses, notitle: true, lt: 3, lc: "'green'"], 
    [dates.x, v_aves.y, with: :lines, notitle: true, lt: 3 ]
  unset multiplot: true
end

sample5

必要なチャートは大体書けるようになると思います。numo-gnuplotを利用しない場合はRubyで一旦データファイルを作成し、それをgnuplotで読み込んでチャートを作成するという流れになると思います。Rなどの利用も考えると、こちらの方法が断然柔軟性は有ると思いますが、このサイトでは極力Rubyの中で完結させることを優先にすすめていきたいと思います。

まとめ

gnuplot を使ってチャートの出力を行いました。売買判定時にマーキングをする、だとか、出来高分布図を右に追加するだとか、ほしい機能はまだまだ有ると思いますが。そういった機能については必要時に随時追加していきます。チャートの作成に当たってはテンプレートを作ってそれを呼び出すと言うかたちになると思います。次回からバックテストツールの作成に入っていきます。

Recent Entries
Categories
    Tags
    Archives
    Search