2016年4月27日水曜日

GMMA

GMMAというチャートがあるそうです。

アイネット証券のサイトによれば、

「GMMAチャートとは、12本の指数平滑移動平均線(EMA)を一度に表示して、価格トレンドをビジュアル化しようとするトレンド系のテクニカル指標です。開発者Daryl Guppy氏の名前を取ってGuppy Multi Moving Averageと呼ばれ、GMMAと略されます。 」

とのことです。更に、

「短期線は、計測期間の短い3・5・8・10・12・15のEMA6本、長期線は、計測期間の長い30・35・40・45・50・60のEMA6本で構成されています。」

面白そうなので、quantmodでやってみました。

6行目のTAの指定がポイントです。

chartSeriesのTAに渡す文字列TAを、1・2行目で作っています。短期線は青、長期線はピンクとしました。

文字列TAが長くなるので2列にしました。途中に改行コードが入りますが、chartSeriesの方では問題なく動きました。だめならpaste,collapseを使います。

(Rの文字列結合は面倒で閉口します。)




7行め、multi.col=Tは、陽線・陰線の区別だけでなく、前日の終値と当日の始値との関係で4色にするものです。

例えば灰色は、当日は陽線で、前日の終値が当日の始値より高い場合です。

2016年4月21日木曜日

データフレームのxts化

データフレームwは4つの列名Open,Close,High,Lowからできています。これをxts化します。

これは、自動的に1970年1月2日からの日付が振られます。
日付データがあれば、それを関数xtsの第2引数に指定します。

この場合、変換するデータに日付があると全体が文字列に変換されてしまうので、数値データのみ指定しています。(6行目のw[1:4])

2016年4月17日日曜日

xtsでの単純な足し算

xtsオブジェクトで単純な足し算ができないという現象に悩まされました。
zは御覧の通りのxtsデータです。

先頭の終値は35550円です。

先頭とその次の終値を足してみます。

関数Clがquantmodのものなので、それを使わないでみましょう。

解消法を2つ

この現象はzooでも起きるようですが、tsでは起きませんでした。

同じ日付の場合、計算できるようです。

zがxtsの場合、z[[n]]でn番目の要素にアクセスできます。要素番号nは縦並びで数えます。matrixの場合と同じです。
上記の操作の結果がまたxtsになるので、[[ ]]でアクセス可能です。tsとの違いをご覧ください。


2016年4月10日日曜日

バックテスト2(昨日の反省)

 昨日、「 My Life as a Mock Quant(2011-03-29) およびその中で紹介されている FOSS Trading: How to backtest a strategy in R を参考にして」と書きましたが、落ち着いて見直してみると、参考にしたことになっているのかどうか心配になってきたので、現在感じている問題点を論じてみたいと思います。

 まず、本質的でない点を2点。

 その1、昨日の東証1部でのシミュレーションでは株式分割について考慮していません。手持ちのデータでは株式分割を知るすべはありません。また、あったとして、どのような対処が必要かについて考えていません。原典でも考慮していないと思われます。

 その2、指標について。原典のFOSSではDVIを使っています。DVIではデフォルトで252日分以上のデータが必要であるように思われます。My Life as a Mock Quant(2011-03-29)ではrsiを用いています。最終的なパフォーマンスではどのような指標を作るかが問題になるのでしょうが、今回は本質的でない話題ということで処理いたしました。

 今回本質的と思うのはステップ4:トレーディングルールについてです。

 昨日のモデルは、現金に注目して、売買は寄成に限りました。

 FOSSでは昨日書いたようにロングアンドショートという、株を買うか、空売りするかのどちらかというモデルでした。

 この場合は現金に注目してもうまくいかないのでしょう。FOSSの日々のリターンを計算するコードは次の通りでした。



 sigはステップ3で作成した指標です。日々1または-1の値をとっています。1がロング(買い)、-1がショート(空売り)です。

 GSPCは株価データです。

 Clで日々の終値をとっています。

 ROCはrate of change 変化率とでも訳すのでしょうか。イメージとしては「(当日の終値-前日の終値)/前日の終値」です。

ROCの定義をネット上でいろいろ調べてみたのですが、どうもはっきりとした定義が与えられていない。で関数のコードを見ました。要点を書くと、


の2つの定義があり、オプションでどちらを使うかが指定できます。デフォルトは下の式です。

上の定義はイメージ通りのものです。

下の定義では、log(x)-log(lag(x))=log(x/lag(x))ですから、x/lag(x)が1に近いとき、x/lag(x)-1で近似できます。これが上の式です。

ret はこの値を持ちます。

総資産の評価に


という式が出てきます。

終値を古いほうからx1, x2, x3, ..., xnと書くことにしましょう。

