MQL5 CopyTicksとは?使い方・構文・エラー対策まで完全解説

目次

1. MQL5のCopyTicksとは何か

1.1 CopyTicksの概要

CopyTicksは、MQL5においてティックデータ(最小単位の価格変動)を取得するための関数です。
ティックとは、価格が1回変化するごとに記録されるデータであり、以下のような情報を含みます。

  • Bid(売値)
  • Ask(買値)
  • Last(約定価格)
  • Volume(取引量)
  • Time(時刻)

通常のチャートで扱うローソク足(バー)は、これらティックを一定時間ごとに集約したものです。
そのため、CopyTicksを使うことでローソク足よりも細かい粒度のデータを扱うことが可能になります。

特に以下のようなケースでは必須の関数です。

  • スキャルピング(短時間売買)
  • 高頻度トレード(ミリ秒単位の判断)
  • スプレッド変動の監視

注意点(初心者がつまずくポイント)

  • 「CopyTicks=価格履歴取得」と誤解しやすいが、バーではなくティック単位
  • ティックデータはブローカーや環境によって取得量が異なる
  • MT5に履歴がない場合、データが取得できないことがある

1.2 CopyRatesとの違い

CopyTicksとよく比較されるのがCopyRatesです。
両者の違いは、取得するデータの粒度(細かさ)にあります。

関数 データ単位 内容
CopyRates バー(OHLC) 始値・高値・安値・終値
CopyTicks ティック 価格変動ごとの生データ

具体的な違い

  • CopyRates
    → 「1分足」「5分足」などのまとまったデータ
  • CopyTicks
    → 価格が動いたすべての瞬間のデータ

使い分けの基準

  • 通常のインジケーター・分析 → CopyRates
  • 精密なタイミング制御 → CopyTicks

よくある失敗

  • CopyTicksでローソク足的な処理をしようとして非効率になる
  • CopyRatesでスプレッド変動を取ろうとして精度不足になる

1.3 どんな場面で使うか

CopyTicksは、主に「リアルタイム性」と「精度」が求められる場面で使われます。

代表的な用途

  • スプレッド監視
    → BidとAskの差をリアルタイム取得
  • エントリータイミング最適化
    → ティック単位で価格変化を検出
  • 約定直前の価格判断
    → スリッページ対策(注文価格のズレ)

実務での重要性

例えば、同じロジックでも

  • バー単位 → 遅れる(機会損失)
  • ティック単位 → 即応(精度向上)

となるため、EAの性能に直結する要素になります。


注意点(実務レベル)

  • ティックデータは「重い」
    → 毎Tickで大量取得するとパフォーマンス低下
  • データの完全性は保証されない
    → VPS・回線・ブローカー依存
  • バックテストと実運用で差が出る
    → ティック生成方式の違い

よくある誤解まとめ

  • 「CopyTicksは万能」→ ❌
    → 用途を限定しないと非効率
  • 「すべてのティックが取れる」→ ❌
    → 環境に依存
  • 「CopyRatesより優れている」→ ❌
    → 役割が異なるだけ

2. CopyTicksの基本構文とパラメータ

2.1 関数シグネチャ

CopyTicksの基本構文は以下の通りです。

int CopyTicks(
   string symbol,
   MqlTick& ticks[],
   uint flags,
   ulong from,
   uint count
);

この関数は、指定した条件に基づいてティックデータを配列に格納し、取得した件数(成功時)または -1(失敗時)を返します。

戻り値の意味

  • 0以上:取得したティック数
  • -1:エラー(GetLastError()で原因確認)

最重要ポイント

  • 「戻り値=取得件数」なので、必ずチェックする必要がある
  • 0は「失敗」ではなく「データなし」の可能性もある

2.2 各引数の意味

CopyTicksは5つの引数で構成されています。初心者がつまずきやすいのは「flags」と「from」です。

symbol(通貨ペア)

"EURUSD"
  • 対象となるシンボル(銘柄)
  • _Symbol を使うのが一般的

