「スプレッド表示インジケーター」のサンプルコードをそのままコピペしてコンパイルしたのに、チャート上に何も表示されない——という経験はありませんか。
原因の多くは、インジケーターなのに表示処理をスクリプト専用の関数に書いてしまっていることです。この記事では、チャート上にスプレッドを表示するインジケーターの作り方を、実際にMetaEditorでコンパイルしてチャートに表示できる形で解説します。
チャート上にスプレッドを表示するインジケーター
チャート上にスプレッドを表示するインジケーターを作成していきます。
- チャート上にスプレッドを表示させる
メタエディタを開く
メタエディタ(MetaEditor)を立ち上げましょう。操作は以下に記載しています。

今回は名前を「trade-spread」で作成します。
OnCalculate()関数に記述する
このインジケーターの表示処理は、スクリプト専用のOnStart()ではなく、インジケーターが毎ティック呼び出すOnCalculate()に書きます。OnStart()はスクリプト(Scripts)として実行した場合にしか呼び出されないため、カスタムインジケーターとしてコンパイル・チャートへ追加しても、OnStart()の中身は一度も実行されません。
double spread変数では、スプレッドの値に0.1をかけた値を代入しています。
MarketInfo関数については以下の記事を参照してください。

double spread = MarketInfo(Symbol(),MODE_SPREAD)*0.1;//スプレッドの値を取得
オブジェクトの作成・位置・文字の設定は、OnInit()で一度だけ行い、OnCalculate()では表示するテキストだけを毎回更新します。こうすることで、ティックが来るたびにオブジェクトを作り直す無駄や、オブジェクト名の重複を避けられます。
ObjectCreate(0,"spread",OBJ_LABEL,0,0,0);//オブジェクトを設定(OnInit()で1回だけ) ObjectSetInteger(0,"spread",OBJPROP_XDISTANCE,5);//原点からX軸に距離5 ObjectSetInteger(0,"spread",OBJPROP_YDISTANCE,18);//原点からY軸に距離18
OnCalculate()では、最新のスプレッド値でテキストだけを更新します。
ObjectSetString(0,"spread","Spread:"+DoubleToString(spread,1),20,"MS ゴシック",clrWhite);//表示形式
これで、OnCalculate()関数の記述は完了です。
double spread = MarketInfo(Symbol(),MODE_SPREAD)*0.1;//スプレッドの値を取得 ObjectSetString(0,"spread","Spread:"+DoubleToString(spread,1));//表示テキストを更新
OnInit()関数に記述する
OnInit()関数に、オブジェクトの作成・位置・文字色などの初期設定を記述しましょう。
ObjectCreate(0,"spread",OBJ_LABEL,0,0,0);//オブジェクトを設定 ObjectSetInteger(0,"spread",OBJPROP_XDISTANCE,5);//原点からX軸に距離5 ObjectSetInteger(0,"spread",OBJPROP_YDISTANCE,18);//原点からY軸に距離18 ObjectSetInteger(0,"spread",OBJPROP_COLOR,clrWhite);//文字色
これでOnInit()関数の記述は完了です。
OnDeinit()関数に記述する
OnDeinit()関数に記述しましょう。
OnDeinit()関数を記述することでインジケーターを削除すると表示が消えます。
ObjectDelete(0,"spread");//インジケーター削除すると表示が消える
これでOnDeinit()関数の記述は完了です。
void OnDeinit(const int reason)
{
ObjectDelete(0,"spread");//インジケーター削除すると表示が消える
}
コピペしてコンパイルが通らないときに確認すること
このインジケーターをコンパイルしたのにチャート上に何も表示されない場合、表示処理をOnStart()に書いてしまっていないか確認してください。OnStart()はスクリプト専用の関数で、インジケーターとして動かしても呼び出されません。表示に関わる処理は必ずOnInit()(初期設定)かOnCalculate()(毎ティックの更新)に書きます。
コンパイルする
コンパイルしましょう。通貨ペアの隣にSpreadと表示されていたら成功です。

ソースコード全体
trade-spreadのソースコード全体は以下に記載しています。
//+------------------------------------------------------------------+
//| trade-spread.mq4 |
//| Copyright 2020, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, FX-EA System Project Creator"
#property link "https://creator.fx-ea-system-project.com/"
#property version "1.01"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
ObjectCreate(0,"spread",OBJ_LABEL,0,0,0);//オブジェクトを設定
ObjectSetInteger(0,"spread",OBJPROP_XDISTANCE,5);//原点からX軸に距離5
ObjectSetInteger(0,"spread",OBJPROP_YDISTANCE,18);//原点からY軸に距離18
ObjectSetInteger(0,"spread",OBJPROP_COLOR,clrWhite);//文字色
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectDelete(0,"spread");//インジケーター削除すると表示が消える
}
//+------------------------------------------------------------------+
//| 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[])
{
//---
double spread_value = MarketInfo(Symbol(),MODE_SPREAD)*0.1;//スプレッドの値を取得
ObjectSetString(0,"spread",OBJPROP_TEXT,"Spread:"+DoubleToString(spread_value,1));//表示テキストを更新
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
まとめ
今回はスプレッドを表示させてみました。表示処理はOnStart()ではなくOnInit()・OnCalculate()に書く、という点さえ押さえておけば、他の情報を表示するインジケーターにも応用できます。
MarketInfoを活用することで他の情報を表示させることも可能になります。
コメント