<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>自動売買を作ろう！</title>
	<atom:link href="https://mql-programing.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://mql-programing.com/</link>
	<description>MQLプログラミング学習サイト</description>
	<lastBuildDate>Wed, 01 Apr 2026 03:43:44 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://mql-programing.com/main29/wp-content/uploads/2021/02/cropped-ブログアイコン-32x32.jpg</url>
	<title>自動売買を作ろう！</title>
	<link>https://mql-programing.com/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【MQL4】iCustom関数の使い方を徹底解説！カスタムインジケーターをEAから呼び出す方法とサンプルコード</title>
		<link>https://mql-programing.com/archives/13043/%e3%80%90mql4%e3%80%91icustom%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81%e3%82%ab%e3%82%b9%e3%82%bf%e3%83%a0%e3%82%a4%e3%83%b3%e3%82%b8/</link>
		
		<dc:creator><![CDATA[朝日奈りさ]]></dc:creator>
		<pubDate>Thu, 16 Apr 2026 01:00:00 +0000</pubDate>
				<category><![CDATA[【中級編】MQLプログラムの読み方・書き方]]></category>
		<category><![CDATA[注文関係]]></category>
		<category><![CDATA[MQL4]]></category>
		<category><![CDATA[EA自動売買]]></category>
		<category><![CDATA[iCustom]]></category>
		<category><![CDATA[カスタムインジケーター]]></category>
		<category><![CDATA[サンプルコード]]></category>
		<guid isPermaLink="false">https://mql-programing.com/?p=13043</guid>

					<description><![CDATA[<p>「お気に入りのインジケーターを使って自動売買したい！」——そんな夢を叶えてくれるのが、MQL4のiCustom関数です。 iCustom関数を使えば、MT4のIndicatorsフォルダにあるカスタムインジケーターの値を [&#8230;]</p>
<p>投稿 <a href="https://mql-programing.com/archives/13043/%e3%80%90mql4%e3%80%91icustom%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81%e3%82%ab%e3%82%b9%e3%82%bf%e3%83%a0%e3%82%a4%e3%83%b3%e3%82%b8/">【MQL4】iCustom関数の使い方を徹底解説！カスタムインジケーターをEAから呼び出す方法とサンプルコード</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[<p>「お気に入りのインジケーターを使って自動売買したい！」——そんな夢を叶えてくれるのが、MQL4の<strong>iCustom関数</strong>です。</p>
<p>iCustom関数を使えば、MT4の<strong>Indicatorsフォルダにあるカスタムインジケーターの値をEA（エキスパートアドバイザー）から自由に取得</strong>できます。つまり、チャート上で矢印やラインを表示するインジケーターのシグナルを、そのまま自動売買のロジックに組み込めるのです。</p>
<p>この記事では、iCustom関数の基本的な構文から、実践的なサンプルコードまで、初心者にもわかりやすく解説していきます。</p>
<h2><span id="toc1">iCustom関数とは？</span></h2>
<p>iCustom関数は、<strong>指定したカスタムインジケーターの計算結果（バッファの値）を取得する</strong>MQL4の組み込み関数です。</p>
<p>MT4にはiMA（移動平均線）やiRSI（RSI）など、標準インジケーター用の関数が用意されていますが、自作のインジケーターやネットで配布されているインジケーターにはこうした専用関数がありません。そこで活躍するのがiCustom関数です。</p>
<p>iCustom関数を利用すると、Indicatorsフォルダに保存されているあらゆるカスタムインジケーターの値を取得できます。これにより、インジケーターのシグナルをEAのエントリー条件・決済条件として使うことが可能になります。</p>
<h2><span id="toc2">iCustom関数の構文（シンタックス）</span></h2>
<p>iCustom関数の基本構文は以下の通りです。</p>
<pre><code class="language-mql4">double iCustom(
    string symbol,      // 通貨ペア（NULLで現在のチャート）
    int    timeframe,    // 時間足（0で現在の時間足）
    string name,         // カスタムインジケーター名
    ...                  // インジケーターの入力パラメーター（可変）
    int    mode,         // バッファ番号（0〜7）
    int    shift         // 取得するバーの位置（0が最新）
);
</code></pre>
<p>各パラメーターの意味を詳しく見ていきましょう。</p>
<h3><span id="toc3">① symbol（通貨ペア）</span></h3>
<p>値を取得したい通貨ペアを文字列で指定します。現在のチャートの通貨ペアを指定する場合は <code>NULL</code> または <code>_Symbol</code> を使います。別の通貨ペアを指定したい場合は <code>"USDJPY"</code> のように気配値表示ウィンドウの表記通りに記述します。</p>
<h3><span id="toc4">② timeframe（時間足）</span></h3>
<p>時間軸の種類を指定します。現在のチャートの時間足を使う場合は <code>0</code> または <code>PERIOD_CURRENT</code> を指定します。別の時間足を指定する場合は、以下の定数を使います。</p>
<table border="1" cellpadding="6" cellspacing="0" style="border-collapse: collapse; margin: 16px 0;">
<tr style="background-color: #f0f0f0;">
<th>定数</th>
<th>値</th>
<th>意味</th>
</tr>
<tr>
<td>PERIOD_M1</td>
<td>1</td>
<td>1分足</td>
</tr>
<tr>
<td>PERIOD_M5</td>
<td>5</td>
<td>5分足</td>
</tr>
<tr>
<td>PERIOD_M15</td>
<td>15</td>
<td>15分足</td>
</tr>
<tr>
<td>PERIOD_M30</td>
<td>30</td>
<td>30分足</td>
</tr>
<tr>
<td>PERIOD_H1</td>
<td>60</td>
<td>1時間足</td>
</tr>
<tr>
<td>PERIOD_H4</td>
<td>240</td>
<td>4時間足</td>
</tr>
<tr>
<td>PERIOD_D1</td>
<td>1440</td>
<td>日足</td>
</tr>
<tr>
<td>PERIOD_W1</td>
<td>10080</td>
<td>週足</td>
</tr>
<tr>
<td>PERIOD_MN1</td>
<td>43200</td>
<td>月足</td>
</tr>
</table>
<h3><span id="toc5">③ name（インジケーター名）</span></h3>
<p>カスタムインジケーター名を文字列で指定します。指定するカスタムインジケーターの.ex4ファイルが、MQL4\Indicatorsフォルダまたはそのサブフォルダに保存されている必要があります。</p>
<p>サブディレクトリに配置されている場合は、&#8221;サブディレクトリ名\\カスタムインジケータ名&#8221;で指定します。</p>
<pre><code class="language-mql4">// Indicatorsフォルダ直下の場合
iCustom(NULL, 0, "MyIndicator", ...);

// サブフォルダ「Examples」内の場合
iCustom(NULL, 0, "Examples\\MyIndicator", ...);
</code></pre>
<h3><span id="toc6">④ &#8230;（インジケーターの入力パラメーター）</span></h3>
<p>カスタムインジケータの入力パラメータです。渡された入力パラメータの順序は、カスタムインジケータの宣言順に対応する必要があります。ここが一番混乱しやすいポイントです。</p>
<p>パラメーターを省略した場合は、インジケーター側のデフォルト値が使用されます。ただし、<strong>途中のパラメーターだけを省略することはできません</strong>。変更したいパラメーターより前のパラメーターは、すべてデフォルト値であっても記述する必要があります。</p>
<h3><span id="toc7">⑤ mode（バッファ番号）</span></h3>
<p>取得したいインジケーターバッファのインデックス番号（0〜7）を指定します。最初のバッファはmode=0です。</p>
<p>例えば、ボリンジャーバンドのようなインジケーターなら：</p>
<ul>
<li>バッファ0：ミドルバンド</li>
<li>バッファ1：アッパーバンド</li>
<li>バッファ2：ロワーバンド</li>
</ul>
<p>のように対応します。バッファ番号の確認方法は後述します。</p>
<h3><span id="toc8">⑥ shift（バーの位置）</span></h3>
<p>カスタムインジケーターの値を取得したいバーの位置を指定します。現在のバーであれば「0」、1本前のバーであれば「1」、2本前のバーであれば「2」と記述します。</p>
<p>EA内では、確定した値を使うため <code>shift=1</code>（1本前の確定バー）を指定するのが一般的です。</p>
<h2><span id="toc9">バッファ番号の調べ方</span></h2>
<p>iCustom関数を使ううえで最も重要なのが、<strong>正しいバッファ番号を知ること</strong>です。バッファ番号を間違えると、まったく違う値を取得してしまいます。</p>
<h3><span id="toc10">方法1：チャート上でマウスカーソルを合わせる</span></h3>
<p>チャート上にセットしたインジケーターのラインや矢印にマウスカーソルをのせて、Value1やValue2などという表示がでれば、iCustomでEA化できます。</p>
<h3><span id="toc11">方法2：データウィンドウで確認する</span></h3>
<p>MT4の<strong>「表示」→「データウィンドウ」</strong>を開くと、各インジケーターのバッファ値が一覧で表示されます。上から順に0, 1, 2&#8230;のバッファ番号に対応しています。</p>
<h3><span id="toc12">方法3：ソースコードを確認する</span></h3>
<p>インジケーターの.mq4ファイルがある場合は、<code>SetIndexBuffer()</code> や <code>SetIndexLabel()</code> の記述からバッファ番号を確認できます。</p>
<pre><code class="language-mql4">// ソースコードの例
SetIndexBuffer(0, UpperBuffer);  // バッファ0 → アッパーライン
SetIndexBuffer(1, LowerBuffer);  // バッファ1 → ロワーライン
SetIndexBuffer(2, BuySignal);    // バッファ2 → 買いシグナル
SetIndexBuffer(3, SellSignal);   // バッファ3 → 売りシグナル
</code></pre>
<h2><span id="toc13">基本的な使い方：サンプルコード</span></h2>
<p>ここからは、実際のサンプルコードを使って使い方を解説します。</p>
<h3><span id="toc14">サンプル1：移動平均線カスタムインジケーターの値を取得</span></h3>
<p>まずは、最もシンプルな例です。カスタムインジケーター「MyMA」の値を取得してチャートにコメント表示します。</p>
<pre><code class="language-mql4">void OnTick()
{
    // MyMAインジケーターの値を取得（期間20、バッファ0、1本前のバー）
    double ma_value = iCustom(NULL, 0, "MyMA", 20, 0, 1);
    
    // チャートにコメント表示
    Comment("MyMA(20)の値: ", DoubleToString(ma_value, Digits));
}
</code></pre>
<h3><span id="toc15">サンプル2：ボリンジャーバンドカスタムインジケーターの複数バッファを取得</span></h3>
<p>iCustom関数でボリンジャーバンドの値を取得する例です。</p>
<pre><code class="language-mql4">void OnTick()
{
    // Bandsインジケーターの各バンドを取得
    int period = 20;
    double deviation = 2.0;
    
    double upper = iCustom(NULL, 0, "Bands", period, 0, deviation, 1, 0);  // アッパーバンド（バッファ1）
    double lower = iCustom(NULL, 0, "Bands", period, 0, deviation, 2, 0);  // ロワーバンド（バッファ2）
    
    Comment("Upper: ", upper, "\nLower: ", lower);
}
</code></pre>
<h3><span id="toc16">サンプル3：矢印シグナルインジケーターでEA化する</span></h3>
<p>これが最も実践的な使い方です。買い矢印・売り矢印を表示するインジケーターのシグナルを使って自動売買するEAのサンプルです。</p>
<pre><code class="language-mql4">#property strict

// --- 入力パラメーター ---
input double Lots       = 0.01;    // ロット数
input int    MagicNumber = 12345;  // マジックナンバー
input int    StopLoss    = 50;     // ストップロス（pips）
input int    TakeProfit  = 100;    // テイクプロフィット（pips）

void OnTick()
{
    // --- カスタムインジケーターのシグナル取得 ---
    // 買いシグナル（バッファ0）と売りシグナル（バッファ1）を1本前のバーから取得
    double buySignal  = iCustom(NULL, 0, "MySignalIndicator", 0, 1);
    double sellSignal = iCustom(NULL, 0, "MySignalIndicator", 1, 1);
    
    // --- 現在のポジション数をカウント ---
    int buyCount = 0, sellCount = 0;
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
        if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
        if(OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
        if(OrderType() == OP_BUY)  buyCount++;
        if(OrderType() == OP_SELL) sellCount++;
    }
    
    // --- 買いエントリー ---
    // シグナルが EMPTY_VALUE でなければ矢印が出現している
    if(buySignal != EMPTY_VALUE && buySignal != 0 && buyCount == 0)
    {
        double sl = Ask - StopLoss * Point * 10;
        double tp = Ask + TakeProfit * Point * 10;
        int ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, sl, tp,
                               "iCustom Buy", MagicNumber, 0, clrBlue);
        if(ticket < 0)
            Print("買い注文エラー: ", GetLastError());
    }
    
    // --- 売りエントリー ---
    if(sellSignal != EMPTY_VALUE &#038;&#038; sellSignal != 0 &#038;&#038; sellCount == 0)
    {
        double sl = Bid + StopLoss * Point * 10;
        double tp = Bid - TakeProfit * Point * 10;
        int ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 3, sl, tp,
                               "iCustom Sell", MagicNumber, 0, clrRed);
        if(ticket < 0)
            Print("売り注文エラー: ", GetLastError());
    }
}
</code></pre>
<p>ポイントは、<strong>矢印が表示されていないバーでは <code>EMPTY_VALUE</code>（空の値）が返される</strong>という点です。矢印系のシグナルインジケーターをEA化する場合、この <code>EMPTY_VALUE</code> との比較がエントリー判定の基本パターンになります。</p>
<h2><span id="toc17">iCustom関数を使う際の注意点</span></h2>
<h3><span id="toc18">1. .ex4ファイルが必要</span></h3>
<p>iCustom関数が参照するのは、コンパイル済みの<strong>.ex4ファイル</strong>です。ソースコード（.mq4）だけではなく、必ずコンパイルして.ex4ファイルを生成しておきましょう。</p>
<h3><span id="toc19">2. バッファレスインジケーターには使えない</span></h3>
<p>オシレーター系のインジケーターの場合はバッファが不可欠なので問題ないのですが、メインチャートに表示される矢印系のインジケーターの場合にはバッファで処理していないことがあります。「バッファでシグナルを処理するようにプログラミングしていないこと」、これがiCustomでインジケーターをEA化できない原因です。バッファレスインジケーターはiCustomではEA化できません。</p>
<h3><span id="toc20">3. パラメーターの順序と型に注意</span></h3>
<p>入力パラメーターは<strong>インジケーターのソースコードで宣言された順番通り</strong>に指定する必要があります。順番を間違えたり、型が合わないと正しい値が返りません。</p>
<h3><span id="toc21">4. パフォーマンスを意識する</span></h3>
<p>iCustom関数は呼び出すたびに計算が実行されるため、ティックごとに何度も呼び出すとパフォーマンスが低下します。新しいバーが確定したタイミングでのみ呼び出し、データをキャッシュすると処理速度を改善できます。</p>
<pre><code class="language-mql4">// 新しいバーの判定例
static datetime lastBarTime = 0;
if(Time[0] != lastBarTime)
{
    lastBarTime = Time[0];
    // ここでiCustomを呼び出す
    double signal = iCustom(NULL, 0, "MyIndicator", 0, 1);
}
</code></pre>
<h3><span id="toc22">5. バッファ番号は0〜7の範囲</span></h3>
<p>MT4ではインジケーターバッファのインデックスは<strong>0〜7</strong>の8個までです。バッファが8個を超えるインジケーターの場合、すべての値をiCustomで取得できるとは限りません。</p>
<h2><span id="toc23">まとめ</span></h2>
<p>iCustom関数は、カスタムインジケーターのシグナルをEAに組み込むための必須関数です。この記事のポイントをまとめます。</p>
<ul>
<li><strong>iCustom関数</strong>を使えば、Indicatorsフォルダにあるカスタムインジケーターの値をEAから取得できる</li>
<li>パラメーターは「通貨ペア → 時間足 → インジケーター名 → <strong>入力パラメーター</strong> → バッファ番号 → バー位置」の順に指定する</li>
<li><strong>バッファ番号</strong>の確認は、データウィンドウやソースコードから行う</li>
<li>矢印シグナル系のインジケーターは <code>EMPTY_VALUE</code> との比較でシグナル判定する</li>
<li><strong>バッファレスインジケーター</strong>（バッファを使わずオブジェクトで描画するもの）には使えない</li>
<li>パフォーマンスのため、新しいバー確定時にのみ呼び出す工夫をすると良い</li>
</ul>
<p>まずは簡単なインジケーターから試して、iCustom関数の使い方に慣れていきましょう。シグナルインジケーターをEA化できるようになれば、自動売買の幅が大きく広がりますよ！</p>
<p>投稿 <a href="https://mql-programing.com/archives/13043/%e3%80%90mql4%e3%80%91icustom%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81%e3%82%ab%e3%82%b9%e3%82%bf%e3%83%a0%e3%82%a4%e3%83%b3%e3%82%b8/">【MQL4】iCustom関数の使い方を徹底解説！カスタムインジケーターをEAから呼び出す方法とサンプルコード</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【MQL4】iWPR関数の使い方を徹底解説！ウィリアムズ%Rでエントリーシグナルを作ろう</title>
		<link>https://mql-programing.com/archives/13040/%e3%80%90mql4%e3%80%91iwpr%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81%e3%82%a6%e3%82%a3%e3%83%aa%e3%82%a2%e3%83%a0%e3%82%bar%e3%81%a7/</link>
		
		<dc:creator><![CDATA[朝日奈りさ]]></dc:creator>
		<pubDate>Wed, 15 Apr 2026 01:00:00 +0000</pubDate>
				<category><![CDATA[【中級編】MQLプログラムの読み方・書き方]]></category>
		<category><![CDATA[注文関係]]></category>
		<category><![CDATA[ウィリアムズ%R]]></category>
		<category><![CDATA[MQL4]]></category>
		<category><![CDATA[EA開発]]></category>
		<category><![CDATA[テクニカルインジケーター]]></category>
		<category><![CDATA[iWPR]]></category>
		<guid isPermaLink="false">https://mql-programing.com/?p=13040</guid>

					<description><![CDATA[<p>「ウィリアムズ%R（Williams&#8217; Percent Range）」というインジケーターをご存知ですか？これはラリー・ウィリアムズ氏が考案したオシレーター系テクニカル指標で、相場の「買われすぎ」「売られすぎ [&#8230;]</p>
<p>投稿 <a href="https://mql-programing.com/archives/13040/%e3%80%90mql4%e3%80%91iwpr%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81%e3%82%a6%e3%82%a3%e3%83%aa%e3%82%a2%e3%83%a0%e3%82%bar%e3%81%a7/">【MQL4】iWPR関数の使い方を徹底解説！ウィリアムズ%Rでエントリーシグナルを作ろう</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[<p>「ウィリアムズ%R（Williams&#8217; Percent Range）」というインジケーターをご存知ですか？これはラリー・ウィリアムズ氏が考案した<strong>オシレーター系テクニカル指標</strong>で、相場の「買われすぎ」「売られすぎ」を判断するのにとても便利なツールです。</p>
<p>MQL4では<strong>iWPR関数</strong>を使うことで、このウィリアムズ%Rの値を簡単に取得できます。この記事では、iWPR関数の基本的な使い方から、実践的なEA（自動売買）への応用まで、段階的にわかりやすく解説していきます。</p>
<h2><span id="toc1">ウィリアムズ%Rとは？</span></h2>
<p>ウィリアムズ%Rは、一定期間における最高値と最安値の範囲のなかで、現在の終値がどの位置にあるかをパーセンテージで示す指標です。</p>
<h3><span id="toc2">計算式</span></h3>
<p>ウィリアムズ%Rの計算式は以下のとおりです。</p>
<pre><code class="language-mql4">// ウィリアムズ%Rの計算式（概念）
// %R = (期間内の最高値 - 現在の終値) / (期間内の最高値 - 期間内の最安値) × (-100)
</code></pre>
<p>この計算により、値は常に<strong>0 ～ -100</strong>の範囲で推移します。ここが他のオシレーターと少し違うポイントで、値がマイナスの範囲で動くことを覚えておきましょう。</p>
<h3><span id="toc3">値の見方</span></h3>
<ul>
<li><strong>0 に近い（-20より上）</strong>：買われすぎゾーン → 売りシグナルの候補</li>
<li><strong>-100 に近い（-80より下）</strong>：売られすぎゾーン → 買いシグナルの候補</li>
<li><strong>-50 付近</strong>：中立的な状態</li>
</ul>
<p>ストキャスティクスと非常に似た性質を持っていますが、ウィリアムズ%Rはスケールが反転している点が特徴です。ストキャスティクスでは値が高いほど買われすぎですが、ウィリアムズ%Rでは値が0に近いほど買われすぎとなります。</p>
<h2><span id="toc4">iWPR関数の構文</span></h2>
<p>MQL4でウィリアムズ%Rの値を取得するには、<strong>iWPR関数</strong>を使います。構文は以下のとおりです。</p>
<pre><code class="language-mql4">double iWPR(
    string symbol,      // 通貨ペア名
    int    timeframe,   // 時間足
    int    period,      // 計算期間
    int    shift        // シフト（何本前のバーか）
);
</code></pre>
<h3><span id="toc5">引数の詳細</span></h3>
<table>
<thead>
<tr>
<th>引数</th>
<th>型</th>
<th>説明</th>
<th>例</th>
</tr>
</thead>
<tbody>
<tr>
<td>symbol</td>
<td>string</td>
<td>通貨ペア名。NULLで現在のチャート</td>
<td>NULL, &#8220;USDJPY&#8221;</td>
</tr>
<tr>
<td>timeframe</td>
<td>int</td>
<td>時間足の定数。0で現在の時間足</td>
<td>0, PERIOD_H1</td>
</tr>
<tr>
<td>period</td>
<td>int</td>
<td>計算に使うバーの本数</td>
<td>14</td>
</tr>
<tr>
<td>shift</td>
<td>int</td>
<td>取得するバーの位置（0が最新）</td>
<td>0, 1</td>
</tr>
</tbody>
</table>
<p><strong>戻り値</strong>はdouble型で、0 ～ -100 の範囲の値が返されます。</p>
<h2><span id="toc6">基本的な使い方</span></h2>
<p>まずは、iWPR関数で値を取得してログに出力するシンプルな例を見てみましょう。</p>
<pre><code class="language-mql4">void OnTick()
{
    // 現在のチャート、現在の時間足、期間14、1本前の確定バーのウィリアムズ%Rを取得
    double wpr = iWPR(NULL, 0, 14, 1);

    // エキスパートログに出力
    Print("Williams %%R (1本前) = ", DoubleToString(wpr, 2));

    // 買われすぎ・売られすぎの判定
    if(wpr > -20)
    {
        Print("→ 買われすぎゾーン");
    }
    else if(wpr < -80)
    {
        Print("→ 売られすぎゾーン");
    }
    else
    {
        Print("→ 中立ゾーン");
    }
}
</code></pre>
<p>ここで<strong>shift に 1 を指定</strong>している点がポイントです。shift=0 だと現在まだ形成中のバーの値を取得してしまい、リアルタイムで値が変動します。EA開発では、確定したバー（shift=1）の値を使うのが基本です。</p>
<h2><span id="toc7">サンプル①：買われすぎ・売られすぎの状態をチャートに表示する</span></h2>
<p>次に、ウィリアムズ%Rの状態をチャートのコメントとしてリアルタイム表示するコードを作ってみましょう。</p>
<pre><code class="language-mql4">// ウィリアムズ%Rの状態表示スクリプト
extern int WPR_Period = 14;          // 計算期間
extern double OverBought = -20.0;    // 買われすぎライン
extern double OverSold   = -80.0;    // 売られすぎライン

void OnTick()
{
    double wprCurrent = iWPR(NULL, 0, WPR_Period, 0);
    double wprPrev    = iWPR(NULL, 0, WPR_Period, 1);

    string status = "";

    if(wprPrev > OverBought)
        status = "★ 買われすぎゾーン（売りに注目）";
    else if(wprPrev < OverSold)
        status = "★ 売られすぎゾーン（買いに注目）";
    else
        status = "― 中立ゾーン";

    Comment(
        "===== Williams %R Monitor =====\n",
        "期間: ", WPR_Period, "\n",
        "現在値 (形成中): ", DoubleToString(wprCurrent, 2), "\n",
        "確定値 (1本前) : ", DoubleToString(wprPrev, 2), "\n",
        "状態: ", status, "\n",
        "================================"
    );
}
</code></pre>
<p>このコードをEAとしてチャートにセットすると、左上にウィリアムズ%Rの値と状態がリアルタイムで表示されます。動きを観察しながら指標の特性を学ぶのに最適です。</p>
<h2><span id="toc8">サンプル②：ゾーン脱出型シグナルのシンプルEA</span></h2>
<p>ウィリアムズ%Rを使ったEAを作る際、単純に「-80以下で買い」とするとダマシが多くなります。そこで、<strong>ゾーン脱出型</strong>の考え方を取り入れます。</p>
<p>ゾーン脱出型とは、以下のようなロジックです。</p>
<ul>
<li><strong>買いシグナル</strong>：売られすぎゾーン（-80以下）に入った後、-80を上回って脱出したとき</li>
<li><strong>売りシグナル</strong>：買われすぎゾーン（-20以上）に入った後、-20を下回って脱出したとき</li>
</ul>
<p>これにより、ゾーン内に張り付いたまま反転しないケースのダマシを軽減できます。</p>
<pre><code class="language-mql4">// ゾーン脱出型 ウィリアムズ%R EA
extern int    WPR_Period  = 14;
extern double LotSize     = 0.01;
extern double OverBought  = -20.0;
extern double OverSold    = -80.0;
extern int    StopLoss    = 100;     // ストップロス（pips）
extern int    TakeProfit  = 200;     // テイクプロフィット（pips）
extern int    MagicNumber = 12345;

void OnTick()
{
    // 新しいバーが確定したときだけ処理する
    static datetime lastBarTime = 0;
    if(Time[0] == lastBarTime) return;
    lastBarTime = Time[0];

    // 確定バーと、その1つ前のバーのウィリアムズ%Rを取得
    double wpr1 = iWPR(NULL, 0, WPR_Period, 1);  // 直近の確定バー
    double wpr2 = iWPR(NULL, 0, WPR_Period, 2);  // その1つ前

    // 既存ポジションの確認
    int posCount = 0;
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
            if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
                posCount++;
        }
    }

    // ポジションがない場合のみエントリー判定
    if(posCount > 0) return;

    double sl, tp;

    // 買いシグナル：売られすぎゾーンから脱出
    if(wpr2 < OverSold &#038;&#038; wpr1 >= OverSold)
    {
        sl = Ask - StopLoss * Point * 10;
        tp = Ask + TakeProfit * Point * 10;
        int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, sl, tp,
                               "WPR Buy Signal", MagicNumber, 0, clrBlue);
        if(ticket > 0)
            Print("買いエントリー: WPR=", DoubleToString(wpr1, 2));
        else
            Print("買い注文エラー: ", GetLastError());
    }

    // 売りシグナル：買われすぎゾーンから脱出
    if(wpr2 > OverBought && wpr1 <= OverBought)
    {
        sl = Bid + StopLoss * Point * 10;
        tp = Bid - TakeProfit * Point * 10;
        int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, sl, tp,
                               "WPR Sell Signal", MagicNumber, 0, clrRed);
        if(ticket > 0)
            Print("売りエントリー: WPR=", DoubleToString(wpr1, 2));
        else
            Print("売り注文エラー: ", GetLastError());
    }
}
</code></pre>
<p>このEAのポイントは以下のとおりです。</p>
<ul>
<li><strong>新しいバー確定時のみ判定</strong>：static変数でバーの時刻を管理し、同じバーで何度も判定しない</li>
<li><strong>ゾーン脱出の判定</strong>：2本前がゾーン内、1本前がゾーン外になったことで「脱出」を検知</li>
<li><strong>ポジション制限</strong>：同時に1ポジションのみ持つようにしている</li>
</ul>
<h2><span id="toc9">サンプル③：移動平均線との組み合わせ（トレンドフィルター付きEA）</span></h2>
<p>オシレーター系指標の弱点は、<strong>強いトレンドが発生している局面</strong>では買われすぎ・売られすぎの状態が長く続き、シグナルが機能しにくいことです。</p>
<p>これを改善するために、<strong>移動平均線によるトレンドフィルター</strong>を追加したEAを作ってみましょう。</p>
<pre><code class="language-mql4">// トレンドフィルター付き ウィリアムズ%R EA
extern int    WPR_Period  = 14;
extern int    MA_Period   = 50;      // 移動平均線の期間
extern int    MA_Method   = MODE_SMA; // 移動平均の種類
extern double LotSize     = 0.01;
extern double OverBought  = -20.0;
extern double OverSold    = -80.0;
extern int    StopLoss    = 100;
extern int    TakeProfit  = 200;
extern int    MagicNumber = 12346;

void OnTick()
{
    // 新しいバー確定時のみ処理
    static datetime lastBarTime = 0;
    if(Time[0] == lastBarTime) return;
    lastBarTime = Time[0];

    // ウィリアムズ%Rの値を取得
    double wpr1 = iWPR(NULL, 0, WPR_Period, 1);
    double wpr2 = iWPR(NULL, 0, WPR_Period, 2);

    // 移動平均線の値を取得
    double ma1 = iMA(NULL, 0, MA_Period, 0, MA_Method, PRICE_CLOSE, 1);

    // 現在の価格と移動平均線の位置関係でトレンドを判定
    double closePrice = Close[1];
    bool isUpTrend   = (closePrice > ma1);  // 上昇トレンド
    bool isDownTrend = (closePrice < ma1);  // 下降トレンド

    // 既存ポジションの確認
    int posCount = 0;
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
            if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
                posCount++;
        }
    }

    if(posCount > 0) return;

    double sl, tp;

    // 買いシグナル：上昇トレンド中 + 売られすぎゾーンから脱出
    if(isUpTrend && wpr2 < OverSold &#038;&#038; wpr1 >= OverSold)
    {
        sl = Ask - StopLoss * Point * 10;
        tp = Ask + TakeProfit * Point * 10;
        int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, sl, tp,
                               "WPR+MA Buy", MagicNumber, 0, clrBlue);
        if(ticket > 0)
            Print("買いエントリー（トレンドフィルター付き）: WPR=",
                  DoubleToString(wpr1, 2), " MA=", DoubleToString(ma1, 5));
    }

    // 売りシグナル：下降トレンド中 + 買われすぎゾーンから脱出
    if(isDownTrend && wpr2 > OverBought && wpr1 <= OverBought)
    {
        sl = Bid + StopLoss * Point * 10;
        tp = Bid - TakeProfit * Point * 10;
        int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, sl, tp,
                               "WPR+MA Sell", MagicNumber, 0, clrRed);
        if(ticket > 0)
            Print("売りエントリー（トレンドフィルター付き）: WPR=",
                  DoubleToString(wpr1, 2), " MA=", DoubleToString(ma1, 5));
    }
}
</code></pre>
<p>このEAでは、以下のフィルタリングを行っています。</p>
<ul>
<li><strong>買いエントリー</strong>：価格が移動平均線より上（上昇トレンド）のときだけ、売られすぎからの脱出シグナルを採用</li>
<li><strong>売りエントリー</strong>：価格が移動平均線より下（下降トレンド）のときだけ、買われすぎからの脱出シグナルを採用</li>
</ul>
<p>こうすることで、<strong>トレンド方向と逆行するエントリーを防ぎ</strong>、勝率の向上が期待できます。</p>
<h2><span id="toc10">iWPR関数を使う際の注意点</span></h2>
<h3><span id="toc11">1. 値の範囲はマイナスである</span></h3>
<p>ウィリアムズ%Rの値は<strong>0 ～ -100</strong>です。RSIのように0～100ではないので、条件式を書くときに符号を間違えないよう注意してください。例えば「-80以下」は <code>wpr &lt; -80</code> と書きます。</p>
<h3><span id="toc12">2. トレーディングスタイルに合わせた期間設定</span></h3>
<p>ウィリアムズ%Rの計算期間は、トレーディングスタイルに合わせて調整するのがおすすめです。</p>
<table>
<thead>
<tr>
<th>スタイル</th>
<th>推奨期間</th>
<th>特徴</th>
</tr>
</thead>
<tbody>
<tr>
<td>スキャルピング</td>
<td>7</td>
<td>シグナルが敏感、ダマシも多い</td>
</tr>
<tr>
<td>デイトレード</td>
<td>14</td>
<td>バランスが良い（デフォルト）</td>
</tr>
<tr>
<td>スイングトレード</td>
<td>21〜28</td>
<td>シグナルは少ないが信頼性が高い</td>
</tr>
</tbody>
</table>
<h3><span id="toc13">3. 強いトレンド相場には注意</span></h3>
<p>オシレーター系指標全般に言えることですが、強い上昇トレンドや下降トレンドでは、ウィリアムズ%Rが買われすぎ・売られすぎゾーンに張り付いたまま動かないことがあります。このような場合、逆張りシグナルが機能しません。サンプル③のように<strong>トレンドフィルターと組み合わせる</strong>ことを強くおすすめします。</p>
<h3><span id="toc14">4. 確定バーの値を使う</span></h3>
<p>EA開発では、形成中のバー（shift=0）ではなく、<strong>確定したバー（shift=1以上）の値を使う</strong>のが鉄則です。形成中のバーの値はティックごとに変動するため、シグナルがチラつく原因になります。</p>
<h2><span id="toc15">まとめ</span></h2>
<p>この記事では、MQL4のiWPR関数を使ってウィリアムズ%Rの値を取得し、EA開発に活用する方法を解説しました。最後にポイントをおさらいしましょう。</p>
<ul>
<li><strong>iWPR関数</strong>は4つの引数（symbol, timeframe, period, shift）を指定してウィリアムズ%Rの値を取得する</li>
<li>値の範囲は<strong>0 ～ -100</strong>で、-20以上が買われすぎ、-80以下が売られすぎ</li>
<li><strong>ゾーン脱出型</strong>のシグナルにすることで、単純なゾーン判定よりダマシを軽減できる</li>
<li><strong>移動平均線などのトレンドフィルター</strong>と組み合わせることで、さらに精度を高められる</li>
<li>EA開発では必ず<strong>確定バー（shift=1）</strong>の値を使うこと</li>
</ul>
<p>ウィリアムズ%Rはシンプルな指標ですが、正しく使えばエントリーポイントの精度を上げる強力な武器になります。まずはサンプルコードをストラテジーテスターで動かして、動作を確認するところから始めてみてください！</p>
<p>投稿 <a href="https://mql-programing.com/archives/13040/%e3%80%90mql4%e3%80%91iwpr%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81%e3%82%a6%e3%82%a3%e3%83%aa%e3%82%a2%e3%83%a0%e3%82%bar%e3%81%a7/">【MQL4】iWPR関数の使い方を徹底解説！ウィリアムズ%Rでエントリーシグナルを作ろう</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【MQL4入門】iMomentum関数の使い方を徹底解説！モメンタムで相場の勢いを判定するEAを作ろう</title>
		<link>https://mql-programing.com/archives/13037/%e3%80%90mql4%e5%85%a5%e9%96%80%e3%80%91imomentum%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81%e3%83%a2%e3%83%a1%e3%83%b3%e3%82%bf/</link>
		
		<dc:creator><![CDATA[朝日奈りさ]]></dc:creator>
		<pubDate>Tue, 14 Apr 2026 01:00:00 +0000</pubDate>
				<category><![CDATA[【初級編】MQLプログラミング基礎]]></category>
		<category><![CDATA[テクニカル指標]]></category>
		<category><![CDATA[EA自動売買]]></category>
		<category><![CDATA[iMomentum]]></category>
		<category><![CDATA[モメンタム]]></category>
		<category><![CDATA[MQL4]]></category>
		<guid isPermaLink="false">https://mql-programing.com/?p=13037</guid>

					<description><![CDATA[<p>「相場の勢いが強いのか弱いのか、数値で判断できたらいいのに…」と思ったことはありませんか？そんなときに役立つのがモメンタム（Momentum）というテクニカル指標です。 MQL4には、モメンタムの値を簡単に取得できるiM [&#8230;]</p>
<p>投稿 <a href="https://mql-programing.com/archives/13037/%e3%80%90mql4%e5%85%a5%e9%96%80%e3%80%91imomentum%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81%e3%83%a2%e3%83%a1%e3%83%b3%e3%82%bf/">【MQL4入門】iMomentum関数の使い方を徹底解説！モメンタムで相場の勢いを判定するEAを作ろう</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[<p>「相場の勢いが強いのか弱いのか、数値で判断できたらいいのに…」と思ったことはありませんか？そんなときに役立つのが<strong>モメンタム（Momentum）</strong>というテクニカル指標です。</p>
<p>MQL4には、モメンタムの値を簡単に取得できる<strong>iMomentum関数</strong>が用意されています。この記事では、iMomentum関数の基本的な使い方から、実際にコピペで動くEAサンプルまで、初心者の方にもわかりやすく徹底解説します。</p>
<h2><span id="toc1">モメンタムとは？相場の「勢い」を測る指標</span></h2>
<p>モメンタム（Momentum）は、現在の価格と過去の価格の差を見ることで、<strong>相場の勢い（速度）</strong>を測るテクニカル指標です。MetaTraderのモメンタムは、差ではなく比率（パーセンテージ）で表現されます。</p>
<h3><span id="toc2">計算式</span></h3>
<p>MetaTraderにおけるモメンタムの計算式は以下のとおりです。</p>
<pre><code class="language-mql5">Momentum = (現在の終値 ÷ N期間前の終値) × 100
</code></pre>
<p>たとえば期間を14に設定した場合、現在の終値と14本前の終値を比較します。</p>
<h3><span id="toc3">100ラインの見方</span></h3>
<p>モメンタムの基準値は<strong>100</strong>です。以下のように判断します。</p>
<ul>
<li><strong>100より上</strong>：現在の価格がN期間前より高い → 上昇の勢いがある</li>
<li><strong>100より下</strong>：現在の価格がN期間前より低い → 下降の勢いがある</li>
<li><strong>100ちょうど</strong>：N期間前と同じ価格 → 勢いがない</li>
</ul>
<p>つまり、モメンタムが100ラインを上抜けたら「上昇の勢いが出てきた」、下抜けたら「下降の勢いが出てきた」と判断できるわけです。</p>
<h2><span id="toc4">iMomentum関数の構文と引数</span></h2>
<p>MQL4でモメンタムの値を取得するには、<strong>iMomentum関数</strong>を使います。構文は以下のとおりです。</p>
<pre><code class="language-mql4">double iMomentum(
   string       symbol,          // 通貨ペア名
   int          timeframe,       // 時間軸
   int          mom_period,      // モメンタムの期間
   int          applied_price,   // 適用価格
   int          shift            // シフト（何本前のバーか）
);
</code></pre>
<p>それぞれの引数を詳しく見ていきましょう。</p>
<h3><span id="toc5">第1引数：symbol（通貨ペア名）</span></h3>
<p>モメンタムを計算する通貨ペアを文字列で指定します。現在のチャートの通貨ペアを使う場合は、<code>NULL</code> または <code>Symbol()</code> を指定します。</p>
<h3><span id="toc6">第2引数：timeframe（時間軸）</span></h3>
<p>どの時間軸のデータを使うかを指定します。現在のチャートの時間軸を使う場合は <code>0</code> または <code>PERIOD_CURRENT</code> を指定します。主な定数は以下のとおりです。</p>
<ul>
<li><code>PERIOD_M1</code>：1分足</li>
<li><code>PERIOD_M5</code>：5分足</li>
<li><code>PERIOD_M15</code>：15分足</li>
<li><code>PERIOD_M30</code>：30分足</li>
<li><code>PERIOD_H1</code>：1時間足</li>
<li><code>PERIOD_H4</code>：4時間足</li>
<li><code>PERIOD_D1</code>：日足</li>
<li><code>PERIOD_W1</code>：週足</li>
</ul>
<h3><span id="toc7">第3引数：mom_period（期間）</span></h3>
<p>モメンタムの計算期間です。一般的には<strong>14</strong>がよく使われます。値を小さくすると敏感に反応し、大きくすると滑らかになります。</p>
<h3><span id="toc8">第4引数：applied_price（適用価格）</span></h3>
<p>計算に使う価格の種類を指定します。通常は終値（<code>PRICE_CLOSE</code>）を使います。</p>
<ul>
<li><code>PRICE_CLOSE</code>（0）：終値</li>
<li><code>PRICE_OPEN</code>（1）：始値</li>
<li><code>PRICE_HIGH</code>（2）：高値</li>
<li><code>PRICE_LOW</code>（3）：安値</li>
<li><code>PRICE_MEDIAN</code>（4）：中央値（(高値+安値)÷2）</li>
<li><code>PRICE_TYPICAL</code>（5）：典型価格（(高値+安値+終値)÷3）</li>
<li><code>PRICE_WEIGHTED</code>（6）：加重終値（(高値+安値+終値+終値)÷4）</li>
</ul>
<h3><span id="toc9">第5引数：shift（シフト）</span></h3>
<p>何本前のバーの値を取得するかを指定します。<code>0</code>で現在のバー、<code>1</code>で1本前のバーです。<strong>確定した値を使いたい場合は1以上を指定</strong>するのが基本です。</p>
<h2><span id="toc10">基本的な使い方 ― 値を取得してログに出力する</span></h2>
<p>まずは最もシンプルな例として、モメンタムの値を取得してエキスパートログに出力するコードを見てみましょう。</p>
<pre><code class="language-mql4">void OnTick()
{
   // 現在のバーのモメンタム値を取得（期間14、終値ベース）
   double mom_current = iMomentum(NULL, 0, 14, PRICE_CLOSE, 0);

   // 1本前のバーのモメンタム値を取得
   double mom_prev = iMomentum(NULL, 0, 14, PRICE_CLOSE, 1);

   // ログに出力
   Print("現在のモメンタム: ", mom_current, " | 1本前: ", mom_prev);

   // 100ラインとの比較
   if(mom_current > 100.0)
   {
      Print("上昇の勢いあり");
   }
   else if(mom_current < 100.0)
   {
      Print("下降の勢いあり");
   }
   else
   {
      Print("勢いなし（ニュートラル）");
   }
}
</code></pre>
<p>このコードをEAとしてコンパイルしてチャートにセットすれば、ティックごとにモメンタムの値がログに表示されます。まずはこの基本形を理解しておきましょう。</p>
<h2><span id="toc11">実践サンプル①：100ラインクロスでエントリーするEA</span></h2>
<p>ここからが本番です。モメンタムが100ラインを上抜けたら買い、下抜けたら売りという、シンプルなEAを作ってみましょう。</p>
<pre><code class="language-mql4">//+------------------------------------------------------------------+
//| Momentum Cross EA                                                 |
//+------------------------------------------------------------------+
#property strict

// 入力パラメータ
input int    MomPeriod   = 14;       // モメンタム期間
input double LotSize     = 0.01;     // ロットサイズ
input int    Slippage    = 3;        // スリッページ
input int    StopLoss    = 100;      // ストップロス（ポイント）
input int    TakeProfit  = 200;      // テイクプロフィット（ポイント）
input int    MagicNumber = 12345;    // マジックナンバー

//+------------------------------------------------------------------+
//| Expert tick function                                              |
//+------------------------------------------------------------------+
void OnTick()
{
   // 新しいバーが確定したときだけ処理する
   static datetime lastBarTime = 0;
   if(Time[0] == lastBarTime) return;
   lastBarTime = Time[0];

   // モメンタム値を取得（確定バーを使うためshift=1と2）
   double mom1 = iMomentum(NULL, 0, MomPeriod, PRICE_CLOSE, 1);
   double mom2 = iMomentum(NULL, 0, MomPeriod, PRICE_CLOSE, 2);

   // 現在のポジション数を確認
   int buyCount  = 0;
   int sellCount = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != Symbol()) continue;
      if(OrderMagicNumber() != MagicNumber) continue;

      if(OrderType() == OP_BUY)  buyCount++;
      if(OrderType() == OP_SELL) sellCount++;
   }

   // SLとTPの価格を計算するための変数
   double sl = 0, tp = 0;

   // 買いシグナル：モメンタムが100を下から上にクロス
   if(mom2 <= 100.0 &#038;&#038; mom1 > 100.0)
   {
      // 売りポジションがあれば決済
      ClosePositions(OP_SELL);

      // 買いポジションがなければエントリー
      if(buyCount == 0)
      {
         sl = (StopLoss  > 0) ? Ask - StopLoss  * Point : 0;
         tp = (TakeProfit > 0) ? Ask + TakeProfit * Point : 0;
         int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, sl, tp, "Mom Buy", MagicNumber, 0, clrBlue);
         if(ticket < 0)
            Print("Buy OrderSend error: ", GetLastError());
      }
   }

   // 売りシグナル：モメンタムが100を上から下にクロス
   if(mom2 >= 100.0 && mom1 < 100.0)
   {
      // 買いポジションがあれば決済
      ClosePositions(OP_BUY);

      // 売りポジションがなければエントリー
      if(sellCount == 0)
      {
         sl = (StopLoss  > 0) ? Bid + StopLoss  * Point : 0;
         tp = (TakeProfit > 0) ? Bid - TakeProfit * Point : 0;
         int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, sl, tp, "Mom Sell", MagicNumber, 0, clrRed);
         if(ticket < 0)
            Print("Sell OrderSend error: ", GetLastError());
      }
   }
}

//+------------------------------------------------------------------+
//| 指定タイプのポジションを全決済する関数                            |
//+------------------------------------------------------------------+
void ClosePositions(int type)
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != Symbol()) continue;
      if(OrderMagicNumber() != MagicNumber) continue;
      if(OrderType() != type) continue;

      double closePrice = (type == OP_BUY) ? Bid : Ask;
      if(!OrderClose(OrderTicket(), OrderLots(), closePrice, Slippage, clrWhite))
         Print("OrderClose error: ", GetLastError());
   }
}
</code></pre>
<h3><span id="toc12">コードのポイント解説</span></h3>
<ul>
<li><strong>新しいバー判定</strong>：<code>Time[0]</code>を使って、バーが確定したタイミングだけ処理を実行します。これにより無駄な注文の重複を防ぎます。</li>
<li><strong>shift=1と2を使用</strong>：確定済みのバーを使ってクロス判定を行います。shift=0は未確定バーなので、シグナルがチラつく原因になります。</li>
<li><strong>マジックナンバー</strong>：このEAのポジションだけを管理するための識別番号です。他のEAとの干渉を防ぎます。</li>
<li><strong>決済処理</strong>：反対シグナルが出たら既存ポジションを決済してからエントリーする、ドテン売買のロジックです。</li>
</ul>
<h2><span id="toc13">実践サンプル②：移動平均線と組み合わせたフィルター関数</span></h2>
<p>モメンタム単体だとダマシが多くなりがちです。そこで、<strong>移動平均線（MA）をトレンドフィルター</strong>として組み合わせる方法を紹介します。</p>
<pre><code class="language-mql4">//+------------------------------------------------------------------+
//| モメンタム＋移動平均線のシグナル判定関数                          |
//+------------------------------------------------------------------+
int GetFilteredSignal(int momPeriod, int maPeriod)
{
   // モメンタム値（確定バー）
   double mom1 = iMomentum(NULL, 0, momPeriod, PRICE_CLOSE, 1);
   double mom2 = iMomentum(NULL, 0, momPeriod, PRICE_CLOSE, 2);

   // 移動平均線の値（確定バー）
   double ma = iMA(NULL, 0, maPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);

   // 現在の終値（確定バー）
   double closePrice = Close[1];

   // 買いシグナル：MA より上 かつ モメンタム100上抜け
   if(closePrice > ma && mom2 <= 100.0 &#038;&#038; mom1 > 100.0)
   {
      return 1;  // 買い
   }

   // 売りシグナル：MA より下 かつ モメンタム100下抜け
   if(closePrice < ma &#038;&#038; mom2 >= 100.0 && mom1 < 100.0)
   {
      return -1;  // 売り
   }

   return 0;  // シグナルなし
}
</code></pre>
<p>この関数の使い方はシンプルです。OnTick内で以下のように呼び出します。</p>
<pre><code class="language-mql4">void OnTick()
{
   int signal = GetFilteredSignal(14, 50);

   if(signal == 1)
   {
      // 買い処理
      Print("フィルター通過：買いシグナル発生！");
   }
   else if(signal == -1)
   {
      // 売り処理
      Print("フィルター通過：売りシグナル発生！");
   }
}
</code></pre>
<p>ポイントは、<strong>価格がMAより上のときだけ買いシグナルを採用し、MAより下のときだけ売りシグナルを採用する</strong>という点です。これにより、トレンドに逆らったエントリーを減らすことができます。</p>
<h2><span id="toc14">iMomentum関数を使う際の注意点</span></h2>
<h3><span id="toc15">1. shift値は1以上を使おう</span></h3>
<p>shift=0は現在形成中のバーの値です。ティックごとに値が変わるため、<strong>シグナル判定には確定済みのshift=1以降を使う</strong>のが鉄則です。shift=0は参考表示用として使いましょう。</p>
<h3><span id="toc16">2. マルチタイムフレーム使用時の注意</span></h3>
<p>第2引数で現在のチャートと異なる時間軸を指定すると、マルチタイムフレーム分析ができます。ただし、上位足のデータが読み込まれていない場合は正しい値が返りません。必要に応じて事前にチャートを開くか、<code>iMomentum</code>の戻り値が<code>0</code>でないかチェックしましょう。</p>
<pre><code class="language-mql4">// 日足のモメンタムを取得
double momDaily = iMomentum(NULL, PERIOD_D1, 14, PRICE_CLOSE, 1);
if(momDaily == 0)
{
   Print("日足データが取得できません");
   return;
}
</code></pre>
<h3><span id="toc17">3. ブローカーによる桁数の違いに注意</span></h3>
<p>StopLossやTakeProfitをポイント単位で指定する場合、3桁/5桁ブローカーでは値の調整が必要です。モメンタム自体の値は比率（パーセンテージ）なので桁数の影響は受けませんが、EA全体のロジックでは注意しましょう。</p>
<h2><span id="toc18">まとめ</span></h2>
<p>今回は、MQL4の<strong>iMomentum関数</strong>について基礎から実践まで解説しました。最後に要点を整理しておきます。</p>
<ul>
<li><strong>モメンタム</strong>は相場の勢いを数値化する指標で、基準値は<strong>100</strong></li>
<li><strong>iMomentum関数</strong>は5つの引数（symbol, timeframe, period, applied_price, shift）で値を取得できる</li>
<li>シグナル判定には<strong>確定バー（shift=1以降）</strong>を使うのが基本</li>
<li><strong>100ラインのクロス</strong>でエントリータイミングを判断するEAが作れる</li>
<li><strong>移動平均線などと組み合わせる</strong>ことで、ダマシを減らしてシグナルの精度を高められる</li>
</ul>
<p>モメンタムはシンプルながら奥が深い指標です。まずは今回のサンプルEAをストラテジーテスターで動かして、パラメータを変えながら挙動を確認してみてください。実際に手を動かすことで、理解が一気に深まりますよ！</p>
<p>投稿 <a href="https://mql-programing.com/archives/13037/%e3%80%90mql4%e5%85%a5%e9%96%80%e3%80%91imomentum%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81%e3%83%a2%e3%83%a1%e3%83%b3%e3%82%bf/">【MQL4入門】iMomentum関数の使い方を徹底解説！モメンタムで相場の勢いを判定するEAを作ろう</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【MQL4】iADX関数の使い方を徹底解説！ADXでトレンドの強さを判定するサンプルプログラム付き</title>
		<link>https://mql-programing.com/archives/13034/%e3%80%90mql4%e3%80%91iadx%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81adx%e3%81%a7%e3%83%88%e3%83%ac%e3%83%b3%e3%83%89%e3%81%ae%e5%bc%b7/</link>
		
		<dc:creator><![CDATA[朝日奈りさ]]></dc:creator>
		<pubDate>Mon, 13 Apr 2026 01:00:00 +0000</pubDate>
				<category><![CDATA[【中級編】MQLプログラムの読み方・書き方]]></category>
		<category><![CDATA[iADX]]></category>
		<category><![CDATA[MQL4]]></category>
		<category><![CDATA[EA開発]]></category>
		<category><![CDATA[テクニカルインジケーター]]></category>
		<category><![CDATA[ADX]]></category>
		<guid isPermaLink="false">https://mql-programing.com/?p=13034</guid>

					<description><![CDATA[<p>「トレンドが出ているのか、レンジなのか」を判断できたら、EAの精度は格段に上がりますよね。そんなときに頼りになるのがADX（Average Directional Index）というインジケーターです。 MQL4には、A [&#8230;]</p>
<p>投稿 <a href="https://mql-programing.com/archives/13034/%e3%80%90mql4%e3%80%91iadx%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81adx%e3%81%a7%e3%83%88%e3%83%ac%e3%83%b3%e3%83%89%e3%81%ae%e5%bc%b7/">【MQL4】iADX関数の使い方を徹底解説！ADXでトレンドの強さを判定するサンプルプログラム付き</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[<p>「トレンドが出ているのか、レンジなのか」を判断できたら、EAの精度は格段に上がりますよね。そんなときに頼りになるのが<strong>ADX（Average Directional Index）</strong>というインジケーターです。</p>
<p>MQL4には、ADXの値を簡単に取得できる<strong>iADX()関数</strong>が用意されています。この記事では、iADX()関数のパラメーターを一つひとつ解説し、実際にEAで使えるサンプルコードまで紹介します。</p>
<h2><span id="toc1">ADXインジケーターとは？</span></h2>
<p>ADXは、J. Welles Wilder Jr.（ワイルダー）が開発したテクニカル指標で、<strong>トレンドの「強さ」を0〜100の数値で表す</strong>ものです。トレンドの方向（上昇・下降）ではなく、「どれくらい強いトレンドが出ているか」を測定します。</p>
<p>ADXは以下の<strong>3本のライン</strong>で構成されています。</p>
<ul>
<li><strong>ADX（メインライン）</strong> — トレンドの強さを示す（値が大きいほどトレンドが強い）</li>
<li><strong>+DI（プラス方向指標）</strong> — 上昇の勢いを示す</li>
<li><strong>-DI（マイナス方向指標）</strong> — 下降の勢いを示す</li>
</ul>
<p>一般的には、<strong>ADXが25以上</strong>でトレンドが発生していると判断します。また、+DIが-DIより上にあれば上昇トレンド、-DIが+DIより上にあれば下降トレンドと判断できます。</p>
<h2><span id="toc2">iADX()関数の書式とパラメーター</span></h2>
<p>MQL4のiADX()関数の書式は以下の通りです。</p>
<pre><code class="language-mql4">double iADX(
    string   symbol,          // 通貨ペア名
    int      timeframe,       // 時間足
    int      period,          // 計算期間
    int      applied_price,   // 適用価格
    int      mode,            // 取得するライン
    int      shift            // シフト（何本前の足か）
);
</code></pre>
<p>各パラメーターの意味を詳しく見ていきましょう。</p>
<h3><span id="toc3">symbol（通貨ペア名）</span></h3>
<p>対象の通貨ペアを文字列で指定します。現在のチャートの通貨ペアを使う場合は<strong>NULL</strong>または<strong>Symbol()</strong>と記述します。</p>
<h3><span id="toc4">timeframe（時間足）</span></h3>
<p>計算に使う時間足を指定します。現在のチャートの時間足を使う場合は<strong>0</strong>または<strong>PERIOD_CURRENT</strong>を指定します。他にも<code>PERIOD_M1</code>、<code>PERIOD_H1</code>、<code>PERIOD_D1</code>などが使えます。</p>
<h3><span id="toc5">period（計算期間）</span></h3>
<p>ADXの計算期間です。ワイルダーが推奨した<strong>14</strong>がデフォルトとしてよく使われます。</p>
<h3><span id="toc6">applied_price（適用価格）</span></h3>
<p>価格の種類を指定します。ADXでは通常<strong>PRICE_CLOSE</strong>（終値）を指定します。</p>
<h3><span id="toc7">mode（取得するライン）</span></h3>
<p>ADXの3本のラインのうち、どれを取得するかを指定します。ここが最も重要なパラメーターです。</p>
<table>
<thead>
<tr>
<th>定数</th>
<th>値</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>MODE_MAIN</strong></td>
<td>0</td>
<td>ADXメインライン（トレンドの強さ）</td>
</tr>
<tr>
<td><strong>MODE_PLUSDI</strong></td>
<td>1</td>
<td>+DI（上昇の勢い）</td>
</tr>
<tr>
<td><strong>MODE_MINUSDI</strong></td>
<td>2</td>
<td>-DI（下降の勢い）</td>
</tr>
</tbody>
</table>
<h3><span id="toc8">shift（シフト）</span></h3>
<p>何本前の足のデータを取得するかを指定します。<strong>0</strong>が現在の足（形成中）、<strong>1</strong>が1本前の確定済み足です。EAのロジックでは、確定した値を使うために<strong>1以上</strong>を指定するのが一般的です。</p>
<h2><span id="toc9">基本的な値の取得方法</span></h2>
<p>まずは、3本のラインの値をそれぞれ取得する基本コードを見てみましょう。</p>
<pre><code class="language-mql4">void OnTick()
{
    // 1本前の確定足からADXの各ラインを取得（期間14）
    double adxValue  = iADX(NULL, 0, 14, PRICE_CLOSE, MODE_MAIN,    1);
    double plusDI     = iADX(NULL, 0, 14, PRICE_CLOSE, MODE_PLUSDI,  1);
    double minusDI    = iADX(NULL, 0, 14, PRICE_CLOSE, MODE_MINUSDI,1);

    // ログに出力して確認
    Print("ADX=", DoubleToString(adxValue, 2),
          " +DI=", DoubleToString(plusDI, 2),
          " -DI=", DoubleToString(minusDI, 2));
}
</code></pre>
<p>このコードをEAに貼り付けてストラテジーテスターで実行すると、操作ログにADXの各値が表示されます。まずはここから試してみてください。</p>
<h2><span id="toc10">実践サンプル①：ADXをトレンドフィルターとして使う</span></h2>
<p>ADXの最もポピュラーな使い方は、<strong>トレンドフィルター</strong>です。「ADXが一定値以上のときだけエントリーする」というルールを加えるだけで、レンジ相場での無駄なエントリーを減らせます。</p>
<pre><code class="language-mql4">// --- 入力パラメーター ---
input int    ADX_Period    = 14;     // ADX期間
input double ADX_Threshold = 25.0;   // トレンド判定のしきい値

void OnTick()
{
    double adxValue = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_MAIN, 1);
    double plusDI    = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_PLUSDI, 1);
    double minusDI   = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_MINUSDI, 1);

    // トレンドが弱い場合は何もしない
    if(adxValue < ADX_Threshold)
    {
        // レンジ相場と判断 → エントリーしない
        return;
    }

    // +DI > -DI なら上昇トレンド
    if(plusDI > minusDI)
    {
        // ここに買いエントリーのロジックを記述
        Print("上昇トレンド検出！ ADX=", DoubleToString(adxValue, 2));
    }
    // -DI > +DI なら下降トレンド
    else if(minusDI > plusDI)
    {
        // ここに売りエントリーのロジックを記述
        Print("下降トレンド検出！ ADX=", DoubleToString(adxValue, 2));
    }
}
</code></pre>
<p>この仕組みを他の売買ロジック（移動平均線のクロスなど）と組み合わせることで、エントリー精度を高められます。</p>
<h2><span id="toc11">実践サンプル②：+DI/-DIクロスで売買するEA</span></h2>
<p>ここでは、+DIと-DIのクロスをシグナルとして実際にエントリーを行うEAの完全なコードを紹介します。</p>
<h3><span id="toc12">売買ルール</span></h3>
<ul>
<li><strong>買い条件</strong>：+DIが-DIを上抜け（ゴールデンクロス）＋ ADXがしきい値以上</li>
<li><strong>売り条件</strong>：-DIが+DIを上抜け（デッドクロス）＋ ADXがしきい値以上</li>
<li>既に同方向のポジションがある場合はエントリーしない</li>
</ul>
<pre><code class="language-mql4">//+------------------------------------------------------------------+
//| ADX Cross EA                                                      |
//+------------------------------------------------------------------+
#property strict

// --- 入力パラメーター ---
input int    ADX_Period    = 14;     // ADX期間
input double ADX_Threshold = 25.0;   // ADXしきい値
input double LotSize       = 0.1;    // ロットサイズ
input int    StopLossPips  = 50;     // ストップロス（pips）
input int    TakeProfitPips= 100;    // テイクプロフィット（pips）
input int    MagicNumber   = 12345;  // マジックナンバー

//+------------------------------------------------------------------+
//| pip補正値を取得する関数                                            |
//+------------------------------------------------------------------+
double PipPoint()
{
    if(Digits == 3 || Digits == 5)
        return Point * 10;
    else
        return Point;
}

//+------------------------------------------------------------------+
//| 指定方向のポジション数を数える関数                                  |
//+------------------------------------------------------------------+
int CountOrders(int orderType)
{
    int count = 0;
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
            if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
            {
                if(OrderType() == orderType)
                    count++;
            }
        }
    }
    return count;
}

//+------------------------------------------------------------------+
//| OnTick - メイン処理                                                |
//+------------------------------------------------------------------+
void OnTick()
{
    // --- 1本前（確定足）の値 ---
    double adx_1      = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_MAIN,    1);
    double plusDI_1    = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_PLUSDI,  1);
    double minusDI_1  = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_MINUSDI, 1);

    // --- 2本前の値（クロス判定に使用） ---
    double plusDI_2    = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_PLUSDI,  2);
    double minusDI_2  = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_MINUSDI, 2);

    double pip = PipPoint();

    // --- 買いシグナル判定 ---
    // 2本前は +DI <= -DI だったのに、1本前で +DI > -DI になった（ゴールデンクロス）
    bool buySignal  = (plusDI_2 <= minusDI_2) &#038;&#038; (plusDI_1 > minusDI_1) && (adx_1 >= ADX_Threshold);

    // --- 売りシグナル判定 ---
    // 2本前は -DI <= +DI だったのに、1本前で -DI > +DI になった（デッドクロス）
    bool sellSignal = (minusDI_2 <= plusDI_2) &#038;&#038; (minusDI_1 > plusDI_1) && (adx_1 >= ADX_Threshold);

    // --- 買いエントリー ---
    if(buySignal && CountOrders(OP_BUY) == 0)
    {
        double sl = Ask - StopLossPips * pip;
        double tp = Ask + TakeProfitPips * pip;
        int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, sl, tp,
                               "ADX Cross Buy", MagicNumber, 0, clrBlue);
        if(ticket > 0)
            Print("買いエントリー成功 ADX=", DoubleToString(adx_1, 2),
                  " +DI=", DoubleToString(plusDI_1, 2),
                  " -DI=", DoubleToString(minusDI_1, 2));
        else
            Print("買いエントリー失敗 Error=", GetLastError());
    }

    // --- 売りエントリー ---
    if(sellSignal && CountOrders(OP_SELL) == 0)
    {
        double sl = Bid + StopLossPips * pip;
        double tp = Bid - TakeProfitPips * pip;
        int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, sl, tp,
                               "ADX Cross Sell", MagicNumber, 0, clrRed);
        if(ticket > 0)
            Print("売りエントリー成功 ADX=", DoubleToString(adx_1, 2),
                  " +DI=", DoubleToString(plusDI_1, 2),
                  " -DI=", DoubleToString(minusDI_1, 2));
        else
            Print("売りエントリー失敗 Error=", GetLastError());
    }
}
</code></pre>
<h3><span id="toc13">コードのポイント解説</span></h3>
<p><strong>クロス判定の仕組み：</strong>2本前の足と1本前の足で+DIと-DIの大小関係が逆転したかどうかで判定しています。例えば、2本前は「+DI ≤ -DI」だったのに1本前で「+DI > -DI」になっていれば、+DIが-DIを上抜けた（ゴールデンクロス）と判断します。</p>
<p><strong>pip補正（PipPoint関数）：</strong>3桁・5桁の通貨ペア（例：ドル円が110.123のように小数点3桁）では、Pointが0.001になります。pipsとして扱うにはPoint×10が必要なので、Digitsに応じて補正しています。</p>
<p><strong>重複エントリー防止：</strong>CountOrders()関数で同方向のポジションが既にあるかチェックし、重複エントリーを防いでいます。マジックナンバーで他のEAのポジションと区別している点も実用的なテクニックです。</p>
<h2><span id="toc14">iADX()を使うときの注意点</span></h2>
<h3><span id="toc15">1. 確定足の値を使おう</span></h3>
<p>shift=0で取得する値は、現在形成中の足の値なので、ティックごとに変動します。売買判定には<strong>shift=1以上</strong>（確定済みの足）の値を使うのが安定したロジックのコツです。</p>
<h3><span id="toc16">2. ADXは「方向」を示さない</span></h3>
<p>ADXのメインラインはあくまで「トレンドの強さ」だけを示します。上昇・下降の方向は+DIと-DIの位置関係で判断する必要があります。ADXが高い＝上昇トレンドではない点に注意してください。</p>
<h3><span id="toc17">3. MQL5との違い</span></h3>
<p>MQL4のiADX()は直接double値を返しますが、<strong>MQL5</strong>ではiADX()が「ハンドル」（整数値）を返し、実際の値は<code>CopyBuffer()</code>で配列にコピーして取得する仕組みに変わっています。MQL5に移行する際はコードの書き換えが必要になるので覚えておきましょう。</p>
<h2><span id="toc18">他のインジケーターとの組み合わせ</span></h2>
<p>ADXは単体でも有用ですが、他のインジケーターと組み合わせるとさらに効果的です。</p>
<h3><span id="toc19">移動平均線（MA）+ ADX</span></h3>
<p>MAのゴールデンクロス・デッドクロスをエントリーシグナルとし、ADXが25以上のときだけエントリーするフィルターとして使います。レンジ相場でのダマシを大幅に減らせます。</p>
<h3><span id="toc20">RSI + ADX</span></h3>
<p>RSIの買われすぎ・売られすぎをシグナルとしつつ、ADXが低い（レンジ相場）ときだけ逆張りエントリーする手法です。ADXが高いとき（トレンド発生時）にはRSIの逆張りを控えることで、トレンドに逆らうリスクを回避できます。</p>
<h3><span id="toc21">マルチタイムフレーム分析</span></h3>
<p>iADX()のtimeframe引数を変えれば、異なる時間足のADX値を取得できます。例えば、日足のADXでトレンドを確認し、1時間足で具体的なエントリータイミングを計る、といった使い方が可能です。</p>
<pre><code class="language-mql4">// 日足のADX値を取得
double adx_daily = iADX(NULL, PERIOD_D1, 14, PRICE_CLOSE, MODE_MAIN, 1);