ticks[](格納先配列)

MqlTick ticks[];
  • ティックデータを格納する配列
  • 参照渡し(&)なので事前宣言が必要

flags(取得するデータ種類)

  • 取得対象のティック種類を指定
  • 詳細は後述(非常に重要)

from(開始位置)

  • 取得開始の基準(時間 or チケットID)
  • 初心者が最もミスするポイント

count(取得件数)

  • 取得するティック数
  • 上限指定として使う

2.3 flagsの種類(重要)

flagsは、どの種類のティックを取得するかを指定します。

主な種類

  • COPY_TICKS_ALL
    → すべてのティック(基本はこれ)
  • COPY_TICKS_INFO
    → Bid/Askの変化のみ
  • COPY_TICKS_TRADE
    → 約定関連(Last/Volume)

flagsの使い分け

基本

COPY_TICKS_ALL

→ 初心者はこれ一択で問題なし

最適化する場合

  • スプレッド監視 → COPY_TICKS_INFO
  • 約定分析 → COPY_TICKS_TRADE

よくある失敗(flags)

  • flagsを指定せず適当に使う
    → 意図しないデータになる
  • COPY_TICKS_INFOでLastを参照
    → 値が入らない

2.4 fromの扱い(重要)

fromは取得開始位置を指定する引数ですが、扱いがやや特殊です。

基本的な使い方

0

→ 最新データから取得

時刻指定する場合

ulong from = (ulong)TimeCurrent() - 60;

注意点

  • fromはミリ秒単位の時間(datetimeではない)
  • 過去すぎるとデータが取れない
  • 未来を指定すると0件になる

よくある失敗(from)

  • datetimeそのまま入れてズレる
  • 大きすぎる値で取得できない
  • 意図せず古いデータを取る

2.5 countの考え方

countは取得する最大件数です。

10

→ 最大10件取得

注意点

  • 必ずしも指定数取得できるとは限らない
  • データがなければ少なくなる

よくある失敗(count)

  • countを大きくしすぎる → パフォーマンス低下
  • 小さすぎる → データ不足

重要まとめ(実務視点)

CopyTicksで重要なのは以下の3点です。

  • flags → 何を取るか
  • from → どこから取るか
  • count → どれだけ取るか

この3つを正しく理解しないと、「動いているが間違っているコード」になります。

3. CopyTicksの使い方(コード例付き)

3.1 最も基本的な使用例

まずは、CopyTicksの最小構成のサンプルです。
最新のティックを取得して表示する基本パターンになります。

void OnTick()
{
   MqlTick ticks[];

   int copied = CopyTicks(_Symbol, ticks, COPY_TICKS_ALL, 0, 10);

   if(copied > 0)
   {
      for(int i = 0; i < copied; i++)
      {
         Print("Time:", ticks[i].time,
               " Bid:", ticks[i].bid,
               " Ask:", ticks[i].ask);
      }
   }
   else
   {
      Print("CopyTicks failed. Error:", GetLastError());
   }
}

処理の流れ

  • 配列を宣言(MqlTick ticks[])
  • CopyTicksで取得
  • 戻り値をチェック
  • 配列をループ処理

ポイント

  • 0指定で最新データ取得
  • COPY_TICKS_ALLで全データ対象
  • 戻り値チェックは必須

3.2 MqlTick構造体の中身

CopyTicksで取得されるデータは、MqlTick構造体に格納されます。

主なメンバ

struct MqlTick
{
   datetime time;     // 秒単位の時刻
   double   bid;      // 売値
   double   ask;      // 買値
   double   last;     // 約定価格
   ulong    volume;   // 約定量
   long     time_msc; // ミリ秒
   uint     flags;    // ティック種別
};

初心者向け補足

  • time → 秒単位の時間
  • time_msc → より精密な時間(ミリ秒)
  • flags → Bid/Ask/Lastのどれが更新されたか

3.3 スプレッド取得の実例

