この誤差は何?
EAの中で平均足を計算するコードを作成し、動作チェックを行いました。具体的には、EAで計算した平均足の値と、MT5のHeiken_Ashiインディケーターがデータウィンドウに表示した値を比較しました。
(備考)MT5においては、Heikin_Ashiではなく、Heiken_Ashiとなっています。
2023年のヒストリカルデータから生成したGBPUSDの15分足チャートを使って比較したところ、場合によって1ポイントの誤差が生じていることに気づきました。
// EAから出力した値 2023.10.31 22:45 close = 1.21531 2023.10.31 23:00 close = 1.21511 // Heiken_Ashiインディケーターがデータウィンドウに表示した値 2023.10.31 22:45 close = 1.21531 2023.10.31 23:00 close = 1.21512
23:00の行を見ると、EAから出力した値とHeiken_Ashiインディケーターがデータウィンドウに表示した値が異なっています。
切上げも四捨五入もされていない?
平均足の終値は、その足の4値(始値、高値、安値、終値)の平均値です。そこで、23:00の4値を調べて、電卓で計算してみました。計算結果は「1.215115」でした。
この結果を見た時は「MT5のHeiken_Ashiインディケーターでは、小数点第6位を見て切上げまたは四捨五入を行っている」と考えました。
しかし、そうではありませんでした。
22:45のローソク足の4値を元に平均値を電卓で計算したら、結果は「1.215315」でした。もしMT5のHeiken_Ashiインディケーターが切上げまたは四捨五入を行っているのなら、データウィンドウに表示される値は「1.21532」となるはずです。しかし、データウィンドウに表示されている値は以下のとおりでした。
// Heiken_Ashiインディケーターがデータウィンドウに表示した値 2023.10.31 22:45 close = 1.21531
これを見ると、切上げも四捨五入もされていません。
以下は、電卓で計算した値です。
// 4値を元に電卓で計算した値 2023.10.31 22:45 close = 1.215315 2023.10.31 23:00 close = 1.215115
4値の中身に問題は無し
念のため4値の中身も調べました。私がEAで計算する際に用いた4値と、MT5のHeiken_Ashiインディケーターが計算するのに用いた4値との間に誤差があるのだろうか、と。
しかし、Print文を用いて出力したログを見ると、EAの計算でもHeiken_Ashiインディケーターの計算でも同じ4値が使用されていました。
ついでに書いておきますと、データを出力する際にはDoubleToString(値, _Digits)を使用していました。このためGBPUSDの場合、小数点第5位までしか表示されません。
もし4値データに小数点第6位や第7位が存在する場合、それらが計算結果に影響を与えた可能性があります。
そこで、この実験に使用したヒストリカルデータをチェックしました。しかし、始値、高値、安値、終値のデータはいずれも小数点第5位までで、第6位以下は存在しませんでした。
実験したこと
Heiken_Ashiインディケーターのコードを見たところ、「切上げ、切捨て、四捨五入」といった処理を行っているようには見えなかったので、バッファに入れる数値によって出力される結果が変わっているのかなと想像しました。
Heiken_Ashiインディケーターのコードには以下の部分があります。
double ha_open = (ExtOBuffer[i - 1] + ExtCBuffer[i - 1]) / 2; double ha_close = (open[i] + high[i] + low[i] + close[i]) / 4; double ha_high = MathMax(high[i], MathMax(ha_open, ha_close)); double ha_low = MathMin(low[i], MathMin(ha_open, ha_close)); ExtLBuffer[i] = ha_low; ExtHBuffer[i] = ha_high; ExtOBuffer[i] = ha_open; ExtCBuffer[i] = ha_close;
このうち、最後の4行の右辺を(変数ではなく)具体的な数値に置き換えて、データウィンドウに表示される値を見てみました。
// パターンA 小数点第6位は全て5で、第5位を1~4とした場合 ExtOBuffer[i] = 1.215115; → 1.21512 切上げ or 四捨五入? ExtHBuffer[i] = 1.215125; → 1.21513 切上げ or 四捨五入? ExtLBuffer[i] = 1.215135; → 1.21514 切上げ or 四捨五入? ExtCBuffer[i] = 1.215145; → 1.21514 切捨て? // パターンB 小数点第5位・6位は全て15で、第4位を1~8とした場合 ExtOBuffer[i] = 1.215115; → 1.21512 切上げ or 四捨五入? ExtHBuffer[i] = 1.215215; → 1.21522 切上げ or 四捨五入? ExtLBuffer[i] = 1.215315; → 1.21531 切捨て? ExtCBuffer[i] = 1.215415; → 1.21541 切捨て? ExtOBuffer[i] = 1.215515; → 1.21551 切捨て? ExtHBuffer[i] = 1.215615; → 1.21561 切捨て? ExtLBuffer[i] = 1.215715; → 1.21572 切上げ or 四捨五入? ExtCBuffer[i] = 1.215815; → 1.21582 切上げ or 四捨五入?
矢印より右側の数値がデータウィンドウに表示された値です。
いずれも小数点第5位がどのように変化するのかをチェックしました。
パターンAを見ると、小数点第6位が全て同じ値にも関わらず、第5位に生じる影響が一貫していません。
パターンBでは、第6位を全て5、第5位を全て1にして、第4位を変化させてみました。しかし、こちらにも一貫性が無いように見えます。
念のため、代入先のバッファを入れ替えてみました(たとえば、ExtOBufferに代入する代わりに、ExtCBufferに代入)。しかし、代入先バッファが異なることによる影響は無さそうでした。
よって、どんな数値を代入するかによって結果が変わることは間違いなさそうですが、そこにどんな規則性があるのかは不明です。
もしかしたら、10進法で考えるのではなく、ビット演算など他の次元で考えたら答えが得られるかもしれませんが、自分にはその技量がありません(汗)。