// 1時間足の+DI/-DIを取得
double plusDI_H1  = iADX(NULL, PERIOD_H1, 14, PRICE_CLOSE, MODE_PLUSDI, 1);
double minusDI_H1 = iADX(NULL, PERIOD_H1, 14, PRICE_CLOSE, MODE_MINUSDI, 1);

// 日足でトレンドが出ていて、1時間足で+DI優勢なら買い
if(adx_daily >= 25 && plusDI_H1 > minusDI_H1)
{
    Print("マルチタイムフレーム分析：買い条件成立");
}
</code></pre>
<h2><span id="toc22">まとめ</span></h2>
<p>この記事では、MQL4の<strong>iADX()関数</strong>の使い方を基礎から実践まで解説しました。ポイントを振り返りましょう。</p>
<ul>
<li>ADXはトレンドの<strong>「強さ」</strong>を0〜100で数値化するインジケーター</li>
<li>iADX()関数の<strong>mode引数</strong>で、ADX本体・+DI・-DIの3つのラインを切り替えて取得する</li>
<li>ADXが25以上でトレンド発生、+DIと-DIの位置関係でトレンドの方向を判定</li>
<li>売買判定には<strong>確定足（shift=1以上）</strong>の値を使うのが基本</li>
<li>他のインジケーターの<strong>トレンドフィルター</strong>として組み合わせると効果的</li>
</ul>
<p>ADXはシンプルながら非常に強力なインジケーターです。まずは基本の値取得から試して、自分のEAにトレンドフィルターとして組み込んでみてください。レンジ相場での無駄なエントリーが減り、トレード成績の改善が期待できるはずです！</p>
<p>投稿 <a href="https://mql-programing.com/archives/13034/%e3%80%90mql4%e3%80%91iadx%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81adx%e3%81%a7%e3%83%88%e3%83%ac%e3%83%b3%e3%83%89%e3%81%ae%e5%bc%b7/">【MQL4】iADX関数の使い方を徹底解説！ADXでトレンドの強さを判定するサンプルプログラム付き</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【MQL4】iATR関数の使い方を徹底解説！ATR（アベレージ・トゥルー・レンジ）でボラティリティを味方につけよう</title>
		<link>https://mql-programing.com/archives/13028/%e3%80%90mql4%e3%80%91iatr%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81atr%ef%bc%88%e3%82%a2%e3%83%99%e3%83%ac%e3%83%bc%e3%82%b8%e3%83%bb/</link>
		
		<dc:creator><![CDATA[朝日奈りさ]]></dc:creator>
		<pubDate>Sat, 11 Apr 2026 01:00:00 +0000</pubDate>
				<category><![CDATA[【中級編】MQLプログラムの読み方・書き方]]></category>
		<category><![CDATA[インジケーター関数]]></category>
		<category><![CDATA[iATR]]></category>
		<category><![CDATA[ATR]]></category>
		<category><![CDATA[MQL4]]></category>
		<category><![CDATA[EA開発]]></category>
		<guid isPermaLink="false">https://mql-programing.com/?p=13028</guid>

					<description><![CDATA[<p>「相場の勢いが強いのか弱いのか、数値で判断できたらいいのに…」そんな風に思ったことはありませんか？ MQL4には、ボラティリティ（価格変動の大きさ）を数値化できる便利な関数iATRが用意されています。ATR（Averag [&#8230;]</p>
<p>投稿 <a href="https://mql-programing.com/archives/13028/%e3%80%90mql4%e3%80%91iatr%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81atr%ef%bc%88%e3%82%a2%e3%83%99%e3%83%ac%e3%83%bc%e3%82%b8%e3%83%bb/">【MQL4】iATR関数の使い方を徹底解説！ATR（アベレージ・トゥルー・レンジ）でボラティリティを味方につけよう</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[<p>「相場の勢いが強いのか弱いのか、数値で判断できたらいいのに…」そんな風に思ったことはありませんか？</p>
<p>MQL4には、ボラティリティ（価格変動の大きさ）を数値化できる便利な関数<strong>iATR</strong>が用意されています。ATR（Average True Range：アベレージ・トゥルー・レンジ）は、多くのプロトレーダーも活用している指標で、ストップロスの設定やエントリーフィルターなど、EA開発で大活躍します。</p>
<p>この記事では、iATR関数の基本的な使い方から、実践的なEAへの組み込み方まで、サンプルコード付きで徹底解説します！</p>
<h2><span id="toc1">ATR（アベレージ・トゥルー・レンジ）とは？</span></h2>
<p>ATRを理解するには、まず<strong>TR（トゥルー・レンジ）</strong>を知る必要があります。TRは「そのローソク足の本当の値動き幅」を表すもので、次の3つの値のうち最も大きいものを採用します。</p>
<ul>
<li><strong>当日の高値 − 当日の安値</strong>（通常の値幅）</li>
<li><strong>当日の高値 − 前日の終値</strong>の絶対値（上方向へのギャップを考慮）</li>
<li><strong>当日の安値 − 前日の終値</strong>の絶対値（下方向へのギャップを考慮）</li>
</ul>
<p>ATRは、このTRを指定した期間で<strong>平均化</strong>したものです。一般的には14期間がよく使われます。</p>
<p>ATRの値が大きいほど「ボラティリティが高い（値動きが激しい）」、小さいほど「ボラティリティが低い（値動きが穏やか）」と判断できます。なお、ATRはあくまで値動きの「大きさ」を示すものであり、方向（上昇・下降）は示しません。</p>
<h2><span id="toc2">iATR関数の基本構文</span></h2>
<p>MQL4でATRの値を取得するには、<strong>iATR関数</strong>を使います。基本構文は以下の通りです。</p>
<pre><code class="language-mql4">double iATR(
    string symbol,      // 通貨ペア名
    int    timeframe,   // 時間足
    int    period,      // 平均期間
    int    shift        // シフト（何本前のバーか）
);</code></pre>
<p>各引数の詳細を見ていきましょう。</p>
<table>
<thead>
<tr>
<th>引数</th>
<th>型</th>
<th>説明</th>
<th>例</th>
</tr>
</thead>
<tbody>
<tr>
<td>symbol</td>
<td>string</td>
<td>対象の通貨ペア名。NULL を指定すると現在のチャートの通貨ペアになります。</td>
<td>NULL, &#8220;USDJPY&#8221;</td>
</tr>
<tr>
<td>timeframe</td>
<td>int</td>
<td>時間足を指定します。0 を指定すると現在のチャートの時間足になります。</td>
<td>0, PERIOD_H1, PERIOD_D1</td>
</tr>
<tr>
<td>period</td>
<td>int</td>
<td>ATRを計算する平均期間。一般的には14が使われます。</td>
<td>14, 20</td>
</tr>
<tr>
<td>shift</td>
<td>int</td>
<td>何本前のバーの値を取得するか。0は現在の未確定バー、1は直近の確定バーです。</td>
<td>0, 1</td>
</tr>
</tbody>
</table>
<h2><span id="toc3">基本的な使い方 ― ATR値を取得してみよう</span></h2>
<p>まずは最もシンプルな使い方です。現在のチャートで14期間ATRの値を取得し、エキスパートログに出力してみましょう。</p>
<pre><code class="language-mql4">void OnTick()
{
    // 直近の確定バー（shift=1）のATR値を取得
    double atrValue = iATR(NULL, 0, 14, 1);

    // ログに出力
    Print("現在のATR(14) = ", DoubleToString(atrValue, 5));
}</code></pre>
<p>ここで重要なポイントは<strong>shift=1</strong>を使っていることです。shift=0だと現在形成中のバー（まだ確定していない）の値を参照するため、ティックごとに値が変動してしまいます。EAのロジックでは、基本的にshift=1（直近の確定バー）を使うのが安定した判断につながります。</p>
<h2><span id="toc4">実践サンプル①：ATRベースの動的ストップロス＆テイクプロフィット</span></h2>
<p>ATRの最も人気のある活用法の一つが、<strong>ボラティリティに応じてSL（ストップロス）とTP（テイクプロフィット）を動的に変える</strong>方法です。相場が激しく動いているときは広めに、穏やかなときは狭めに設定できます。</p>
<pre><code class="language-mql4">// --- 入力パラメータ ---
input int    ATR_Period    = 14;      // ATR期間
input double SL_Multiplier = 1.5;    // SLに使うATRの倍率
input double TP_Multiplier = 2.0;    // TPに使うATRの倍率
input double LotSize       = 0.1;    // ロットサイズ

void OnTick()
{
    // 既にポジションがあれば何もしない（簡略化のため）
    if(OrdersTotal() > 0) return;

    // ATR値を取得（確定バーを使用）
    double atr = iATR(NULL, 0, ATR_Period, 1);

    // ATRが0の場合は処理しない
    if(atr <= 0) return;

    // 動的なSL・TPを計算
    double sl_distance = atr * SL_Multiplier;
    double tp_distance = atr * TP_Multiplier;

    // 現在の価格を取得
    double askPrice = Ask;
    double bidPrice = Bid;

    // 買い注文の例
    double sl = askPrice - sl_distance;
    double tp = askPrice + tp_distance;

    // 小数点桁数を通貨ペアに合わせて丸める
    sl = NormalizeDouble(sl, Digits);
    tp = NormalizeDouble(tp, Digits);

    int ticket = OrderSend(
        Symbol(), OP_BUY, LotSize,
        askPrice, 3, sl, tp,
        "ATR-based SL/TP", 0, 0, clrBlue
    );

    if(ticket > 0)
    {
        Print("注文成功！ SL=", DoubleToString(sl, Digits),
              " TP=", DoubleToString(tp, Digits),
              " ATR=", DoubleToString(atr, 5));
    }
    else
    {
        Print("注文失敗: エラーコード=", GetLastError());
    }
}</code></pre>
<p>この例では、ATRの1.5倍をストップロスに、2.0倍をテイクプロフィットに設定しています。こうすることで、ボラティリティが高い相場では自然とSL/TP幅が広がり、低い相場では狭まります。固定pipsのSL/TPと比べて、相場環境に柔軟に対応できるのが大きなメリットです。</p>
<h2><span id="toc5">実践サンプル②：ATRでボラティリティフィルターを作る</span></h2>
<p>もう一つの活用法が、<strong>ボラティリティフィルター</strong>です。「ボラティリティが一定以上あるときだけトレードする」というフィルターを作ることで、値動きが小さすぎるレンジ相場でのムダなエントリーを避けられます。</p>
<pre><code class="language-mql4">// ボラティリティが十分かどうかを判定する関数
bool IsVolatilityEnough(int atrPeriod, int checkBars, double threshold)
{
    // 現在のATR
    double currentATR = iATR(NULL, 0, atrPeriod, 1);

    // 過去のATRの平均を計算
    double sumATR = 0;
    for(int i = 2; i <= checkBars + 1; i++)
    {
        sumATR += iATR(NULL, 0, atrPeriod, i);
    }
    double avgATR = sumATR / checkBars;

    // 平均に対する比率で判定
    if(avgATR <= 0) return false;

    double ratio = currentATR / avgATR;

    // 比率がしきい値以上ならボラティリティ十分と判定
    if(ratio >= threshold)
    {
        Print("ボラティリティOK: 現在ATR=", DoubleToString(currentATR, 5),
              " 平均ATR=", DoubleToString(avgATR, 5),
              " 比率=", DoubleToString(ratio, 2));
        return true;
    }

    return false;
}

// 使用例
void OnTick()
{
    // 過去20本のATR平均と比較して、0.8倍以上なら十分と判定
    if(!IsVolatilityEnough(14, 20, 0.8))
    {
        // ボラティリティが低いのでトレードしない
        return;
    }

    // ここにエントリーロジックを記述
    // ...
}</code></pre>
<p>この関数は、直近のATRが過去の平均ATRに対してどの程度の比率かを計算し、指定したしきい値以上であれば「ボラティリティ十分」と判定します。レンジ相場で無駄にエントリーしてしまう問題を軽減できる、実用的なフィルターです。</p>
<h2><span id="toc6">iATR関数を使う際の注意点</span></h2>
<h3><span id="toc7">① shift=1を基本にしよう</span></h3>
<p>先ほども触れましたが、EA内でATR値をロジック判定に使うときは<strong>shift=1</strong>（直近の確定バー）を使いましょう。shift=0はティックごとに値が変わるため、バックテストとリアルトレードで結果が乖離する原因になります。</p>
<h3><span id="toc8">② ATR値をpipsに換算する方法</span></h3>
<p>ATRの戻り値は「価格の値幅」です。pipsに換算したい場合は、以下のようにします。</p>
<pre><code class="language-mql4">double atr = iATR(NULL, 0, 14, 1);

// pipsに換算（3桁/5桁ブローカー対応）
double atrPips;
if(Digits == 3 || Digits == 5)
    atrPips = atr / (Point * 10);
else
    atrPips = atr / Point;

Print("ATR = ", DoubleToString(atrPips, 1), " pips");</code></pre>
<p>多くのブローカーは5桁（例：USDJPY = 110.123）または3桁（例：USDJPY = 110.12の場合もあり）の価格表示を使っています。Digitsの値を確認してpips換算することで、どのブローカーでも正しく動作するコードになります。</p>
<h3><span id="toc9">③ マルチタイムフレームでの活用</span></h3>
<p>iATR関数のtimeframe引数を使えば、現在のチャートとは異なる時間足のATRを取得できます。</p>
<pre><code class="language-mql4">// 日足のATRを5分足チャート上で取得
double dailyATR = iATR(NULL, PERIOD_D1, 14, 1);

// 4時間足のATRを取得
double h4ATR = iATR(NULL, PERIOD_H4, 14, 1);

Print("日足ATR=", DoubleToString(dailyATR, 5),
      " 4時間足ATR=", DoubleToString(h4ATR, 5));</code></pre>
<p>例えば、5分足でスキャルピングEAを作りつつ、日足のATRでその日全体のボラティリティを確認する、という使い方ができます。上位足のボラティリティ情報を加味することで、より精度の高いトレード判断が可能になります。</p>
<h2><span id="toc10">まとめ</span></h2>
<p>この記事では、MQL4の<strong>iATR関数</strong>を使ってATR（アベレージ・トゥルー・レンジ）を取得・活用する方法を解説しました。最後にポイントを振り返りましょう。</p>
<ul>
<li><strong>ATR</strong>はボラティリティ（値動きの大きさ）を数値化した指標で、方向性は示さない</li>
<li><strong>iATR関数</strong>は4つの引数（symbol, timeframe, period, shift）で手軽にATR値を取得できる</li>
<li>EAのロジックでは<strong>shift=1</strong>（確定バー）を使うのが基本</li>
<li><strong>動的SL/TP</strong>に活用すれば、相場のボラティリティに応じた柔軟なリスク管理が可能</li>
<li><strong>ボラティリティフィルター</strong>として使えば、レンジ相場でのムダなエントリーを回避できる</li>
<li>pips換算やマルチタイムフレーム対応も忘れずに実装しよう</li>
</ul>
<p>ATRは地味に見えるかもしれませんが、EA開発においては非常に汎用性の高い指標です。ストップロス、テイクプロフィット、ロットサイズの計算、エントリーフィルターなど、さまざまな場面で活躍します。ぜひ自分のEAに組み込んで、ボラティリティを味方につけてください！</p>
<p>投稿 <a href="https://mql-programing.com/archives/13028/%e3%80%90mql4%e3%80%91iatr%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81atr%ef%bc%88%e3%82%a2%e3%83%99%e3%83%ac%e3%83%bc%e3%82%b8%e3%83%bb/">【MQL4】iATR関数の使い方を徹底解説！ATR（アベレージ・トゥルー・レンジ）でボラティリティを味方につけよう</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【MQL4】iCCI関数の使い方を徹底解説！CCI（商品チャネル指数）でトレンド転換を捉えるEAを作ろう</title>
		<link>https://mql-programing.com/archives/13025/%e3%80%90mql4%e3%80%91icci%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81cci%ef%bc%88%e5%95%86%e5%93%81%e3%83%81%e3%83%a3%e3%83%8d%e3%83%ab/</link>
		
		<dc:creator><![CDATA[朝日奈りさ]]></dc:creator>
		<pubDate>Fri, 10 Apr 2026 01:00:00 +0000</pubDate>
				<category><![CDATA[【中級編】MQLプログラムの読み方・書き方]]></category>
		<category><![CDATA[注文関係]]></category>
		<category><![CDATA[MQL4]]></category>
		<category><![CDATA[EA開発]]></category>
		<category><![CDATA[インジケーター関数]]></category>
		<category><![CDATA[iCCI]]></category>
		<category><![CDATA[CCI]]></category>
		<guid isPermaLink="false">https://mql-programing.com/?p=13025</guid>

					<description><![CDATA[<p>CCI（商品チャネル指数）は、相場の「買われすぎ・売られすぎ」を数値で判断できる人気のオシレーター系インジケーターです。MQL4ではiCCI関数を使うことで、EA（自動売買）の中から簡単にCCIの値を取得できます。 この [&#8230;]</p>
<p>投稿 <a href="https://mql-programing.com/archives/13025/%e3%80%90mql4%e3%80%91icci%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81cci%ef%bc%88%e5%95%86%e5%93%81%e3%83%81%e3%83%a3%e3%83%8d%e3%83%ab/">【MQL4】iCCI関数の使い方を徹底解説！CCI（商品チャネル指数）でトレンド転換を捉えるEAを作ろう</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[<p>CCI（商品チャネル指数）は、相場の「買われすぎ・売られすぎ」を数値で判断できる人気のオシレーター系インジケーターです。MQL4では<strong>iCCI関数</strong>を使うことで、EA（自動売買）の中から簡単にCCIの値を取得できます。</p>
<p>この記事では、iCCI関数の基本的な使い方からパラメータの意味、そしてCCIのクロスを利用した実践的なEAの作成方法まで、ステップバイステップで解説していきます。</p>
<h2><span id="toc1">CCI（商品チャネル指数）とは？</span></h2>
<p>CCIは1980年にドナルド・ランバート氏が開発した<strong>モメンタム系オシレーター</strong>です。もともとは商品先物市場向けに作られましたが、現在ではFXや株式など幅広い市場で使われています。</p>
<p>CCIの特徴は、RSIやストキャスティクスのように0〜100の範囲に収まるのではなく、<strong>上下に制限なく動く</strong>点です。一般的には以下の基準で判断します。</p>
<ul>
<li><strong>+100を上回る</strong>：買われすぎ（上昇トレンドが強い）</li>
<li><strong>-100を下回る</strong>：売られすぎ（下降トレンドが強い）</li>
<li><strong>0ライン</strong>：トレンドの方向転換の目安</li>
</ul>
<h3><span id="toc2">CCIの計算式</span></h3>
<p>CCIの計算式は以下の通りです。</p>
<pre><code class="language-mql4">CCI = (TP - MA) / (0.015 × MD)

// TP（ティピカルプライス）= (高値 + 安値 + 終値) / 3
// MA = TPの単純移動平均（期間N）
// MD = TPと移動平均の平均偏差
// 0.015 = CCI値の約70〜80%が±100以内に収まるように設定された定数
</code></pre>
<p>計算式を覚える必要はありませんが、TPをベースにしていることは頭に入れておきましょう。iCCI関数の<code>applied_price</code>パラメータに関わってきます。</p>
<h2><span id="toc3">iCCI関数の構文</span></h2>
<p>MQL4でCCIの値を取得するには、<strong>iCCI関数</strong>を使います。構文は以下の通りです。</p>
<pre><code class="language-mql4">double iCCI(
   string       symbol,          // 通貨ペア名
   int          timeframe,       // 時間足
   int          period,          // 平均期間
   int          applied_price,   // 適用価格
   int          shift            // シフト（何本前の足か）
);
</code></pre>
<h3><span id="toc4">パラメータ一覧</span></h3>
<table>
<thead>
<tr>
<th>パラメータ</th>
<th>型</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td>symbol</td>
<td>string</td>
<td>通貨ペア名。現在のチャートなら<code>NULL</code>または<code>Symbol()</code></td>
</tr>
<tr>
<td>timeframe</td>
<td>int</td>
<td>時間足。<code>0</code>で現在のチャートの時間足。<code>PERIOD_H1</code>など定数も使用可能</td>
</tr>
<tr>
<td>period</td>
<td>int</td>
<td>CCIの計算期間。一般的には<strong>14</strong>や<strong>20</strong>がよく使われる</td>
</tr>
<tr>
<td>applied_price</td>
<td>int</td>
<td>計算に使う価格の種類</td>
</tr>
<tr>
<td>shift</td>
<td>int</td>
<td>何本前のローソク足のCCI値を取得するか。0が現在の足、1が1本前の確定足</td>
</tr>
</tbody>
</table>
<h3><span id="toc5">applied_price（適用価格）の定数一覧</span></h3>
<p>CCIの計算に使用する価格タイプを指定します。デフォルトのCCIではティピカルプライスが使われます。</p>
<table>
<thead>
<tr>
<th>定数名</th>
<th>値</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td>PRICE_CLOSE</td>
<td>0</td>
<td>終値</td>
</tr>
<tr>
<td>PRICE_OPEN</td>
<td>1</td>
<td>始値</td>
</tr>
<tr>
<td>PRICE_HIGH</td>
<td>2</td>
<td>高値</td>
</tr>
<tr>
<td>PRICE_LOW</td>
<td>3</td>
<td>安値</td>
</tr>
<tr>
<td>PRICE_MEDIAN</td>
<td>4</td>
<td>中央値（高値+安値）/ 2</td>
</tr>
<tr>
<td>PRICE_TYPICAL</td>
<td>5</td>
<td>ティピカルプライス（高値+安値+終値）/ 3</td>
</tr>
<tr>
<td>PRICE_WEIGHTED</td>
<td>6</td>
<td>加重終値（高値+安値+終値×2）/ 4</td>
</tr>
</tbody>
</table>
<p>チャート上にCCIインジケーターを表示して比較する場合は、<strong>applied_priceを同じ設定にしないと値がずれる</strong>ので注意してください。標準のCCIは<code>PRICE_TYPICAL</code>を使用しています。</p>
<h2><span id="toc6">基本的な使い方</span></h2>
<p>まずは最もシンプルな使い方を見てみましょう。1本前の確定足のCCI値を取得してコメントに表示する例です。</p>
<pre><code class="language-mql4">void OnTick()
{
   // 1本前の確定足のCCI（期間14、ティピカルプライス）を取得
   double cciValue = iCCI(NULL, 0, 14, PRICE_TYPICAL, 1);
   
   // チャート上にCCI値を表示
   Comment("CCI(14) = ", DoubleToString(cciValue, 2));
}
</code></pre>
<p><strong>ポイント：</strong>shiftに<code>1</code>を指定して確定足の値を使うのが基本です。<code>0</code>（現在の足）はティックごとに値が変動するため、売買シグナルの判定には向きません。</p>
<h2><span id="toc7">CCIクロスで売買するEAを作ろう</span></h2>
<p>ここからが本番です。CCIが<strong>-100を下から上にクロスしたら買い</strong>、<strong>+100を上から下にクロスしたら売り</strong>、<strong>0ラインクロスで決済</strong>するEAを作成します。</p>
<h3><span id="toc8">トレードロジックの整理</span></h3>
<ul>
<li><strong>買いエントリー</strong>：CCI（1本前）が-100以上 かつ CCI（2本前）が-100未満 → -100を上抜け</li>
<li><strong>売りエントリー</strong>：CCI（1本前）が+100以下 かつ CCI（2本前）が+100超 → +100を下抜け</li>
<li><strong>買いポジション決済</strong>：CCIが0を下回った時</li>
<li><strong>売りポジション決済</strong>：CCIが0を上回った時</li>
</ul>
<h3><span id="toc9">完全なEAコード</span></h3>
<pre><code class="language-mql4">//+------------------------------------------------------------------+
//| CCI Cross EA                                                       |
//+------------------------------------------------------------------+
#property strict

// 入力パラメータ
input int    CCI_Period      = 14;            // CCI期間
input double LotSize         = 0.1;           // ロットサイズ
input int    StopLoss        = 100;           // ストップロス（pips）
input int    TakeProfit      = 200;           // テイクプロフィット（pips）
input int    MagicNumber     = 20240101;      // マジックナンバー

//+------------------------------------------------------------------+
//| Expert tick function                                               |
//+------------------------------------------------------------------+
void OnTick()
{
   // CCI値を取得（確定足を使用）
   double cci1 = iCCI(NULL, 0, CCI_Period, PRICE_TYPICAL, 1); // 1本前
   double cci2 = iCCI(NULL, 0, CCI_Period, PRICE_TYPICAL, 2); // 2本前
   
   // 現在のポジション状態を確認
   int buyCount  = CountPositions(OP_BUY);
   int sellCount = CountPositions(OP_SELL);
   
   // --- 決済ロジック ---
   // 買いポジション保有中：CCIが0を下回ったら決済
   if(buyCount > 0 && cci1 < 0)
   {
      ClosePositions(OP_BUY);
   }
   
   // 売りポジション保有中：CCIが0を上回ったら決済
   if(sellCount > 0 && cci1 > 0)
   {
      ClosePositions(OP_SELL);
   }
   
   // --- エントリーロジック ---
   // ポジションがない場合のみエントリー
   if(buyCount == 0 && sellCount == 0)
   {
      // 買いシグナル：CCIが-100を下から上にクロス
      if(cci2 < -100 &#038;&#038; cci1 >= -100)
      {
         double sl = (StopLoss > 0)   ? Ask - StopLoss * Point * 10 : 0;
         double tp = (TakeProfit > 0)  ? Ask + TakeProfit * Point * 10 : 0;
         
         int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 30, sl, tp,
                                "CCI Buy", MagicNumber, 0, clrBlue);
         if(ticket < 0)
            Print("Buy OrderSend error: ", GetLastError());
      }
      
      // 売りシグナル：CCIが+100を上から下にクロス
      if(cci2 > 100 && cci1 <= 100)
      {
         double sl = (StopLoss > 0)   ? Bid + StopLoss * Point * 10 : 0;
         double tp = (TakeProfit > 0)  ? Bid - TakeProfit * Point * 10 : 0;
         
         int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 30, sl, tp,
                                "CCI Sell", MagicNumber, 0, clrRed);
         if(ticket < 0)
            Print("Sell OrderSend error: ", GetLastError());
      }
   }
}

//+------------------------------------------------------------------+
//| 指定タイプのポジション数をカウント                                    |
//+------------------------------------------------------------------+
int CountPositions(int type)
{
   int count = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == type)
            count++;
      }
   }
   return count;
}

//+------------------------------------------------------------------+
//| 指定タイプのポジションを全て決済                                      |
//+------------------------------------------------------------------+
void ClosePositions(int type)
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == type)
         {
            double closePrice = (type == OP_BUY) ? Bid : Ask;
            if(!OrderClose(OrderTicket(), OrderLots(), closePrice, 30, clrYellow))
               Print("OrderClose error: ", GetLastError());
         }
      }
   }
}
</code></pre>
<h3><span id="toc10">コードのポイント解説</span></h3>
<p><strong>① MagicNumberの活用</strong></p>
<p>MagicNumberを使うことで、このEAが出した注文だけを識別できます。手動注文や他のEAの注文を誤って決済してしまう事故を防げます。</p>
<p><strong>② 確定足（shift=1, 2）でクロスを検出</strong></p>
<p>2本前と1本前の確定足を比較してクロスを検出しています。現在の足（shift=0）を使うと、ティックごとに値が変わるためシグナルが不安定になります。</p>
<p><strong>③ 決済を逆方向ではなく0ラインで行う</strong></p>
<p>CCIが0ラインをクロスした時点で決済することで、利益の取りこぼしを減らす設計になっています。もちろん、SL/TPによる自動決済も併用しています。</p>
<h2><span id="toc11">応用テクニック：マルチタイムフレーム分析</span></h2>
<p>iCCI関数の第2引数（timeframe）を変えるだけで、<strong>上位足のCCIをフィルターとして使う</strong>ことができます。例えば、日足のCCIの方向に合わせてエントリーを絞り込む手法です。</p>
<pre><code class="language-mql4">// 上位足（日足）のCCIでトレンド方向を判定
double cciDaily = iCCI(NULL, PERIOD_D1, 14, PRICE_TYPICAL, 1);

