perlでローソク足
ググったけども日本語の記事がなかったので。
最初はなぜかgnuplotで描こうとしていたのですが、gnuplotは対話式であるため、スクリプトでガンガン描けないため方針転換。
cpanmで落としてきたGD::Graph::candlesticksを使用。下記のサンプルコードは、マイクロソフトを例に取っているところまで含めてほぼコピペ。
データは米Yahoo!financeから落としたものを想定。
#!/usr/bin/perl use strict; use warnings FATAL => 'all'; use GD::Graph::candlesticks; no warnings 'redefine'; my (@date, @kabu_data, $max_price, $min_price); open(MSFT,"<","MSFT\.csv") or die("Cannt open MSFT\.csv!\n"); while(<MSFT>){ if(($_ =~ /^[0-9][0-9][0-9][0-9]\-/)&&($_ =~ /\,/)){ $_ =~ s/\n//; my @date_data = split(/\,/,$_); push(@date,$date_data[0]); push(@kabu_data,[@date_data[1..4]]); $max_price = $date_data[2]; $min_price = $date_data[3]; last; } } while(<MSFT>){ if(($_ =~ /^[0-9][0-9][0-9][0-9]\-/)&&($_ =~ /\,/)){ $_ =~ s/\n//; my @date_data = split(/\,/,$_); unshift(@date,$date_data[0]); unshift(@kabu_data,[@date_data[1..4]]); if($date_data[2] > $max_price){ $max_price = $date_data[2]; } if($min_price > $date_data[3]){ $min_price = $date_data[3]; } } } close(MSFT); my $graph = GD::Graph::candlesticks->new(800, 400); $graph->set( x_labels_vertical => 1, x_label => 'Trade Date', y_label => 'US $', title => "NASDAQ:MSFT", transparent => 0, candlestick_width => 7, dclrs => [qw(blue)], y_min_value => $min_price -0.2, y_max_value => $max_price +0.2, y_number_format => '%0.2f', ) or warn $graph->error; my $data_candlesticks = [ [ @date ], # date [ @kabu_data ], # candlesticks ]; my $gd = $graph->plot($data_candlesticks) or die $graph->error; open my $dump, ">", "candlesticks_example.png" or die $!; print $dump $gd->png; close $dump; exit;
出力サンプルはこの記事の右上。小さくてすまぬ。先週末にかなり下落したもよう。
GD::Graph::mixedを使って他のグラフとも重ね合わせられた。
下記の例は、当方で年移動平均を計算済み、かつ、米Yahoo!とは時系列が逆のデータを使用しているのであしからず。
#!/usr/bin/perl use strict; use warnings FATAL => 'all'; use GD::Graph::candlesticks; no warnings 'redefine'; my (@date, @kabu_data, @year_ave, $max_price, $min_price); open(TWTR,"<","TWTR\.csv") or die("Cannt open TWTR\.csv!\n"); while(<TWTR>){ if(($_ =~ /^[0-9][0-9][0-9][0-9]\-/)&&($_ =~ /\,/)){ $_ =~ s/\n//; my @date_data = split(/\,/,$_); push(@date,$date_data[0]); push(@kabu_data,[@date_data[1..4]]); push(@year_ave,$date_data[10]); $max_price = $date_data[2]; $min_price = $date_data[3]; last; } } while(<TWTR>){ if(($_ =~ /^[0-9][0-9][0-9][0-9]\-/)&&($_ =~ /\,/)){ $_ =~ s/\n//; my @date_data = split(/\,/,$_); push(@date,$date_data[0]); push(@kabu_data,[@date_data[1..4]]); push(@year_ave,$date_data[10]); if($date_data[2] > $max_price){ $max_price = $date_data[2]; } if($min_price > $date_data[3]){ $min_price = $date_data[3]; } } } close(TWTR); my $graph = GD::Graph::mixed->new(3600, 600); $graph->set( x_labels_vertical => 1, x_label => 'Trade Date', y_label => 'US $', title => "NASDAQ:TWTR", transparent => 0, types => [ qw(candlesticks lines) ], dclrs => [qw(blue red)], fgclr => "dgray", y_min_value => $min_price -0.2, y_max_value => $max_price +0.2, y_number_format => '%0.2f', ) or warn $graph->error; my $graph_data = [ [ @date ], # date [ @kabu_data ], # candlesticks [ @year_ave ], # lines ]; my $gd = $graph->plot($graph_data) or die $graph->error; open my $dump, ">", "candlesticks_example.png" or die $!; print $dump $gd->png; close $dump; exit;