2019年9月28日土曜日

python

毎日Rといいながら、最近は毎日python生活です。バックテストをしてみたので公開します。
・データは株ドラゴンの時系列データを使いました。マザースの約290銘柄、約120日ずつの4本値と出来高です。
・ストーリーは、前日終値より5%下がったら買い、買値より5%上がるか下がったら売るというものです。
・結果はマイナスです。(プラスだったら発表しません)
データは次のようなデータフレームです。列が縦にそろっていなくて見にくくてすみません。右側の5列は自分で付け加えました。

                O     H    L     C     V   code    dC     C1      V1   V5m  L5H5
d                                                                         
2019-03-20  926  926  908  908   500  3634   NaN    NaN     NaN  NaN   NaN
2019-03-22  907  930  870  905  3400  3634  -3.0  908.0   500.0  NaN   NaN
2019-03-25  950  950  895  896  3500  3634  -9.0  905.0  3400.0  NaN   NaN
2019-03-26  895  915  895  915   900  3634  19.0  896.0  3500.0  NaN   NaN
2019-03-27  960  960  930  956  3800  3634  41.0  915.0   900.0  NaN   NaN

 買の判定は以下の通りです。寄り付きで前日終値の-5%であれば買、寄り付きが買値となります。寄り付きでは前日終値の-5%以下にならなかった場合、日中を見ることになるので、当日安値が前日終値のー5%以下になったら買、買値は前日安値のー5%としました。実際にはこれより安いわけですが。
  1. def in_underC(df,k=0.95):
  2.   ins = df.C1*k
  3.   df["f"]=df.L<ins
  4.   df.f=df.f.astype(int)
  5.   #in値の設定
  6.   df["I"]=-1
  7.   df.loc[(df.f)&(df.O>ins),"I"]=ins
  8.   df.loc[(df.f)&(df.O<=ins),"I"]=df.O
  9.   return df

 売の判定は冗長なのでコードは示さないことにしますが、あらすじは次の通りです。
買値の+5%を利確値、-5%を損切値ということにします。利確値以上で利確、損切値以下で損切します。
 2日目以降はまず、始値を見て利確、損切になれば始値を売値とします。どちらにも当たらない場合、高値と安値を利確値、損切値と比べます。売りになった場合は利確値、損切値が売値になります。
 買った当日は始値の比較をしないで高値安値との比較のみをします。
 売になった場合は、その値とかかった日数を記録します。買った当日売った場合は0日、売りにならなかった場合マイナス1日とします。

結果のデータフレームです。
              f      I    days         g    S   state
d                                           
2019-04-25  1  515.0     1 -0.050000  489    ba
2019-04-26  0   -1.0    -1  0.000000    0     -
2019-05-07  1  495.0     0 -0.050000  470    ba
2019-05-08  1  476.0     3  0.050000  499    ba
2019-05-09  1  486.0     2  0.050000  510    ba
2019-05-10  1  478.0     1  0.050000  501    ba
2019-05-13  0   -1.0    -1  0.000000    0     -
2019-05-14  1  483.0     1  0.066253  515     O

先ほどのデータフレームの右側にくっついて出てきますが、その部分だけです。
相変わらず見にくいです。
fは買に入ったかどうかのフラグ
Iは買値。inなのでIを使いました。
daysは売までの日数。入ってないときはー1。0は当日売った場合。
Sは売値
gはS/I-1 いわゆるリターンですが、ゲインという意味でg
stateは売ったのが寄りか場中か。baは場中、最終行はOですが始値で売ったということです。

これを先ほどのデータで検証した結果が次です。

計=36038 f=3732 days=3681 g.mean=-0.0009
100<C<5000 V5m>10000 g.mean=-0.0020
100<C<5000 g.mean=-0.0008
100<C<5000 V5m>10000 5日以内 g.mean=-0.0017
100<C<5000 5日以内 g.mean=-0.0005

計は約290銘柄×約120日=36038本のローソク足を検証した。
fは入った日数。約10分の1入っています。
daysは日数が0以上のものすなわち、売りになった数
g.meanはゲインの平均です。
2行目以降は同じ数字に制限をかけたものです。
100<C<5000は終値が100円より大で5000円より小。100円以下は怪しいし、5000円以上は買えません。V5mは前日までの5日間の出来高平均。1日当たり10000株くらいの売買がないといけません。
5日以内は5日以内に売れたもののみの集計です。
いずれの場合も売れなかった部分については平均から除外しています。

バックテストでいい数字が出てぬか喜びをしたことは何回もあります。で、心配なので目で見て確認したいです。

ローソク足の上のvは買った日です。
ローソク足中にXがありますが、買った値です。
ローソク足の下にoxがありますが、勝ったか負けたかです。
バックテストだいたい正しいようです。