// 現在の時間足のCCIでエントリータイミングを判定
double cciCurrent1 = iCCI(NULL, 0, 14, PRICE_TYPICAL, 1);
double cciCurrent2 = iCCI(NULL, 0, 14, PRICE_TYPICAL, 2);

// 日足CCIが0以上（上昇傾向）の時だけ買いエントリー
if(cciDaily > 0 && cciCurrent2 < -100 &#038;&#038; cciCurrent1 >= -100)
{
   // 買いエントリー処理
}

// 日足CCIが0以下（下降傾向）の時だけ売りエントリー
if(cciDaily < 0 &#038;&#038; cciCurrent2 > 100 && cciCurrent1 <= 100)
{
   // 売りエントリー処理
}
</code></pre>
<p>上位足のトレンド方向に逆らわないことで、ダマシのシグナルを大幅に減らすことが期待できます。</p>
<h2><span id="toc12">iCCI関数を使う際の注意点</span></h2>
<h3><span id="toc13">1. applied_priceの不一致に注意</span></h3>
<p>チャート上に表示しているCCIインジケーターと、iCCI関数で指定した<code>applied_price</code>が異なると、値がずれます。検証時は必ず同じ設定にしましょう。標準のCCIは<code>PRICE_TYPICAL</code>です。</p>
<h3><span id="toc14">2. レンジ相場での連続シグナルに注意</span></h3>
<p>CCIはモメンタム指標なので、レンジ相場では±100ラインを頻繁に行き来し、ダマシが多発します。移動平均線やADXなどのトレンドフィルターを組み合わせることをおすすめします。</p>
<h3><span id="toc15">3. 計算に必要なバー数</span></h3>
<p>CCIの計算には、指定した期間分のローソク足データが必要です。チャートのバー数が少ないと正確な値が得られません。バックテスト時は十分なヒストリカルデータを用意してください。</p>
<h2><span id="toc16">まとめ</span></h2>
<p>今回はMQL4の<strong>iCCI関数</strong>の使い方を、基本から実践的なEA作成まで解説しました。</p>
<ul>
<li><strong>iCCI関数</strong>は5つのパラメータでCCIの値を簡単に取得できる</li>
<li><strong>±100ラインのクロス</strong>をエントリーシグナルに、<strong>0ラインクロス</strong>を決済シグナルに使うのが王道的な手法</li>
<li><strong>確定足（shift=1以上）</strong>を使ってシグナル判定するのが安定した運用のコツ</li>
<li><strong>マルチタイムフレーム分析</strong>で上位足のトレンド方向にフィルターをかけると精度が向上する</li>
<li><strong>applied_price</strong>はチャート上のインジケーターと合わせることを忘れずに</li>
</ul>
<p>CCIはシンプルながら奥が深いインジケーターです。まずはサンプルEAをストラテジーテスターで動かしてみて、パラメータを変えながらCCIの振る舞いを体感してみてください！</p>
<p>投稿 <a href="https://mql-programing.com/archives/13025/%e3%80%90mql4%e3%80%91icci%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81cci%ef%bc%88%e5%95%86%e5%93%81%e3%83%81%e3%83%a3%e3%83%8d%e3%83%ab/">【MQL4】iCCI関数の使い方を徹底解説！CCI（商品チャネル指数）でトレンド転換を捉えるEAを作ろう</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【MQL4】iStochastic関数の使い方を完全解説！ストキャスティクスを使ったEAサンプル付き</title>
		<link>https://mql-programing.com/archives/13022/%e3%80%90mql4%e3%80%91istochastic%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%ae%8c%e5%85%a8%e8%a7%a3%e8%aa%ac%ef%bc%81%e3%82%b9%e3%83%88%e3%82%ad%e3%83%a3%e3%82%b9%e3%83%86/</link>
		
		<dc:creator><![CDATA[朝日奈りさ]]></dc:creator>
		<pubDate>Thu, 09 Apr 2026 01:00:00 +0000</pubDate>
				<category><![CDATA[【中級編】MQLプログラムの読み方・書き方]]></category>
		<category><![CDATA[注文関係]]></category>
		<category><![CDATA[テクニカルインジケーター]]></category>
		<category><![CDATA[iStochastic]]></category>
		<category><![CDATA[MQL4]]></category>
		<category><![CDATA[ストキャスティクス]]></category>
		<category><![CDATA[EA自動売買]]></category>
		<guid isPermaLink="false">https://mql-programing.com/?p=13022</guid>

					<description><![CDATA[<p>ストキャスティクスは、相場の「買われすぎ」「売られすぎ」を判断するための代表的なオシレーター系インジケーターです。MQL4ではiStochastic関数を使うことで、EA（自動売買プログラム）やカスタムインジケーターの中 [&#8230;]</p>
<p>投稿 <a href="https://mql-programing.com/archives/13022/%e3%80%90mql4%e3%80%91istochastic%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%ae%8c%e5%85%a8%e8%a7%a3%e8%aa%ac%ef%bc%81%e3%82%b9%e3%83%88%e3%82%ad%e3%83%a3%e3%82%b9%e3%83%86/">【MQL4】iStochastic関数の使い方を完全解説！ストキャスティクスを使ったEAサンプル付き</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[<p>ストキャスティクスは、相場の「買われすぎ」「売られすぎ」を判断するための代表的なオシレーター系インジケーターです。MQL4では<strong>iStochastic関数</strong>を使うことで、EA（自動売買プログラム）やカスタムインジケーターの中からストキャスティクスの値を簡単に取得できます。</p>
<p>この記事では、iStochastic関数の書式・引数をひとつずつ丁寧に解説し、最後にストキャスティクスのクロスで売買する実践的なEAサンプルを紹介します。</p>
<h2><span id="toc1">ストキャスティクスとは？</span></h2>
<p>ストキャスティクス（Stochastic Oscillator）は、一定期間の価格レンジの中で現在の価格がどの位置にあるかを0〜100の数値で示すテクニカル指標です。</p>
<h3><span id="toc2">3本のラインを理解しよう</span></h3>
<p>ストキャスティクスには以下の3種類のラインがあります。</p>
<ul>
<li><strong>%K（Fast %K）</strong>：直近の価格が一定期間の高値・安値レンジのどこに位置するかを示す、最も感度の高いライン</li>
<li><strong>%D（Fast %D / Slow %K）</strong>：%Kを移動平均で平滑化したライン。MetaTrader4のストキャスティクスではこれがメインラインになります</li>
<li><strong>Slow %D（シグナルライン）</strong>：%Dをさらに移動平均で平滑化したライン</li>
</ul>
<h3><span id="toc3">80と20のレベルライン</span></h3>
<p>一般的に、ストキャスティクスの値が<strong>80以上</strong>になると「買われすぎ」、<strong>20以下</strong>になると「売られすぎ」と判断します。この水準でのラインのクロスが売買シグナルとしてよく使われます。</p>
<h2><span id="toc4">iStochastic関数の書式と引数を完全解説</span></h2>
<p>iStochastic関数の書式は以下のとおりです。</p>
<pre><code class="language-mql4">double iStochastic(
   string       symbol,        // ① 通貨ペア
   int          timeframe,     // ② 時間足
   int          Kperiod,       // ③ %K期間
   int          Dperiod,       // ④ %D期間
   int          slowing,       // ⑤ スローイング
   int          method,        // ⑥ 移動平均の種類
   int          price_field,   // ⑦ 価格フィールド
   int          mode,          // ⑧ 取得するライン
   int          shift          // ⑨ シフト（何本前のバーか）
);</code></pre>
<p>引数が9つもあるので少し多く感じますが、一つずつ見ていきましょう。</p>
<h3><span id="toc5">① symbol（通貨ペア）</span></h3>
<p>値を取得したい通貨ペアを文字列で指定します。現在のチャートの通貨ペアを使う場合は<code>NULL</code>または<code>Symbol()</code>と書きます。</p>
<h3><span id="toc6">② timeframe（時間足）</span></h3>
<p>時間足を定数で指定します。現在のチャートの時間足を使う場合は<code>0</code>または<code>PERIOD_CURRENT</code>と書きます。主な定数は以下のとおりです。</p>
<table>
<thead>
<tr>
<th>定数</th>
<th>時間足</th>
</tr>
</thead>
<tbody>
<tr>
<td>PERIOD_M1</td>
<td>1分足</td>
</tr>
<tr>
<td>PERIOD_M5</td>
<td>5分足</td>
</tr>
<tr>
<td>PERIOD_M15</td>
<td>15分足</td>
</tr>
<tr>
<td>PERIOD_M30</td>
<td>30分足</td>
</tr>
<tr>
<td>PERIOD_H1</td>
<td>1時間足</td>
</tr>
<tr>
<td>PERIOD_H4</td>
<td>4時間足</td>
</tr>
<tr>
<td>PERIOD_D1</td>
<td>日足</td>
</tr>
<tr>
<td>PERIOD_W1</td>
<td>週足</td>
</tr>
</tbody>
</table>
<h3><span id="toc7">③ Kperiod（%K期間）</span></h3>
<p>%Kラインの計算に使う期間です。一般的には<strong>5</strong>や<strong>14</strong>がよく使われます。</p>
<h3><span id="toc8">④ Dperiod（%D期間）</span></h3>
<p>%Kを平滑化して%Dを求める際の移動平均の期間です。一般的には<strong>3</strong>がよく使われます。</p>
<h3><span id="toc9">⑤ slowing（スローイング）</span></h3>
<p>スローストキャスティクスのスローイング値です。<strong>1</strong>にするとファスト、<strong>3</strong>にするとスローストキャスティクスになります。通常は<strong>3</strong>を指定します。</p>
<h3><span id="toc10">⑥ method（移動平均の種類）</span></h3>
<p>%Dラインの平滑化に使用する移動平均の種類を指定します。</p>
<table>
<thead>
<tr>
<th>定数</th>
<th>種類</th>
</tr>
</thead>
<tbody>
<tr>
<td>MODE_SMA</td>
<td>単純移動平均（最も一般的）</td>
</tr>
<tr>
<td>MODE_EMA</td>
<td>指数移動平均</td>
</tr>
<tr>
<td>MODE_SMMA</td>
<td>平滑移動平均</td>
</tr>
<tr>
<td>MODE_LWMA</td>
<td>線形加重移動平均</td>
</tr>
</tbody>
</table>
<h3><span id="toc11">⑦ price_field（価格フィールド）</span></h3>
<p>ストキャスティクスの計算に使う価格の種類です。</p>
<table>
<thead>
<tr>
<th>値</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>高値/安値（Low/High）を使用 ※一般的</td>
</tr>
<tr>
<td>1</td>
<td>終値（Close/Close）を使用</td>
</tr>
</tbody>
</table>
<p>通常は<strong>0（高値/安値）</strong>を使います。</p>
<h3><span id="toc12">⑧ mode（取得するライン）</span></h3>
<p>どのラインの値を取得するかを指定します。</p>
<table>
<thead>
<tr>
<th>定数</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td>MODE_MAIN（= 0）</td>
<td>メインライン（%D）</td>
</tr>
<tr>
<td>MODE_SIGNAL（= 1）</td>
<td>シグナルライン（Slow %D）</td>
</tr>
</tbody>
</table>
<h3><span id="toc13">⑨ shift（シフト）</span></h3>
<p>何本前のバーの値を取得するかを指定します。<strong>0</strong>で現在のバー、<strong>1</strong>で1本前のバー（確定済み）です。</p>
<h2><span id="toc14">基本的な使い方</span></h2>
<p>まずはストキャスティクスの値を取得してチャートに表示するシンプルなコードを見てみましょう。</p>
<pre><code class="language-mql4">#property strict

void OnTick()
{
   // メインライン（%D）を取得 - 1本前の確定バー
   double stochMain = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_MAIN, 1);

   // シグナルライン（Slow %D）を取得 - 1本前の確定バー
   double stochSignal = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_SIGNAL, 1);

   // チャートに表示
   Comment("Stochastic Main: ", DoubleToString(stochMain, 2),
           "\nStochastic Signal: ", DoubleToString(stochSignal, 2));
}</code></pre>
<p>このコードでは、期間5・3・3のスローストキャスティクス（SMA）のメインラインとシグナルラインの値を取得し、Comment関数でチャート左上に表示しています。shift=1を指定しているので、確定済みの1本前のバーの値を取得しています。</p>
<h2><span id="toc15">実践サンプルEA ― ストキャスティクスのクロスで売買</span></h2>
<p>ここからは、ストキャスティクスのゴールデンクロス（買いシグナル）とデッドクロス（売りシグナル）で売買する実践的なEAを作ってみましょう。</p>
<h3><span id="toc16">売買ルール</span></h3>
<ul>
<li><strong>買いエントリー</strong>：ストキャスティクスが20以下のゾーンで、メインラインがシグナルラインを下から上にクロス（ゴールデンクロス）</li>
<li><strong>売りエントリー</strong>：ストキャスティクスが80以上のゾーンで、メインラインがシグナルラインを上から下にクロス（デッドクロス）</li>
<li>既にポジションがある場合は新規エントリーしない</li>
</ul>
<h3><span id="toc17">EAの完全なコード</span></h3>
<pre><code class="language-mql4">//+------------------------------------------------------------------+
//|                                          StochasticCrossEA.mq4   |
//|                         ストキャスティクス クロスEA サンプル        |
//+------------------------------------------------------------------+
#property strict

// --- 入力パラメータ ---
input int    KPeriod      = 5;       // %K期間
input int    DPeriod      = 3;       // %D期間
input int    Slowing      = 3;       // スローイング
input double UpperLevel   = 80.0;    // 上限レベル（売られすぎ判定）
input double LowerLevel   = 20.0;    // 下限レベル（買われすぎ判定）
input double LotSize      = 0.1;     // ロットサイズ
input int    StopLoss     = 100;     // ストップロス（pips）
input int    TakeProfit   = 200;     // テイクプロフィット（pips）
input int    MagicNumber  = 12345;   // マジックナンバー

// --- 新バー判定用変数 ---
datetime lastBarTime = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                     |
//+------------------------------------------------------------------+
int OnInit()
{
   Print("StochasticCrossEA が初期化されました");
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 新しいバーが生成されたか判定する関数                                  |
//+------------------------------------------------------------------+
bool IsNewBar()
{
   datetime currentBarTime = iTime(NULL, 0, 0);
   if(lastBarTime != currentBarTime)
   {
      lastBarTime = currentBarTime;
      return true;
   }
   return false;
}

//+------------------------------------------------------------------+
//| 現在のポジション数を取得する関数                                     |
//+------------------------------------------------------------------+
int CountPositions(int type)
{
   int count = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            if(OrderType() == type)
               count++;
         }
      }
   }
   return count;
}

//+------------------------------------------------------------------+
//| Expert tick function                                               |
//+------------------------------------------------------------------+
void OnTick()
{
   // 新しいバーが確定したときだけ処理
   if(!IsNewBar())
      return;

   // --- ストキャスティクスの値を取得 ---
   // 1本前（確定済み）のメインライン
   double mainCurr   = iStochastic(NULL, 0, KPeriod, DPeriod, Slowing,
                                    MODE_SMA, 0, MODE_MAIN, 1);
   // 1本前（確定済み）のシグナルライン
   double signalCurr = iStochastic(NULL, 0, KPeriod, DPeriod, Slowing,
                                    MODE_SMA, 0, MODE_SIGNAL, 1);
   // 2本前のメインライン
   double mainPrev   = iStochastic(NULL, 0, KPeriod, DPeriod, Slowing,
                                    MODE_SMA, 0, MODE_MAIN, 2);
   // 2本前のシグナルライン
   double signalPrev = iStochastic(NULL, 0, KPeriod, DPeriod, Slowing,
                                    MODE_SMA, 0, MODE_SIGNAL, 2);

   // --- ゴールデンクロス判定（買いシグナル） ---
   bool goldenCross = (mainPrev < signalPrev) &#038;&#038; (mainCurr > signalCurr);

   // --- デッドクロス判定（売りシグナル） ---
   bool deadCross = (mainPrev > signalPrev) && (mainCurr < signalCurr);

   // --- 買いエントリー ---
   if(goldenCross &#038;&#038; mainCurr < LowerLevel &#038;&#038; CountPositions(OP_BUY) == 0)
   {
      double sl = NormalizeDouble(Ask - StopLoss * Point, Digits);
      double tp = NormalizeDouble(Ask + TakeProfit * Point, Digits);

      int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, sl, tp,
                              "Stoch GoldenCross", MagicNumber, 0, clrBlue);
      if(ticket > 0)
         Print("買い注文成功: チケット=", ticket);
      else
         Print("買い注文失敗: エラー=", GetLastError());
   }

   // --- 売りエントリー ---
   if(deadCross && mainCurr > UpperLevel && CountPositions(OP_SELL) == 0)
   {
      double sl = NormalizeDouble(Bid + StopLoss * Point, Digits);
      double tp = NormalizeDouble(Bid - TakeProfit * Point, Digits);

      int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, sl, tp,
                              "Stoch DeadCross", MagicNumber, 0, clrRed);
      if(ticket > 0)
         Print("売り注文成功: チケット=", ticket);
      else
         Print("売り注文失敗: エラー=", GetLastError());
   }

   // --- チャート表示 ---
   Comment("Main[1]: ", DoubleToString(mainCurr, 2),
           "  Signal[1]: ", DoubleToString(signalCurr, 2),
           "\nMain[2]: ", DoubleToString(mainPrev, 2),
           "  Signal[2]: ", DoubleToString(signalPrev, 2));
}</code></pre>
<h2><span id="toc18">サンプルコードのポイント解説</span></h2>
<h3><span id="toc19">ポイント1：新バー判定で無駄な処理を防ぐ</span></h3>
<p><code>IsNewBar()</code>関数を使い、新しいバーが確定したタイミングでのみ売買判定を行っています。OnTick()はティックごとに呼ばれるため、そのまま処理すると同じバーで何度もシグナルを検出してしまいます。新バー判定を入れることで、確定した値に基づく安定したシグナル検出ができます。</p>
<h3><span id="toc20">ポイント2：2本のバーでクロスを検出する</span></h3>
<p>クロスの判定には、<strong>1本前（shift=1）</strong>と<strong>2本前（shift=2）</strong>の値を比較しています。</p>
<pre><code class="language-mql4">// ゴールデンクロス：2本前は「メイン ＜ シグナル」→ 1本前は「メイン ＞ シグナル」
bool goldenCross = (mainPrev < signalPrev) &#038;&#038; (mainCurr > signalCurr);

// デッドクロス：2本前は「メイン ＞ シグナル」→ 1本前は「メイン ＜ シグナル」
bool deadCross = (mainPrev > signalPrev) && (mainCurr < signalCurr);</code></pre>
<p>shift=0（現在のバー）を使うと、バーが確定するまで値が変動し続けるため、誤ったシグナルが出る可能性があります。確定済みのshift=1とshift=2を使うのが安全です。</p>
<h3><span id="toc21">ポイント3：ゾーンフィルタでダマシを減らす</span></h3>
<p>単純なクロスだけではダマシ（偽シグナル）が多くなります。そこで、<strong>買いはLowerLevel（20）以下のゾーン</strong>、<strong>売りはUpperLevel（80）以上のゾーン</strong>でのみエントリーするフィルタを入れています。売られすぎ・買われすぎの極端な領域でのクロスに絞ることで、シグナルの精度を高めています。</p>
<h2><span id="toc22">カスタマイズのヒント</span></h2>
<h3><span id="toc23">マルチタイムフレーム分析</span></h3>
<p>iStochastic関数の第2引数（timeframe）を変えることで、異なる時間足のストキャスティクスを取得できます。例えば、日足のトレンド方向を確認してからエントリーするといった使い方が可能です。</p>
<pre><code class="language-mql4">// 日足のストキャスティクスを取得
double dailyMain = iStochastic(NULL, PERIOD_D1, 5, 3, 3, MODE_SMA, 0, MODE_MAIN, 1);

// 日足が50以上なら上昇傾向 → 買いのみエントリーする、など
if(dailyMain > 50.0 && goldenCross && mainCurr < LowerLevel)
{
   // 買いエントリー処理
}</code></pre>
<h3><span id="toc24">他のインジケーターとの併用</span></h3>
<p>ストキャスティクス単体よりも、移動平均線（iMA関数）やRSI（iRSI関数）など他のインジケーターと組み合わせることで、より信頼性の高い売買ルールを構築できます。例えば、移動平均線の上にいるときだけ買いシグナルを採用する、といったフィルタが考えられます。</p>
<h3><span id="toc25">ストラテジーテスターで最適化</span></h3>
<p>KPeriod、DPeriod、Slowing、UpperLevel、LowerLevelなどのパラメータは、MetaTraderのストラテジーテスターで最適化できます。input変数として宣言しているので、テスターの最適化機能でベストな組み合わせを探してみましょう。ただし、過剰最適化（カーブフィッティング）には注意が必要です。</p>
<h2><span id="toc26">まとめ</span></h2>
<p>この記事で学んだポイントを整理します。</p>
<ol>
<li><strong>iStochastic関数</strong>は9つの引数を持ち、MQL4からストキャスティクスの値を取得できる関数です</li>
<li><strong>MODE_MAIN</strong>でメインライン（%D）、<strong>MODE_SIGNAL</strong>でシグナルライン（Slow %D）を取得します</li>
<li><strong>price_field</strong>は通常0（高値/安値ベース）を使い、1（終値ベース）との違いを理解しておきましょう</li>
<li>クロス判定にはshift=1とshift=2の<strong>確定済みバー</strong>を使うのが安全です</li>
<li>80/20のゾーンフィルタやマルチタイムフレーム分析を組み合わせることで、<strong>ダマシを減らして精度を向上</strong>させることができます</li>
</ol>
<p>ストキャスティクスはシンプルながら強力なオシレーター指標です。まずは今回のサンプルEAをストラテジーテスターで動かして、パラメータを変えながら挙動を確認してみてください。実際に手を動かすことで、iStochastic関数の使い方がしっかり身につくはずです！</p>
<p>投稿 <a href="https://mql-programing.com/archives/13022/%e3%80%90mql4%e3%80%91istochastic%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%ae%8c%e5%85%a8%e8%a7%a3%e8%aa%ac%ef%bc%81%e3%82%b9%e3%83%88%e3%82%ad%e3%83%a3%e3%82%b9%e3%83%86/">【MQL4】iStochastic関数の使い方を完全解説！ストキャスティクスを使ったEAサンプル付き</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【MQL4】iMACD関数の使い方を徹底解説！MACDの値を取得してEAに組み込もう【サンプルコード付き】</title>
		<link>https://mql-programing.com/archives/13019/%e3%80%90mql4%e3%80%91imacd%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81macd%e3%81%ae%e5%80%a4%e3%82%92%e5%8f%96%e5%be%97%e3%81%97/</link>
		
		<dc:creator><![CDATA[朝日奈りさ]]></dc:creator>
		<pubDate>Wed, 08 Apr 2026 01:00:00 +0000</pubDate>
				<category><![CDATA[関数]]></category>
		<category><![CDATA[【辞書】MQLリファレンス]]></category>
		<category><![CDATA[MQL4]]></category>
		<category><![CDATA[EA開発]]></category>
		<category><![CDATA[インジケーター関数]]></category>
		<category><![CDATA[MACD]]></category>
		<category><![CDATA[iMACD]]></category>
		<guid isPermaLink="false">https://mql-programing.com/?p=13019</guid>

					<description><![CDATA[<p>「MACDのクロスで自動売買したい！」──テクニカル分析の定番指標MACDをEAに組み込むなら、まず覚えるべきなのがiMACD関数です。 この記事では、MQL4のiMACD関数の書式・引数の意味から、ゴールデンクロス・デ [&#8230;]</p>
<p>投稿 <a href="https://mql-programing.com/archives/13019/%e3%80%90mql4%e3%80%91imacd%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81macd%e3%81%ae%e5%80%a4%e3%82%92%e5%8f%96%e5%be%97%e3%81%97/">【MQL4】iMACD関数の使い方を徹底解説！MACDの値を取得してEAに組み込もう【サンプルコード付き】</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[<p>「MACDのクロスで自動売買したい！」──テクニカル分析の定番指標MACDをEAに組み込むなら、まず覚えるべきなのが<strong>iMACD関数</strong>です。</p>
<p>この記事では、MQL4の<strong>iMACD関数</strong>の書式・引数の意味から、ゴールデンクロス・デッドクロスの判定ロジック、そして実際に動くEAのサンプルコードまで、ステップバイステップで解説します。初心者の方でも、この記事を読み終える頃にはMACDを使ったEAの原型が作れるようになるはずです。</p>
<h2><span id="toc1">MACDのおさらい</span></h2>
<p>コードの話に入る前に、MACD（Moving Average Convergence Divergence）の基本をおさらいしておきましょう。MACDは以下の<strong>3つの要素</strong>で構成されます。</p>
<h3><span id="toc2">MACDの3つの構成要素</span></h3>
<ul>
<li><strong>メインライン（MACDライン）</strong>：短期EMA（通常12期間）と長期EMA（通常26期間）の差</li>
<li><strong>シグナルライン</strong>：メインラインのEMA（通常9期間）</li>
<li><strong>ヒストグラム</strong>：メインライン − シグナルラインの差をバーで表示したもの</li>
</ul>
<h3><span id="toc3">基本的な売買シグナル</span></h3>
<ul>
<li><strong>ゴールデンクロス（買いシグナル）</strong>：メインラインがシグナルラインを下から上に抜ける</li>
<li><strong>デッドクロス（売りシグナル）</strong>：メインラインがシグナルラインを上から下に抜ける</li>
</ul>
<p>このクロスをプログラムで検出するのが、MACD系EAの基本中の基本です。</p>
<h2><span id="toc4">iMACD関数の書式と引数</span></h2>
<p>MQL4でMACDの値を取得するには、<strong>iMACD関数</strong>を使います。書式は以下のとおりです。</p>
<pre><code class="language-mql4">double iMACD(
   string       symbol,           // 通貨ペア名
   int          timeframe,        // 時間足
   int          fast_ema_period,  // 短期EMAの期間
   int          slow_ema_period,  // 長期EMAの期間
   int          signal_period,    // シグナルラインの期間
   int          applied_price,    // 適用価格
   int          mode,             // 取得するライン
   int          shift             // シフト（何本前のバーか）
);</code></pre>
<h3><span id="toc5">各引数の詳細</span></h3>
<table>
<thead>
<tr>
<th>引数</th>
<th>説明</th>
<th>よく使う値</th>
</tr>
</thead>
<tbody>
<tr>
<td>symbol</td>
<td>通貨ペア名。現在のチャートならNULL</td>
<td>NULL, Symbol()</td>
</tr>
<tr>
<td>timeframe</td>
<td>時間足。0で現在のチャートの時間足</td>
<td>0, PERIOD_H1 など</td>
</tr>
<tr>
<td>fast_ema_period</td>
<td>短期EMAの期間</td>
<td>12</td>
</tr>
<tr>
<td>slow_ema_period</td>
<td>長期EMAの期間</td>
<td>26</td>
</tr>
<tr>
<td>signal_period</td>
<td>シグナルラインの期間</td>
<td>9</td>
</tr>
<tr>
<td>applied_price</td>
<td>計算に使う価格の種類</td>
<td>PRICE_CLOSE</td>
</tr>
<tr>
<td>mode</td>
<td>取得するライン（後述）</td>
<td>MODE_MAIN, MODE_SIGNAL</td>
</tr>
<tr>
<td>shift</td>
<td>何本前のバーの値を取得するか</td>
<td>0（現在）, 1（1本前）</td>
</tr>
</tbody>
</table>
<h3><span id="toc6">modeパラメータの値</span></h3>
<p><strong>mode</strong>には以下の2つの定数を指定できます。</p>
<ul>
<li><strong>MODE_MAIN（0）</strong>：MACDメインラインの値を返す</li>
<li><strong>MODE_SIGNAL（1）</strong>：シグナルラインの値を返す</li>
</ul>
<p>なお、ヒストグラムの値は直接取得する定数がありません。<strong>メインライン − シグナルライン</strong>を自分で計算して求めます。</p>
<h3><span id="toc7">適用価格（applied_price）の定数一覧</span></h3>
<table>
<thead>
<tr>
<th>定数名</th>
<th>値</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td>PRICE_CLOSE</td>
<td>0</td>
<td>終値</td>
</tr>
<tr>
<td>PRICE_OPEN</td>
<td>1</td>
<td>始値</td>
</tr>
<tr>
<td>PRICE_HIGH</td>
<td>2</td>
<td>高値</td>
</tr>
<tr>
<td>PRICE_LOW</td>
<td>3</td>
<td>安値</td>
</tr>
<tr>
<td>PRICE_MEDIAN</td>
<td>4</td>
<td>中央値 (High+Low)/2</td>
</tr>
<tr>
<td>PRICE_TYPICAL</td>
<td>5</td>
<td>代表値 (High+Low+Close)/3</td>
</tr>
<tr>
<td>PRICE_WEIGHTED</td>
<td>6</td>
<td>加重終値 (High+Low+Close+Close)/4</td>
</tr>
</tbody>
</table>
<p>特別な理由がなければ、<strong>PRICE_CLOSE（終値）</strong>を使うのが一般的です。</p>
<h2><span id="toc8">基本的な使い方</span></h2>
<p>まずは最もシンプルな使い方を見てみましょう。現在のチャートでMACDのメインラインとシグナルラインの値を取得するコードです。</p>
<pre><code class="language-mql4">void OnTick()
{
   // 1本前の確定バーからMACDメインラインの値を取得
   double macdMain = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);
   
   // 1本前の確定バーからシグナルラインの値を取得
   double macdSignal = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 1);
   
   // ヒストグラムの値を計算
   double histogram = macdMain - macdSignal;
   
   // ログに出力して確認
   Print("MACD Main: ", macdMain, " Signal: ", macdSignal, " Histogram: ", histogram);
}</code></pre>
<p><strong>ポイント：</strong>shiftに<strong>1</strong>を指定しているのは、「1本前の確定したバー」の値を取得するためです。shift=0は現在形成中のバーなので値が変動します。売買判定にはshift=1以降の確定した値を使うのが基本です。</p>
<h2><span id="toc9">MACDクロス判定ロジック</span></h2>
<p>MACDのゴールデンクロス・デッドクロスを判定するには、<strong>1本前と2本前</strong>のバーの値を比較します。</p>
<pre><code class="language-mql4">// --- 1本前のバー（直近の確定バー）---
double macdMain1   = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);
double macdSignal1 = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 1);

// --- 2本前のバー ---
double macdMain2   = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 2);
double macdSignal2 = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 2);

