前の記事で、相場の進行方向の判定方法を紹介しました。
確かに通常であれば、分毎にデータを更新して、方向判定でも良いのですが、急激な乱高下相場変動の場合、ダイナミックに対応できなくなります。
特に重大発表前後の相場、数百Pipsの変動を数十秒の間に一気に変わることがあります。
この場合、等時間間隔の更新は、遅れます。
この極端なシーンにEAの有効性、安全性が問われます。
元々、方向の変更は上下座標の変更が評価対象で、時間とは無関係です。
この意味ではiOpen, iCloseなど時間軸をベースに上下座標を取り入れても、指定時間外の変動が反映されないから、問題です。
それを解決するには、ダイナミックにカレントの相場(Ask, Bid)を取り入れる必要があります。
そうすると、OnTickでAsk, Bidを関数GeneralManager_UpdateDirectionに渡す必要があります。
void GeneralManager_UpdateDirection(const double ask, const double bid) export
{
//static int count = 0; // Test code.
double currDir = 0;
double s1 = 0, s2 = 0;
//count += 1; // Test code.
//if (count < 200) // Test code.
//{ // Test code.
// Update direction data.
avgX = 0;
for (int i = MOVING_AVERAGE_N - 1; i > 0; i--)
{
// i = 0:newest close value, MOVING_AVERAGE_N-1:oldest value.
closeValue[i] = closeValue[i-1];
// Sum xi.
avgX += closeValue[i];
//Print("The close value of ", i, " minutes ago is ", DoubleToStr(closeValue[i], Digits));
}
closeValue[0] = (ask + bid) / 2;
avgX += closeValue[0];
// Average xi, yi.
avgX = avgX / MOVING_AVERAGE_N;
for (int i = 0; i < MOVING_AVERAGE_N; i++)
{
// sum[1~n]((xi-x)*(yi-y))
s1 += (closeValue[i] - avgX) * (y[i] - avgY);
// sum[1~n]((xi-x)^2)
s2 += (closeValue[i] - avgX) * (closeValue[i] - avgX);
}
// a = sum[1~n]((xi-x)*(yi-y)) / sum[1~n]((xi-x)^2)
if (s1 / s2 > 0)
{
// a > 0, but the data are reversed, so the gradient is a minus value.
currDirection = DIRECTION_DN;
//Print(__FUNCTION__, ", Current direction is Down. Line:", __LINE__);
} else {
// a < 0, but the data are reversed, so the gradient is a plus value.
currDirection = DIRECTION_UP;
//Print(__FUNCTION__, ", Current direction is Up. Line:", __LINE__);
}
//} // Test code.
}
これでは方向の判定計算はダイナミックに行えることになります。
一方で、一個前の記事で、次のコメントがあります。
「※「if (minute != Minute())」にガードしているのは頻繁な実行を抑えるために、分ペースでチェックしています。」
これは分ペースで方向判定を行う設計の出発点でした。
しかし、OnTickの場合、ご存知のように、1秒間で相場の変動により数回も呼ばれることがあります。
そうなると、何もガードがなければ、OnTickが呼ばれる度にGeneralManager_UpdateDirectionを実行させる場合、元々の設計では1分間で1回の呼び出しに対して、100回以上の数100回も呼び出しがされることがあり得ることになります。
それを防ぐため、一定間隔の相場変動が発生されてから、方向判定計算に移るように制御する必要があります。
それを次回にしましょう。
コメント