<?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/archives/tag/%E3%83%86%E3%82%AF%E3%83%8B%E3%82%AB%E3%83%AB%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%B1%E3%83%BC%E3%82%BF%E3%83%BC/feed/" rel="self" type="application/rss+xml" />
	<link>https://mql-programing.com/archives/tag/テクニカルインジケーター/</link>
	<description>MQLプログラミング学習サイト</description>
	<lastBuildDate>Wed, 01 Apr 2026 03:33:20 +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/archives/tag/テクニカルインジケーター/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<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[MQL4]]></category>
		<category><![CDATA[EA開発]]></category>
		<category><![CDATA[テクニカルインジケーター]]></category>
		<category><![CDATA[iWPR]]></category>
		<category><![CDATA[ウィリアムズ%R]]></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】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[EA開発]]></category>
		<category><![CDATA[テクニカルインジケーター]]></category>
		<category><![CDATA[ADX]]></category>
		<category><![CDATA[iADX]]></category>
		<category><![CDATA[MQL4]]></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】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[iStochastic]]></category>
		<category><![CDATA[MQL4]]></category>
		<category><![CDATA[ストキャスティクス]]></category>
		<category><![CDATA[EA自動売買]]></category>
		<category><![CDATA[テクニカルインジケーター]]></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>
	</channel>
</rss>
