恥は/dev/nullへ by 初心者

プログラミング素人がのろのろと学んだことをつづっています♪

[MQL5]MT5のチャートに表示されている通貨ペアを切り替えやすくする

インジ作成の背景

トレードをしていると、個別通貨(JPY、EUR、AUD等)の状況を確認したい場面がしばしばあります。このため、次のようにしている人をちらほら見かけます。

・小さなウィンドウを沢山配置して各通貨ペアのチャートを表示  
・モニターを複数枚使って各通貨ペアのチャートを表示  

しかし、私は小さなウィンドウでチャートを見ることが好きではありませんし、モニターを何枚も設置したくありません。というわけで、全画面表示のまま、画面に表示する通貨ペアを切り替えています。

この時に、MT5の気配値ボードは少し使いにくいです。
たとえば、アルファベット順に並べ替えると次のようになります。

この並び順だと、AUD、EURGBP等で始まる通貨は比較的まとまっているので探しやすいです。しかし、たとえば、円やスイスフランなどは〇〇〇JPY、〇〇〇CHFという風になっているので、気配値ボードではバラバラに配置されています。このため、「クロス円の通貨ペアを探したい」、「スイスフランを含む通貨ペアを探したい」といった場合に不便です。

このような事情から、チャートに表示されている通貨ペアを切り替えやすくするためにインジを作ってみました。


インジの使い方

インジをチャートに挿入すると、画面の右端に通貨ペア名の一覧が表示されます。
この一覧にある通貨ペア名をクリックすると、チャートの通貨ペアが切り替わります。

(背景なしの見本)

(背景ありの見本)


なお、同一系統の通貨をチェックする場合、私は次のように一覧を見ています。





一部の業者で生じる問題

FX業者によって通貨ペア名が若干異なるケースがあります。

私が使用している業者では「GBPUSD」「EURJPY」といった感じですが、ネット上で見かけた某業者では通貨ペアの末尾に「.pro」が付いていました。すなわち、「GBPUSD.pro」「EURJPY.pro」といった通貨ペア名になっていました。

このような場合、今回作成したインジでは通貨ペアの切り替えに失敗します。

私が今後使う業者の中にもそういう業者があるかもしれないので、チャートにインジを挿入する時に現れるパラメーター設定ウィンドウで「通貨ペア名の接尾辞」を指定できるようにしました。

たとえば、上述した例のように、通貨ペア名の末尾に「.pro」が付いている場合、「通貨ペアの接尾辞」という欄に「.pro」を記入します。
これにより通貨ペアの切り替えが可能となります。


コード(MT5用)

#property copyright "Copyright 2022, PHILOJUAN"
#property version   "1.00"
#property indicator_chart_window
#property strict
#property indicator_plots 0
#define NUM_LINE   6         // symbols[]配列の行
#define NUM_COLUMN 6         // symbols[]配列の列

enum OnOff {OFF, ON};

input color  symbolColor  = clrBlue;        // 通貨ペア名の色
input OnOff  makeBoard    = OFF;            // 通貨ペア一覧に背景枠を付ける
input color recColor      = C'78, 78, 78';  // 背景枠の色
input string symbolSuffix = "";             // 通貨ペア名の接尾辞(ある場合のみ指定)
// FX業者によっては、通貨ペア名がGBPAUD等ではなく、GBPAUD.pro等となっている場合がある。
// この場合、symbolSuffixには .pro を指定する。

input int symbolLabelPos_X = 325;           // 通貨ペア名の表示位置(X軸)
input int symbolLabelPos_Y = 300;           // 通貨ペア名の表示位置(Y軸)

input int recPosition_X = 388;              // 背景枠の表示位置(X軸)
input int recPosition_Y = 280;              // 背景枠の表示位置(Y軸)

// 接頭辞とオブジェクト名
string prefix     = "ZZWQEQZZ";
string recName    = prefix + "SIKAKU";

// 通貨ペア名配列
string symbols[NUM_LINE][NUM_COLUMN] = {
    {"GBPCAD", "GBPCHF", "GBPJPY", "GBPUSD", "GBPNZD", "GBPAUD"},
    {"EURCAD", "EURCHF", "EURJPY", "EURUSD", "EURNZD", "EURAUD"},
    {"AUDCAD", "AUDCHF", "AUDJPY", "AUDUSD", "AUDNZD", "EURGBP"},
    {"NZDCAD", "NZDCHF", "NZDJPY", "NZDUSD", "999888", "999888"},
    {"USDCAD", "USDCHF", "USDJPY", "999888", "999888", "999888"},
    {"CADJPY", "CADCHF", "CHFJPY", "999888", "999888", "999888"},
};

int OnInit()
{
    // 必要に応じて、背景となる四角形を描画
    if(makeBoard == ON)
        MakeRectangle(recName, recPosition_X, recPosition_Y, recColor, 380, 210);

    // 通貨ペア名ラベルを配置
    MakeTableOfSymbols(prefix, symbolLabelPos_X, symbolLabelPos_Y, symbolColor);

    ChartRedraw();

    return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
    ObjectsDeleteAll(0, prefix);
    ChartRedraw();
}

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[])
{
    return 0;
}

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
    if (id == CHARTEVENT_OBJECT_CLICK) {

        // クリックされたのが通貨ペア名なら、現在チャートの通貨ペアを切り換える
        string textOfObject = ObjectGetString(0, sparam, OBJPROP_TEXT);  // オブジェクト内のテキスト
        if(CheckSymbolOrNot(textOfObject)) 
            ChartSetSymbolPeriod(0, textOfObject + symbolSuffix, PERIOD_CURRENT);
    }
}