空売りなしの場合には、retの内容は log(x2)-log(x1), log(x3)-log(x2), log(x4)-log(x3), ... と続きます。

これのcumsumをとりますから、隣同士消えて、log(xn)-log(x1)となります。exp(log(xn)-log(x1))ですから、これはxn/x1となります。

すなわち、最初の価格が何倍になったかを示すことになります。

FOSSのステップ4の最後は


総資産の変化の様子を見て終わります。

昨日の記事とだいぶ違いますか?参考にしてバックテストをしてみたというスタンスでご理解ください。

ステップ5は今後の課題ということで。


2016年4月9日土曜日

バックテスト

 ブログ My Life as a Mock Quant(2011-03-29) およびその中で紹介されている FOSS Trading: How to backtest a strategy in R を参考にして、バックテストを作ってみました。
ステップ1:データを取得する。
ステップ2:指標作成。
ステップ3:トレーディング戦略を作る。
ステップ4:トレーディングルール。
ステップ5:戦略のパフォーマンス評価
となっています。FOSSでの戦略はロングアンドショートというものらしいです。買うか空売りするかという選択をしているようです。ちょっと敷居が高いので、買うか売るかだけの戦略にしてみました。パフォーマンス評価の部分はまだ未学習ですが、その前のところについては、大方理解が進んだのではないかと考えています。
問題を次のように整理しました。
1:1株を、持つか、持たないかの2つの状態のうち1つである。
2:それを判断するために指標を作る。この指標が1なら「持つ」。すなわち、買うまたは既に買ってあればそのまま。指標が0なら「持たない」売るかまたは既に売ってあればそのまま。
3:指標は、今回は簡単のため、前日が陽線なら当日「持つ」(1)、それ以外なら「持たない」(0)とした。
4:買い、売りは当日の寄成とした。すなわち、始値で売り買いする。
5:現金は0円スタートとし、買えばマイナス、売ればプラスとなる。


省略しましたが、quantmodパッケージを利用しています。
1行め:zはxts型の変数です。約1年分の特定銘柄(極洋)のデータです。
2行め:指標です。前日が陽線(終値>始値)なら、1、それ以外なら0をとります。前日のデータを見るのでlagです。OpClは(終値-始値)/始値の値を計算する関数です。騰落率という言い方でよいでしょうか?符号だけ利用しています。Cl(z)-Op(z)でもよいですね。Clは終値(Close)、Opは始値(Open)をとる関数です。quantmodの関数です。
3行め:lagをとっているのでsig[1]がNAになります。うまくないので0にしました。
4行め:現金の出し入れについては、前日と当日の株の保有状態によって4つのケースがあります。
① 前日保有・当日保有・・・現金の出し入れはありません
② 前日保有・当日なし・・・当日売るので、現金が入ります。
③ 前日なし・当日保有・・・当日買うので現金が出ます。
④ 前日なし・当日なし・・・現金の出し入れはありません
現金の出入りがあるのは②と③の場合だけです。lag(sig)-sigによって②の時は1、③の時は-1、①④の時は0となります。売り買いする値段は始値ですからOp(z)です。
5行め:4行めでやはり初日はNAになるのでその修正です。
6行め:累積和をとればそれぞれの日の現金の状態がわかります。lastで最後の現金を変数genkinに代入します。
7行め:最後に株を持って終わるか売って終わるかの違いがあります。終値でその株を評価します。
8行め:手持ち現金、株資産、合計最終損益を表示します。

最終

という状況でした。現金-265円、持ち株評価額259円で最終損益-6円です。


動作を確認するため、zとsigとmoneyを並べて示しました。OpCl.zはsigのことです。しばらく買いサインが出ず(OpCl.z0が5日続いた)3月23日に、終値>始値となって3月24日に買いサインが出ました。3月24日の始値303円で買うので、現金-303円となります。この日は始値≧終値なので、3月25日は買いサインがでませんから、始値301円で売ります。・・・とこのような調子です。
このルールで、手持ちの東証1部1956銘柄に適用してみたところ、平均-78円、最大6765円、最小-25498円。利益が出た銘柄845銘柄、損失1096銘柄、±0が5銘柄、データ不足で計算不能10銘柄でした。
記事には、バックテスト後のパフォーマンス評価が大事だと書かれています。今後学んで報告できれば良いですが、本日の記事でアップアップなので、いつになりますか。

2016年4月8日金曜日

連続回数

同じ値が何回続いているか調べたいことがあったので、そのような関数を作ってみました。出来上がりイメージは次のようになります。

8が5回、9が2回、0が1回、8が3回出たことを示しています。ソースは次のようになります。


全然Rっぽくないのが不満です。

2016年4月2日土曜日

ボリンジャーバンド