// ゴールデンクロス判定：2本前ではメインがシグナル以下 → 1本前でメインがシグナルを超えた
bool goldenCross = (macdMain2 <= macdSignal2) &#038;&#038; (macdMain1 > macdSignal1);

// デッドクロス判定：2本前ではメインがシグナル以上 → 1本前でメインがシグナルを下回った
bool deadCross = (macdMain2 >= macdSignal2) && (macdMain1 < macdSignal1);</code></pre>
<p>この「2時点を比較してクロスを検出する」パターンは、移動平均線やRSIなど他のインジケーターでも応用できる重要なテクニックです。</p>
<h2><span id="toc10">実践！MACDクロスEAのサンプルコード</span></h2>
<p>ここからは、MACDのゴールデンクロスで買い、デッドクロスで売り（ドテン方式）のEAを作ってみましょう。実際にMT4で動作する完全なコードです。</p>
<pre><code class="language-mql4">//+------------------------------------------------------------------+
//|                                              MACD_Cross_EA.mq4   |
//|                        MACDクロスで売買するシンプルなEA            |
//+------------------------------------------------------------------+
#property strict

// --- 入力パラメータ ---
input int    FastEMA        = 12;          // 短期EMA期間
input int    SlowEMA        = 26;          // 長期EMA期間
input int    SignalPeriod    = 9;           // シグナル期間
input double LotSize        = 0.1;         // ロット数
input int    MagicNumber    = 20240101;    // マジックナンバー
input int    Slippage       = 3;           // スリッページ（ポイント）