//---------------------------------------------------------------------------------------
// 指定した文字列がsymbols[]配列の中に含まれているか調べる関数
//---------------------------------------------------------------------------------------
// [備考] この関数内では グローバル配列のsymbols[]を使用している
bool CheckSymbolOrNot(string target)
{
    for(int i = 0; i < NUM_LINE; i++) {
        for(int j = 0; j < NUM_COLUMN; j++) {
            if(target == symbols[i][j]) return true;
        }
    }
    return false;
}

//---------------------------------------------------------------------------------------
// 通貨ペアの一覧ラベルを作成する関数
//---------------------------------------------------------------------------------------
// [備考] この関数内では グローバル配列のsymbols[]を使用している
void MakeTableOfSymbols(string prefixLetters, int beginX, int beginY, color labelColor)
{
    int x = beginX;
    int y = beginY;

    int xSize = 60;  // ラベルの横幅
    int ySize = 20;  // ラベルの高さ

    for(int i = 0; i < NUM_LINE; i++) {
        for(int j = 0; j < NUM_COLUMN; j++) {
            string symbolName = symbols[i][j];
            if(symbolName == "999888") break;

            MakeLabel(prefixLetters + symbolName, x, y, symbolName, 7, "Arial", labelColor, xSize, ySize);
            x -= xSize;
        }
        x = beginX;
        y += ySize + 10;
    }
}

//---------------------------------------------------------------------------------------
// ボタンのテキストや色を変更する関数
//---------------------------------------------------------------------------------------
void ChangeButtonDesign(string objName, string text, color textColor, color bgColor)
{
    ObjectSetString( 0, objName, OBJPROP_TEXT, text);
    ObjectSetInteger(0, objName, OBJPROP_COLOR, textColor);
    ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, bgColor);
    ChartRedraw();
}

//---------------------------------------------------------------------------------------
// 四角形ラベルを描画する関数
//---------------------------------------------------------------------------------------
void MakeRectangle(string objName,   // 1 ラベルオブジェクトの名前
                   int    xDistance, // 2 ラベル配置位置の起点(X軸)
                   int    yDistance, // 3 ラベル配置位置の起点(Y軸) 
                   color  objColor,  // 4 色
                   int    xSize,     // 5 ラベルのサイズ(横)
                   int    ySize      // 6 ラベルのサイズ(縦)
                  )
{
    ObjectCreate(    0, objName, OBJ_RECTANGLE_LABEL, 0, 0, 0);
    ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_RIGHT_UPPER); // 基準コーナーは右上
    ObjectSetInteger(0, objName, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER); // 基準アンカーは右上
    ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xDistance);
    ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yDistance);
    ObjectSetInteger(0, objName, OBJPROP_XSIZE, xSize);
    ObjectSetInteger(0, objName, OBJPROP_YSIZE, ySize);
    ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false);
    ObjectSetInteger(0, objName, OBJPROP_HIDDEN, true);
    ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, objColor);
}

//---------------------------------------------------------------------------------------
// ラベル作成関数
//---------------------------------------------------------------------------------------
void MakeLabel(string objName,   // 1 ラベルオブジェクトの名前
               int    xDistance, // 2 ラベル配置位置の起点(X軸)
               int    yDistance, // 3 ラベル配置位置の起点(Y軸)
               string text,      // 4 表示するテキスト
               int    fontSize,  // 5 フォントサイズ
               string font,      // 6 フォント
               color  textColor, // 7 色
               int    xSize,     // 8 ラベルのサイズ(横)
               int    ySize      // 9 ラベルのサイズ(縦)
              )
{
    ObjectCreate(    0, objName, OBJ_LABEL, 0, 0, 0);
    ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_RIGHT_UPPER);   // 基準コーナーは右上
    ObjectSetInteger(0, objName, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER);   // 基準アンカーは右上
    ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xDistance);
    ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yDistance);
    ObjectSetInteger(0, objName, OBJPROP_XSIZE, xSize);
    ObjectSetInteger(0, objName, OBJPROP_YSIZE, ySize);
    ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false);
    ObjectSetInteger(0, objName, OBJPROP_SELECTED, false);
    ObjectSetInteger(0, objName, OBJPROP_HIDDEN, true);
    SetObjectText(      objName, text, fontSize, font, textColor);
    ObjectSetString( 0, objName, OBJPROP_TOOLTIP, "\n");
    // [MQLのヘルプ] A tooltip can be disabled by setting the "\n" (line feed) value to it
}

//----------------------------------------------------------------------------------------
// ラベルオブジェクトの内容を書き換える関数  (MQL4のObjectSetTextの代わり)
//----------------------------------------------------------------------------------------
void SetObjectText(string objName, string text, int fontSize, string font, int textColor)
{
    ObjectSetString( 0, objName, OBJPROP_TEXT, text);
    ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize);
    ObjectSetString( 0, objName, OBJPROP_FONT, font);
    ObjectSetInteger(0, objName, OBJPROP_COLOR, textColor);
}