もうちょっとquantmodを使っている感のあるものをやってみたいと思う。ボリンジャーバンドとは、平均から±2σのところに引いた線のことである。正規分布理論によれば±2σからはずれるのはおよそ5%。ここから外れれば次は戻るだろうという理論と理解してよいだろうか。BBandsという関数がある。quantmodというかxtsパッケージの説明によると、(H+L+C)/3をTP(typical price)といい、TPの直近20日間の移動平均と移動標準偏差σを用いて、-2σの位置を0、+2σの位置を1として、当日のTPの位置を返す。


大きなデータを引用した。xt[[1]]はある銘柄のおよそ250日間の株価データで、xts型である。BBandsではHigh,Low,Closeの3つのデータを使うので、xt[[1]][,2:4]としている。20日間の移動平均を用いるので最初の19日間はNAである。項目名のmavgはmoving average 移動平均である。dnとupはそれぞれ-2σと+2σの値である。pctBは%Bなどと表記されるが、当日の値の位置である。位置の表し方は先に述べたようにー2σのところを0、+2σのところを1とした数値である。-2σを割るというのは%Bが0より小さくなるという意味である。本日の株価がー2σを割っているかどうかが問題なので、次のようにする。

なんと、最初から割れている。なにせ、本日は大荒れの日だったから。これを各銘柄について確認して、割れている銘柄のコードを集める。

やはりいろいろとエラーが出るので、tryで囲んでおいた。

いい加減にやるので、文字列になってしまった。"TRUE"の数を数えよう。

銘柄総数は
> length(xt)
[1] 1956
であるので、実に32%がー2σを割っている。異常事態である。xt[[1]]のチャートを描く。


ろうそく足の上下にある赤い点線の間のグレーゾーンがボリンジャーバンドである。最終日、すなわち右端ではー2σを割っているのがわかる。明日、反発するのかなあ??過去の様子を見るとー2σに沿ってだらだら下降している時期も短からずあるし・・・。

陽線の次は陽線か陰線か

陽線の翌日は陽線が多いのだろうか、陰線が多いのだろうか。陰線の翌日はどうだろうか。調べてみよう。

xtについての説明は、本日のブログを参照。東証1部各銘柄の直近250日間のxts型のデータのリストである。
陽線か陰線かはClose-Openでわかる。正なら陽線、負なら陰線だ。特定の銘柄についてClose-Openを求めてみよう。上記のzを使う。

sとlag(s)については

lag(s)は前日のデータである。lag(s)の3月20日のところには3月19日のデータが来ている。すると、一つ上の表の表示、ttについては、左側縦列が当日、上側横行が前日ということになるので、この表からは陽線の翌日は陽線が33、陰線が37ということになる。同様に、陰線の翌日は陽線38、陰線51ということになる。

陽線と陰線について、前日と翌日が独立だという仮説は棄却されない。簡単に言えば前日の状況から翌日は予測できないということだ。実に残念である。さて、これを全銘柄に適用してみよう。p-valueの値を取得する。

最初tryなしでやってみたがxは最低2要素が必要だとのエラーが出た。いずれかの銘柄で、データが(少)ないものがあったようだ。とりあえずtryで囲んで実行できるようにしてみた。

小さいほうから表示してみよう。

通例、p-valueが5%以下だと有意であると判断する。これらの銘柄は有力か??
p-valueが0.05以下の銘柄がいくつあるか数えてみよう。

ところで、

であった。

有意水準5%で検定するということは、偶然でも5%程度は発生するということだ。この数字はただの偶然だと言っているのだろうか。ちなみに有意っぽい銘柄を紹介しておく。

4月1日大荒れ

今、xに三菱UFJの直近250日分のxtsデータが入っている。
> head(x)
Open High Low Close Volume B
2015-03-26 777.0 777.7 761.0 765.1 76876300 59066990800
2015-03-27 756.0 775.4 747.0 752.2 79314300 60202202570
2015-03-30 749.5 761.0 738.6 756.5 56267600 42334099610
2015-03-31 769.0 771.9 743.7 743.7 63092000 47765287060
2015-04-01 742.6 758.1 735.6 748.7 75510400 56313185200
2015-04-02 748.7 781.7 747.8 773.0 100087400 77006686960
>
このようなデータを東証1部の各銘柄について、用意し、codeで参照できるようにした。
例えば、
> head(xt[["8306-T"]])
Open High Low Close Volume B
2015-03-13 781.0 795.4 778.0 789.5 134578900 105896527510
2015-03-16 797.1 809.5 790.0 797.0 92907600 74319257560
2015-03-17 807.0 811.0 792.5 793.2 72521700 58100512040
2015-03-18 792.1 808.9 787.0 806.6 75154500 59901916890
2015-03-19 803.0 805.6 781.2 785.0 101420600 80007293730
2015-03-20 783.7 790.0 777.0 790.0 59188500 46364901100
>
上記xと違うのは、xtはしばらく前にダウンロードしたデータをもとに作ったので、開始日が早い。その後、日々のデータを追加している。
xtはxtsデータからなるリストである。これを用いて、4月1日の株価下落の様子を調べてみよう。
前日の終値と比べて、本日(4月1日)の終値が下がっているか上がっているかを調べる。