CopyTicksの実務用途として多いのがスプレッド監視です。

void OnTick()
{
   MqlTick ticks[];

   if(CopyTicks(_Symbol, ticks, COPY_TICKS_INFO, 0, 1) > 0)
   {
      double spread = ticks[0].ask - ticks[0].bid;
      Print("Spread:", spread);
   }
}

ポイント

  • COPY_TICKS_INFOで軽量化
  • 最新1件だけ取得(高速)
  • 無駄なループを省略

3.4 特定時間以降のデータ取得

過去から現在までのティックを取得する場合の例です。

void OnStart()
{
   MqlTick ticks[];

   ulong from = (ulong)TimeCurrent() - 60; // 直近60秒

   int copied = CopyTicks(_Symbol, ticks, COPY_TICKS_ALL, from, 100);

   Print("Copied:", copied);
}

注意点

  • 時間指定はミリ秒ではなく秒ベースに見えるが内部は注意
  • 実際には環境依存でズレる場合あり

3.5 よくあるミスと対処法

ミス①:配列サイズ未確保

MqlTick ticks[];

→ OK(MQL5は自動拡張)
ただし、大量取得時はメモリ注意


ミス②:戻り値をチェックしない

CopyTicks(...);

→ NG
→ 必ず以下を実施

if(copied <= 0)
{
   Print(GetLastError());
}

ミス③:毎Tickで大量取得

CopyTicks(_Symbol, ticks, COPY_TICKS_ALL, 0, 1000);

→ パフォーマンス悪化

対策

  • 必要最小限の件数にする
  • 最新のみなら count=1

ミス④:flagsの誤用

  • INFOでlastを使う → 値なし
  • TRADEでbid/ask期待 → 不完全

3.6 実務での最適パターン

軽量・高効率な例

void OnTick()
{
   MqlTick tick[];

   if(CopyTicks(_Symbol, tick, COPY_TICKS_INFO, 0, 1) == 1)
   {
      double spread = tick[0].ask - tick[0].bid;

      if(spread < 0.0002)
      {
         // エントリー処理
      }
   }
}

設計意図

  • 1件取得 → 最速
  • INFO限定 → 軽量
  • 条件分岐 → 実戦向け

実務上の注意

  • CopyTicksは「重い処理」になりやすい
  • EAでは最小回数・最小データが基本

まとめ(この章の核心)

  • CopyTicksは「使い方次第で性能が大きく変わる」
  • 無駄な取得は即パフォーマンス悪化
  • 実務では「1件取得」が基本戦略

4. CopyTicksのエラー原因と対処法

4.1 CopyTicksが失敗する主な原因

CopyTicksは正常に動作しているように見えても、内部的に失敗しているケースが多い関数です。
特に初心者は「データが取得できない=コードが間違っている」と判断しがちですが、実際は環境依存の要因が多く関係します。

主な失敗パターン

  • データが存在しない(履歴不足)
  • 指定条件が不適切(from / count)
  • flagsの指定ミス
  • サーバー接続・同期状態の問題

4.2 GetLastErrorで原因を特定する

CopyTicksが失敗した場合、必ず以下を確認します。

int copied = CopyTicks(_Symbol, ticks, COPY_TICKS_ALL, 0, 10);

if(copied < 0)
{
   Print("Error:", GetLastError());
}

重要ポイント

  • copied < 0 の場合のみエラー
  • copied == 0 は「データなし」の可能性

4.3 よくあるエラーと対策

エラー①:データが取得できない(copied = 0)

原因
  • ティック履歴が存在しない
  • 指定範囲にデータがない
対策
  • MT5で該当通貨ペアのチャートを開く
  • 時間をスクロールして履歴を読み込む
  • VPSや回線状態を確認

エラー②:ERR_HISTORY_WILL_UPDATED(履歴更新中)

原因
  • データがまだダウンロードされていない
対策
  • 少し待って再実行
  • ループでリトライ処理を入れる