//+------------------------------------------------------------------+
//| 新しいバーが形成されたか判定する関数                                |
//+------------------------------------------------------------------+
bool IsNewBar()
{
   static datetime lastBarTime = 0;
   datetime currentBarTime = iTime(NULL, 0, 0);
   
   if(lastBarTime != currentBarTime)
   {
      lastBarTime = currentBarTime;
      return true;
   }
   return false;
}

//+------------------------------------------------------------------+
//| 自分のEAが持つポジションの種類を返す関数                           |
//| 戻り値: 1=買いポジあり, -1=売りポジあり, 0=ポジなし                |
//+------------------------------------------------------------------+
int GetMyPosition()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            if(OrderType() == OP_BUY)  return 1;
            if(OrderType() == OP_SELL) return -1;
         }
      }
   }
   return 0;
}

//+------------------------------------------------------------------+
//| 自分のEAが持つポジションを全決済する関数                           |
//+------------------------------------------------------------------+
void CloseMyPositions(int posType)
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            if(posType == 1 && OrderType() == OP_BUY)
               OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clrNone);
            if(posType == -1 && OrderType() == OP_SELL)
               OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clrNone);
         }
      }
   }
}

//+------------------------------------------------------------------+
//| メインのティック処理                                               |
//+------------------------------------------------------------------+
void OnTick()
{
   // 新しいバーが形成されたときだけ処理する
   if(!IsNewBar()) return;
   
   // --- MACDの値を取得 ---
   double macdMain1   = iMACD(NULL, 0, FastEMA, SlowEMA, SignalPeriod, PRICE_CLOSE, MODE_MAIN, 1);
   double macdSignal1 = iMACD(NULL, 0, FastEMA, SlowEMA, SignalPeriod, PRICE_CLOSE, MODE_SIGNAL, 1);
   double macdMain2   = iMACD(NULL, 0, FastEMA, SlowEMA, SignalPeriod, PRICE_CLOSE, MODE_MAIN, 2);
   double macdSignal2 = iMACD(NULL, 0, FastEMA, SlowEMA, SignalPeriod, PRICE_CLOSE, MODE_SIGNAL, 2);
   
   // --- クロス判定 ---
   bool goldenCross = (macdMain2 <= macdSignal2) &#038;&#038; (macdMain1 > macdSignal1);
   bool deadCross   = (macdMain2 >= macdSignal2) && (macdMain1 < macdSignal1);
   
   // --- 現在のポジション状態を取得 ---
   int myPos = GetMyPosition();
   
   // --- ゴールデンクロス → 買いエントリー ---
   if(goldenCross)
   {
      // 売りポジションがあれば先に決済
      if(myPos == -1) CloseMyPositions(-1);
      
      // 買いポジションがなければ新規注文
      if(GetMyPosition() != 1)
      {
         int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, 0, 0,
                                "MACD GC Buy", MagicNumber, 0, clrBlue);
         if(ticket < 0)
            Print("Buy OrderSend Error: ", GetLastError());
         else
            Print("Buy Order Success! Ticket: ", ticket);
      }
   }
   
   // --- デッドクロス → 売りエントリー ---
   if(deadCross)
   {
      // 買いポジションがあれば先に決済
      if(myPos == 1) CloseMyPositions(1);
      
      // 売りポジションがなければ新規注文
      if(GetMyPosition() != -1)
      {
         int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, 0, 0,
                                "MACD DC Sell", MagicNumber, 0, clrRed);
         if(ticket < 0)
            Print("Sell OrderSend Error: ", GetLastError());
         else
            Print("Sell Order Success! Ticket: ", ticket);
      }
   }
}</code></pre>
<h3><span id="toc11">サンプルEAのポイント解説</span></h3>
<ul>
<li><strong>IsNewBar関数</strong>：新しいバーが形成されたときだけ処理を実行します。これにより無駄な重複注文を防ぎます。</li>
<li><strong>MagicNumber</strong>：このEAが出した注文を識別するための番号です。他のEAや手動注文と区別できます。</li>
<li><strong>ドテン方式</strong>：ゴールデンクロスで買いに転換、デッドクロスで売りに転換する仕組みです。反対ポジションを先に決済してから新規注文を出します。</li>
<li><strong>GetMyPosition関数</strong>：自分のEAが持つポジションの状態を調べる関数です。ポジション管理はEA開発で必須のテクニックです。</li>
</ul>
<h2><span id="toc12">応用：ゼロラインフィルターでダマシを減らす</span></h2>
<p>MACDクロスだけだと「ダマシ」（偽のシグナル）が多くなりがちです。精度を上げるテクニックとして、<strong>ゼロラインフィルター</strong>があります。</p>
<p>考え方はシンプルです。</p>
<ul>
<li><strong>買いシグナル</strong>：ゴールデンクロス かつ MACDメインラインが<strong>ゼロより下</strong>で発生したとき（底からの反転を狙う）</li>
<li><strong>売りシグナル</strong>：デッドクロス かつ MACDメインラインが<strong>ゼロより上</strong>で発生したとき（天井からの反転を狙う）</li>
</ul>
<p>コードに組み込むなら、クロス判定の条件に1行追加するだけです。</p>
<pre><code class="language-mql4">// ゼロラインフィルター付きのゴールデンクロス判定
bool filteredGoldenCross = goldenCross && (macdMain1 < 0);

