なぜそんなことを考える
実際の取引のイメージを練習しようとした場合、過去のデータを使って試してみるというのは一つの方法だろう。ただ、入手できるデータというのは大体日足データであるので、始値か引値で取引するというような単純な仮定しか置けない。ここを日足を再現しつつも日中の値動きを仮想的にシミュレーションすることができれば、もう少し違った仮定の取引を試すことができるかもしれない。
また、現実的な為替レートの値動きを再現したい場合に、ランダムウォークでは不十分な部分もあり、過去データを使ったシミュレーションをすることでよりリアリティのある価格の動きを作ることができるかもしれない。特に複数の通貨を同時にシミュレーションするといった場合、ランダムウォークで現実味のあるシミュレーションを生成するのは容易ではないだろう。これを日足を再現するシミュレーションができれば、より現実的な相関(値動きの連動性)を持ったシミュレーションを行うことができる。という意味で、結構重要な研究課題なのである。
Brownian Bridge
始点の値と終点の値が決まっているランダムウォークのことをBrownian Bridgeという。始点と終点の値が0固定の Brownian Bridgeを式で表すと、独立な正規分布に従う乱数を\(\small \epsilon_1, \epsilon_2,\cdots, \epsilon_n\)とすれば、$$\small b_i = b_{i-1}+\epsilon_i-\frac{1}{n} \sum_{j=1}^n \epsilon_j = \sum_{j=1}^i \epsilon_j-\frac{i}{n} \sum_{j=1}^n \epsilon_j $$と表すことができる。ランダムウォークと比較して第3項目が追加されている。あきらかに\(\small b_n=0 \)になることがわかるだろう。始点が\(\small x_0 \)、終点が \(\small x_n \)で指定されている時系列データの間の値をランダムにシミュレーションする場合は、トレンドが期間中一定であると仮定して$$\small x_i = x_{i-1} + \frac{1}{n} (x_{n}-x_{0})+ b_i $$とシミュレーションすればよい。これを利用することで指定された引値を通過するランダムウォークをシミュレーションすることができる。
高値と安値を通過させる方法
OHLCをそれぞれ始値、高値、安値、引値を表すものとする。高値と安値を通過させるためには、高値を付ける時点\(\small \tau_H \)と安値を付ける時点\(\small \tau_L \)を定めてあげれば、3つのBrownian Bridgeをつなげることで高値、安値、引値を通過するランダムウォークを生成することができる。問題はいかにそれっぽい\(\small \tau_H \)と\(\small \tau_L \)を決定するかだろう。いくつか満たすべき性質を列挙すると
- 始値が安値に近いほど、高値から遠いほど、安値は前半側である確率が高い(O-Lが小さいほど、H-Oが大きいほど\(\small \tau_L \leq \tau_H\) )。
- 引値が高値に近いほど、安値から遠いほど、安値は前半側である確率が高い(C-Lが大きいほど、H-Cが小さいほど\(\small \tau_L \leq \tau_H\) )。
- 安値=始値、または、高値=引値である場合、確率1で\(\small \tau_L \leq \tau_H\)でなければならない。
となる。上記の制約を満たすように安値と高値でどちらが先に到達するかの確率を定めると、$$ \small Pr[\tau_L\leq \tau_H] = \frac{(H-O)(C-L)}{ (H-O)(C-L)+(O-L)(H-C)} \\ \small Pr[\tau_L>\tau_H] = \frac{(O-L)(H-C)}{ (H-O)(C-L)+(O-L)(H-C) } $$と計算できる(安直!)。安直すぎるがおそらく、そこまでの違和感は生じないと予想される。
先にどちらが先に到達するかを乱数で定めてしまえば、それぞれの期待値は以下のように推定できる。\(\small \tau_L\leq \tau_H \)の場合、不確実性がない場合の変動幅の総量は、$$ \small (O-L)+(H-L)+(H-C)=2(H-L)+O-C $$であるから、価格変化の速度を一定と仮定して期待値を求めると、 $$\small E[\tau_L] = \frac{n(O-L)}{2(H-L)+O-C} \\ \small E[\tau_H] = \frac{n(O+H-2L)}{2(H-L)+O-C} $$と計算できる。同様に \(\small \tau_L>\tau_H \)の場合、 不確実性がない場合の変動幅の総量は、$$ \small (H-O)+(H-L)+(C-L)=2(H-L)-O+C $$であるから、$$\small E[\tau_H] = \frac{n(H-O)}{2(H-L)-O+C} \\ \small E[\tau_L] = \frac{n(2H-O-L)}{2(H-L)-O+C} $$と計算できる。
不確定性については、期待値が中心に近いほど分散が高く、端であるほど低いと考えられる。確率分布は正規分布が良いだろうが、範囲を\(\small [1,n-1] \)に収まるようにしたいところである。一様分布に従う乱数をいくつか振って足し合わせると範囲が有限で正規分布のような釣り鐘型(Bell Shape)の分布になることが知られている。例えば、\(\small \tau_L< \tau_H \)を仮定して$$\small \tau_L=\frac{2}{m}\sum_{i=1}^{m} E[\tau_L] u_i, \; u_i\sim U[0,1)$$と乱数を生成し結果が整数になるように切り上げれば、平均値が大体\(\small E[\tau_L] \)で定義域が\(\small [1, 2E[\tau_L]] \)の正規分布に類似した釣り鐘型の確率分布になる。\(\small u_i \)は一様乱数であり、大抵のプログラミング言語では機能として提供されているものである。
同様にして、\(\small \tau_H \)について、$$\small \tau_H = \tau_L+\frac{2}{m}\sum_{i=1}^{m} (E[\tau_H]-E[\tau_L]) u_i, \; u_i\sim U[0,1)$$と乱数を生成すればよい。\(\small \tau_L + 2 (E[\tau_H]-E[\tau_L]) > n-1 \)の場合は \( \small \delta = \frac{1}{2} (\tau_L + 2 (E[\tau_H]-E[\tau_L]) -(n-1)) \)とおいて、 $$\small \tau_H = \tau_L+\delta-\frac{1}{m}\sum_{i=1}^{m} ((n-1)-\tau_L-\delta) u_i, \; u_i\sim U[0,1)$$ と計算し結果が整数になるように切り上げれば 、期待値が大体\(\small E[\tau_H] \)かつ、\(\small n-1 \)以下の釣り鐘型の確率分布になる。一様乱数の数\(\small m \)は適当な整数を定めればよい。これが大きいほど分散が小さくなり、小さいほど大きくなる。以上により、到達時点のシミュレーションができる。
高値と安値を超えないように補正する方法
上記の方法で、高値、安値、引値を通過するランダムウォークを作ることができるが、正規乱数でシミュレーションすると、途中で高値や安値を超過してしまう経路が生成される。これは一応補正したいので、Brownian Bridgeをシミュレーションする際は、 $$\small L \leq x_i = x_{i-1}+\frac{1}{n}(x_{n}-x_{0}) + b_i \leq H$$満たすように調整する必要がある。最もシンプルな方法は上記の関係を満たすように\(\small b_i \)のスケールを調整することだろう。すなわち、すべての\(\small i\)について$$\small L \leq x_i = x_{i-1}+\frac{1}{n}(x_{n}-x_{0}) + \gamma b_i \leq H, \quad -1 \leq \gamma \leq 1 $$を満たす絶対値が最大の\(\small \gamma \)を求めればよい。この値は、\(\small \gamma = 1,-1,0.99,-0.99,0.98,-0.98,\cdots \)のように総当たりで比較して最初に範囲に収まった値を使えばよいだろう。\( \small \gamma \)が小さくなりすぎないように、絶対値が一定値(例えば、0.8)を下回ったらリサンプリングするようにするなどの工夫をすると良いだろう。L,H近傍は容易に超過するため、その場合は前後の一定期間は強制的に丸めるようにする。
まとめ
一応上記の方法で、高値、安値、引値を通過するランダムウォークのシミュレーションが実現できると考えられる。論より証拠だとと思うので、実際にシミュレーターを開発して、メニューのところにピン止めランダムウォークという名称で追加した。お試しあれ。