for(int i = 0; i < 5; i++)
{
   int copied = CopyTicks(_Symbol, ticks, COPY_TICKS_ALL, 0, 10);
   if(copied > 0) break;

   Sleep(100);
}

エラー③:無効な引数(flags / from)

原因
  • flagsの組み合わせミス
  • fromの値が不正
対策
  • flagsは基本 COPY_TICKS_ALL
  • fromは 0 から試す

エラー④:配列アクセスミス

原因
  • copied = 0なのに配列アクセス
ticks[0] // NG
対策
if(copied > 0)
{
   ticks[0] // OK
}

4.4 実務での安定化パターン

CopyTicksは「一発で成功する前提」で書くと不安定になります。
そのため、実務ではリトライ+フォールバック設計が基本です。

安定コード例

bool GetLatestTick(MqlTick &tick)
{
   MqlTick ticks[];

   for(int i = 0; i < 3; i++)
   {
      int copied = CopyTicks(_Symbol, ticks, COPY_TICKS_INFO, 0, 1);

      if(copied == 1)
      {
         tick = ticks[0];
         return true;
      }

      Sleep(50);
   }

   return false;
}

設計ポイント

  • 最大3回リトライ
  • 軽量取得(1件)
  • 成功時のみ処理

4.5 バックテストと実運用の違い

CopyTicksは、バックテストとリアル環境で挙動が異なることがあります。

主な違い

項目 バックテスト 実運用
ティック精度 モデル依存 実データ
データ量 制限あり ブローカー依存
タイミング 疑似 リアル

注意点

  • バックテストで動いても実運用で失敗するケースあり
  • 特にスキャル系EAで影響が大きい

4.6 よくある失敗まとめ

  • エラーチェックしない → 原因不明になる
  • copied=0を失敗扱い → 誤判定
  • 毎Tickで重い処理 → 遅延・約定悪化
  • 履歴未取得 → データ不足

実務視点の結論

CopyTicksは

  • 「使える」ではなく「制御する」関数
  • 成功前提ではなく「失敗前提で設計する」

これが安定運用の前提になります。

5. CopyTicksを使うべきケース・使わないべきケース

5.1 CopyTicksを使うべきケース

CopyTicksは強力な関数ですが、用途を限定しないとパフォーマンス悪化や設計ミスの原因になります。
まずは「使うべき場面」を明確にします。

ケース①:スプレッド監視

  • Bid / Askの差をリアルタイムで取得
  • スプレッドフィルター(例:スプレッドが狭い時のみエントリー)
double spread = tick.ask - tick.bid;

実務価値

  • 約定精度に直結
  • 特にスキャルピングでは必須

ケース②:ティック単位のエントリー判断

  • 「価格が◯pips動いた瞬間」を検知
  • ブレイクアウト系ロジック

  • 直前Tickとの差分を計算
  • 一定以上ならエントリー

ケース③:約定前の価格チェック

  • スリッページ対策
  • 注文直前に価格確認

実務メリット

  • 約定拒否・滑りの低減
  • 高頻度EAで重要

ケース④:ティックベースの分析

  • ティックボリューム分析
  • フロー解析(上昇・下降の連続性)

5.2 CopyTicksを使わない方が良いケース

次に、「使うと逆効果になるケース」です。

ケース①:通常のインジケーター

  • 移動平均
  • RSI
  • MACD

→ CopyRatesで十分


ケース②:時間足ベースのロジック

  • 1分足・5分足の戦略
  • 日足ベースのトレード

→ ティックは不要


ケース③:重い処理を伴うEA

  • 毎Tickで大量データ取得
  • 複雑なループ処理

→ パフォーマンス低下


ケース④:バックテスト重視の戦略

  • ティック精度が不安定
  • モデル依存が強い

→ 結果がブレる


5.3 CopyTicks vs CopyRates(最終判断基準)

判断フロー

  • リアルタイム精度が必要か?
    → YES → CopyTicks
    → NO → CopyRates
  • 処理速度を優先するか?
    → YES → CopyRates
  • スプレッドや瞬間変動を見るか?
    → YES → CopyTicks

