1. iDeMarker関数の概要と実務での活用法
iDeMarkerは、著名なテクニカルアナリストであるトム・デマーク(Tom DeMark)氏が考案した「DeMarker(デマーカー)」インジケーターの値を取得するための関数です。DeMarkerはRSIと同様に「買われすぎ・売られすぎ」を判断するオシレーター系の指標ですが、最大の特徴は「現在の期間の高値・安値を前回の期間と比較し、需要の強弱を測定する」という計算ロジックにあります。
実務での活用法
実務での開発において、DeMarkerは一般的に「0.7以上なら買われすぎ(反転売り)」「0.3以下なら売られすぎ(反転買い)」という逆張り戦略に使われます。しかし、単体で使うと強いトレンド発生時に「張り付き(ダマシ)」に遭いやすいため、クオンツの現場では以下の手法がよく取られます。
- フィルターとしての活用: 他のトレンド指標(移動平均線など)と組み合わせ、トレンド方向にのみDeMarkerの押し目・戻りを狙う。
- ダイバージェンスの検知: 価格が最高値を更新しているのにDeMarkerが更新していない場合、トレンドの終焉を予測する。
初心者の方は「関数の戻り値をそのまま価格だと思ってしまう」というミスをしやすいですが、MQL5では「ハンドル」を取得し、その後に「値をコピーする」という2段階の手順が必要である点に注意が必要です。
2. 構文と戻り値
MQL5における iDeMarker 関数の構文は以下の通りです。
構文
int iDeMarker(
string symbol, // 通貨ペア名(NULLなら現在の通貨)
ENUM_TIMEFRAMES period, // 時間足(0なら現在の時間足)
int ma_period // 平均化期間(通常は14)
);
パラメーター
- symbol: 対象とする銘柄。
_Symbolと記述すると、EAをセットしたチャートの通貨ペアになります。 - period: 対象とする時間足。
_Periodと記述すると、チャートの時間足になります。 - ma_period: 計算に用いる期間。デフォルトでは「14」が一般的です。
戻り値
- int型: 成功するとインジケーターの「ハンドル」が返されます。
- 失敗した場合は
INVALID_HANDLEが返されます。この数値は実際の指標の値ではなく、あくまで「指標データを呼び出すための整理番号」のようなものです。
3. 具体的な使い方・実践サンプルコード
以下は、DeMarkerが0.3を下回ったら買い、0.7を上回ったら売りというシンプルなロジックをベースにした、MQL5のEAサンプルコードです。
//+------------------------------------------------------------------+
//| SimpleDeMarker.mq5 |
//| Copyright 2023, Quant Engineer |
//+------------------------------------------------------------------+
#property strict
// 入力パラメーター
input int InpDeMPeriod = 14; // DeMarkerの期間
input double InpUpperLevel = 0.7; // 売りレベル
input double InpLowerLevel = 0.3; // 買いレベル
// グローバル変数
int handleDeM; // DeMarkerのハンドルを格納
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// 1. DeMarkerハンドルの作成
handleDeM = iDeMarker(_Symbol, _Period, InpDeMPeriod);
// ハンドル取得に失敗した場合の処理
if(handleDeM == INVALID_HANDLE)
{
Print("DeMarkerハンドルの作成に失敗しました。エラーコード:", GetLastError());
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
double demBuffer[]; // 値を格納するための配列
ArraySetAsSeries(demBuffer, true); // 配列を時系列順(最新がインデックス0)に設定
// 2. 指標データのコピー(最新の2本分を取得)
if(CopyBuffer(handleDeM, 0, 0, 2, demBuffer) < 0)
{
Print("データのコピーに失敗しました。");
return;
}
double currentDeM = demBuffer[0]; // 最新のDeMarker値
double prevDeM = demBuffer[1]; // 1本前のDeMarker値
// 3. ロジック判定
// 0.3を上に突き抜けたら「売られすぎからの回復」と見て買い
if(prevDeM <= InpLowerLevel && currentDeM > InpLowerLevel)
{
Print("買いシグナル発生: ", currentDeM);
// ここにオーダー送信処理を記述
}
// 0.7を下に突き抜けたら「買われすぎからの反落」と見て売り
else if(prevDeM >= InpUpperLevel && currentDeM < InpUpperLevel)
{
Print("売りシグナル発生: ", currentDeM);
// ここにオーダー送信処理を記述
}
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 使用したハンドルを解放(メモリ管理)
IndicatorRelease(handleDeM);
}
4. 使用上の注意点とよくあるエラー
① ハンドルの作成を OnTick で行わない
最も多いミスは、iDeMarker() 関数を OnTick の中で毎回呼び出すことです。ハンドル作成は負荷の高い処理であり、ティックごとに実行するとメモリを過剰に消費し、ターミナルの動作が極端に重くなります。必ず OnInit で一度だけ作成するようにしてください。
② CopyBufferの失敗
EAを起動した直後や、チャートのヒストリーデータが不足している場合、CopyBuffer は失敗します。戻り値を確認し、失敗した場合はそのティックの処理をスキップするなどのエラーハンドリングが必須です。
③ 時系列設定(ArraySetAsSeries)
MQL5の動的配列はデフォルトでは古い順([0]が最も古いデータ)になっています。FXシストレでは [0] を最新データとして扱う方が直感的であるため、必ず ArraySetAsSeries(buffer, true) を実行して時系列を反転させましょう。
5. 【重要】自動売買における約定スピードと環境の罠
アルゴリズム取引において、ロジックが完璧であっても勝てない最大の要因は「ネットワーク遅延(レイテンシ)」にあります。自宅のPCから一般的なインターネット回線を通じて自動売買を行う場合、ブローカーのサーバーとの通信に数十〜数百ミリ秒の遅延が発生します。この遅延は、DeMarkerのようなオシレーターが反転シグナルを出した瞬間の「最良価格」を逃すことを意味し、結果として大きなスリッページを招き、期待期待値を大幅に削り取ります。
プロのクオンツエンジニアが共通して認識しているのは、物理的な距離の壁です。約定スピードを極限まで高め、優位性を確保するには、ブローカーのデータセンターに物理的に近い場所に設置された「専用のVPS(仮想専用サーバー)」の活用が不可欠です。24時間稼働の安定性と低レイテンシ環境を手に入れることは、シストレ開発において手法を洗練させること以上に、利益に直結する重要な技術的基盤となります。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント