前回の記事で、もし相場のレート変化時の OnTick 関数呼び出し時に各処理のシーケンスを行うなら、頻繁な処理で計算コストが高いことを説明しました。
ここでレート変動判定に閾値を導入して、ダイナミックに相場の変化を捉えた上で、計算コストを抑える方法を紹介します。
まずはレート変動幅の定義です。
つまり、どの位のレート変動が発生したら評価を行うかの変動幅を決めます。
普通に考えれば、1〜2pipsの単位は最小で問題ないでしょう。
手動で売買を行う場合、2pipsが動いたからと言って売買しなければいけばいことはほとんどの人にとってはないのです。
売買のスプレッドもあるから、通常の手動売買の場合、3pip以上の変動でなければ、利益があっても、30円以下のもので、お勧めしません。
次は変動幅の定義です。もちろん数値の5をご自身の考えで3にするか10にするかを変えても良いでしょう。
CommonDefineHeader.mqh
#define TICK_MOVE_JUDGE_INTERVAL 5
次に、EA起動時にこの値を読み込んで、変数に格納します。
次のように、EA起動時のデータマネージャーライブラリーの初期化処理時に値を読み込んで、外部に読み出せるようにインターフェースも用意する必要があります。
DataManagerLib.mq4
int tickMovedJudgeInterval;
double tickMovedJudgeIntervalPips;
double lastAskTick;
double lastBidTick;
void DataManager_InitializeData(const int magic) export
{
tickMovedJudgeInterval = TICK_MOVE_JUDGE_INTERVAL;
tickMovedJudgeIntervalPips = tickMovedJudgeInterval * pipFloat; // USDJPY PipPoint:0.01
lastAskTick = Ask;
lastBidTick = Bid;
}
double DataManager_GetTickMoveEnoughPips(void) export
{
return tickMovedJudgeIntervalPips;
}
そして、データ部のデータを汎用部の GenenalManagerLib で利用する必要があるので、ここも初期化時に読んでおく必要があります。
GeneralManager_IsTickMovedEnough は今回の判定用目的関数です。
各部門(処理モジュール)の設計についてを遡って前の記事をご参考ください。
また、その他の変数の定義などをここで省略します。必要に応じて追加してくださDataManager_GetLastAskTick は上記データ部の lastAskTick の呼び出しで、必要に応じてそのインターフェースを追加してください。
GeneralManagerLib.mq4
void GeneralManager_InitializeData(const int magic) export
{
Print(__FUNCTION__, " Line:", __LINE__);
Common_InitializeData(magic);
DataManager_InitializeData(magic);
currDirection = DIRECTION_DN;
tickMoveEnoughPips = DataManager_GetTickMoveEnoughPips();
}
bool GeneralManager_IsTickMovedEnough(const double ask, const double bid) export
{
bool isTickMoved = false;
double gapAsk = MathAbs(ask - DataManager_GetLastAskTick());
double gapBid = MathAbs(bid - DataManager_GetLastBidTick());
if ((gapAsk > tickMoveEnoughPips) ||
(gapBid > tickMoveEnoughPips))
{
isTickMoved = true;
}
return isTickMoved;
}
最後に OnTick でこの判定関数を利用するところです。
DreamCreator.mq4
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
double ask = Ask;
double bid = Bid;
if (GeneralManager_IsTickMovedEnough(ask, bid))
{
int currDirection, prevDirection;
// Get privious direction and current direction.
prevDirection = GeneralManager_GetDirection();
GeneralManager_UpdateDirection(ask, bid);
currDirection = GeneralManager_GetDirection();
// same direction
if (currDirection == prevDirection)
{
...
...
...
}
このように、5pips(TICK_MOVE_JUDGE_INTERVAL) 以上のレート変動が発生した場合のみ、続きの全体の処理が行われるので、頻繁に無駄な判定などの処理が省かれることで、計算コストが最大限に抑止できます。
|
|
コメント