2016年6月25日土曜日

quantmod チャート上をクリックする

quantmodのチャートをクリックして、特定の日を選んだり、直線を引いたりしたいと思った。

quantmodにはzooomという関数がある。これはチャートの2点をクリックするとその期間をzoomしてくれるというものだ。

その関数のソースを調べてみた。その中でget.chobという関数でチャートオブジェクトを得ている。このオブジェクトにはチャートに関する様々な情報が格納されていた。また、関数chartSeriesのソースを調べると、実際に描くのはchartSeries.chobという関数であることがわかり、さらにchartSeries.chobを調べて、チャートオブジェクトの情報のうちで、使えそうなものを見つけた。それらの調査から次のような関数を作った。

この関数は、実行するとlocatorの十字が表示されるので、クリックすると、その日のデータを表示するというものである。参考として関数内で得ている値も表示した。プログラムと実行結果は次の通り。


3行めのcoがチャートオブジェクトである。

xdataはチャートを描くxts型のデータ。

xsubsetはsubsetで指定されたデータを整数値で示したもの、例えば125,126,127,...などとなっている、xdata内の行番号の列である。

nはデータ数(=xsubsetの長さ)

dxは1日分のデータのx軸上の幅である。

chartSeries.chobのソースによれば、i番目のデータのx座標は 1+(i-1)*dx を中心とするので、その前後 dx/2 の範囲をi番目のデータと認識するようにした。8行めである。

14行目以降が表示されたものである。

これができるといろいろできそうだ。

2016年6月20日月曜日

新高値更新回数を数える・・・累積最大値cummax

5月29日に、新高値の回数を数える問題を考えた。

当日の最高値がそれ以前の最高値以上となる日数を数える問題だ。

for文で回していたのだが、cummaxの存在を忘れていた。

zはxts型のオブジェクト(約1年分の4値データ)である。


これだけでOKだ。

一応解説しておく。

Hiは4値のうちの高値を求める関数。高値のベクトル(実はxts型)となる。
cummaxは累積最大値。それ以前の最大値からなるベクトルとなる。(xts型)
sum関数内では、TRUEは1、FALSEは0として扱われる。

恥ずかしいことです。

なお、前日以前の最高値と当日の高値が同じ場合は、本来は新高値ではないけれど、上の方法では新高値としてカウントされてしまう。
それを避けるなら、


lagで前日までの最高値を求め、当日の高値の方が高い日を数える。lagを使うと初日にNAが入る。NAが入るとsumはNAになってしまう。従って、na.rm=TでNAは除いて数えている。

2016年6月12日日曜日

複数チャート(plot.xts)

quantmodのチャートは詳細で素晴らしいのだが、画面分割できない。こんなに素晴らしくなくてよいので、ざっくり複数のチャートを見る方法を探ってみた。

あった。plot.xtsでチャートを描いてくれる。



zはxts型のオブジェクトである。ポイントはwidthであろか。width=25000。この位の大きさでないと、線のようなチャートになる。

また、通常のローソク足とは違って、土日など空いている日は空間が開く。これはこれでいいのではないかと思って受け入れることにする。

髭の色がgrayなので見にくい。髭・陽線・陰線の色などを指定すると次のようになる。



これに、移動平均線とボリンジャーバンドを入れると次の通り。



線が出てこないので日数をちょっと増やした。

SMAとBBandsはモジュールxtsの関数。5日移動平均が青色、25日移動平均が緑、ボリンジャーバンドはデフォルトの20日移動平均と±2σのラインを赤で描いてある。

これを複数描いたのが次の図だ。画面分割、余白調整、最小値の1.5倍及び整数倍に横線、コード・銘柄・最終終値を付け加えた。

2016年6月10日(金)に至る最終の3日間終値が前日の終値を上回っているマザーズの銘柄のチャート。

期間は2016年4月以降である。

線が左端から描かれているのは、データは約1年分を与えて、チャートを描く範囲のみを制限しているからである。





2016年5月29日日曜日

コロン演算子

値がない場合の処理ネタです。

ベクトルvに対して for(i in 1:length(v))という回し方をすることがあります。

ついlength(v)が0だったら1回も実行しないことを期待してしまうのですが

とんでもないことです。

0回どころか、1と0の2回実行してしまいます。4:1は動作確認です。

ついでに調べてみました。


これは、高値を更新した回数を数えるという問題で遭遇した『問題』です。


【3行目】xts型からnumericに変換しなおかつna.omitをして用心深くやっています。xts型のままだと日付が違うと比較してくれないとかいろいろな問題が起きそうなので。こんなに用心したのに、

【4・5行め】泣く泣く入れました。

【7行め】問題の個所です。

【9行め】エラーはこの行で出ます。nが0の時、hの値がないので、比較できないと怒られます。

最初、forを使わないバージョンを作ったのですが、「それぞれの日の高値」と「それ以前の最高値」と比較するために、毎回maxをとるのはおかしいのではないかと思い、はじめの方から見ていき、最高値(m)の更新と、更新した回数を一回で調べています。1回で済むんですね、と変に感激。【行番号9】

例によって全銘柄に適用して、高値更新回数の多いほうからリストしてみます。


最近高値更新したかに関心があります。どのようにしたらよいか、またいずれ考えます。

なお、コロン演算子というのは私の勝手な命名です。pythonにありましたっけ?しばらく使ってないので忘れています。

2016年5月28日土曜日

従前



比率がわかるように、最小値の1、1.5、2、2.5、3、・・・倍に横線を入れてみた。

Vテクノロジーと関西スパは似たようなチャートだが実は比率がまるで違うことがわかる。

複数チャート

新高値銘柄の検索をしたのでそれらのチャートを一斉に見たくなった。

5月27日新高値を付けた銘柄の終値のチャート。

参考までに、5月26日新高値は


参考までにスクリプト。

値がない場合の処理・・・新高値のスクリーニング

値がない場合の処理は頭痛の種だ。今回の経緯は次の通り。

本日新高値を付けた銘柄を検索したいと思った。

いつも通りだが、ytは日本株式市場の各銘柄の直近約1年間の4本値(+α)データ(xts型)からなるリスト。たとえば、yt[[1]]は極洋の約1年間のデータ。

【行番号2~3】dayには本日の日付が入っている。day="2016-05-27"

【行番号4~12】zをytのうちの1つのデータとする。すなわち1銘柄のデータである。

【行番号14~16】max(Hi(z))==Hi(z[day])で本日が新高値かどうかの判定ができる。

【行番号17~27】これを全銘柄に適用すると、中には出来高のないものも存在するのが頭の痛いところである。

【行番号28~33】出来高のないものの検出にis.nullやis.na、is.nanなどを試みたが駄目であった。

【行番号34~36】直接sapplyした悲惨な結果が。

【行番号37、38】ところで、z["2016"]とすれば、2016年の全データが指定できる。z[day]で返るものは、xtsデータで、複数の値が返ることが想定されている。したがって、lengthを調べれば値がないことがわかるのではないか。

【行番号39】全銘柄に適用してみよう

【行番号40~45】うまくいった。

ifelseでlengthが0の時は0、それ以外の時はHi(z[day])を採用するようにした。0はFALSE扱いになることを用いている。



値がないことをlengthで判断したという、どうということのない話題であった。

xts型のデータの判定なのでnrowを使う方が適切かもしれない。というのはlengthで返るのはnrow×ncolだから。悩ましいが結局はxtsは何者であるかという理解が問われる問題であったようだ。

ちなみに