1. MQL5のOnTickとは何か
1.1 OnTickの基本役割
OnTick は、MQL5でEA(Expert Advisor:自動売買プログラム)を開発する際に最も重要な関数の一つです。
この関数は 価格のティック(Tick:価格更新イベント)を受信した瞬間に自動実行されるイベント関数 です。
MetaTrader 5のEAは、通常のプログラムのように「順番に処理を実行する構造」ではなく、イベント駆動型(Event-driven) という仕組みで動きます。
イベント駆動とは、特定の出来事が発生したときにプログラムが動く仕組みです。
EAの場合、最も重要なイベントが 価格更新(Tick) です。
そのため、EAの売買ロジックの大部分は OnTick関数の中に記述される のが一般的です。
基本構文は非常にシンプルです。
void OnTick()
{
// ティック受信時に実行される処理
}
例えば、ティックを受信したときにログを出力するだけの最小コードは次のようになります。
void OnTick()
{
Print("Tick received");
}
このコードは、価格が更新されるたびに 「Tick received」 とログに出力されます。
EA開発では、OnTickの内部で次のような処理を行うのが一般的です。
- インジケーターの値を取得する
- 売買条件を判定する
- 条件を満たした場合に注文を出す
- ポジションを管理する
つまり EAの意思決定の中心がOnTick です。
1.2 ティックとは何か(初心者向け)
OnTickを理解するためには、まず ティック(Tick) の概念を理解する必要があります。
ティックとは、市場から新しい価格が届いた瞬間のイベントのことです。
簡単に言うと、価格が更新されたタイミングです。
例えば次のような変化が起きた場合、ティックが発生します。
| 時刻 | Bid価格 |
|---|---|
| 10:00:01 | 150.100 |
| 10:00:02 | 150.101 |
| 10:00:03 | 150.101 |
| 10:00:04 | 150.102 |
このように価格が変化すると、そのたびに 新しいティックが発生します。
重要なポイントは次の通りです。
- ローソク足とは別の概念
- ローソク足は一定時間の価格をまとめたもの
- ティックは リアルタイムの価格更新
つまり、1本のローソク足の中でも 数百〜数千ティック が発生することがあります。
市場の状況によってティック頻度は大きく変わります。
| 市場状況 | ティック頻度 |
|---|---|
| ロンドン市場 | 非常に多い |
| ニューヨーク市場 | 多い |
| 東京市場 | 中程度 |
| 週末 | ほぼ無し |
ティックが発生すると、そのたびに OnTickが呼び出されます。
1.3 EAの中でのOnTickの位置
MQL5のEAは、通常次のようなイベント関数で構成されます。
OnInit()
OnTick()
OnDeinit()
それぞれの役割は次の通りです。
| 関数 | 役割 |
|---|---|
| OnInit | EA起動時に1回実行 |
| OnTick | 価格更新ごとに実行 |
| OnDeinit | EA終了時に実行 |
処理の流れは次のようになります。
- EAをチャートにセット
- OnInit() が実行される
- 価格が更新される
- OnTick() が実行される
- ティックが来るたびにOnTickが繰り返される
つまり、EAが実際にトレード判断を行うタイミングは OnTickが呼ばれた瞬間です。
よくある誤解(つまずきポイント)
初心者がよく誤解するポイントがあります。
① OnTickは一定時間ごとに動くわけではない
OnTickはタイマーではありません。
価格更新がない限り実行されません。
例
- 市場停止(週末)
- 流動性の低い通貨
この場合、OnTickはしばらく呼ばれないことがあります。
② ティックはローソク足とは別
初心者はよく
「1分足が更新されたらOnTickが動く」
と考えがちですが、これは誤りです。
実際は
- 価格が更新されるたびにOnTickが動く
という仕組みです。
③ OnTickに重い処理を書くとEAが遅くなる
ティックは 非常に高頻度で発生します。
通貨ペアによっては
- 1秒に数回
- ニュース時は数十回
OnTickの処理が重いと
- EAが遅くなる
- バックテストが極端に遅くなる
といった問題が発生します。
よくある失敗
EA初心者が最初に起こしやすいミスがあります。
無限注文バグ
void OnTick()
{
if(condition)
{
OrderSend(...);
}
}
このコードは、条件がtrueの間 毎ティック注文を出してしまいます。
結果
- 数秒で数百ポジション
- 証拠金破綻
という事故が起きることがあります。
そのため通常は
- ポジション確認
- 新バー判定
などを入れて制御します。
2. OnTickの基本構文と使い方
2.1 OnTick関数の基本構文
MQL5における OnTick関数 は、EA(Expert Advisor)専用のイベント関数です。
市場から 新しいティック(価格更新)が届いた瞬間 に自動的に実行されます。
基本構文は次の通りです。
void OnTick()
{
// ティック受信時に実行される処理
}
ポイントは次の3つです。
- 戻り値は必ず
void - 引数は持たない
- EAでのみ使用できる
インジケーターやスクリプトではOnTickは使用できません。
これは EAがリアルタイム価格イベントに反応するプログラムだからです。
2.2 最小構成のOnTickコード
最もシンプルなOnTickの例です。
void OnTick()
{
Print("New Tick");
}
このコードをEAとしてチャートにセットすると、
価格が更新されるたびにログへ出力されます。
ログ例
New Tick
New Tick
New Tick
このように ティックごとにOnTickが実行される ことを確認できます。
2.3 現在価格を取得する例
EAでは通常、OnTick内で現在価格を取得します。
void OnTick()
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
Print("Bid:", bid, " Ask:", ask);
}
ここで使われている主な要素は次の通りです。
| 要素 | 説明 |
|---|---|
_Symbol |
現在の通貨ペア |
SYMBOL_BID |
売値 |
SYMBOL_ASK |
買値 |
このコードは リアルタイムの価格を取得する基本パターンです。
EAの多くは次の流れになります。
- 現在価格取得
- インジケーター取得
- 売買条件判定
- 注文送信
2.4 売買条件を書く基本パターン
OnTickの典型的な構造は次の形です。
void OnTick()
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
if(bid > 150.000)
{
Print("Buy condition");
}
}
実際のEAではここに
- 移動平均
- RSI
- ボリンジャーバンド
などのインジケーター条件が追加されます。
例
void OnTick()
{
double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
if(price > 150.000)
{
// ここに注文処理を書く
}
}
2.5 EAの典型構造(実践パターン)
実際のEAは次のような構造になります。
void OnTick()
{
CheckSignal();
ManagePosition();
}
関数分割の例
void CheckSignal()
{
// エントリー判定
}
void ManagePosition()
{
// 利確や損切り管理
}
このようにすることで
- 可読性向上
- バグ減少
- メンテナンス性向上
というメリットがあります。
つまずきやすいポイント
初心者がOnTickでよく間違える部分があります。
① OnTickは自分で呼び出さない
OnTickは 自動実行されるイベント関数です。
次のように書く必要はありません。
OnTick();
これは 完全に不要です。
② OnTickは複数作れない
次のようなコードはエラーになります。
void OnTick()
{
}
void OnTick()
{
}
EA内では OnTickは1つだけ 定義できます。
③ 重い処理を書きすぎない
ティックは非常に多く発生します。
通貨ペアによっては
- 1秒に数回
- ニュース時は数十回
そのため次のような処理は注意が必要です。
- 重い計算
- 大量ループ
- ファイル処理
これらは パフォーマンス問題の原因になります。
よくある失敗
初心者が最初に作るEAでよく起きる問題があります。
毎ティック注文バグ
void OnTick()
{
if(signal)
{
OrderSend(...);
}
}
このコードでは、
条件がtrueの間ずっと注文を出し続けます。
結果
- 同じ注文が連続発生
- 数秒で大量ポジション
という事故になります。
対策としては
- ポジション確認
- 新バー判定
- フラグ管理
などを行います。
3. OnTickが呼び出されるタイミング(ティック処理の仕組み)
3.1 OnTickは価格更新イベントで実行される
MQL5の OnTick関数 は、市場から新しいティック(価格更新)が届いた瞬間に実行されます。
つまり、OnTickは 時間ではなく価格変化に反応するイベント関数です。
EAの実行フローは次のようになります。
価格更新(Tick発生)
↓
MetaTraderがイベント検出
↓
OnTick() が呼び出される
↓
EAの売買ロジックが実行される
この処理は ティックごとに繰り返されます。
例えば、EURUSDのような流動性の高い通貨では
- 数百ミリ秒ごと
- 1秒に数回
OnTickが実行されることがあります。
逆に、流動性が低い時間帯では
- 数秒
- 数十秒
OnTickが呼ばれない場合もあります。
重要なのは次の点です。
OnTickは「一定時間ごと」に動く関数ではない
ということです。
3.2 ティックとローソク足の違い
初心者が最も混乱しやすいポイントが
ティック(Tick)とローソク足(Bar)の違い
です。
| 概念 | 内容 |
|---|---|
| ティック | 価格が更新された瞬間 |
| ローソク足 | 一定時間の価格データ |
例えば 1分足チャートの場合でも、内部では次のような動きが発生しています。
10:00:01 150.100
10:00:01 150.101
10:00:02 150.100
10:00:03 150.102
10:00:05 150.101
このすべてが ティックです。
しかし、1分足では
10:00〜10:01
の価格をまとめて 1本のローソク足として表示します。
つまり
- OnTick → ティックごと
- インジケーター → 通常はバー単位
という違いがあります。
この違いを理解していないと、次のような誤解が生まれます。
「1分足更新でEAが動く」
これは正しくありません。
実際には
価格更新のたびにEAは動いています。
3.3 市場状況によるティック頻度の違い
OnTickの実行頻度は 市場の流動性によって大きく変わります。
一般的な目安は次の通りです。
| 市場 | ティック頻度 |
|---|---|
| ロンドン市場 | 非常に多い |
| ニューヨーク市場 | 多い |
| 東京市場 | 中程度 |
| 週末 | ほぼゼロ |
特に次のタイミングではティックが急増します。
- 経済指標発表
- 要人発言
- 市場オープン直後
このとき OnTickの実行回数が急増します。
そのためEAでは
- 軽量な処理
- 適切な条件チェック
が重要になります。
3.4 ティックが来ないケース
初心者がよく疑問に思うのが
「EAが動かない」
という問題です。
その原因の多くは ティックが発生していないことです。
次のような状況ではOnTickは実行されません。
- 市場が閉まっている(週末)
- 流動性の低い銘柄
- デモ口座のデータ遅延
- チャートが停止
つまり
OnTickはティックが来ないと絶対に実行されない
という仕組みです。
もし定期処理が必要な場合は、MQL5では次のイベントを使います。
OnTimer()
これは 指定時間ごとに実行されるイベントです。
つまずきポイント
OnTickの仕組みで初心者がよく混乱する部分があります。
① ティック数はバックテストと違う
バックテストでは
- モデリング方式
- ティック生成方法
によってティック数が変わります。
そのため
- 実運用
- バックテスト
で OnTick回数が一致しないことがあります。
これは正常な動作です。
② 高速EAはティック数の影響を受ける
スキャルピングEAなどでは
- ティック精度
- データ品質
が結果に大きく影響します。
環境によって
- 約定回数
- トレードタイミング
が変わることがあります。
よくある失敗
ティック処理を理解せずにEAを書く
初心者がよく書くコードの例です。
void OnTick()
{
if(signal)
{
OrderSend(...);
}
}
このコードは
ティックごとに注文を出す
ため、次の問題が起きます。
- 同じ条件で連続注文
- 数秒で大量ポジション
- 証拠金破綻
実際のEAでは次のような制御が必要です。
- 新バー判定
- ポジションチェック
- エントリー回数制御
4. OnTickを使ったEAの基本構造(実践コード例)
4.1 EAの基本構造(OnInit・OnTick・OnDeinit)
MQL5のEAは、通常次の3つのイベント関数で構成されます。
| 関数 | 役割 |
|---|---|
| OnInit | EA起動時に1回実行 |
| OnTick | ティックごとに実行 |
| OnDeinit | EA終了時に実行 |
基本的なEAのテンプレートは次のようになります。
int OnInit()
{
Print("EA started");
return(INIT_SUCCEEDED);
}
void OnTick()
{
// 売買ロジック
}
void OnDeinit(const int reason)
{
Print("EA stopped");
}
処理の流れは次の通りです。
- EAをチャートにセット
- OnInit()が実行される
- ティックが到着
- OnTick()が実行される
- EAを外すと OnDeinit()が実行される
実際のトレード判断は OnTickの中で行う のが基本です。
4.2 シンプルなEAの例(価格条件)
最も簡単なEAの例を示します。
void OnTick()
{
double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
if(price > 150.000)
{
Print("Price is above 150");
}
}
このEAは
- 現在価格を取得
- 条件を判定
- 条件成立時にログ出力
という基本構造になっています。
EA開発ではまずこの 基本パターン を理解することが重要です。
4.3 インジケーターを使ったEAの基本形
実際のEAではインジケーターを使って売買判断を行います。
例として 移動平均(MA) を使う場合の構造を示します。
int maHandle;
int OnInit()
{
maHandle = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
return(INIT_SUCCEEDED);
}
void OnTick()
{
double maBuffer[];
CopyBuffer(maHandle, 0, 0, 1, maBuffer);
double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
if(price > maBuffer[0])
{
Print("Buy signal");
}
}
処理の流れ
- OnInitでインジケーター作成
- OnTickで値を取得
- 条件判定
この構造は多くのEAで使われています。
4.4 EAの実務的な構造(おすすめパターン)
実際のEAでは、OnTickにすべてを書くとコードが非常に読みにくくなります。
そのため通常は 関数分割 を行います。
例
void OnTick()
{
CheckEntry();
ManagePosition();
}
エントリー判定
void CheckEntry()
{
// エントリー条件
}
ポジション管理
void ManagePosition()
{
// 利確・損切り処理
}
この設計にすると
- コードが読みやすい
- バグが減る
- 機能追加が簡単
というメリットがあります。
つまずきポイント
① OnTickに全部書く
初心者が最初に書くEAは次のようになります。
void OnTick()
{
// 100行以上のコード
}
この構造では
- バグ発見が困難
- メンテナンス不可
になります。
EAは 関数分割が基本です。
② インジケーターを毎ティック作る
初心者がよくやるミスです。
void OnTick()
{
int handle = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
}
このコードは ティックごとにインジケーターを作成します。
結果
- メモリ消費
- パフォーマンス低下
になります。
正しくは OnInitで作成します。
よくある失敗
無限注文EA
次のコードは初心者がよく作る危険なEAです。
void OnTick()
{
if(signal)
{
trade.Buy(0.1);
}
}
このコードは
条件がtrueの間、ティックごとに注文します。
結果
- 数秒で数百ポジション
- 証拠金破綻
という事故になります。
対策
- ポジション確認
- 新バー判定
- フラグ管理
が必要です。
5. OnTickで絶対に覚えるべき実装テクニック(新バー判定・処理制御)
5.1 なぜOnTickに制御ロジックが必要なのか
OnTickは ティック(価格更新)ごとに実行されるイベント関数です。
そのため、何も制御しない場合、EAは 非常に高頻度で同じ処理を繰り返すことになります。
例えば次のようなコードです。
void OnTick()
{
if(signal)
{
trade.Buy(0.1);
}
}
このコードは条件が成立している間、
- 1秒に数回
- 市場が活発な場合は数十回
注文を出し続ける可能性があります。
結果として
- 同じポジションが大量発生
- 証拠金不足
- EA停止
といった重大な問題が発生します。
この問題を防ぐために、EAでは次のような制御を行います。
- 新バー判定
- ポジション確認
- フラグ管理
- 時間制御
特に 新バー判定 はほぼすべてのEAで使用される基本テクニックです。
5.2 新バー判定(最も重要なテクニック)
新バー判定とは
ローソク足が更新されたタイミングで処理を実行する方法
です。
これにより
- ティックごとの処理を防ぐ
- バックテストの安定
- EAの負荷軽減
が可能になります。
基本コードは次の通りです。
bool IsNewBar()
{
static datetime lastBarTime = 0;
datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
if(currentBarTime != lastBarTime)
{
lastBarTime = currentBarTime;
return true;
}
return false;
}
OnTickでは次のように使用します。
void OnTick()
{
if(!IsNewBar())
return;
Print("New bar detected");
}
このコードの動作
- 新しいローソク足が生成されたときだけ処理
- それ以外のティックでは処理をスキップ
結果として
EAの処理は1バーに1回だけ実行されます。
5.3 ポジション確認(重複注文防止)
EAでは 既存ポジション確認も重要です。
次のように書くと安全です。
void OnTick()
{
if(PositionSelect(_Symbol))
return;
if(signal)
{
trade.Buy(0.1);
}
}
このコードの意味
- すでにポジションがある場合
- 新しい注文を出さない
つまり 重複エントリー防止です。
EAでは非常によく使われるパターンです。
5.4 フラグ管理(エントリー回数制御)
もう一つの重要テクニックが フラグ管理です。
例
bool traded = false;
void OnTick()
{
if(traded)
return;
if(signal)
{
trade.Buy(0.1);
traded = true;
}
}
このコードでは
- 一度注文したら
- 同じ注文は出さない
という制御になります。
EAでは
- 1日1回トレード
- 1バー1回トレード
などの制御に使われます。
つまずきポイント
① 新バー判定を書かない
初心者EAの多くは
ティックごとに売買判断
をしています。
その結果
- バックテストが不安定
- スプレッド影響増加
- 約定数過多
になります。
多くのEAは バー単位ロジックで設計されています。
② iTimeの使い方を間違える
新バー判定では
iTime(_Symbol, PERIOD_CURRENT, 0)
を使います。
意味
| 引数 | 内容 |
|---|---|
| Symbol | 通貨ペア |
| Timeframe | 時間足 |
| 0 | 最新バー |
この理解がないと、誤動作するEAになります。
よくある失敗
バックテストと実運用のズレ
ティックEAの場合
- ティック品質
- ブローカー
- 約定速度
の影響を受けます。
その結果
- バックテストでは利益
- 実運用では損失
というケースが発生します。
この問題を減らすために
バー単位ロジック
が多くのEAで採用されています。
6. OnTickのパフォーマンス最適化(EAを高速化する方法)
6.1 なぜOnTickの最適化が重要なのか
OnTickは ティック(価格更新)ごとに実行される関数です。
そのため、EAのパフォーマンスは OnTick内部の処理効率に大きく依存します。
例えば流動性の高い通貨ペアでは、1秒間に次のような回数でティックが発生することがあります。
| 市場状況 | ティック数(目安) |
|---|---|
| 通常市場 | 1秒に数回 |
| ロンドン市場 | 1秒に10回以上 |
| ニュース発表 | 1秒に数十回 |
もしOnTickに重い処理を書いてしまうと
- EAが遅くなる
- バックテストが極端に遅くなる
- VPSのCPU使用率が上がる
といった問題が発生します。
そのためEA開発では OnTickをできるだけ軽量にする設計が重要です。
6.2 不要な処理を減らす(早期リターン)
最も基本的な最適化テクニックが 早期リターン(Early Return) です。
不要な条件の場合は すぐに処理を終了します。
例
void OnTick()
{
if(!IsNewBar())
return;
CheckSignal();
}
このコードの意味
- 新バーでない場合
- それ以上処理しない
結果として
- 計算量削減
- CPU負荷軽減
になります。
この方法は ほぼすべてのEAで使われる基本テクニックです。
6.3 インジケーターはOnInitで作成する
初心者がよくやるミスが
OnTick内でインジケーターを作成することです。
誤った例
void OnTick()
{
int ma = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
}
このコードは ティックごとにインジケーターを生成します。
問題
- メモリ消費増加
- CPU負荷増大
- EAが遅くなる
正しい方法は OnInitで作成することです。
int maHandle;
int OnInit()
{
maHandle = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
return(INIT_SUCCEEDED);
}
そしてOnTickでは値だけ取得します。
void OnTick()
{
double buffer[];
CopyBuffer(maHandle,0,0,1,buffer);
}
この設計は EA開発の基本パターンです。
6.4 不要なログ出力を減らす
Print() はデバッグには便利ですが、
大量に使うと ログ処理がボトルネックになります。
例
void OnTick()
{
Print("Tick received");
}
ティックが多い通貨では
- 1分で数千ログ
が出力されます。
その結果
- ログファイル肥大化
- MT5パフォーマンス低下
が発生することがあります。
対策
- デバッグ時のみPrint使用
- 条件付きログ
例
if(signal)
{
Print("Entry signal");
}
6.5 ループ処理を最小化する
OnTick内で大きなループを書くと、
ティック頻度によっては EAが極端に遅くなることがあります。
例(非推奨)
for(int i=0;i<10000;i++)
{
// heavy calculation
}
このような処理は
- OnTimer
- OnInit
などへ移動する方が安全です。
つまずきポイント
① ティックEAはCPU負荷が高い
ティックベースEAは
- 高頻度実行
- 高CPU負荷
になりやすいです。
そのため
- VPSスペック
- EA設計
が重要になります。
② バックテスト速度が極端に遅い
OnTick処理が重いと
- テストが数時間
- 最適化が不可能
になることがあります。
原因の多くは
- 重いインジケーター
- 不要な計算
- 無駄なループ
です。
よくある失敗
インジケーターを毎ティック作る
これは初心者EAで最も多いミスです。
結果
- MT5フリーズ
- テスト速度低下
- メモリ消費
になります。
EAでは必ず
OnInitでインジケーター作成
という設計にしましょう。
7. OnTickを使う際の注意点(EA開発で起きやすいトラブル)
7.1 同一条件での連続エントリー
OnTickを使うEAで最も多いトラブルは 同じ条件で何度も注文してしまう問題です。
例えば次のコードです。
void OnTick()
{
if(signal)
{
trade.Buy(0.1);
}
}
このコードでは、条件が成立している限り ティックごとに注文します。
例えば次の状況を考えます。
| 時刻 | 状態 |
|---|---|
| 10:00:01 | 条件成立 |
| 10:00:01 | ティック |
| 10:00:01 | 注文 |
| 10:00:01 | 次ティック |
| 10:00:01 | 再注文 |
この結果
- 数秒で大量ポジション
- 証拠金不足
- EA停止
という事故が起きることがあります。
対策としては次の方法を使います。
- 新バー判定
- ポジション確認
- フラグ管理
例
void OnTick()
{
if(PositionSelect(_Symbol))
return;
if(signal)
{
trade.Buy(0.1);
}
}
これにより 既存ポジションがある場合は新規注文しない設計になります。
7.2 ティックが来ないとEAは動かない
OnTickは 価格更新イベントで動く関数です。
そのため次の状況では EAが実行されません。
- 市場休場(週末)
- 流動性の低い銘柄
- データ停止
- チャート更新停止
初心者がよく
「EAが止まっている」
と感じるケースの多くは ティックが来ていないだけです。
もし一定時間ごとに処理したい場合は OnTimerイベントを使います。
例
EventSetTimer(60);
これにより 60秒ごとにOnTimerが実行されます。
7.3 バックテストと実運用の違い
OnTickベースEAでは
- バックテスト
- 実運用
で挙動が変わることがあります。
理由は次の通りです。
| 要因 | 説明 |
|---|---|
| ティック生成 | テストでは疑似ティック |
| 約定速度 | 実口座は遅延あり |
| スプレッド | ブローカー差 |
| 流動性 | 市場状況 |
そのため
- テストでは利益
- 実運用では結果が変わる
というケースがあります。
特に
- スキャルピングEA
- 高頻度EA
では影響が大きくなります。
7.4 VPS環境の影響
EAは通常 VPS(仮想サーバー)で動かします。
VPS環境によって
- CPU性能
- ネットワーク遅延
- MT5安定性
が変わります。
OnTickは高頻度処理なので
- 低スペックVPS
- CPU共有型
では処理遅延が起きることがあります。
EA運用では
- 安定したVPS
- 低レイテンシ
が重要です。
つまずきポイント
① OnTickが動いているか確認しない
EAが動いているか確認するには
Print("Tick");
などでログ確認すると分かります。
② デモとリアルの違い
デモ口座では
- ティック頻度
- 約定速度
がリアルと異なる場合があります。
EA検証では
- フォワードテスト
- リアル小ロット
が推奨されます。
よくある失敗
ティックEAを理解せずに設計する
初心者が作るEAの多くは
- ティック処理
- エントリー制御
を考慮していません。
その結果
- 連続注文
- 不安定トレード
- 再現性低下
になります。
EA設計では
- 新バー判定
- ポジション管理
- 処理最適化
を組み合わせることが重要です。
8. FAQ(よくある質問)
8.1 OnTickとは何ですか?
OnTickは、価格のティック(Tick:価格更新)が発生したときに自動実行されるMQL5のイベント関数です。
EA(Expert Advisor)はイベント駆動型のプログラムであり、市場から新しい価格が届くとOnTickが呼び出されます。
多くのEAでは、この関数の中で
- 売買条件の判定
- 注文処理
- ポジション管理
などを行います。
8.2 OnTickはどのくらいの頻度で実行されますか?
OnTickの実行頻度は 市場のティック頻度に依存します。
例えば
| 市場状況 | ティック頻度 |
|---|---|
| 通常市場 | 1秒に数回 |
| ロンドン市場 | 1秒に10回以上 |
| ニュース発表時 | 1秒に数十回 |
ただし、流動性が低い時間帯では 数秒〜数十秒OnTickが呼ばれないこともあります。
つまり、OnTickは
時間ではなく価格更新に反応するイベント
です。
8.3 OnTickとOnTimerの違いは何ですか?
両者の違いは 実行トリガーです。
| 関数 | 実行タイミング |
|---|---|
| OnTick | 価格更新時 |
| OnTimer | 指定時間ごと |
OnTickは市場イベントに反応する関数であり、OnTimerは 一定時間ごとに処理したい場合に使います。
例えば
- 定期チェック
- ログ出力
- リスク監視
などではOnTimerが使われることがあります。
8.4 OnTickはインジケーターでも使えますか?
使えません。
OnTickは EA専用のイベント関数です。
インジケーターでは通常
OnCalculate()
という関数が使用されます。
8.5 OnTickは複数定義できますか?
できません。
EAの中でOnTickは 1つだけ定義できます。
次のようなコードはコンパイルエラーになります。
void OnTick()
{
}
void OnTick()
{
}
8.6 OnTickに重い処理を書くとどうなりますか?
ティックは高頻度で発生するため、OnTickに重い処理を書くと
- EAが遅くなる
- バックテストが極端に遅くなる
- CPU負荷が増える
といった問題が発生します。
そのためEAでは
- 新バー判定
- 早期リターン
- 関数分割
などの最適化を行います。
8.7 OnTickが動かない場合の原因は何ですか?
OnTickが動かない場合、次の原因が考えられます。
- 市場が閉まっている(週末)
- ティックが発生していない
- EAが停止している
- 自動売買が無効
- チャートが更新されていない
最も多い原因は ティックが来ていないことです。
8.8 OnTickだけでEAを作れますか?
基本的なEAは OnTickだけでも作成可能です。
ただし実際のEAでは次の関数を併用することが多いです。
OnInit()(初期化)OnTick()(売買ロジック)OnDeinit()(終了処理)
この構造が EAの基本テンプレートになります。