2016年8月20日土曜日

ローソク足の順序変更 その2 移動平均乖離率

 先のローソク足の順序変更で議論したものを関数化した。次のようなチャートになる。

チャート中の赤い曲線はオープンギャップ(当日始値/前日終値-1)の値である。また、ローソク足は、実際の金額ではなくて、始値からの比率とした。例えば、終値については 終値/始値-1 の値である。そのほかも同じで、始値は0となる。
オープンギャップだけではもったいないので、ほか指数でも同様にソートしてローソク足を表示するようにしてみた。
関数名はsortChartで第1引数に日足4本値データ、第2引数に指数を書く。5日移動平均からの乖離率を指数とするには次のように使う。


第2引数 lag(Delt(SMA(Cl(z),5),Cl(z))) について説明する。zは日足4本値データxts型で、Cl(z)はその終値である。SMAは移動平均を求める関数で、SMA(Cl(Z),5)で5日移動平均を求めている。Deltは比率を求める関数で、Delt(a,b)でb/a-1を計算する。Delt(SMA(Cl(z),5),Cl(z))で5日移動平均からの乖離率となる。lagを付けないとピッタリ符合するのだが、前日の終値の乖離率から判断するのだからlagが必要だ。チャートの赤い線が乖離率である。



同様に25日移動平均からの乖離率でみると


参考までにソースは次の通り

8行め中ほどのinfo(z)は私設の関数。zのコード・銘柄名・市場・業種と、次の1は貸借銘柄を意味する文字列を返す。もしも万が一このコードを動かしてみたいと思われるのならば、この部分を削除し、先頭に library(quantmod) と入れれば動くと思われる。 

9行めのコメントは10行めと取り換えると、指数をチャート内に表示するように縮尺する。

第2引数を省略するとオープンギャップを採用する。

各値がわかるように、データフレームを返すようにしてある。

ローソク足の順序変更・・・OGP オープンギャッププレー

 前日の終値と当日の始値の差をギャップというらしい。ギャップと当日の様子を比較するにはどうしたらよいかと考えるうちに、ギャップ順にソートしたローソク足を見たいと思い立った。
 xts型のデータの順序を変えてチャートを描けばよいのだが、うまくいかない。悪戦苦闘の状況を以下に記す。試してうまくいかなかったことも記録したので(こちらの方が主かもしれない)冗長である。
 コンソール出力に続いて、コメントの形でその解説という順序で記述してある。

> z
Open High Low Close Volume B
2016-08-15 734 775 732 762 107200 80887900
2016-08-16 754 805 754 783 178800 140945300
2016-08-17 768 792 726 726 177100 133505500
2016-08-18 705 712 671 676 157300 108283000
2016-08-19 666 704 651 695 226500 152292900

#zは4本値データである。

> g=Delt(lag(Cl(z)),Op(z))
> g
Delt.0.arithmetic
2016-08-15 NA
2016-08-16 -0.01049869
2016-08-17 -0.01915709
2016-08-18 -0.02892562
2016-08-19 -0.01479290

#ギャップの計算。前日終値と当日始値の差ではなくて、比率を採用した。
#具体的には g = 当日始値/前日終値-1

> order(g)
[1] 4 3 5 2 1
> z[order(g)]
Open High Low Close Volume B
2016-08-15 734 775 732 762 107200 80887900
2016-08-16 754 805 754 783 178800 140945300
2016-08-17 768 792 726 726 177100 133505500
2016-08-18 705 712 671 676 157300 108283000
2016-08-19 666 704 651 695 226500 152292900

#order(g)順に並べると、先頭は4番目のデータであるから08-18であるが、順序は変わっていない。xts型のデータの表示には自動的に日付順に並べ替えられるのだろう。ということは、zのxts属性を落とせばいいのではないか。

> as.data.frame(z)[order(g),]
Open High Low Close Volume B
2016-08-18 705 712 671 676 157300 108283000
2016-08-17 768 792 726 726 177100 133505500
2016-08-19 666 704 651 695 226500 152292900
2016-08-16 754 805 754 783 178800 140945300
2016-08-15 734 775 732 762 107200 80887900
#お、うまくいっている。

> mc0(as.data.frame(z)[order(g),])

#mc0はchartSeriesのラッパー関数だ。chartSeriesで再び日付順に並べ替えられてしまうらしい。ということは、結局、日付を変えなければだめということか。方針変更

> rank(g)
Error in if (xi == xj) 0L else if (xi > xj) 1L else -1L :
argument is of length zero

#gの順位を日付に埋め込もうと思う。またしてもgがxts型であることが問題らしい。

> rank(unclass(g))
[1] 5 4 2 1 3

#gの型をなくしたらうまくいった。

> xts(z,as.Date(rank(unclass(g))))
Open High Low Close Volume B
1970-01-02 734 775 732 762 107200 80887900
1970-01-03 754 805 754 783 178800 140945300
1970-01-04 768 792 726 726 177100 133505500
1970-01-05 705 712 671 676 157300 108283000
1970-01-06 666 704 651 695 226500 152292900

