前回の続きです。
3連休はアルゴリズムトレードで利益が出せるかという遊びをやっています。
前回(昨日)は全体のフローを作成し、アルゴリズムのざっくりとした流れについて説明しました。
今回はアルゴリズムの肝となるプライシングとタイミングについて考えてみたいと思います。
プライシングやタイミングの考える際に使う時系列は、cryptowatchやbitcoinchartsのAPIを使ってbitflyerから引っ張ってくるようにしたいと思います。
bitflyerを使っているのは、将来のことを考えると売買APIが整っているbitflyer(coincheckでも可)で売買を行うことが好ましいと考えたからです。
また行列計算、平均、標準偏差などの計算などデータ解析が簡単にできるようにpythonを使って、numpyやpandasといったライブラリを使っています。
pythonを電卓のように使いこなせるようになることも目的の一つです。
前回もご紹介しましたが、実際にマーケットに売買注文を出す方法で短期間の成果を出すことについては既に実証済みです。
そこで、今回はこの短期売買を長期間繰り返した時にリターンの再現性があるのかという点について、アルゴリズムを使ってシミュレーションで検証してみたいと思います。
シミュレーションとは言え、実際の値動きから発注価格を決めて、実際に約定したかどうかをリアルタイムで値動きを拾うので、実際の取引と全く同じ結果になります。
またシミュレーションを繰り返すことで、短期的な騰落や方向感が目まぐるしく変わる仮想通貨市場でロバストなアルゴリズムの検証ができるようになります。
もちろん、実際のバジェットを考慮せずに気軽にシミュレーションを回せるのでPDCAが早く回せるというメリットもあります。
まずはガチ統計というほどではありませんが、統計的知識でどこまで短期的に利益が出せるかを思考実験をしてみたいと思います。
統計の基礎として、平均、標準偏差というパラメータがありますね。
経済学的にはリスク資産というものは、発行体のファンダメンタルズに基づいてプライシングされますが、短期的なマーケットマイクロストラクチャーのアプローチでは非合理的な投資家の存在によってランダムに推移することが知られています。
金融工学の分野では有名なブラックとショールズはリスク資産の価格変動をウィーナー過程に基づく幾何ブラウン運動で表現し、ブラックショールズモデルというプライシングの基礎を構築しました。
このプライシングモデルを一言で言ってしまえば株式などのリスク資産の価格はランダムな価格変動を示すというものです。
そこで価格変動が過去の平均値と標準偏差に基づいた正規分布に従うと仮定した時に、平均回帰の原理を使ったアービトラージを考えます。
下図は正規分布そのものを表したものですが、ここで書かれている数字が今回のアルゴリズムの基礎となります。
リスク資産は短期的には方向感を持たないので、価格変化は上下方向にバイアスがないという点で正規分布を仮定することができます。
真ん中の最もとんがっている部分が中央値であり平均値となります。
またこのグラフは平均値から左右両方向に1σ(標準偏差)変化する確率は34%ずつの合計64%となることを示しています。
つまりある時点において過去の平均値と標準偏差を算出すると、平均から1標準偏差下回る確率は下の計算から16%であることが分かります。
50% - 34.1%=15.9%
これはどういうことかというと過去の平均価格から1標準偏差を下回る価格で買い注文を100回入れるとそのうち16回、つまり6回に1回は約定することになります。
単純化のため、実際の注文を全て独立とすると、注文を出して引っ込めて再度計算して注文を出すという施行を6回繰り返せば成功確率は100%に近くなります。
ちなみにここでの独立性とは、施行(注文)によって約定確率が変わらないということを指しています。
結構高い確率で約定できるじゃないかと思ったのですが、よくよく考えるとこの1回の施行は過去30個のデータの標準偏差を使って計算しているため、施行の独立性を担保するためには注文と注文の間隔はこの30個分のデータ期間だけ空ける必要があります。
そこで問題になるのがデータ頻度の問題です。
つまりデータのサンプリング間隔を1秒で取るのか、1分ごとに取るのか、5分ごとに取るのかということが問題になってきます。
仮にサンプリング間隔を1分で取るとデータ取得期間は30分ということになりますが、注文間隔も30分あける必要があり、これでは6回の独立施行を繰り返すためには3時間かかってしまうためお話になりません。
そもそも一定のサンプリング間隔を設定してしまうと、その間隔の分注文間隔も開けなければならず、制約になってしまうのでここではtickデータを使うことにします。
つまり直近に発生したトランザクションで平均や標準偏差を取得することにします。
なぜ、こんな話をしているかというと、統計を使った実証分析では標準偏差や平均が正しく計算できていることと、施行の独立性が担保できていることが満足できなければ平均回帰の法則が使えなくなってしまう、ひいては利益を得られなくなってしまうからです。
直近のTickデータはbitcoincharts.comを使って以下のようにして取得します。
def get_ticks(): df_tick = pd.read_csv("http://api.bitcoincharts.com/v1/trades.csv?symbol=bitflyerJPY", header=None, parse_dates=True, names=['datetime', 'price', 'amount']) df_tick["time"] = pd.to_datetime(df_tick.datetime, unit='s').dt.tz_localize('UTC').dt.tz_convert('Asia/Tokyo') df_tick = df_tick.sort_index(ascending=False)#時系列で降順 return df_tick
アルゴリズムの中で容易に使えるようにするために関数にしています。
このように得られた直近の標準偏差を使って、現在の値段をベースに買い注文の値段を決定します。
ちなみに買い注文は現在の値段に対して1標準偏差安くしていますが、2標準偏差としても問題ありませんが、その分平均回帰する確率が大きくなるため利確しやすくなる反面、当然ですが、買い注文そのものが約定しにくくなります。
逆に現値に対する乖離を小さくするほど買い注文が約定しやすくなる反面、利確しづらくなります。
先ほどの正規分布を仮定した際の標準偏差が含まれる34.1%の数字をどう捉えるかという問題になりますが、今回は1標準偏差として置いています。
おいおいこのパラメータを動的に変えることでどんな影響があるのか、最適化できるのかについて調べてみたいと思います。
売り注文についても同様に買い注文同様、1標準偏差と置いてもいいのですが、ロングポジションを持ってしまう分リスクを取っているため、より利確しやすいよう売りの指値は約定金額から0.5標準偏差だけ高く設定します。
当然、この売り注文のパラメータも最適化要素の一つです。
ここまできたらあとはこの値段で指値注文を実行して、前回のフローチャートに従って売買するだけです。
次回に続きます。
↓ポチっと押して頂けるととても喜びます。
続き↓
この記事を読んだ人は以下も読んでいます...

パウエル五郎

最新記事 by パウエル五郎 (全て見る)
- 【ポストコロナの世界】様々な民主化の流れが加速する - 2020年4月25日
- コロナを受け保有銘柄の入れ替えを行う - 2020年4月23日
- コロナを受けてポートフォリオ戦略を変更する! - 2020年4月22日