複数チャートの通貨ペア同期ツールを作ってみました(ソース公開) 新しいコメント Kazutaka Okuno 2026.05.05 02:28 MT5で複数チャートを並べて使っていると、 シンボルや時間足をいちいち合わせるのが面倒 だと感じることが多いと思います。 特に、 チャートをドッキングして細かく配置している時は、 上部の時間足バーが遠かったり隠れたりして操作しづらい ことがあります。 そこで、 複数チャートの通貨ペアと時間足を、 ボタン一発で切り替えられるツール を作ってみました。 ソースもそのまま公開します。 ■ このツールでできること 送信側のボタンで通貨ペアを一括切り替え → 複数チャートを同じ銘柄に揃えるのが簡単 受信側のボタンで時間足を一発切り替え → ドッキング環境で特に便利(上のバーを探さなくていい) チャートごとにIDを設定して役割を分けられる → 例:メイン足、監視足、補助足など グローバル変数でチャート間を識別して同期 → MT5標準機能だけで動作(外部DLLなし) ソースがシンプルなので改造しやすい ■ ソースコード(そのまま貼っています) 送信側 #property strict #property indicator_chart_window #property indicator_plots 0 input string byo = "_S5"; input int mado = 0; // 画像のリスト string symbols[] = {"USDJPY", "EURJPY", "AUDJPY", "EURUSD", "GBPUSD", "AUDUSD", "ETHUSD", "BTCUSD", "GOLD"}; //--------------------------------------------- // ボタン作成 //--------------------------------------------- void CreateButton(string name, int x, int y, string text) { if(ObjectFind(0, name) == -1) { ObjectCreate(0, name, OBJ_BUTTON, mado, 0, 0); ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, name, OBJPROP_XSIZE, 50); ObjectSetInteger(0, name, OBJPROP_YSIZE, 18); ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 7); ObjectSetString (0, name, OBJPROP_TEXT, text); ObjectSetInteger(0, name, OBJPROP_COLOR, clrWhite); ObjectSetInteger(0, name, OBJPROP_BGCOLOR, clrDarkSlateGray); ObjectSetInteger(0, name, OBJPROP_BORDER_COLOR, clrSilver); ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false); } } int OnInit() { for(int i=0; i<ArraySize(symbols); i++) { CreateButton("btn_sym_" + symbols[i], 5, 15 + (i * 20), symbols[i]); } return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { ObjectsDeleteAll(0, "btn_sym_"); } //--------------------------------------------- // メイン処理:自分を変え、他も変える //--------------------------------------------- void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK && StringFind(sparam, "btn_sym_") == 0) { // 1. 選択された銘柄名(例:USDJPY)を取得 string baseName = StringSubstr(sparam, 8); // 2. 自分自身の切り替え(_S5を付加、M1固定) string myTarget = baseName + "_S" + byo; if(!ChartSetSymbolPeriod(0, myTarget, PERIOD_M1)) { Print("エラー: ", myTarget, " が見つかりません。"); } // 3. 他の目印付きチャート(Receiver)を探して同期 long currChart = ChartFirst(); while(currChart >= 0) { // 自分以外のチャートをチェック if(currChart != ChartID()) { string flagName = "Receiver_" + IntegerToString(currChart); if(GlobalVariableCheck(flagName)) { int targetID = (int)GlobalVariableGet(flagName); // IDに応じた銘柄名のルール // ID 1なら秒足(_S5)、それ以外(ID 2など)なら通常銘柄 string suffix = (targetID == 1) ? byo : ""; string syncSymbol = baseName + suffix; // ※時間足は、そのチャートの「今の設定」を維持したまま銘柄だけ変える ChartSetSymbolPeriod(currChart, syncSymbol, ChartPeriod(currChart)); } } currChart = ChartNext(currChart); } ObjectSetInteger(0, sparam, OBJPROP_STATE, false); 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(rates_total); } 受信側 #property strict #property indicator_chart_window #property indicator_plots 0 //--- 追加:目印用の設定 --- input int MyID = 2; // このチャートのID(1:秒足用, 2:分足用など) string timeFrames[] = {"M1", "M5", "M15", "M30", "H1"}; //--------------------------------------------- // ボタン作成(右上起点の座標系) //--------------------------------------------- void CreateButton(string name, int x, int y, string text) { if(ObjectFind(0, name) == -1) { ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0); ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_RIGHT_UPPER); ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, name, OBJPROP_XSIZE, 30); ObjectSetInteger(0, name, OBJPROP_YSIZE, 15); ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 8); ObjectSetString (0, name, OBJPROP_TEXT, text); ObjectSetInteger(0, name, OBJPROP_COLOR, clrWhite); ObjectSetInteger(0, name, OBJPROP_BGCOLOR, clrDarkSlateGray); ObjectSetInteger(0, name, OBJPROP_BORDER_COLOR, clrSilver); ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false); } } //--------------------------------------------- // 初期化 //--------------------------------------------- int OnInit() { // --- 目印フラグをグローバル変数にセット --- string flagName = "Receiver_" + IntegerToString(ChartID()); GlobalVariableSet(flagName, MyID); // ID表示用ラベル(確認用:不要なら消してもOK) ObjectCreate(0, "ID_Label", OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, "ID_Label", OBJPROP_CORNER, CORNER_RIGHT_UPPER); ObjectSetInteger(0, "ID_Label", OBJPROP_XDISTANCE, 35); ObjectSetInteger(0, "ID_Label", OBJPROP_YDISTANCE, 0); ObjectSetInteger(0, "ID_Label", OBJPROP_FONTSIZE, 7); ObjectSetInteger(0, "ID_Label", OBJPROP_COLOR, clrGray); ObjectSetString(0, "ID_Label", OBJPROP_TEXT, "ID:" + IntegerToString(MyID)); for(int i=0; i<ArraySize(timeFrames); i++) { CreateButton("btn_" + timeFrames[i], 35, 15 + (i * 15), timeFrames[i]); } return(INIT_SUCCEEDED); } //--------------------------------------------- // 終了処理 //--------------------------------------------- void OnDeinit(const int reason) { string flagName = "Receiver_" + IntegerToString(ChartID()); if(GlobalVariableCheck(flagName)) GlobalVariableDel(flagName); ObjectsDeleteAll(0, "btn_"); ObjectDelete(0, "ID_Label"); } //--------------------------------------------- // ボタンクリック処理 //--------------------------------------------- void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { if(StringFind(sparam, "btn_") == 0) { string tfString = StringSubstr(sparam, 4); ENUM_TIMEFRAMES newTF = StringToTimeframe(tfString); if(newTF != WRONG_VALUE) { ChartSetSymbolPeriod(0, _Symbol, newTF); } ObjectSetInteger(0, sparam, OBJPROP_STATE, false); ChartRedraw(); } } } // 時間足変換補助 ENUM_TIMEFRAMES StringToTimeframe(string tf) { if(tf == "M1") return PERIOD_M1; if(tf == "M5") return PERIOD_M5; if(tf == "M15") return PERIOD_M15; if(tf == "M30") return PERIOD_M30; if(tf == "H1") return PERIOD_H1; if(tf == "H4") return PERIOD_H4; if(tf == "D1") return PERIOD_D1; return WRONG_VALUE; } 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(rates_total); } ■ 最後に こういう “複数チャートの同期ツール” は アイデアとして持っている人は多いと思いますが、 実際に形にして公開されている例はあまり見ない ので、 誰かの参考になればと思い公開しました。 もし改善案や追加機能のアイデアがあれば教えてください。 新しいコメント 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
MT5で複数チャートを並べて使っていると、 シンボルや時間足をいちいち合わせるのが面倒 だと感じることが多いと思います。
特に、 チャートをドッキングして細かく配置している時は、 上部の時間足バーが遠かったり隠れたりして操作しづらい ことがあります。
そこで、 複数チャートの通貨ペアと時間足を、 ボタン一発で切り替えられるツール を作ってみました。 ソースもそのまま公開します。
■ このツールでできること
送信側のボタンで通貨ペアを一括切り替え → 複数チャートを同じ銘柄に揃えるのが簡単
受信側のボタンで時間足を一発切り替え → ドッキング環境で特に便利(上のバーを探さなくていい)
チャートごとにIDを設定して役割を分けられる → 例:メイン足、監視足、補助足など
グローバル変数でチャート間を識別して同期 → MT5標準機能だけで動作(外部DLLなし)
ソースがシンプルなので改造しやすい
■ ソースコード(そのまま貼っています)
受信側
■ 最後に
こういう “複数チャートの同期ツール” は アイデアとして持っている人は多いと思いますが、 実際に形にして公開されている例はあまり見ない ので、 誰かの参考になればと思い公開しました。
もし改善案や追加機能のアイデアがあれば教えてください。