MACDのヒストグラム(OsMA)を表示していても、
ゼロラインをまたいだ瞬間を目で追い続けるのは、意外と見落としがちです。
この記事では、OsMAがゼロラインを下から上へ、
または上から下へクロスした確定足だけに、矢印を表示するインジケーターを作ります。
OsMAとは何か、MACDとの関係
OsMA(Oscillator of Moving Average)は、
MACDのメインライン(2本の移動平均線の差)と、
シグナルライン(メインラインの移動平均)の、
差をヒストグラムで表したものです。
補足: MT4の標準MACDインジケーターは、
実はメインラインとシグナルラインの2本ではなく、
ヒストグラム(OsMA相当)とメインラインを表示しています。
この記事のOsMAは、そのヒストグラム部分に相当します。
OsMAがプラスならメインラインがシグナルラインより上、
マイナスなら下にある状態を意味します。
なぜ「ゼロクロスの瞬間」だけを検知したいのか
「OsMAがプラスかマイナスか」という条件だけで矢印を出すと、
プラスが続く間ずっと矢印が出続けてしまいます。
要点: 知りたいのは「プラスの状態が続いていること」ではなく、
「いまマイナスからプラスに切り替わったこと」です。
状態ではなく、変化を検知する設計にします。
現在値だけの条件の弱点
osma > 0
この条件だけでは、OsMAがプラスの間の全ての足が条件を満たします。
1本前との比較でクロスを検知する
クロスの瞬間だけを検知するには、1本前の値との比較を加えます。
//下から上へゼロラインを超えた currentOsma > 0 && previousOsma <= 0 //上から下へゼロラインを割った currentOsma < 0 && previousOsma >= 0
形成中の0番足は値が変化し続けるため、
この記事のコードは1本前(確定足)を基準に判定します。
iOsMA関数の引数
double iOsMA( string symbol, int timeframe, int fast_ema_period, int slow_ema_period, int signal_period, int applied_price, int shift );
`fast_ema_period`・`slow_ema_period`、
`signal_period`のこの3つは、
標準的なMACDの設定(12・26・9)と揃えるのが一般的です。
`shift`に1を指定すると、1本前の確定足の値を取得できます。
実際に動くコード全体(ゼロクロス矢印インジケーター)
チャート上に、上クロスを緑の矢印、
下クロスを赤の矢印で表示する、実際にMetaEditorでコンパイルできるコードです。
//+------------------------------------------------------------------+
//| OsmaCrossArrow.mq4 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link "https://creator.fx-ea-system-project.com/"
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 LimeGreen
#property indicator_color2 Tomato
input int FastEmaPeriod = 12;
input int SlowEmaPeriod = 26;
input int SignalPeriod = 9;
input int ArrowGapPoints = 30;//高値・安値から矢印を離すポイント数
double UpArrow[];
double DownArrow[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, UpArrow);
SetIndexStyle(0, DRAW_ARROW, STYLE_SOLID, 2);
SetIndexArrow(0, 233);
SetIndexEmptyValue(0, EMPTY_VALUE);
SetIndexBuffer(1, DownArrow);
SetIndexStyle(1, DRAW_ARROW, STYLE_SOLID, 2);
SetIndexArrow(1, 234);
SetIndexEmptyValue(1, EMPTY_VALUE);
IndicatorShortName("OsMA Zero Cross Arrow");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
int needed = SlowEmaPeriod + SignalPeriod + 3;
if(rates_total < needed)
return(0);
int limit = (prev_calculated == 0) ? rates_total-2 : rates_total-prev_calculated+1;
if(limit > rates_total-2)
limit = rates_total-2;
for(int i=limit; i>=1; i--)
{
double currentOsma = iOsMA(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, i);
double previousOsma = iOsMA(NULL, 0, FastEmaPeriod, SlowEmaPeriod, SignalPeriod, PRICE_CLOSE, i+1);
UpArrow[i] = EMPTY_VALUE;
DownArrow[i] = EMPTY_VALUE;
if(currentOsma > 0 && previousOsma <= 0)
UpArrow[i] = Low[i] - ArrowGapPoints * Point;
else if(currentOsma < 0 && previousOsma >= 0)
DownArrow[i] = High[i] + ArrowGapPoints * Point;
}
return(rates_total);
}
//+------------------------------------------------------------------+
MetaEditorで実際に動かす手順
- MT4のMetaEditorで「ファイル」→「新規作成」→「カスタムインディケータ」を選ぶ
- 「OsmaCrossArrow」という名前で作成し、テンプレートの中身をすべて削除して上のコードを貼り付ける
- F7キーでコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
- チャートへ適用し、標準MACDインジケーターも同時に表示する
- MACDのヒストグラムがゼロラインをまたぐ足で、矢印が出ることを目視で確認する
よくあるエラーと対処
- 矢印が全く表示されない: `needed`の本数に足りるヒストリーデータがあるか確認してください。読み込み直後は表示までに少し時間がかかることがあります
- 矢印が価格に近すぎて見づらい: `ArrowGapPoints`を大きくしてください。5桁ブローカーでは30ポイントでも近く感じる場合があります
- 同じ方向の矢印が連続で出る: 1本前との比較条件が正しく効いていない可能性があります。`previousOsma`に渡す`shift`が`i+1`になっているか確認してください
- MACDのクロスと矢印のタイミングがずれる: MACDのゴールデンクロス(2本の移動平均線の交差)と、OsMAのゼロクロスは別の条件です。次の見出しで違いを解説します
MACDのゴールデンクロスとの違い
MACDのゴールデンクロス・デッドクロスは、
メインラインとシグナルラインという2本の線の交差を見る手法です。
OsMAのゼロクロスは、その2本の「差」がゼロを超えた瞬間を見る手法です。
実は同じ現象: メインラインとシグナルラインの差がOsMAなので、
2本のクロスとOsMAのゼロクロスは、
理論上は同じタイミングで発生します。
違いが出る場面: 表示上の見やすさは異なります。
線の交差は目で追いにくい一方、
ヒストグラムの符号反転は判定しやすい、という実務上の差があります。
OsMAゼロクロスの使いどころと限界
OsMAのゼロクロスは、トレンドの初動を捉えやすい一方、
レンジ相場ではゼロライン付近を何度も往復し、
ダマシのシグナルが連発しやすい弱点があります。
注意: このインジケーターは矢印を表示するだけで、
トレンドの強さまでは判定していません。
ADXなど別の指標と組み合わせて、
レンジ相場のシグナルを除外する設計が実務的です。
よくある質問
OsMAゼロクロスの実装でよく検索されている疑問を、3つにまとめて回答します。
EAのエントリー条件にそのまま使えますか?
この記事のコードは表示専用のインジケーターです。
`currentOsma`と`previousOsma`を比較するif文の部分だけを、
EAの`OnTick()`内にコピーすれば、エントリー条件として使えます。
適用価格をPRICE_CLOSE以外にできますか?
`iOsMA()`の第6引数(`applied_price`)を、
`PRICE_TYPICAL`等の他の定数に変更すれば、
終値以外の平均価格でOsMAを計算できます。
上位足のOsMAを判定する方法はありますか?
`iOsMA()`の第2引数(`timeframe`)に、
`PERIOD_H4`等の上位足を指定すれば、
下位足のチャートのまま上位足のOsMAを取得できます。
【MQL4】OsMAのゼロクロスだけを矢印表示するインジケーターの作り方|MACDのクロスとの違いも解説:まとめ
この記事では、OsMAがゼロラインをクロスした確定足だけに、
矢印を表示するインジケーターの作り方を解説しました。
「プラスかマイナスか」という状態ではなく、
「いま切り替わったか」という変化を検知することが、
矢印を連発させないための設計のポイントです。
OsMAのゼロクロスはMACDのゴールデンクロスと理論上は同じ現象ですが、
ヒストグラムの符号反転として見る方が判定しやすい、という実務上の利点があります。
レンジ相場のダマシを減らすには、ADXなど別の指標との組み合わせも検討してください。
コメント