5.4 実務での最適設計パターン

実務では「両方使う」が最適解です。

ハイブリッド構成

  • ロジック判断 → CopyRates
  • 最終チェック → CopyTicks
// ロジック判定(軽量)
CopyRates(...);

// 最終価格チェック(高精度)
CopyTicks(...);

メリット

  • パフォーマンス維持
  • 精度確保
  • 再現性向上

5.5 よくある設計ミス

ミス①:全部CopyTicksで処理

→ 重い・遅い・非効率


ミス②:CopyRatesだけで完結

→ 精度不足(特にスキャル)


ミス③:用途を分けていない

→ 設計が曖昧


5.6 期待値・リスク観点の整理

CopyTicks使用の期待値

  • エントリー精度向上
  • スリッページ低減
  • 高頻度戦略の優位性

リスク

  • パフォーマンス低下
  • データ不整合(環境依存)
  • バックテストとの乖離

結論(重要)

CopyTicksは

  • 「強い」ではなく「尖った機能」
  • 適材適所で使うことで初めて価値が出る

最終まとめ(意思決定)

  • 精度重視 → CopyTicks
  • 速度・安定性 → CopyRates
  • 実務 → ハイブリッド

6. FAQ(よくある質問と回答)

6.1 CopyTicksでデータが取得できません。なぜですか?

回答方針:環境依存・履歴不足を確認する

主な原因は以下です。

  • ティック履歴が存在しない
  • MT5がデータをまだ読み込んでいない
  • 指定したfrom範囲にデータがない

対処

  • チャートを開いて履歴を読み込む
  • 少し待って再取得する
  • fromを「0」にして確認する

6.2 CopyTicksとCopyRatesはどちらを使うべきですか?

回答方針:用途で明確に分ける

  • 通常の分析・インジケーター → CopyRates
  • スプレッド・瞬間変動 → CopyTicks

結論

  • 精度が必要ならCopyTicks
  • 基本はCopyRates
  • 実務は併用(ハイブリッド)

6.3 flagsはどれを使えば良いですか?

回答方針:初心者は1択、上級者は最適化

  • 初心者 → COPY_TICKS_ALL
  • スプレッド監視 → COPY_TICKS_INFO
  • 約定分析 → COPY_TICKS_TRADE

注意

  • flagsによって取得できるデータが変わる

6.4 fromはどう指定すれば良いですか?

回答方針:まずは0でOK

  • 基本 → 0(最新データ)
  • 過去取得 → 時刻指定(環境により差あり)

よくあるミス

  • datetimeをそのまま使う
  • 古すぎる時間を指定

6.5 CopyTicksは重いですか?

回答方針:使い方次第で重くなる

  • 1件取得 → 軽い
  • 大量取得 → 重い

対策

  • countは最小限にする
  • 毎Tickで大量取得しない

6.6 バックテストと実運用で結果が違うのはなぜですか?

回答方針:ティック生成方式の違い

  • バックテスト → 疑似ティック
  • 実運用 → 実ティック

影響

  • スキャル系で差が大きい
  • スプレッド挙動が変わる

6.7 CopyTicksで最も重要なポイントは何ですか?

回答方針:設計思想を提示

  • 必要最小限だけ取得する
  • 戻り値を必ずチェックする
  • エラー前提で設計する

結論
→ 「精度」と「負荷」のバランス管理


6.8 CopyTicksは必ず使うべきですか?

回答方針:不要なケースを明確化

  • 使うべき → スキャル・高頻度
  • 不要 → 長期・インジ系

結論
→ 必須ではないが、使いどころで大きな差が出る機能

This website stores cookies on your computer. These cookies are used to provide a more personalized experience and to track your whereabouts around our website in compliance with the European General Data Protection Regulation. If you decide to to opt-out of any future tracking, a cookie will be setup in your browser to remember this choice for one year.

Accept or Deny