#関数xtsの第2引数は日付(時間)をとる。確かに日付は変わっているが、順序が変わっていない。zがxts型のせいだろう。

> xts(unclass(z),as.Date(rank(unclass(g))))
Open High Low Close Volume B
1970-01-02 705 712 671 676 157300 108283000
1970-01-03 768 792 726 726 177100 133505500
1970-01-04 666 704 651 695 226500 152292900
1970-01-05 754 805 754 783 178800 140945300
1970-01-06 734 775 732 762 107200 80887900

#おお、うまくいった。

> mc0(xts(unclass(z),as.Date(rank(unclass(g)))))


#これでよい。

> mc0(xts(unclass(z-as.numeric(Op(z))),as.Date(rank(unclass(g)))))

#始値をそろえてみた。左の方が前日終値より始値の方が低いので、当日は陽線が期待されるのだが、この5つの例では低いほうがさらに陰線になるという、ほんとかいなという状況である。

以下は、2132アイレップ、7203トヨタ、8411みずほの2016年について同様の操作をしたものである。


左の方が陽線が目立つ。

2016年7月18日月曜日

損切ラインと利益確定ラインについて

 私は、始値で買って、±5%程度で、指値と逆指値を入れるということを試しています。損切も利益確定も同じ幅にしています。それはなぜかというと、損切を小さく、利益確定を大きくすると損切に達する確率が高くなって、結局のところいつも損切にあってしまうのではないかとの危惧と、同じ幅にしておけば、上がると予想したことが外れたと原因がはっきりすると考えたからです。

今回この戦略をテストしてみました。対象は2132アイレップ 2015-03-13~2016-07-13です。

始値で買って、損切ラインや利益確定ラインに達すればその値段で売り、売れなかったら大引けで手仕舞うという想定です。

手元のデータは4本値だけなので、損切と利益確定の両方に達した時、どちらに先に達しているかは判別できません。

次は、損切を始値の5円下、利益確定を10円上に設定した場合です。

1行目、入力の説明をします。

culcは関数名です。

zはアイレップの4本値データ(xts)です。

続く引数の5,10は損切幅と利益確定幅の指定です。

2・3行目 出力の説明をします。

損回は損切に達した回数です。 Lo(z) <= Op(z)-5 の回数を数えています。 利回は利益確定ラインに達した回数です。 Hi(z)>= Op(z)+10 の回数を数えています。

損利両回は両方のラインに達した回数です。実際にはどちらに達しているのかわかりません。

引回は両ラインに到達せず、大引けで売った回数です。

引損益は大引けで売ったときの損益です。

損切は損切ラインの値段で売れたものと仮定しています。実際にはそれより下がることもありますが。従って損の合計は損回*-5円となります。同様に利益確定の合計は利回*10円、全計はこの2つに引損益を加えたものです。

修正計は、両ラインに達した時、損切ラインに達したものとして同様の合計を出したものです。

この場合は、損切ライン到達が160回、利益確定ラインに到達が122回、両ラインに到達したものが63回。大引けで売ったのが109回で、両方に到達しているときすべて損切ラインに到達したとすると、最終損益は-180円であるということを意味しています。

損切ラインと利益確定ラインを変えると、どうなるでしょうか。損切ラインを1~100円、利益確定ラインも1~100円にして、10000通りの組み合わせで、計算してみました。10000行表示してもいかがかと思うので、主なところを以下に示します。write.csv出力してexcelで開いた画面のハードコピーです。



最も成績の良いのが損切-18円、利益確定+57円です。

損切ライン到達が57回、損益-18*57=-1206円。利益確定ラインに到達が11回、57*11=+627円。両方に到達したケースはありませんでした。大引けまで行ったのが260回、+1201円。最終損益は802円です。

現在の終値は872円ですので、18円というのは2%にあたります。

この期間の始値292円、終値872円。単に持っていれば+580円です。

損切ラインは思いのほか小さいこと、利益確定ラインはなくてもいいくらいですが、高いところに設定しておけば、引けに向けて値下がりするときに有効なことがあるということでしょうか。勉強になりました。

ほかの銘柄で同様なことをやってみると、損切幅1円などという銘柄が多数出てきました。全体に値下がりしている銘柄はそうなるのでしょう。アイレップは右肩上がりの銘柄であったということも大きな要因かと思います。また、アイレップにしても現在大幅な下降局面に入った感があり、この戦略を今、当てはめてみようとは、思いません。なお、アイレップは2015年の11月ごろから値動きの様子が大幅に変化しました。この時期後で同じことをやってみると損切幅17円でした。

見る人もいますまいが、一応culcのソースをあげておきます。



2016年7月14日木曜日

xtsのcsv出力

zzはxts型のデータである。

これをcsv出力すると、次のようになる。

日付が消えてしまう。この場合は、write.zooを使う


Stack Overflow に出ていた。


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年分を与えて、チャートを描く範囲のみを制限しているからである。