MQL5のチャート操作関数を完全網羅。ChartOpen・ChartSetInteger・ChartGetInteger・ChartScreenShot・座標変換など、EA開発で使うすべてのチャート関数をコード付きで解説します。マルチチャート管理、インジケーターの動的追加、スクリーンショット自動化、GUIの座標変換まで、実践的なパターンを豊富に紹介。MQL4との違いも併記しています。
目次
MQL5チャート操作の基礎知識
MQL5のチャート関数を使うと、チャートの外観変更、複数チャートの管理、インジケーターの動的追加・削除、スクリーンショットの自動撮影など、プログラムからチャートを完全に制御できます。
MQL4とMQL5のチャート操作の違い
| 項目 | MQL4 | MQL5 |
|---|---|---|
| チャートID取得 | ChartID()(ビルド600+) | ChartID() |
| プロパティ設定 | 限定的 | ChartSetInteger/Double/Stringで完全制御 |
| インジケーター操作 | 限定的 | ChartIndicatorAdd/Delete/Nameで動的管理 |
| スクリーンショット | WindowScreenShot() | ChartScreenShot() |
| 座標変換 | 対応(ChartTimePriceToXY / ChartXYToTimePrice) | ChartTimePriceToXY / ChartXYToTimePrice |
| テンプレート適用 | ChartApplyTemplate() | ChartApplyTemplate() |
| チャートイベント | 限定的 | OnChartEventで完全対応 |
ChartID — 現在のチャートIDの取得
long ChartID();
// 戻り値: 現在のチャートのID(EAが動作しているチャート)
// 使用例
long myChart = ChartID();
Print("現在のチャートID: ", myChart);
// チャートプロパティの取得
string symbol = ChartSymbol(myChart);
ENUM_TIMEFRAMES tf = ChartPeriod(myChart);
Print("Symbol: ", symbol, " TF: ", EnumToString(tf));ChartOpen / ChartClose — チャートの開閉
long ChartOpen(
string symbol, // 通貨ペア
ENUM_TIMEFRAMES period // 時間足
);
// 戻り値: 新しいチャートのID(失敗時 0)
bool ChartClose(
long chart_id = 0 // チャートID(0=現在のチャート)
);
// 複数通貨ペアのチャートを一括で開く
void OpenMultipleCharts()
{
string symbols[] = {"EURUSD", "GBPUSD", "USDJPY", "AUDUSD"};
long chartIds[];
ArrayResize(chartIds, ArraySize(symbols));
for(int i = 0; i < ArraySize(symbols); i++)
{
chartIds[i] = ChartOpen(symbols[i], PERIOD_H1);
if(chartIds[i] > 0)
Print("チャートを開きました: ", symbols[i], " ID=", chartIds[i]);
else
Print("チャートオープン失敗: ", symbols[i]);
}
}
// 開いたチャートを閉じる
void CloseChart(long chartId)
{
if(chartId > 0 && chartId != ChartID()) // 自分自身のチャートは閉じない
ChartClose(chartId);
}
重要
ChartClose(0)やChartClose(ChartID())で自分自身のチャートを閉じると、EAも停止します。通常は他のチャートのみを閉じるようにしてください。
ChartFirst / ChartNext — 全チャートの巡回
long ChartFirst(); // 最初のチャートIDを取得
long ChartNext(long chart_id); // 次のチャートIDを取得(-1で終了)
// ターミナル内のすべてのチャートを列挙
void ListAllCharts()
{
long chartId = ChartFirst();
int count = 0;
while(chartId >= 0)
{
count++;
string symbol = ChartSymbol(chartId);
ENUM_TIMEFRAMES tf = ChartPeriod(chartId);
bool isMyChart = (chartId == ChartID());
PrintFormat("#%d ID=%I64d %s %s%s",
count, chartId, symbol, EnumToString(tf),
isMyChart ? " ← 自分" : "");
chartId = ChartNext(chartId);
}
Print("合計: ", count, "チャート");
}
// 特定の通貨ペアのチャートを検索
long FindChart(string symbol, ENUM_TIMEFRAMES tf)
{
long chartId = ChartFirst();
while(chartId >= 0)
{
if(ChartSymbol(chartId) == symbol && ChartPeriod(chartId) == tf)
return chartId;
chartId = ChartNext(chartId);
}
return -1; // 見つからない
}ChartSymbol / ChartPeriod — チャート情報の取得
string ChartSymbol(long chart_id = 0); // 通貨ペア
ENUM_TIMEFRAMES ChartPeriod(long chart_id = 0); // 時間足
// 現在のチャート情報
Print("Symbol: ", ChartSymbol()); // USDJPY等
Print("Period: ", EnumToString(ChartPeriod())); // PERIOD_H1等
Print("Period(分): ", PeriodSeconds() / 60); // 60等ChartSetInteger — チャートの整数プロパティ設定
チャートの表示設定を整数値で変更します。色、表示/非表示、モードなど多数のプロパティを制御できます。
bool ChartSetInteger(
long chart_id, // チャートID(0=現在)
ENUM_CHART_PROPERTY_INTEGER prop_id, // プロパティID
long value // 設定値
);
// サブウィンドウ指定版
bool ChartSetInteger(
long chart_id,
ENUM_CHART_PROPERTY_INTEGER prop_id,
int sub_window, // サブウィンドウ番号
long value
);主要なチャートプロパティ(整数型)
| プロパティ | 型 | 説明 |
|---|---|---|
| CHART_MODE | ENUM_CHART_MODE | チャートモード(バー/ローソク/ライン) |
| CHART_FOREGROUND | bool | 前景表示 |
| CHART_SHIFT | bool | チャートシフト(右側に余白) |
| CHART_AUTOSCROLL | bool | 自動スクロール |
| CHART_SHOW_GRID | bool | グリッド表示 |
| CHART_SHOW_VOLUMES | ENUM_CHART_VOLUME_MODE | 出来高表示 |
| CHART_SHOW_OHLC | bool | OHLC表示 |
| CHART_SHOW_ASK_LINE | bool | Ask線表示 |
| CHART_SHOW_BID_LINE | bool | Bid線表示 |
| CHART_SHOW_TRADE_LEVELS | bool | 取引レベル表示 |
| CHART_COLOR_BACKGROUND | color | 背景色 |
| CHART_COLOR_FOREGROUND | color | 前景色(テキスト等) |
| CHART_COLOR_CANDLE_BULL | color | 陽線の色 |
| CHART_COLOR_CANDLE_BEAR | color | 陰線の色 |
| CHART_COLOR_CHART_UP | color | 上昇バーの色 |
| CHART_COLOR_CHART_DOWN | color | 下降バーの色 |
// ダークテーマの設定
void SetDarkTheme(long chartId = 0)
{
ChartSetInteger(chartId, CHART_MODE, CHART_CANDLES);
ChartSetInteger(chartId, CHART_COLOR_BACKGROUND, clrBlack);
ChartSetInteger(chartId, CHART_COLOR_FOREGROUND, clrWhite);
ChartSetInteger(chartId, CHART_COLOR_GRID, clrDarkSlateGray);
ChartSetInteger(chartId, CHART_COLOR_CANDLE_BULL, clrLime);
ChartSetInteger(chartId, CHART_COLOR_CANDLE_BEAR, clrRed);
ChartSetInteger(chartId, CHART_COLOR_CHART_UP, clrLime);
ChartSetInteger(chartId, CHART_COLOR_CHART_DOWN, clrRed);
ChartSetInteger(chartId, CHART_SHOW_GRID, false);
ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, true);
ChartSetInteger(chartId, CHART_AUTOSCROLL, true);
ChartSetInteger(chartId, CHART_SHIFT, true);
ChartRedraw(chartId);
}
// EA用のクリーンな表示設定
void SetCleanChart(long chartId = 0)
{
ChartSetInteger(chartId, CHART_SHOW_GRID, false);
ChartSetInteger(chartId, CHART_SHOW_OHLC, false);
ChartSetInteger(chartId, CHART_SHOW_VOLUMES, CHART_VOLUME_HIDE);
ChartSetInteger(chartId, CHART_SHOW_TRADE_LEVELS, true);
ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, true);
ChartRedraw(chartId);
}ChartSetDouble / ChartSetString — その他のプロパティ設定
// Double型プロパティ
bool ChartSetDouble(long chart_id, ENUM_CHART_PROPERTY_DOUBLE prop_id, double value);
// CHART_FIXED_MAX / CHART_FIXED_MIN: 固定スケール
ChartSetInteger(0, CHART_SCALEFIX, true); // 固定スケールON
ChartSetDouble(0, CHART_FIXED_MAX, 151.000); // 最大値
ChartSetDouble(0, CHART_FIXED_MIN, 149.000); // 最小値
// CHART_SHIFT_SIZE: チャートシフトの幅(%)
ChartSetDouble(0, CHART_SHIFT_SIZE, 20.0); // 右側20%の余白
// String型プロパティ
bool ChartSetString(long chart_id, ENUM_CHART_PROPERTY_STRING prop_id, string value);
// CHART_COMMENT: チャートコメント(Comment()と同等)
ChartSetString(0, CHART_COMMENT, "EA Status: Running\nProfit: $123.45");ChartGetInteger / ChartGetDouble / ChartGetString — プロパティの取得
long ChartGetInteger(long chart_id, ENUM_CHART_PROPERTY_INTEGER prop_id, int sub_window = 0);
double ChartGetDouble(long chart_id, ENUM_CHART_PROPERTY_DOUBLE prop_id, int sub_window = 0);
string ChartGetString(long chart_id, ENUM_CHART_PROPERTY_STRING prop_id);
// チャートの寸法を取得
int chartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
int chartHeight = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
Print("チャートサイズ: ", chartWidth, "x", chartHeight, " px");
// 表示範囲の取得
int visibleBars = (int)ChartGetInteger(0, CHART_VISIBLE_BARS);
int firstBar = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR);
Print("表示バー数: ", visibleBars, " 最初のバー: ", firstBar);
// 価格範囲の取得
double priceMax = ChartGetDouble(0, CHART_PRICE_MAX);
double priceMin = ChartGetDouble(0, CHART_PRICE_MIN);
Print("価格範囲: ", priceMin, " - ", priceMax);
// サブウィンドウ数の取得
int windows = (int)ChartGetInteger(0, CHART_WINDOWS_TOTAL);
Print("ウィンドウ数: ", windows); // 1=メインのみ、2以上=サブウィンドウありChartRedraw / ChartNavigate — 再描画とナビゲーション
void ChartRedraw(long chart_id = 0); // チャートの再描画を強制
bool ChartNavigate(
long chart_id, // チャートID
ENUM_CHART_POSITION position, // 基準位置
int shift = 0 // シフト量(バー数)
);
// position: CHART_BEGIN(最初)、CHART_CURRENT_POS(現在位置)、CHART_END(最後)
// 最新バーに移動
ChartNavigate(0, CHART_END, 0);
// 100本前に移動
ChartNavigate(0, CHART_END, -100);
// 最初のバーに移動
ChartNavigate(0, CHART_BEGIN, 0);
// プロパティ変更後は必ずRedraw
ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrBlack);
ChartRedraw(0); // 変更を反映チャートプロパティの変更後はChartRedraw()を呼び出して変更を反映させてください。呼び出さなくても次の描画サイクルで反映されますが、即座に反映したい場合は明示的に呼び出します。
ChartIndicatorAdd / Delete / Name / Total — インジケーターの動的管理
bool ChartIndicatorAdd(
long chart_id, // チャートID
int sub_window, // サブウィンドウ番号(0=メインウィンドウ)
int indicator_handle // インジケーターハンドル
);
bool ChartIndicatorDelete(
long chart_id,
int sub_window,
const string indicator_shortname // インジケーターの短い名前
);
string ChartIndicatorName(
long chart_id,
int sub_window,
int index // インデックス(0から)
);
int ChartIndicatorsTotal(
long chart_id,
int sub_window
);
// MAをチャートに追加
int maHandle = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
if(maHandle != INVALID_HANDLE)
ChartIndicatorAdd(0, 0, maHandle); // メインウィンドウに追加
// RSIをサブウィンドウに追加
int rsiHandle = iRSI(_Symbol, PERIOD_CURRENT, 14, PRICE_CLOSE);
if(rsiHandle != INVALID_HANDLE)
ChartIndicatorAdd(0, 1, rsiHandle); // サブウィンドウ1に追加
// チャート上のインジケーター一覧
void ListChartIndicators()
{
int windows = (int)ChartGetInteger(0, CHART_WINDOWS_TOTAL);
for(int w = 0; w < windows; w++)
{
int total = ChartIndicatorsTotal(0, w);
Print("ウィンドウ ", w, ": ", total, "個のインジケーター");
for(int i = 0; i < total; i++)
{
string name = ChartIndicatorName(0, w, i);
Print(" [", i, "] ", name);
}
}
}
// 特定のインジケーターを削除
void RemoveIndicator(string shortname)
{
int windows = (int)ChartGetInteger(0, CHART_WINDOWS_TOTAL);
for(int w = 0; w < windows; w++)
{
int total = ChartIndicatorsTotal(0, w);
for(int i = 0; i < total; i++)
{
if(ChartIndicatorName(0, w, i) == shortname)
{
ChartIndicatorDelete(0, w, shortname);
Print("インジケーター削除: ", shortname);
return;
}
}
}
}ChartScreenShot — スクリーンショットの自動撮影
bool ChartScreenShot(
long chart_id, // チャートID
string filename, // ファイル名(MQL5\Filesに保存)
int width, // 幅(ピクセル)
int height, // 高さ(ピクセル)
ENUM_ALIGN_MODE align_mode = ALIGN_RIGHT // 整列モード
);
// align_mode: ALIGN_RIGHT(右端=最新バー)、ALIGN_LEFT(左端)
// 基本スクリーンショット
ChartScreenShot(0, "screenshot.png", 1920, 1080);
// トレード時に自動撮影
void TakeTradeScreenshot(string action, ulong ticket)
{
MqlDateTime dt;
TimeCurrent(dt);
string filename = StringFormat("trades\\%s_%s_%I64u_%04d%02d%02d_%02d%02d.png",
_Symbol, action, ticket,
dt.year, dt.mon, dt.day, dt.hour, dt.min);
// フォルダ作成
FolderCreate("trades");
// スクリーンショット撮影
if(ChartScreenShot(0, filename, 1280, 720))
Print("スクリーンショット保存: ", filename);
else
Print("スクリーンショット失敗: ", GetLastError());
}
// 定期的なスクリーンショット(タイマーで使用)
void OnTimer()
{
MqlDateTime dt;
TimeCurrent(dt);
// 1時間ごとにスクリーンショット
if(dt.min == 0 && dt.sec < 10)
{
string filename = StringFormat("hourly\\%s_%04d%02d%02d_%02d00.png",
_Symbol, dt.year, dt.mon, dt.day, dt.hour);
FolderCreate("hourly");
ChartScreenShot(0, filename, 1920, 1080);
}
}ChartTimePriceToXY / ChartXYToTimePrice — 座標変換
チャート上の時間・価格座標とピクセル座標(XY)を相互変換します。GUIやカスタムオブジェクトの配置に使用します。
bool ChartTimePriceToXY(
long chart_id, // チャートID
int sub_window, // サブウィンドウ番号
datetime time, // 時間
double price, // 価格
int& x, // 出力: X座標(ピクセル)
int& y // 出力: Y座標(ピクセル)
);
bool ChartXYToTimePrice(
long chart_id,
int x, // X座標
int y, // Y座標
int& sub_window, // 出力: サブウィンドウ番号
datetime& time, // 出力: 時間
double& price // 出力: 価格
);
// 特定の価格・時間のピクセル位置を取得
void GetPixelPosition()
{
datetime time = iTime(_Symbol, PERIOD_CURRENT, 0);
double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
int x, y;
if(ChartTimePriceToXY(0, 0, time, price, x, y))
Print("現在の価格位置: x=", x, " y=", y, " px");
}
// クリック位置の価格を取得(OnChartEvent内で使用)
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
if(id == CHARTEVENT_CLICK)
{
int subWindow;
datetime clickTime;
double clickPrice;
if(ChartXYToTimePrice(0, (int)lparam, (int)dparam, subWindow, clickTime, clickPrice))
{
PrintFormat("クリック位置: Time=%s Price=%.5f Window=%d",
TimeToString(clickTime), clickPrice, subWindow);
}
}
}ChartApplyTemplate — テンプレートの適用
bool ChartApplyTemplate(
long chart_id, // チャートID
const string filename // テンプレートファイル名
);
// テンプレートの適用
ChartApplyTemplate(0, "my_ea_template.tpl");
// 新しいチャートにテンプレートを適用
long newChart = ChartOpen("GBPUSD", PERIOD_H4);
if(newChart > 0)
{
ChartApplyTemplate(newChart, "trading_setup.tpl");
ChartRedraw(newChart);
}
重要
テンプレートファイル(.tpl)はMQL5\Profiles\Templates\フォルダに配置する必要があります。MQL5\Files\ではありません。セキュリティ上、テンプレートにはEAの設定が含まれる場合があるため、信頼できるテンプレートのみ使用してください。
ChartWindowFind — サブウィンドウの検索
int ChartWindowFind(
long chart_id, // チャートID
string indicator_shortname // インジケーターの短い名前
);
// 戻り値: サブウィンドウ番号(見つからない場合 -1)
// 現在のEAが動作しているウィンドウを取得
int myWindow = ChartWindowFind(0, ""); // 空文字列=自分自身
// RSIのサブウィンドウを探す
int rsiWindow = ChartWindowFind(0, "RSI(14)");
if(rsiWindow >= 0)
Print("RSIはウィンドウ", rsiWindow, "にあります");
else
Print("RSIが見つかりません");実践パターン:EA開発でのチャート操作
パターン1:マルチチャート監視システム
// 複数通貨ペアの監視チャートを一括管理
class CChartManager
{
private:
long m_chartIds[];
string m_symbols[];
int m_count;
public:
CChartManager() : m_count(0) {}
~CChartManager() { CloseAll(); }
// 監視チャートを開く
bool OpenChart(string symbol, ENUM_TIMEFRAMES tf)
{
long id = ChartOpen(symbol, tf);
if(id <= 0) return false;
m_count++;
ArrayResize(m_chartIds, m_count);
ArrayResize(m_symbols, m_count);
m_chartIds[m_count-1] = id;
m_symbols[m_count-1] = symbol;
// デフォルト設定
ChartSetInteger(id, CHART_MODE, CHART_CANDLES);
ChartSetInteger(id, CHART_SHOW_GRID, false);
ChartSetInteger(id, CHART_AUTOSCROLL, true);
ChartRedraw(id);
return true;
}
// 全チャートにインジケーターを追加
void AddIndicatorToAll(int indicatorHandle)
{
for(int i = 0; i < m_count; i++)
ChartIndicatorAdd(m_chartIds[i], 0, indicatorHandle);
}
// 全チャートのスクリーンショットを撮影
void ScreenshotAll(string folder)
{
FolderCreate(folder);
MqlDateTime dt;
TimeCurrent(dt);
for(int i = 0; i < m_count; i++)
{
string filename = StringFormat("%s\\%s_%04d%02d%02d_%02d%02d.png",
folder, m_symbols[i],
dt.year, dt.mon, dt.day, dt.hour, dt.min);
ChartScreenShot(m_chartIds[i], filename, 1280, 720);
}
}
// 全チャートを閉じる
void CloseAll()
{
for(int i = 0; i < m_count; i++)
if(m_chartIds[i] > 0)
ChartClose(m_chartIds[i]);
m_count = 0;
ArrayFree(m_chartIds);
ArrayFree(m_symbols);
}
};
// 使用例
CChartManager chartMgr;
int OnInit()
{
chartMgr.OpenChart("EURUSD", PERIOD_H1);
chartMgr.OpenChart("GBPUSD", PERIOD_H1);
chartMgr.OpenChart("AUDUSD", PERIOD_H1);
EventSetTimer(3600); // 1時間ごとにスクリーンショット
return INIT_SUCCEEDED;
}
void OnTimer()
{
chartMgr.ScreenshotAll("monitoring");
}
void OnDeinit(const int reason)
{
chartMgr.CloseAll();
}パターン2:取引時のスクリーンショット自動保存
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
// 新規取引の約定時にスクリーンショット
if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
{
ulong dealTicket = trans.deal;
if(dealTicket == 0) return;
// ディールの情報を取得
HistoryDealSelect(dealTicket);
ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(dealTicket, DEAL_ENTRY);
string action = "";
if(entry == DEAL_ENTRY_IN) action = "ENTRY";
if(entry == DEAL_ENTRY_OUT) action = "EXIT";
if(StringLen(action) == 0) return;
// チャートを最新に更新
ChartRedraw(0);
// スクリーンショット撮影(少し待って確実に反映させる)
MqlDateTime dt;
TimeCurrent(dt);
string filename = StringFormat("trades\\%s_%s_%I64u_%04d%02d%02d_%02d%02d%02d.png",
_Symbol, action, dealTicket,
dt.year, dt.mon, dt.day,
dt.hour, dt.min, dt.sec);
FolderCreate("trades");
ChartScreenShot(0, filename, 1920, 1080);
Print("取引スクリーンショット: ", filename);
}
}チャート関数一覧リファレンス
| 関数 | 機能 | 主な用途 |
|---|---|---|
| ChartID | 現在のチャートID取得 | 自チャートの識別 |
| ChartOpen / Close | チャートの開閉 | マルチチャート管理 |
| ChartFirst / Next | チャートの巡回 | 全チャートの列挙 |
| ChartSymbol / Period | 通貨ペア・時間足取得 | チャート情報の確認 |
| ChartSetInteger | 整数プロパティ設定 | 色・表示設定の変更 |
| ChartSetDouble | 浮動小数点プロパティ設定 | スケール・余白設定 |
| ChartSetString | 文字列プロパティ設定 | コメント表示 |
| ChartGetInteger/Double/String | プロパティ取得 | チャート情報の読み取り |
| ChartRedraw | 再描画の強制 | プロパティ変更の即時反映 |
| ChartNavigate | チャートのナビゲーション | 表示位置の移動 |
| ChartIndicatorAdd/Delete | インジケーター管理 | 動的なインジケーター追加・削除 |
| ChartScreenShot | スクリーンショット | 取引記録の自動撮影 |
| ChartTimePriceToXY | 時間価格→ピクセル変換 | GUI・オブジェクト配置 |
| ChartXYToTimePrice | ピクセル→時間価格変換 | クリック位置の解析 |
| ChartApplyTemplate | テンプレート適用 | チャート設定の一括適用 |
| ChartWindowFind | サブウィンドウ検索 | インジケーターの位置特定 |
- ChartSetIntegerでチャートの外観を完全にカスタマイズ可能
- ChartScreenShotでトレード時に自動スクリーンショットを保存
- ChartFirst/Nextで全チャートを巡回し、一括操作が可能
- 座標変換(ChartTimePriceToXY/XYToTimePrice)でGUI開発に対応
- プロパティ変更後はChartRedraw()で即座に反映
プロが開発したEAをお探しの方は → シストレ.COM EA一覧