yを見てみると

Close
2016-03-31 258
2016-04-01 252

この銘柄は6円下がっている。差をとるには、numericに変換しないといけないようだ。


[1] -6
これを全銘柄に適用する。

> head(v)
1301-T 1332-T 1333-T 1352-T 1377-T 1379-T
-6  -8   -70  -1  -57  -45
>
先頭の6銘柄についての様子である。ちなみに

> length(v)
[1] 1956

下落した銘柄数、上昇した銘柄数を調べてみる。

> table(sign(v))
-1  0  1
1862  17 73

なんてこった。(一応説明すると下落1862銘柄、上昇73銘柄、変わらず17銘柄)
業種別にどうなっているか知りたくなった。
業種については

で取得したデータ
> head(d)
コード 市場 銘柄名 業種 始値 高値 安値 終値 出来高 売買代金
1 1301-T 東証1部 極洋 水産・農林業 258 259 251 252 408000 103496000
2 1305-T 東証 ダイワ上場投信-トピックス その他 1411 1411 1362 1364 625380 861540000
3 1306-T 東証 TOPIX連動型上場投資信託 その他 1390 1392 1344 1346 11197880 15220495740
4 1308-T 東証 上場インデックスファンドTOPIX その他 1378 1378 1331 1334 2757600 3700777800
5 1309-T 東証 上海株式指数・上証50連動型上場投資信託 その他 26750 26750 26200 26280 385 10206250
6 1310-T 東証 ダイワ上場投信-トピックス・コア30 その他 635 635 616 619 2330 1445340
>
に業種があるのでこれを使う。項目名をaからjに付け替え、更に、コードで参照できるようにする。

コードがa、業種がdである。例えば
> d["1301-T","c"]
[1] 極洋
> d["1301-T","d"]
[1] 水産・農林業
なお、それぞれの下にLevels表示がされたがカットした。

出力をこのまま乗せると形が崩れるので、データフレームの形にして乗せることにする。このようにやるようだ。
> as.data.frame.matrix(tt)





株式データ

Rで株式データを扱ってみる。データは、k-db.comからダウンロードする。k-db.comさんに大変大変、感謝感謝。

このコードを実行すると文字列sに次のようなデータが取得できる。
> head(s)
[1] "2016年04月01日"
[2] "コード,市場,銘柄名,業種,始値,高値,安値,終値,出来高,売買代金"
[3] "1301-T,東証1部,極洋,水産・農林業,258,259,251,252,408000,103496000"
[4] "1305-T,東証,ダイワ上場投信-トピックス,その他,1411,1411,1362,1364,625380,861540000"
[5] "1306-T,東証,TOPIX連動型上場投資信託,その他,1390,1392,1344,1346,11197880,15220495740"
[6] "1308-T,東証,上場インデックスファンドTOPIX,その他,1378,1378,1331,1334,2757600,3700777800"
>
確定した1日分のデータの最新のものである。これをcsvファイルとして読み込むには次のように行う。

1行目はスキップし、-はNAと変換する。
特定の銘柄について、時系列(日足)データを取得するには、

> head(d)
日付 始値 高値 安値 終値 出来高 売買代金
1 2016-04-01 520.0 523.0 507.8 508.7 92551200 47375260340
2 2016-03-31 517.7 534.2 517.1 521.5 92844400 48863109720
3 2016-03-30 530.0 532.0 510.6 512.2 71910100 37377438410
4 2016-03-29 527.0 535.7 524.3 532.9 62651300 33226625400
5 2016-03-28 540.0 540.6 530.2 538.1 60656100 32445384790
6 2016-03-25 522.4 539.7 520.5 535.7 65428500 34793388440
>
三菱UFJの直近250日分のデータである。どのようなアドレスにすればよいかは、k-db.comで希望のデータを表示させ、その時のアドレスバーの表示を参考にすればよい。
quantmodという素晴らしいパッケージがある。インストール方法は、ほかで調べてもらうとして、このデータからローソク足チャートを描いてみる。

まず、項目名を英語表記にする。
quantmodで処理するには、データをxts形式に変換しなければならない。xtsは拡張された時系列データ(extensible time series)の意味らしい。chartSeriesはチャートを描いてくれる。デフォルトでろうそく足(candle chart)となっている。themeを省略するとバックが黒になる。重苦しいので白にしてみた。
なんと簡単なんだろう。