<?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%ad%e3%83%bc%e3%82%bd%e3%82%af%e8%b6%b3/feed/" rel="self" type="application/rss+xml" />
	<link>https://mql-programing.com/archives/tag/ローソク足/</link>
	<description>MQLプログラミング学習サイト</description>
	<lastBuildDate>Wed, 01 Apr 2026 03:57:57 +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入門】iClose・iOpen・iHigh・iLow・iTimeで過去のローソク足データを取得しよう</title>
		<link>https://mql-programing.com/archives/13046/%e3%80%90mql4%e5%85%a5%e9%96%80%e3%80%91iclose%e3%83%bbiopen%e3%83%bbihigh%e3%83%bbilow%e3%83%bbitime%e3%81%a7%e9%81%8e%e5%8e%bb%e3%81%ae%e3%83%ad%e3%83%bc%e3%82%bd%e3%82%af%e8%b6%b3%e3%83%87%e3%83%bc/</link>
		
		<dc:creator><![CDATA[朝日奈りさ]]></dc:creator>
		<pubDate>Fri, 17 Apr 2026 01:00:00 +0000</pubDate>
				<category><![CDATA[【初級編】MQLプログラミング基礎]]></category>
		<category><![CDATA[iClose]]></category>
		<category><![CDATA[iOpen]]></category>
		<category><![CDATA[時系列アクセス関数]]></category>
		<category><![CDATA[MQL4]]></category>
		<category><![CDATA[ローソク足]]></category>
		<guid isPermaLink="false">https://mql-programing.com/?p=13046</guid>

					<description><![CDATA[<p>EA（自動売買プログラム）やカスタムインジケーターを作るとき、「過去のローソク足の価格を取得したい」という場面は非常に多く出てきます。たとえば「1本前の足が陽線だったら買い」「直近5本の高値の中で最も高い価格を調べたい」 [&#8230;]</p>
<p>投稿 <a href="https://mql-programing.com/archives/13046/%e3%80%90mql4%e5%85%a5%e9%96%80%e3%80%91iclose%e3%83%bbiopen%e3%83%bbihigh%e3%83%bbilow%e3%83%bbitime%e3%81%a7%e9%81%8e%e5%8e%bb%e3%81%ae%e3%83%ad%e3%83%bc%e3%82%bd%e3%82%af%e8%b6%b3%e3%83%87%e3%83%bc/">【MQL4入門】iClose・iOpen・iHigh・iLow・iTimeで過去のローソク足データを取得しよう</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[<p>EA（自動売買プログラム）やカスタムインジケーターを作るとき、「過去のローソク足の価格を取得したい」という場面は非常に多く出てきます。たとえば「1本前の足が陽線だったら買い」「直近5本の高値の中で最も高い価格を調べたい」など、ローソク足データの取得はMQL4プログラミングの基本中の基本です。</p>
<p>この記事では、MQL4でローソク足の<strong>始値・終値・高値・安値・開始時刻</strong>を取得するための5つの関数――<code>iOpen()</code>、<code>iClose()</code>、<code>iHigh()</code>、<code>iLow()</code>、<code>iTime()</code>の使い方を、サンプルコード付きでわかりやすく解説します。</p>
<h2><span id="toc1">5つの時系列アクセス関数の概要</span></h2>
<p>MQL4には、ローソク足（バー）の価格情報を取得するための<strong>時系列アクセス関数</strong>が用意されています。iOpen関数は指定した通貨ペア・時間軸・バーシフトに対応するバーの始値を、iClose関数は終値を、iHigh関数は高値を、iLow関数は安値を返す関数です。それぞれの役割は以下のとおりです。</p>
<table border="1" cellpadding="8" cellspacing="0" style="border-collapse: collapse; width: 100%; margin: 1em 0;">
<thead>
<tr style="background-color: #f0f0f0;">
<th>関数名</th>
<th>取得できる値</th>
<th>戻り値の型</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>iOpen()</code></td>
<td>指定バーの<strong>始値</strong>（Open）</td>
<td>double</td>
</tr>
<tr>
<td><code>iClose()</code></td>
<td>指定バーの<strong>終値</strong>（Close）</td>
<td>double</td>
</tr>
<tr>
<td><code>iHigh()</code></td>
<td>指定バーの<strong>高値</strong>（High）</td>
<td>double</td>
</tr>
<tr>
<td><code>iLow()</code></td>
<td>指定バーの<strong>安値</strong>（Low）</td>
<td>double</td>
</tr>
<tr>
<td><code>iTime()</code></td>
<td>指定バーの<strong>形成開始時刻</strong></td>
<td>datetime</td>
</tr>
</tbody>
</table>
<p>5つの関数はすべて<strong>同じ引数の構成</strong>を持っており、一度覚えればすべてすぐに使いこなせます。</p>
<h2><span id="toc2">関数の書式と引数の意味</span></h2>
<p>ここでは<code>iClose()</code>を例に解説しますが、他の4つの関数もまったく同じ形式です。</p>
<pre><code class="language-mql5">double iClose(
    string symbol,    // 通貨ペア名
    int    timeframe, // 時間軸
    int    shift      // バーの位置（シフト）
);
</code></pre>
<h3><span id="toc3">① symbol（通貨ペア名）</span></h3>
<p>通貨ペア名は「気配値表示ウィンドウ」に表示されているとおりに記述します。特定の通貨ペア名を指定せず、EA等を適用したチャートの通貨ペアの終値を取得したい場合は、「NULL」と記述します。</p>
<ul>
<li><code>NULL</code> または <code>Symbol()</code> → EAやインジケーターを適用中のチャートの通貨ペア</li>
<li><code>"USDJPY"</code> → ドル円を明示的に指定</li>
<li><code>"EURUSD"</code> → ユーロドルを明示的に指定</li>
</ul>
<p>通貨ペアを直接記述するとどの通貨ペアチャートにセットしてもその通貨ペアを強制的にトレードしてしまうため、Symbol()と記述しましょう。</p>
<h3><span id="toc4">② timeframe（時間軸）</span></h3>
<p>どの時間足のデータを取得するかを指定します。<code>0</code>またはPERIOD定数を使います。</p>
<table border="1" cellpadding="8" cellspacing="0" style="border-collapse: collapse; width: 100%; margin: 1em 0;">
<thead>
<tr style="background-color: #f0f0f0;">
<th>定数</th>
<th>値</th>
<th>時間足</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>PERIOD_CURRENT</code></td>
<td>0</td>
<td>現在のチャートの時間足</td>
</tr>
<tr>
<td><code>PERIOD_M1</code></td>
<td>1</td>
<td>1分足</td>
</tr>
<tr>
<td><code>PERIOD_M5</code></td>
<td>5</td>
<td>5分足</td>
</tr>
<tr>
<td><code>PERIOD_M15</code></td>
<td>15</td>
<td>15分足</td>
</tr>
<tr>
<td><code>PERIOD_M30</code></td>
<td>30</td>
<td>30分足</td>
</tr>
<tr>
<td><code>PERIOD_H1</code></td>
<td>60</td>
<td>1時間足</td>
</tr>
<tr>
<td><code>PERIOD_H4</code></td>
<td>240</td>
<td>4時間足</td>
</tr>
<tr>
<td><code>PERIOD_D1</code></td>
<td>1440</td>
<td>日足</td>
</tr>
<tr>
<td><code>PERIOD_W1</code></td>
<td>10080</td>
<td>週足</td>
</tr>
<tr>
<td><code>PERIOD_MN1</code></td>
<td>43200</td>
<td>月足</td>
</tr>
</tbody>
</table>
<p><code>0</code>を指定すると、EAやインジケーターを適用しているチャートの時間足が自動的に使われます。マルチタイムフレーム分析（MTF）を行いたい場合は、ここに上位足の定数を明示的に指定します。</p>
<h3><span id="toc5">③ shift（バーの位置）</span></h3>
<p>終値を取得したいバーが現在のバーであれば「０」、１本前のバーであれば「１」、２本前のバーであれば「２」……と記述します。</p>
<ul>
<li><code>0</code> → 現在（最新）のバー</li>
<li><code>1</code> → 1本前のバー</li>
<li><code>2</code> → 2本前のバー</li>
<li><code>n</code> → n本前のバー</li>
</ul>
<p>同じ記述でも時間が進むにつれて値が変化します。数字が大きくなるほど過去のバーを参照します。なお、<strong>shift=0の最新バーはまだ形成中</strong>なので、確定した値を使いたい場合はshift=1以降を使うのが一般的です。</p>
<h2><span id="toc6">基本的な使い方 ― 各関数のサンプルコード</span></h2>
<p>まずは5つの関数それぞれを使って、ログにローソク足情報を出力する基本例を見てみましょう。</p>
<pre><code class="language-mql5">//+------------------------------------------------------------------+
//| 各時系列アクセス関数の基本的な使い方                                 |
//+------------------------------------------------------------------+
#property strict

void OnInit()
{
    // 1本前（確定済み）のバーの各値を取得
    double openPrice  = iOpen(NULL, 0, 1);
    double closePrice = iClose(NULL, 0, 1);
    double highPrice  = iHigh(NULL, 0, 1);
    double lowPrice   = iLow(NULL, 0, 1);
    datetime barTime  = iTime(NULL, 0, 1);

    Print("=== 1本前のローソク足情報 ===");
    Print("開始時刻: ", TimeToString(barTime, TIME_DATE | TIME_MINUTES));
    Print("始値:     ", DoubleToString(openPrice, Digits));
    Print("高値:     ", DoubleToString(highPrice, Digits));
    Print("安値:     ", DoubleToString(lowPrice, Digits));
    Print("終値:     ", DoubleToString(closePrice, Digits));
}
</code></pre>
<p>このコードをEAとしてコンパイルし、チャートにセットすると、「エキスパート」タブに1本前のバーの情報が表示されます。<code>NULL</code>と<code>0</code>を指定しているので、適用したチャートの通貨ペアと時間足のデータが自動的に使われます。</p>
<h2><span id="toc7">実践サンプル① ― 陽線・陰線を判定する</span></h2>
<p>EA開発でよく使うのが「前のローソク足が陽線だったか陰線だったか」の判定です。始値と終値を比較するだけで簡単に実現できます。</p>
<pre><code class="language-mql5">//+------------------------------------------------------------------+
//| 1本前のローソク足が陽線か陰線かを判定                               |
//+------------------------------------------------------------------+
void OnTick()
{
    double prevOpen  = iOpen(Symbol(), 0, 1);
    double prevClose = iClose(Symbol(), 0, 1);

    if(prevClose > prevOpen)
    {
        // 陽線（終値 > 始値）
        Print("1本前は陽線です（上昇）");
    }
    else if(prevClose < prevOpen)
    {
        // 陰線（終値 < 始値）
        Print("1本前は陰線です（下降）");
    }
    else
    {
        // 同値（十字線など）
        Print("1本前は同値線です");
    }
}
</code></pre>
<p>「2本連続で陽線なら買いエントリー」といった条件も、shift=1とshift=2を使って簡単に書けます。</p>
<h2><span id="toc8">実践サンプル② ― 直近N本の最高値・最安値を求める</span></h2>
<p>forループとiHigh/iLowを組み合わせれば、直近N本のバーの中から最高値・最安値を見つけることができます。</p>
<pre><code class="language-mql5">//+------------------------------------------------------------------+
//| 直近N本のバーから最高値・最安値を算出                                |
//+------------------------------------------------------------------+
void OnTick()
{
    int lookback = 20;  // 過去20本分を調べる
    double highest = 0;
    double lowest  = 999999;

    for(int i = 1; i <= lookback; i++)
    {
        double h = iHigh(NULL, 0, i);
        double l = iLow(NULL, 0, i);

        if(h > highest) highest = h;
        if(l < lowest)  lowest  = l;
    }

    Print("直近", lookback, "本の最高値: ", DoubleToString(highest, Digits));
    Print("直近", lookback, "本の最安値: ", DoubleToString(lowest, Digits));
}
</code></pre>
<p>※ブレイクアウト戦略やレンジ判定のロジックに応用できます。</p>
<h2><span id="toc9">実践サンプル③ ― マルチタイムフレーム（MTF）で上位足の値を取得</span></h2>
<p>「チャートの時間足を切り替えても、常に4時間足のオープン時間を取得したい！」という場合にはiTime()関数を使用して引数に「PERIOD_H4」を渡してあげる必要があります。また、EAやインジケーターを適用したチャートの通貨ペアはUSD/JPYだが、取得したい情報がEUR/JPYのものである場合でもiTime()関数が活躍します。これは他のiClose()、iHigh()なども同様です。</p>
<pre><code class="language-mql5">//+------------------------------------------------------------------+
//| 5分足チャート上から日足・4時間足のデータを取得する例                   |
//+------------------------------------------------------------------+
void OnTick()
{
    // 日足の1本前の終値
    double dailyClose = iClose(NULL, PERIOD_D1, 1);
    // 4時間足の1本前の高値
    double h4High     = iHigh(NULL, PERIOD_H4, 1);
    // 4時間足の1本前の安値
    double h4Low      = iLow(NULL, PERIOD_H4, 1);
    // 日足の1本前の開始時刻
    datetime dailyTime = iTime(NULL, PERIOD_D1, 1);

    Print("前日の終値: ", DoubleToString(dailyClose, Digits));
    Print("前日の開始時刻: ", TimeToString(dailyTime, TIME_DATE));
    Print("4H前回バーの高値: ", DoubleToString(h4High, Digits));
    Print("4H前回バーの安値: ", DoubleToString(h4Low, Digits));
}
</code></pre>
<p>たとえば5分足チャート上で「前日の高値・安値」をラインとして引いたり、「4時間足が上昇トレンドなら5分足で押し目買いだけを行う」といったMTFロジックを組むときに活躍します。</p>
<h2><span id="toc10">定義済み配列 Open[] / Close[] / High[] / Low[] / Time[] との違い</span></h2>
<p>MQL4には、i〇〇()関数とは別に、<code>Open[]</code>、<code>Close[]</code>、<code>High[]</code>、<code>Low[]</code>、<code>Time[]</code>という<strong>定義済み配列</strong>も用意されています。EA等を適用したチャートにおける終値は定義済み配列であるClose[]に格納されており、EA等を適用したチャートにおける終値を取得したい場合はClose[]を使用し、EA等を適用したチャート以外の通貨ペアや時間軸における終値を取得したい場合はiClose()関数を使用します。使い分けのポイントは次のとおりです。</p>
<table border="1" cellpadding="8" cellspacing="0" style="border-collapse: collapse; width: 100%; margin: 1em 0;">
<thead>
<tr style="background-color: #f0f0f0;">
<th></th>
<th>定義済み配列<br />（例: <code>Close[1]</code>）</th>
<th>i〇〇()関数<br />（例: <code>iClose(NULL,0,1)</code>）</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>通貨ペア</strong></td>
<td>チャートの通貨ペアのみ</td>
<td>任意の通貨ペアを指定可能</td>
</tr>
<tr>
<td><strong>時間足</strong></td>
<td>チャートの時間足のみ</td>
<td>任意の時間足を指定可能</td>
</tr>
<tr>
<td><strong>記述の簡潔さ</strong></td>
<td>短くシンプル</td>
<td>引数が3つ必要</td>
</tr>
<tr>
<td><strong>MTF対応</strong></td>
<td>×</td>
<td>○</td>
</tr>
</tbody>
</table>
<p>なお、<code>iClose(NULL, 0, 1)</code>と<code>Close[1]</code>は同じ値を返します。どちらを使っても結果は同じですが、後からMTF対応に拡張する可能性がある場合は、最初からi〇〇()関数で書いておくと修正が楽です。</p>
<h2><span id="toc11">よくある注意点・落とし穴</span></h2>
<h3><span id="toc12">shift=0 は未確定のバー</span></h3>
<p><code>iClose(NULL, 0, 0)</code> で取得できる終値は、<strong>現在形成中のバーの最新価格</strong>です。ティックが入るたびに値が変わるため、売買判断には確定済みのshift=1を使うのが安全です。</p>
<h3><span id="toc13">ローカル履歴がない場合は0が返る</span></h3>
<p>ローカル履歴がない（読み込まれていない）場合、関数は0を返します。特にマルチタイムフレームや他通貨ペアのデータを使う場合は、事前にヒストリーデータを取得しておきましょう。</p>
<h3><span id="toc14">Symbol()を使おう</span></h3>
<p>通貨ペア名は<code>"USDJPY"</code>のように直接書くこともできますが、<code>Symbol()</code>や<code>NULL</code>を使えば、どのチャートにセットしても自動的にそのチャートの通貨ペアが適用されるので、汎用性の高いEAが作れます。</p>
<h2><span id="toc15">まとめ</span></h2>
<p>今回学んだ5つの時系列アクセス関数をおさらいしましょう。</p>
<ul>
<li><code>iOpen(symbol, timeframe, shift)</code> → 始値を取得</li>
<li><code>iClose(symbol, timeframe, shift)</code> → 終値を取得</li>
<li><code>iHigh(symbol, timeframe, shift)</code> → 高値を取得</li>
<li><code>iLow(symbol, timeframe, shift)</code> → 安値を取得</li>
<li><code>iTime(symbol, timeframe, shift)</code> → バーの形成開始時刻を取得</li>
</ul>
<p>すべて<strong>同じ3つの引数（通貨ペア・時間軸・バー位置）</strong>で統一されているため、1つ覚えれば残りもすぐに使えます。</p>
<p>これらの関数は、陽線・陰線の判定、ブレイクアウト戦略、マルチタイムフレーム分析など、EA開発のあらゆる場面で必要になります。ぜひサンプルコードを実際にMT4のMetaEditorに入力して動かし、手を動かしながら身につけていきましょう！</p>
<p>投稿 <a href="https://mql-programing.com/archives/13046/%e3%80%90mql4%e5%85%a5%e9%96%80%e3%80%91iclose%e3%83%bbiopen%e3%83%bbihigh%e3%83%bbilow%e3%83%bbitime%e3%81%a7%e9%81%8e%e5%8e%bb%e3%81%ae%e3%83%ad%e3%83%bc%e3%82%bd%e3%82%af%e8%b6%b3%e3%83%87%e3%83%bc/">【MQL4入門】iClose・iOpen・iHigh・iLow・iTimeで過去のローソク足データを取得しよう</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【MQL4リファレンス】MqlRates構造体の使い方！CopyRates()でローソク足データを配列取得する方法</title>
		<link>https://mql-programing.com/archives/12855/%e3%80%90mql4%e3%83%aa%e3%83%95%e3%82%a1%e3%83%ac%e3%83%b3%e3%82%b9%e3%80%91mqlrates%e6%a7%8b%e9%80%a0%e4%bd%93%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%ef%bc%81copyrates%e3%81%a7%e3%83%ad%e3%83%bc/</link>
		
		<dc:creator><![CDATA[朝日奈りさ]]></dc:creator>
		<pubDate>Tue, 31 Mar 2026 02:45:13 +0000</pubDate>
				<category><![CDATA[構造体]]></category>
		<category><![CDATA[【辞書】MQLリファレンス]]></category>
		<category><![CDATA[MQL4]]></category>
		<category><![CDATA[MqlRates]]></category>
		<category><![CDATA[CopyRates]]></category>
		<category><![CDATA[ローソク足]]></category>
		<guid isPermaLink="false">https://mql-programing.com/?p=12855</guid>

					<description><![CDATA[<p>MqlRates構造体とは MqlRates構造体は、MQL4でローソク足（バー）の価格データを格納するための構造体です。1本のローソク足に関する情報（始値・高値・安値・終値・出来高・時刻・スプレッド）をひとまとめに扱う [&#8230;]</p>
<p>投稿 <a href="https://mql-programing.com/archives/12855/%e3%80%90mql4%e3%83%aa%e3%83%95%e3%82%a1%e3%83%ac%e3%83%b3%e3%82%b9%e3%80%91mqlrates%e6%a7%8b%e9%80%a0%e4%bd%93%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%ef%bc%81copyrates%e3%81%a7%e3%83%ad%e3%83%bc/">【MQL4リファレンス】MqlRates構造体の使い方！CopyRates()でローソク足データを配列取得する方法</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[<h2><span id="toc1">MqlRates構造体とは</span></h2>
<p>MqlRates構造体は、MQL4で<strong>ローソク足（バー）の価格データを格納するための構造体</strong>です。1本のローソク足に関する情報（始値・高値・安値・終値・出来高・時刻・スプレッド）をひとまとめに扱うことができます。</p>
<p>この構造体は、主に<strong>CopyRates()関数</strong>と組み合わせて使用し、過去のローソク足データを配列として一括取得する際に活用されます。</p>
<h2><span id="toc2">MqlRates構造体のメンバー</span></h2>
<p>MqlRates構造体は以下のメンバーで構成されています。</p>
<table>
<thead>
<tr>
<th>メンバー名</th>
<th>型</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td>time</td>
<td>datetime</td>
<td>バーの開始時刻</td>
</tr>
<tr>
<td>open</td>
<td>double</td>
<td>始値</td>
</tr>
<tr>
<td>high</td>
<td>double</td>
<td>高値</td>
</tr>
<tr>
<td>low</td>
<td>double</td>
<td>安値</td>
</tr>
<tr>
<td>close</td>
<td>double</td>
<td>終値</td>
</tr>
<tr>
<td>tick_volume</td>
<td>long</td>
<td>ティックボリューム</td>
</tr>
<tr>
<td>spread</td>
<td>int</td>
<td>スプレッド</td>
</tr>
<tr>
<td>real_volume</td>
<td>long</td>
<td>出来高（取引所データが利用可能な場合）</td>
</tr>
</tbody>
</table>
<h3><span id="toc3">構造体の定義</span></h3>
<pre><code class="language-mql4">struct MqlRates
  {
   datetime time;         // バーの開始時刻
   double   open;         // 始値
   double   high;         // 高値
   double   low;          // 安値
   double   close;        // 終値
   long     tick_volume;  // ティックボリューム
   int      spread;       // スプレッド
   long     real_volume;  // 出来高
  };
</code></pre>
<h2><span id="toc4">CopyRates()関数の書式</span></h2>
<p>MqlRates構造体の配列にデータを格納するには、<strong>CopyRates()関数</strong>を使用します。CopyRates()には3つの呼び出し方法があります。</p>
<h3><span id="toc5">書式1：開始位置と本数を指定</span></h3>
<pre><code class="language-mql4">int CopyRates(
   string           symbol_name,   // 通貨ペア名
   ENUM_TIMEFRAMES  timeframe,     // 時間足
   int              start_pos,     // 開始位置（0が最新バー）
   int              count,         // 取得するバーの本数
   MqlRates         rates_array[]  // 格納先の配列
);
</code></pre>
<h3><span id="toc6">書式2：開始日時と本数を指定</span></h3>
<pre><code class="language-mql4">int CopyRates(
   string           symbol_name,   // 通貨ペア名
   ENUM_TIMEFRAMES  timeframe,     // 時間足
   datetime         start_time,    // 開始日時
   int              count,         // 取得するバーの本数
   MqlRates         rates_array[]  // 格納先の配列
);
</code></pre>
<h3><span id="toc7">書式3：開始日時と終了日時を指定</span></h3>
<pre><code class="language-mql4">int CopyRates(
   string           symbol_name,   // 通貨ペア名
   ENUM_TIMEFRAMES  timeframe,     // 時間足
   datetime         start_time,    // 開始日時
   datetime         stop_time,     // 終了日時
   MqlRates         rates_array[]  // 格納先の配列
);
</code></pre>
<h3><span id="toc8">引数の説明</span></h3>
<table>
<thead>
<tr>
<th>引数</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td>symbol_name</td>
<td>通貨ペア名。NULL または Symbol() で現在のチャートの通貨ペアを指定</td>
</tr>
<tr>
<td>timeframe</td>
<td>時間足。PERIOD_CURRENT で現在の時間足を指定</td>
</tr>
<tr>
<td>start_pos</td>
<td>取得開始位置。0が最新のバー</td>
</tr>
<tr>
<td>count</td>
<td>取得するバーの本数</td>
</tr>
<tr>
<td>start_time</td>
<td>取得開始日時</td>
</tr>
<tr>
<td>stop_time</td>
<td>取得終了日時</td>
</tr>
<tr>
<td>rates_array[]</td>
<td>MqlRates型の配列（データ格納先）</td>
</tr>
</tbody>
</table>
<h3><span id="toc9">戻り値</span></h3>
<p>CopyRates()関数は、<strong>コピーに成功した要素数</strong>を返します。失敗した場合は<strong>-1</strong>を返します。エラー内容はGetLastError()で取得できます。</p>
<h2><span id="toc10">プログラム例1：直近のローソク足データを取得して表示する（基本）</span></h2>
<p>まずは最もシンプルな使い方から見ていきましょう。直近10本のローソク足データを取得し、エキスパートログに出力する例です。</p>
<pre><code class="language-mql4">//+------------------------------------------------------------------+
//| スクリプト：直近10本のローソク足データを表示                      |
//+------------------------------------------------------------------+
void OnStart()
  {
   // MqlRates型の配列を宣言
   MqlRates rates[];

   // 配列を時系列順に設定（最新のバーが[0]になる）
   ArraySetAsSeries(rates, true);

   // 現在の通貨ペア・時間足で直近10本のバーデータを取得
   int copied = CopyRates(Symbol(), PERIOD_CURRENT, 0, 10, rates);

   // 取得に失敗した場合のエラーチェック
   if(copied <= 0)
     {
      Print("CopyRates()でエラーが発生しました。エラーコード: ", GetLastError());
      return;
     }

   // 取得成功：バーデータを1本ずつ表示
   Print("===== 直近 ", copied, " 本のローソク足データ =====");

   for(int i = 0; i < copied; i++)
     {
      Print("バー[", i, "] ",
            "時刻=", TimeToString(rates[i].time, TIME_DATE | TIME_MINUTES), " | ",
            "始値=", DoubleToString(rates[i].open, Digits), " | ",
            "高値=", DoubleToString(rates[i].high, Digits), " | ",
            "安値=", DoubleToString(rates[i].low, Digits), " | ",
            "終値=", DoubleToString(rates[i].close, Digits), " | ",
            "出来高=", rates[i].tick_volume, " | ",
            "スプレッド=", rates[i].spread);
     }
  }
</code></pre>
<p>この例のポイントは、<strong>ArraySetAsSeries(rates, true)</strong>を呼び出している点です。これにより配列のインデックス[0]が最新のバーを指すようになり、通常のバー番号と同じ感覚でアクセスできます。</p>
<h2><span id="toc11">プログラム例2：ローソク足の実体とヒゲの長さを分析する</span></h2>
<p>MqlRates構造体の各メンバーを活用して、ローソク足の形状を分析するスクリプトです。陽線・陰線の判定や、実体・ヒゲの長さを計算します。</p>
<pre><code class="language-mql4">//+------------------------------------------------------------------+
//| スクリプト：ローソク足の形状分析                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   MqlRates rates[];
   ArraySetAsSeries(rates, true);

   // 直近20本のバーデータを取得
   int copied = CopyRates(Symbol(), PERIOD_CURRENT, 0, 20, rates);
   if(copied <= 0)
     {
      Print("データ取得に失敗しました。");
      return;
     }

   // 各バーのローソク足形状を分析
   for(int i = 0; i < copied; i++)
     {
      // --- ローソク足の各部分の長さを計算 ---

      // 実体の長さ（始値と終値の差の絶対値）
      double body = MathAbs(rates[i].close - rates[i].open);

      // バー全体の長さ（高値と安値の差）
      double total_range = rates[i].high - rates[i].low;

      // 上ヒゲの長さ
      double upper_shadow = rates[i].high - MathMax(rates[i].open, rates[i].close);

      // 下ヒゲの長さ
      double lower_shadow = MathMin(rates[i].open, rates[i].close) - rates[i].low;

      // 陽線か陰線かを判定
      string candle_type;
      if(rates[i].close > rates[i].open)
         candle_type = "陽線";
      else if(rates[i].close < rates[i].open)
         candle_type = "陰線";
      else
         candle_type = "同値";

      // ピンバー（上ヒゲまたは下ヒゲが実体の2倍以上）の判定
      string pattern = "";
      if(total_range > 0)
        {
         if(upper_shadow > body * 2.0 && upper_shadow > lower_shadow * 2.0)
            pattern = " [上ヒゲピンバー]";
         else if(lower_shadow > body * 2.0 && lower_shadow > upper_shadow * 2.0)
            pattern = " [下ヒゲピンバー]";
        }

      // 結果を出力
      Print("バー[", i, "] ",
            TimeToString(rates[i].time, TIME_DATE | TIME_MINUTES), " | ",
            candle_type, " | ",
            "実体=", DoubleToString(body / Point, 1), "pts | ",
            "上ヒゲ=", DoubleToString(upper_shadow / Point, 1), "pts | ",
            "下ヒゲ=", DoubleToString(lower_shadow / Point, 1), "pts",
            pattern);
     }
  }
</code></pre>
<p>ローソク足の分析では、<strong>open, high, low, close</strong>の4つの値を使って実体やヒゲの長さを算出します。ピンバーなどのパターン検出は、裁量トレードの判断支援やEAのエントリー条件に応用できます。</p>
<h2><span id="toc12">プログラム例3：異なる時間足のデータを比較するEA</span></h2>
<p>CopyRates()の強みは、<strong>現在のチャートとは異なる時間足のデータも取得できる</strong>点です。この例では、マルチタイムフレーム分析として日足と1時間足のデータを同時に取得し、トレンド判定に活用するEAを作成します。</p>
<pre><code class="language-mql4">//+------------------------------------------------------------------+
//| Expert：マルチタイムフレーム分析によるトレンド判定EA              |
//+------------------------------------------------------------------+
#property strict

//+------------------------------------------------------------------+
//| OnTick関数：ティックごとに実行される                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   // --- 日足データの取得（上位時間足のトレンド判定用） ---
   MqlRates daily_rates[];
   ArraySetAsSeries(daily_rates, true);

   int daily_copied = CopyRates(Symbol(), PERIOD_D1, 0, 5, daily_rates);
   if(daily_copied < 5)
     {
      Print("日足データの取得に失敗しました。");
      return;
     }

   // --- 1時間足データの取得（エントリータイミング用） ---
   MqlRates h1_rates[];
   ArraySetAsSeries(h1_rates, true);

   int h1_copied = CopyRates(Symbol(), PERIOD_H1, 0, 10, h1_rates);
   if(h1_copied < 10)
     {
      Print("1時間足データの取得に失敗しました。");
      return;
     }

   // --- 日足のトレンド判定 ---
   // 直近3本の日足の終値が連続して上昇しているか確認
   bool daily_uptrend = (daily_rates[1].close > daily_rates[2].close) &&
                        (daily_rates[2].close > daily_rates[3].close);

   // 直近3本の日足の終値が連続して下降しているか確認
   bool daily_downtrend = (daily_rates[1].close < daily_rates[2].close) &#038;&#038;
                          (daily_rates[2].close < daily_rates[3].close);

   // --- 1時間足のシグナル判定 ---
   // 直前の1時間足が陽線かどうか
   bool h1_bullish = (h1_rates[1].close > h1_rates[1].open);

   // 直前の1時間足が陰線かどうか
   bool h1_bearish = (h1_rates[1].close < h1_rates[1].open);

   // --- マルチタイムフレームの総合判定 ---
   string signal = "待機";

   if(daily_uptrend &#038;&#038; h1_bullish)
      signal = "買いシグナル（日足上昇トレンド＋1時間足陽線）";
   else if(daily_downtrend &#038;&#038; h1_bearish)
      signal = "売りシグナル（日足下降トレンド＋1時間足陰線）";

   // チャート左上にシグナルを表示
   Comment("=== マルチタイムフレーム分析 ===\n",
           "日足トレンド: ", daily_uptrend ? "上昇" : (daily_downtrend ? "下降" : "レンジ"), "\n",
           "日足[1] 始値=", DoubleToString(daily_rates[1].open, Digits),
           " 終値=", DoubleToString(daily_rates[1].close, Digits), "\n",
           "1時間足[1] 始値=", DoubleToString(h1_rates[1].open, Digits),
           " 終値=", DoubleToString(h1_rates[1].close, Digits), "\n",
           "判定: ", signal);
  }
</code></pre>
<p>CopyRates()の第2引数で時間足を指定することで、現在のチャートの時間足に関係なく任意の時間足のデータを取得できます。<strong>PERIOD_D1（日足）</strong>で全体のトレンドを確認し、<strong>PERIOD_H1（1時間足）</strong>でエントリータイミングを計るという実践的なマルチタイムフレーム分析を実装しています。</p>
<h2><span id="toc13">プログラム例4：日時指定でデータ取得し、期間内の最高値・最安値を求める</span></h2>
<p>CopyRates()の書式3（開始日時と終了日時を指定）を使って、特定期間のローソク足データを取得し、その期間内の最高値・最安値やボラティリティを計算する実用的なスクリプトです。</p>
<pre><code class="language-mql4">//+------------------------------------------------------------------+
//| スクリプト：特定期間の価格レンジとボラティリティ分析              |
//+------------------------------------------------------------------+
void OnStart()
  {
   // --- 分析する期間を設定 ---
   datetime start_time = D'2024.01.01 00:00'; // 開始日時
   datetime end_time   = D'2024.01.31 23:59'; // 終了日時

   // MqlRates配列を宣言（時系列設定はしない＝古い順）
   MqlRates rates[];

   // 指定期間のH1（1時間足）データを取得
   int copied = CopyRates(Symbol(), PERIOD_H1, start_time, end_time, rates);

   if(copied <= 0)
     {
      Print("指定期間のデータ取得に失敗しました。エラーコード: ", GetLastError());
      return;
     }

   Print("取得したバー数: ", copied);

   // --- 期間内の最高値・最安値を検索 ---
   double highest_price = rates[0].high;   // 最高値の初期値
   double lowest_price  = rates[0].low;    // 最安値の初期値
   datetime highest_time = rates[0].time;  // 最高値の時刻
   datetime lowest_time  = rates[0].time;  // 最安値の時刻
   long total_volume = 0;                  // 合計出来高
   double total_range = 0;                 // 各バーのレンジ合計

   for(int i = 0; i < copied; i++)
     {
      // 最高値の更新チェック
      if(rates[i].high > highest_price)
        {
         highest_price = rates[i].high;
         highest_time  = rates[i].time;
        }

      // 最安値の更新チェック
      if(rates[i].low < lowest_price)
        {
         lowest_price = rates[i].low;
         lowest_time  = rates[i].time;
        }

      // 出来高の合計
      total_volume += rates[i].tick_volume;

      // 各バーのレンジ（高値−安値）を合計
      total_range += (rates[i].high - rates[i].low);
     }

   // --- 平均ボラティリティの計算 ---
   double avg_range = total_range / copied;           // 平均レンジ（price）
   double avg_range_pts = avg_range / Point;           // 平均レンジ（ポイント）
   double avg_volume = (double)total_volume / copied;  // 平均出来高

   // --- 分析結果を出力 ---
   Print("===========================================");
   Print("  期間分析レポート: ", Symbol(), " H1");
   Print("===========================================");
   Print("分析期間: ", TimeToString(start_time, TIME_DATE), " ～ ",
         TimeToString(end_time, TIME_DATE));
   Print("バー数: ", copied);
   Print("-------------------------------------------");
   Print("期間最高値: ", DoubleToString(highest_price, Digits),
         " (", TimeToString(highest_time, TIME_DATE | TIME_MINUTES), ")");
   Print("期間最安値: ", DoubleToString(lowest_price, Digits),
         " (", TimeToString(lowest_time, TIME_DATE | TIME_MINUTES), ")");
   Print("期間レンジ: ", DoubleToString((highest_price - lowest_price) / Point, 1), " pts");
   Print("-------------------------------------------");
   Print("平均レンジ（1バーあたり）: ", DoubleToString(avg_range_pts, 1), " pts");
   Print("平均出来高（1バーあたり）: ", DoubleToString(avg_volume, 0));
   Print("合計出来高: ", total_volume);
   Print("===========================================");

   // --- 最初の5本と最後の5本のデータを確認表示 ---
   Print("--- 期間先頭のバー ---");
   int show_count = MathMin(5, copied);
   for(int i = 0; i < show_count; i++)
     {
      Print("  ", TimeToString(rates[i].time, TIME_DATE | TIME_MINUTES),
            " O=", DoubleToString(rates[i].open, Digits),
            " H=", DoubleToString(rates[i].high, Digits),
            " L=", DoubleToString(rates[i].low, Digits),
            " C=", DoubleToString(rates[i].close, Digits));
     }

   Print("--- 期間末尾のバー ---");
   for(int i = MathMax(0, copied - 5); i < copied; i++)
     {
      Print("  ", TimeToString(rates[i].time, TIME_DATE | TIME_MINUTES),
            " O=", DoubleToString(rates[i].open, Digits),
            " H=", DoubleToString(rates[i].high, Digits),
            " L=", DoubleToString(rates[i].low, Digits),
            " C=", DoubleToString(rates[i].close, Digits));
     }
  }
</code></pre>
<p>書式3では開始日時と終了日時を直接指定するため、<strong>特定の期間に限定した分析</strong>に非常に便利です。この例では期間内の最高値・最安値の検出に加え、平均ボラティリティや出来高の統計情報も算出しています。なお、日時指定で取得した場合は<strong>ArraySetAsSeries()を使わなければ古い順（時系列ではない順）</strong>で格納されます。</p>
<h2><span id="toc14">よくある使い方のポイント・注意事項</span></h2>
<h3><span id="toc15">1. ArraySetAsSeries()の設定を忘れない</span></h3>
<p>CopyRates()で取得した配列は、デフォルトでは<strong>古いデータから順番に格納</strong>されます。最新のバーを[0]としてアクセスしたい場合は、必ず<strong>CopyRates()の前に</strong>ArraySetAsSeries(rates, true)を呼び出してください。</p>
<pre><code class="language-mql4">// 正しい使い方
MqlRates rates[];
ArraySetAsSeries(rates, true);  // ← CopyRatesの前に設定
CopyRates(Symbol(), PERIOD_CURRENT, 0, 10, rates);
// rates[0]が最新バー、rates[9]が10本前のバー
</code></pre>
<h3><span id="toc16">2. 戻り値のエラーチェックは必須</span></h3>
<p>CopyRates()は、データが利用できない場合やサーバーとの接続が切れている場合に<strong>-1を返す</strong>ことがあります。戻り値を必ずチェックしてからデータにアクセスしてください。</p>
<pre><code class="language-mql4">int copied = CopyRates(Symbol(), PERIOD_CURRENT, 0, 100, rates);
if(copied <= 0)
  {
   Print("データ取得失敗: ", GetLastError());
   return; // データがない状態で処理を続行しない
  }
// copiedの値を上限として配列にアクセスする
for(int i = 0; i < copied; i++)
  {
   // rates[i] を安全に使用できる
  }
</code></pre>
<h3><span id="toc17">3. 他の通貨ペアのデータ取得時の注意</span></h3>
<p>現在のチャートとは異なる通貨ペアのデータを取得する場合、<strong>その通貨ペアのデータがダウンロード済みでないとエラーになる</strong>ことがあります。気配値表示ウィンドウに該当通貨ペアを追加し、過去のデータがダウンロードされていることを確認してください。</p>
<h3><span id="toc18">4. 配列サイズは自動調整される</span></h3>
<p>CopyRates()に渡す配列は<strong>動的配列</strong>である必要があります。関数が自動的に必要なサイズにリサイズしてくれるため、事前にArrayResize()でサイズを指定する必要はありません。ただし、<strong>静的配列（固定サイズの配列）を渡すとエラーになる</strong>場合があるので注意してください。</p>
<pre><code class="language-mql4">// OK：動的配列
MqlRates rates[];
CopyRates(Symbol(), PERIOD_CURRENT, 0, 100, rates);

// NG：静的配列は避ける
// MqlRates rates[100]; ← CopyRatesには動的配列を使うこと
</code></pre>
<h3><span id="toc19">5. iOpen()等の従来関数との使い分け</span></h3>
<p>MQL4にはiOpen()、iClose()、iHigh()、iLow()などの関数もありますが、<strong>複数のバーの情報をまとめて取得したい場合はCopyRates()の方が効率的</strong>です。1本のバー情報だけが必要な場合は従来の関数でも問題ありません。</p>
<pre><code class="language-mql4">// 1本だけ必要な場合 → 従来の関数が簡潔
double close_1 = iClose(Symbol(), PERIOD_CURRENT, 1);

// 複数本まとめて処理する場合 → CopyRates()が効率的
MqlRates rates[];
ArraySetAsSeries(rates, true);
CopyRates(Symbol(), PERIOD_CURRENT, 0, 100, rates);
// rates[0]～rates[99]まで一括でアクセス可能
</code></pre>
<h3><span id="toc20">6. インジケーターでの使用時はバッファとの混同に注意</span></h3>
<p>カスタムインジケーター内でCopyRates()を使う場合、インジケーターバッファの配列とMqlRates配列のインデックス方向が一致しているか注意してください。ArraySetAsSeries()の設定がバッファと同じ方向になっていないと、バー番号がずれてしまいます。</p>
<h2><span id="toc21">まとめ</span></h2>
<p>MqlRates構造体とCopyRates()関数は、MQL4でローソク足データを効率的に扱うための重要な機能です。以下のポイントを押さえておきましょう。</p>
<ul>
<li><strong>MqlRates構造体</strong>は1本のバーのOHLC、出来高、時刻、スプレッドを格納する</li>
<li><strong>CopyRates()</strong>は3つの書式があり、位置指定・日時指定・期間指定で柔軟にデータ取得できる</li>
<li><strong>ArraySetAsSeries()</strong>でインデックスの方向を制御できる</li>
<li>戻り値のエラーチェックを必ず行い、安全にデータにアクセスする</li>
<li>複数バーのデータをまとめて処理する場合に特に威力を発揮する</li>
</ul>
<p>投稿 <a href="https://mql-programing.com/archives/12855/%e3%80%90mql4%e3%83%aa%e3%83%95%e3%82%a1%e3%83%ac%e3%83%b3%e3%82%b9%e3%80%91mqlrates%e6%a7%8b%e9%80%a0%e4%bd%93%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%ef%bc%81copyrates%e3%81%a7%e3%83%ad%e3%83%bc/">【MQL4リファレンス】MqlRates構造体の使い方！CopyRates()でローソク足データを配列取得する方法</a> は <a href="https://mql-programing.com">自動売買を作ろう！</a> に最初に表示されました。</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