// ゼロラインフィルター付きのデッドクロス判定
bool filteredDeadCross = deadCross &#038;&#038; (macdMain1 > 0);</code></pre>
<p>たった1行の条件追加ですが、トレンドの初動を捉えやすくなり、レンジ相場でのダマシを軽減できます。バックテストで効果を確認してみてください。</p>
<h2><span id="toc13">注意点・よくあるつまずきポイント</span></h2>
<h3><span id="toc14">1. MT4とMT5でMACDの表示が異なる</span></h3>
<p>MT4のMACDインジケーターでは、<strong>メインラインがヒストグラム（バー）</strong>で表示され、シグナルラインが点線で表示されます。一方MT5では、メインラインもシグナルラインも<strong>ライン</strong>で表示され、別途ヒストグラムが描画されます。見た目は違いますが、iMACD関数で取得できる値の意味は同じです。</p>
<h3><span id="toc15">2. ヒストグラムは自分で計算する</span></h3>
<p>iMACD関数にはヒストグラムを直接取得するモードがありません。ヒストグラムが必要な場合は、以下のように計算してください。</p>
<pre><code class="language-mql4">double histogram = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1)
                 - iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 1);</code></pre>
<h3><span id="toc16">3. マルチタイムフレーム分析に使える</span></h3>
<p>iMACD関数の第2引数（timeframe）を変えれば、現在のチャートと違う時間足のMACDを取得できます。例えば、5分足チャート上で1時間足のMACDを確認してフィルターに使う、といった活用が可能です。</p>
<pre><code class="language-mql4">// 1時間足のMACDメインラインを取得
double macdH1 = iMACD(NULL, PERIOD_H1, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);</code></pre>
<h3><span id="toc17">4. 引数の順番に注意</span></h3>
<p>iMACD関数は引数が8つもあるため、順番を間違えやすいです。特に<strong>mode</strong>と<strong>shift</strong>を逆にするミスはよくあります。迷ったら公式リファレンスで確認する習慣をつけましょう。</p>
<h2><span id="toc18">まとめ</span></h2>
<p>この記事では、MQL4の<strong>iMACD関数</strong>について以下のポイントを解説しました。</p>
<ul>
<li>iMACD関数は<strong>8つの引数</strong>を持ち、MACDのメインラインとシグナルラインの値を取得できる</li>
<li>クロス判定は<strong>shift=1とshift=2</strong>の値を比較して行う</li>
<li>EA開発では<strong>新規バー判定</strong>・<strong>マジックナンバー管理</strong>・<strong>ポジション管理関数</strong>が重要</li>
<li><strong>ゼロラインフィルター</strong>を追加するだけでダマシを軽減できる</li>
<li>MT4とMT5でMACDの<strong>表示方法が異なる</strong>点に注意</li>
</ul>
<p>今回のサンプルEAはシンプルな構成ですが、ストップロスやテイクプロフィット、トレーリングストップなどを追加していくことで、より実践的なEAに育てていくことができます。まずはバックテストで動作を確認し、少しずつカスタマイズしてみてください！</p>
<p>投稿 <a href="https://mql-programing.com/archives/13019/%e3%80%90mql4%e3%80%91imacd%e9%96%a2%e6%95%b0%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81macd%e3%81%ae%e5%80%a4%e3%82%92%e5%8f%96%e5%be%97%e3%81%97/">【MQL4】iMACD関数の使い方を徹底解説！MACDの値を取得してEAに組み込もう【サンプルコード付き】</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【MQL4】注文情報を取得する関数を徹底解説！OrderOpenPrice・OrderStopLoss・OrderTakeProfit・OrderCloseTime・OrderProfit の使い方</title>
		<link>https://mql-programing.com/archives/13011/%e3%80%90mql4%e3%80%91%e6%b3%a8%e6%96%87%e6%83%85%e5%a0%b1%e3%82%92%e5%8f%96%e5%be%97%e3%81%99%e3%82%8b%e9%96%a2%e6%95%b0%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81orderopenprice%e3%83%bbor/</link>
		
		<dc:creator><![CDATA[朝日奈りさ]]></dc:creator>
		<pubDate>Tue, 07 Apr 2026 01:00:00 +0000</pubDate>
				<category><![CDATA[関数]]></category>
		<category><![CDATA[【辞書】MQLリファレンス]]></category>
		<category><![CDATA[OrderOpenPrice]]></category>
		<category><![CDATA[MQL4]]></category>
		<category><![CDATA[EA開発]]></category>
		<category><![CDATA[注文情報取得]]></category>
		<category><![CDATA[OrderStopLoss]]></category>
		<guid isPermaLink="false">https://mql-programing.com/?p=13011</guid>

					<description><![CDATA[<p>EA（自動売買）を開発していると、「今持っているポジションのエントリー価格はいくらだろう？」「ストップロスはちゃんと設定されているかな？」といった場面に必ず出くわします。MQL4には、選択中の注文からさまざまな情報を取り [&#8230;]</p>
<p>投稿 <a href="https://mql-programing.com/archives/13011/%e3%80%90mql4%e3%80%91%e6%b3%a8%e6%96%87%e6%83%85%e5%a0%b1%e3%82%92%e5%8f%96%e5%be%97%e3%81%99%e3%82%8b%e9%96%a2%e6%95%b0%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81orderopenprice%e3%83%bbor/">【MQL4】注文情報を取得する関数を徹底解説！OrderOpenPrice・OrderStopLoss・OrderTakeProfit・OrderCloseTime・OrderProfit の使い方</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[<p>EA（自動売買）を開発していると、「今持っているポジションのエントリー価格はいくらだろう？」「ストップロスはちゃんと設定されているかな？」といった場面に必ず出くわします。MQL4には、選択中の注文からさまざまな情報を取り出すための専用関数が用意されています。</p>
<p>この記事では、EA開発で頻繁に使う<strong>5つの注文情報取得関数</strong>――<code>OrderOpenPrice()</code>・<code>OrderStopLoss()</code>・<code>OrderTakeProfit()</code>・<code>OrderCloseTime()</code>・<code>OrderProfit()</code>を、サンプルコード付きで徹底解説します。</p>
<h2><span id="toc1">前提知識：OrderSelect() で注文を選択してから使う</span></h2>
<p>MQL4の注文情報取得関数には、共通のルールがあります。それは<strong>「必ず事前に <code>OrderSelect()</code> で注文を選択しておくこと」</strong>です。</p>
<p><code>OrderSelect()</code> を呼ばずにこれらの関数を使うと、意図しない値が返ってきたり、前回選択した注文の情報が返ってしまったりします。これはMQL4初心者が最もハマりやすいポイントの一つです。</p>
<pre><code class="language-mql4">// 基本パターン：注文を選択してから情報を取得する
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
    double openPrice = OrderOpenPrice();   // エントリー価格
    double sl        = OrderStopLoss();    // 損切り価格
    double tp        = OrderTakeProfit();  // 利確価格
    double profit    = OrderProfit();      // 損益額
}
</code></pre>
<p>この前提を押さえた上で、各関数を詳しく見ていきましょう。</p>
<h2><span id="toc2">OrderOpenPrice() — エントリー価格を取得する</span></h2>
<h3><span id="toc3">基本仕様</span></h3>
<p><code>OrderOpenPrice()</code> は、選択中の注文の<strong>約定価格（エントリー価格）</strong>を <code>double</code> 型で返します。</p>
<pre><code class="language-mql4">double OrderOpenPrice();
</code></pre>
<p>成行注文の場合は実際に約定した価格、指値・逆指値注文（未約定の待機注文）の場合は設定した注文価格が返ります。</p>
<h3><span id="toc4">使用例</span></h3>
<pre><code class="language-mql4">if(OrderSelect(0, SELECT_BY_POS, MODE_TRADES))
{
    double entryPrice = OrderOpenPrice();
    Print("エントリー価格: ", entryPrice);
}
</code></pre>
<p>エントリー価格は、損益の計算やトレーリングストップのロジックなど、あらゆる場面で使う最も基本的な注文情報です。</p>
<h2><span id="toc5">OrderStopLoss() — 損切り価格を取得する</span></h2>
<h3><span id="toc6">基本仕様</span></h3>
<p><code>OrderStopLoss()</code> は、選択中の注文に設定されている<strong>ストップロス（損切り）価格</strong>を <code>double</code> 型で返します。</p>
<pre><code class="language-mql4">double OrderStopLoss();
</code></pre>
<p>ストップロスが設定されていない場合は <strong><code>0</code></strong> が返ります。この性質を利用して、「SLが未設定のポジションを検出する」といった処理が可能です（応用例で後述します）。</p>
<h2><span id="toc7">OrderTakeProfit() — 利確価格を取得する</span></h2>
<h3><span id="toc8">基本仕様</span></h3>
<p><code>OrderTakeProfit()</code> は、選択中の注文に設定されている<strong>テイクプロフィット（利益確定）価格</strong>を <code>double</code> 型で返します。</p>
<pre><code class="language-mql4">double OrderTakeProfit();
</code></pre>
<p><code>OrderStopLoss()</code> と同様に、テイクプロフィットが未設定の場合は <strong><code>0</code></strong> が返ります。</p>
<h2><span id="toc9">OrderCloseTime() — 決済時刻を取得する</span></h2>
<h3><span id="toc10">基本仕様</span></h3>
<p><code>OrderCloseTime()</code> は、選択中の注文の<strong>決済時刻</strong>を <code>datetime</code> 型で返します。</p>
<pre><code class="language-mql4">datetime OrderCloseTime();
</code></pre>
<p>ここで重要なのが、<strong>まだ決済されていないポジション（保有中のポジション）の場合は <code>0</code> が返る</strong>という点です。この性質を使えば、「この注文はまだ保有中か、それとも決済済みか」を判定できます。</p>
<h3><span id="toc11">使用例</span></h3>
<pre><code class="language-mql4">if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
    datetime closeTime = OrderCloseTime();
    if(closeTime > 0)
    {
        Print("決済時刻: ", TimeToString(closeTime, TIME_DATE | TIME_MINUTES));
    }
    else
    {
        Print("この注文はまだ未決済です");
    }
}
</code></pre>
<p>履歴からトレード結果を分析するEAや、日報を自動生成するスクリプトを作る際に活躍します。</p>
<h2><span id="toc12">OrderProfit() — 損益額を取得する</span></h2>
<h3><span id="toc13">基本仕様</span></h3>
<p><code>OrderProfit()</code> は、選択中の注文の<strong>損益額（口座通貨建て）</strong>を <code>double</code> 型で返します。</p>
<pre><code class="language-mql4">double OrderProfit();
</code></pre>
<p>保有中のポジションなら含み損益、決済済みの注文なら確定損益が返ります。</p>
<p><strong>重要な注意点：</strong><code>OrderProfit()</code> が返す値には<strong>スワップポイントと取引手数料は含まれません</strong>。スワップを含めた正確な損益を計算するには、<code>OrderSwap()</code> と <code>OrderCommission()</code> を加算する必要があります。</p>
<pre><code class="language-mql4">// スワップと手数料を含めた正確な損益
double totalProfit = OrderProfit() + OrderSwap() + OrderCommission();
</code></pre>
<h2><span id="toc14">実践サンプル：全ポジションの注文情報を一覧表示する</span></h2>
<p>ここまで学んだ5つの関数を組み合わせて、保有中の全ポジション情報をエキスパートログに出力する実践的な関数を作ってみましょう。</p>
<pre><code class="language-mql4">void ShowAllOrderInfo()
{
    int totalOrders = OrdersTotal();
    Print("===== 保有ポジション一覧（全 ", totalOrders, " 件）=====");

    for(int i = totalOrders - 1; i >= 0; i--)
    {
        if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
            continue;

        // 自分のEAの注文だけを対象にする
        if(OrderMagicNumber() != 12345)
            continue;

        // 待機注文を除外し、成行注文（ポジション）のみ対象にする
        if(OrderType() > OP_SELL)
            continue;

        string type = (OrderType() == OP_BUY) ? "BUY" : "SELL";
        double totalPL = OrderProfit() + OrderSwap() + OrderCommission();

        Print("チケット: ", OrderTicket(),
              " | 通貨: ", OrderSymbol(),
              " | ", type,
              " | ロット: ", OrderLots(),
              " | エントリー: ", DoubleToString(OrderOpenPrice(), Digits),
              " | SL: ", DoubleToString(OrderStopLoss(), Digits),
              " | TP: ", DoubleToString(OrderTakeProfit(), Digits),
              " | 損益: ", DoubleToString(totalPL, 2));
    }

    Print("==========================================");
}
</code></pre>
<p>ループを <strong><code>totalOrders - 1</code> から <code>0</code> に向かって逆順</strong>で回しているのがポイントです。これについては後述の注意点で詳しく説明します。</p>
<h2><span id="toc15">応用例：SL未設定ポジションに自動でSLを追加する</span></h2>
<p><code>OrderStopLoss()</code> が <code>0</code> を返す（＝SL未設定）ポジションを検出し、自動的にストップロスを設定する実用的なサンプルです。</p>
<pre><code class="language-mql4">void SetSLForUnprotectedPositions(int magicNumber, int slPips)
{
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
        if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
            continue;

        if(OrderMagicNumber() != magicNumber)
            continue;

        // SLが既に設定されている場合はスキップ
        if(OrderStopLoss() != 0)
            continue;

        double newSL = 0;
        double point = MarketInfo(OrderSymbol(), MODE_POINT);
        int    digits = (int)MarketInfo(OrderSymbol(), MODE_DIGITS);

        // 3桁/5桁業者対応
        if(digits == 3 || digits == 5)
            point *= 10;

        if(OrderType() == OP_BUY)
        {
            newSL = OrderOpenPrice() - slPips * point;
        }
        else if(OrderType() == OP_SELL)
        {
            newSL = OrderOpenPrice() + slPips * point;
        }
        else
        {
            continue; // 待機注文はスキップ
        }

        newSL = NormalizeDouble(newSL, digits);

        bool result = OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrYellow);

        if(result)
        {
            Print("SL設定成功 チケット:", OrderTicket(), " SL:", DoubleToString(newSL, digits));
        }
        else
        {
            Print("SL設定失敗 チケット:", OrderTicket(), " エラー:", GetLastError());
        }
    }
}
</code></pre>
<p><code>OrderStopLoss() != 0</code> で「SLが設定済みかどうか」を判定し、未設定のポジションにのみ <code>OrderModify()</code> でSLを追加しています。リスク管理を自動化する際にとても便利なパターンです。</p>
<h2><span id="toc16">3つの重要な注意点</span></h2>
<h3><span id="toc17">1. OrderSelect() の呼び忘れに注意</span></h3>
<p>繰り返しになりますが、すべての注文情報取得関数は <code>OrderSelect()</code> で注文を選択した後に呼ぶ必要があります。選択せずに使うと、前回選択した注文の情報が返ったり、不正な値が返ったりして、バグの原因になります。</p>
<h3><span id="toc18">2. ループは逆順（降順）で回す</span></h3>
<p>注文一覧をループする際は、<code>for(int i = OrdersTotal() - 1; i >= 0; i--)</code> のように<strong>逆順で回す</strong>のがMQL4の定石です。</p>
<p>なぜなら、ループ中に注文が決済されるとインデックスがズレてしまうからです。昇順（0から）でループすると、途中の注文が消えた際にインデックスが詰まり、一部の注文がスキップされてしまいます。逆順で回せばこの問題を回避できます。</p>
<h3><span id="toc19">3. OrderProfit() にはスワップ・手数料が含まれない</span></h3>
<p><code>OrderProfit()</code> は純粋な為替差益のみを返します。スワップポイントや取引手数料は含まれません。正確なトータル損益を出すには、必ず以下のように計算してください。</p>
<pre><code class="language-mql4">double totalPL = OrderProfit() + OrderSwap() + OrderCommission();
</code></pre>
<p>特にスワップが大きい通貨ペアや、ECN口座のように手数料が発生する環境では、この差が無視できない金額になることがあります。</p>
<h2><span id="toc20">まとめ</span></h2>
<p>今回解説した5つの関数を一覧表で整理します。</p>
<table>
<thead>
<tr>
<th>関数名</th>
<th>戻り値の型</th>
<th>取得できる情報</th>
<th>備考</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>OrderOpenPrice()</code></td>
<td>double</td>
<td>エントリー価格（約定価格）</td>
<td>待機注文の場合は設定した注文価格</td>
</tr>
<tr>
<td><code>OrderStopLoss()</code></td>
<td>double</td>
<td>ストップロス価格</td>
<td>未設定なら0が返る</td>
</tr>
<tr>
<td><code>OrderTakeProfit()</code></td>
<td>double</td>
<td>テイクプロフィット価格</td>
<td>未設定なら0が返る</td>
</tr>
<tr>
<td><code>OrderCloseTime()</code></td>
<td>datetime</td>
<td>決済時刻</td>
<td>未決済なら0が返る</td>
</tr>
<tr>
<td><code>OrderProfit()</code></td>
<td>double</td>
<td>損益額（口座通貨建て）</td>
<td>スワップ・手数料は含まない</td>
</tr>
</tbody>
</table>
<p>いずれの関数も、<strong>事前に <code>OrderSelect()</code> で注文を選択すること</strong>が必須です。また、ループは逆順で回す、<code>OrderProfit()</code> にはスワップが含まれない、といったポイントを押さえておけば、安全で正確なEAを開発できます。</p>
<p>これらの関数をマスターすれば、ポジション管理・リスク管理・トレード分析など、EA開発の幅が大きく広がります。ぜひ実際のコードに組み込んで試してみてください！</p>
<p>投稿 <a href="https://mql-programing.com/archives/13011/%e3%80%90mql4%e3%80%91%e6%b3%a8%e6%96%87%e6%83%85%e5%a0%b1%e3%82%92%e5%8f%96%e5%be%97%e3%81%99%e3%82%8b%e9%96%a2%e6%95%b0%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81orderopenprice%e3%83%bbor/">【MQL4】注文情報を取得する関数を徹底解説！OrderOpenPrice・OrderStopLoss・OrderTakeProfit・OrderCloseTime・OrderProfit の使い方</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
