MT5(おそらくMT4も対応)のチャート背景に画像を設定する方法を解説します。画像をチャートの背景に設定する際に、画像をチャートに合わせて自動調整させたり、透明度を設定して見やすくするテクニックを紹介します。
この記事で学べること:
- チャート背景カスタマイズの基本設定
- BMP画像の読み込みと表示方法
- 透明度調整とサイズ変更の実装手順
- EA開発時の最適化テクニック
チャート背景カスタマイズの基礎知識
目的と利点
チャート背景のカスタマイズについて解説します。例えば、主要通貨ペアには青系の背景を、クロス円には緑系の背景を設定することで、一目で取引対象を識別できます。
また、背景の透明度を調整することで、価格の動きをより見やすく表示できます。特に、重要な価格レベルを示す水平線と背景画像を組み合わせることで、より戦略的な取引が可能になります。
実装に必要な準備
実装を始める前に、開発環境の準備が必要です。まず、最新版のMT5をインストールしましょう。MQL5言語の基本的な知識があれば十分ですが、画像処理に関する理解があるとより効果的な実装が可能です。
準備するものは以下の通りですが、これらは段階的に揃えていけば問題ありません:
- MT5の最新版
- 背景用の画像ファイル
- 基本的なMQL5の知識
対応する画像形式と制限事項
チャート背景に使用する画像には、いくつかの制約があります。最も重要なのは画像形式で、MT5では24ビットまたは32ビットのBMPファイルを使用します。
なぜBMP形式なのでしょうか?これは、MT5が画像データを直接処理できる形式だからです。JPEGやPNGなどの圧縮形式は、展開処理が必要となり、パフォーマンスに影響を与える可能性があります。
以下は参考にした本家記事の添付ファイルに基づいて説明しますので、本家記事からファイルをダウンロードしてください。
プロジェクトの設計と実装手順
効率的な開発のために、まずはプロジェクトの全体像を把握しましょう。背景画像の管理から実際の表示まで、段階的に実装を進めていきます。
ファイル構造の設計
プログラムの保守性を高めるため、適切なファイル構造が重要です。MetaTrader 5の「Files」フォルダ内に以下のような構造を作成します:
Files/
└─ Wallpapers/
├─ Backgrounds/ # 一般的な背景画像用
└─ Logos/ # 通貨ペア別のロゴ画像用
この構造により、画像の管理が容易になり、プログラムからのアクセスも簡単になります。
画像保存ディレクトリの設定
MetaTrader 5では、セキュリティの観点から、プログラムがアクセスできるディレクトリが制限されています。「Files」フォルダへのアクセスには、TerminalInfoString(TERMINAL_DATA_PATH)
を使用して、適切なパスを取得します。
新規インストール時には、以下のような手順でディレクトリを作成します:
- アクセス権限の確認
- Filesフォルダの存在確認
- 必要なサブディレクトリの作成
基本パラメータの定義
ユーザーが簡単にカスタマイズできるよう、以下のパラメータを外部から設定可能にします:
//+------------------------------------------------------------------+
enum eType {IMAGEM, LOGO, COR};
//+------------------------------------------------------------------+
input char user01 = 30; //Transparency ( 0 a 100 )
input string user02 = "WallPaper_01"; //File name
input eType user03 = IMAGEM; //Chart background type
//+------------------------------------------------------------------+
各パラメータの役割:
user01
: 透明度を0-100%の範囲で設定。数値が大きいほど透明になりますuser02
: 背景として使用する画像ファイルの名前を指定。拡張子は自動的に.bmpが付加されますuser03
: 背景タイプを選択- IMAGEM: 一般的な背景画像を使用
- LOGO: 通貨ペアに応じたロゴを使用
- COR: 単色背景を使用
これらのパラメータは、実行中でも変更可能なため、トレード状況に応じて柔軟に調整できます。
画像処理機能の実装
画像処理は、チャート背景カスタマイズの核となる部分です。ここでは、実際の実装方法について、具体的に見ていきましょう。
画像読み込みの実装方法
BMPファイルの読み込みは、ヘッダー情報の解析から始まります。この関数は、指定されたBMPファイルを読み込み、ピクセルデータと画像サイズを返します。
// BMPファイルを読み込み、ピクセルデータと画像サイズを取得する関数
// 引数:
// szFileName - 読み込むBMPファイル名
// data[] - ピクセルデータを格納する配列
// width - 画像の幅を格納する変数
// height - 画像の高さを格納する変数
// 戻り値:
// true - 読み込み成功
// false - 読み込み失敗
bool LoadBitmap(const string szFileName, uint &data[], int &width, int &height)
{
// BMPファイルのヘッダー構造体定義
struct BitmapHeader
{
ushort type; // ファイルタイプ('BM')
uint size; // ファイルサイズ
uint reserv; // 予約領域
uint offbits; // ピクセルデータまでのオフセット
uint imgSSize; // 情報ヘッダサイズ
uint imgWidth; // 画像の幅
uint imgHeight; // 画像の高さ
ushort imgPlanes; // プレーン数(常に1)
ushort imgBitCount; // ビット深度(24または32)
uint imgCompression; // 圧縮形式
uint imgSizeImage; // 画像データサイズ
uint imgXPelsPerMeter; // 水平解像度
uint imgYPelsPerMeter; // 垂直解像度
uint imgClrUsed; // 使用色数
uint imgClrImportant; // 重要色数
} Header;
// ... [以下、元のコードが続く]
透明度調整の実装
透明度の調整は、トレーダーの好みに合わせて細かく設定できることが重要です。実装のポイントは、元の画像の視認性を保ちながら、チャート上の価格情報も見やすく表示することです。
透明度の計算には、以下の方法が効果的です:
実際の透明度 = ユーザー指定値(0-100) × 2.55 / 255.0
この計算式により、0%から100%までの直感的な設定値を、実際のアルファチャンネル値に変換できます。
サイズ変更処理の最適化
チャートのサイズが変更されると、背景画像も適切にリサイズする必要があります。このリサイズ処理では:
- 新しいチャートサイズに基づいてスケーリング係数を計算
- 画像の各ピクセルを新しい位置に配置
- スケーリングによって生じる空白部分を補間処理
- 最後にリソースを作成して画面を更新
この処理により、チャートサイズが変更されても背景画像が適切に表示されます。
// チャートサイズの変更に応じて背景画像をリサイズする関数
// チャートのアスペクト比を維持しながら、画像を適切にスケーリング
void Resize(void)
{
// チャートの現在のサイズを取得
m_Height =(uint) ChartGetInteger(m_Id, CHART_HEIGHT_IN_PIXELS);
m_Width = (uint) ChartGetInteger(m_Id, CHART_WIDTH_IN_PIXELS);
// スケーリング係数の計算
double fx = (m_Width * 1.0) / m_MemWidthBMP; // 幅の比率
double fy = (m_Height * 1.0) / m_MemHeightBMP; // 高さの比率
uint pyi, pyf, pxi, pxf, tmp;
// 新しいサイズに合わせてピクセル配列を初期化
ArrayResize(m_Pixels, m_Height * m_Width);
ArrayInitialize(m_Pixels, 0x00FFFFFF); // 白色で初期化
// 縦方向のスケーリング処理
for (uint cy = 0, y = 0; cy < m_MemHeightBMP; cy++, y += m_MemWidthBMP)
{
// 現在の行の位置を計算
pyf = (uint)(fy * cy) * m_Width;
tmp = pyi = (uint)(fy * (cy - 1)) * m_Width;
// 横方向のスケーリング処理
for (uint x = 0; x < m_MemWidthBMP; x++)
{
// ピクセルの新しい位置を計算
pxf = (uint)(fx * x);
pxi = (uint)(fx * (x - 1));
m_Pixels[pxf + pyf] = m_BMP[x + y]; // ピクセルをコピー
// 空白部分を補間
for (pxi++; pxi < pxf; pxi++) m_Pixels[pxi + pyf] = m_BMP[x + y];
}
// 行間の補間処理
for (pyi += m_Width; pyi < pyf; pyi += m_Width)
for (uint x = 0; x < m_Width; x++)
m_Pixels[x + pyi] = m_Pixels[x + tmp];
}
// リソースの作成と更新
if (ResourceCreate(m_szRcName, m_Pixels, m_Width, m_Height, 0, 0, 0, COLOR_FORMAT_ARGB_NORMALIZE))
ChartRedraw();
}
チャート表示の最適化テクニック
実装した機能を実際のチャート上で効果的に表示するために、いくつかの最適化テクニックを紹介します。
アスペクト比の維持
画像が歪んで表示されると、チャートの見た目が悪くなるだけでなく、重要な情報を見逃す原因にもなります。アスペクト比を維持するためには、以下の計算が重要です:
拡大率 = min(チャート幅/画像幅, チャート高さ/画像高さ)
この計算により、画像の縦横比を保ったまま、最適なサイズで表示することができます。
画質劣化の防止方法
画質の劣化は、特に拡大時に顕著になります。これを防ぐためには、以下の対策が効果的です:
- オリジナル画像は十分な解像度で用意する
- リサイズ時は適切な補間方法を選択する
- 必要以上の拡大を避ける
パフォーマンス最適化のポイント
チャート背景の処理が取引システム全体のパフォーマンスに影響を与えないよう、以下の点に注意します:
- メモリの効率的な使用
- 必要なデータのみを保持
- 不要になったリソースの速やかな解放
- 処理の最適化
- 必要最小限の更新処理
- 効率的なアルゴリズムの採用
実装時の注意点とベストプラクティス
最後に、実装時の重要な注意点とベストプラクティスについて説明します。
エラーハンドリング
エラーが発生しても、システム全体に影響を与えないよう、適切なエラーハンドリングが必要です。
特に注意すべきケース:
- 画像ファイルが存在しない場合
- メモリ不足が発生した場合
- 不正なフォーマットの画像が指定された場合
bool MsgError(const eErr err, int fp = 0)
{
string sz0;
switch(err)
{
case FILE_NOT_FOUND :
sz0 = "File not found";
break;
case FAILED_READ :
sz0 = "Reading error";
break;
case FAILED_ALLOC :
sz0 = "Memory error";
break;
case FAILED_CREATE :
sz0 = "Error creating an internal resource";
break;
};
MessageBox(sz0, "WARNING", MB_OK);
if(fp > 0)
FileClose(fp);
return false;
}
これらのエラーに対して、具体的なエラーメッセージを表示し、プログラムが安全に続行できるようにします。
メモリ管理の考慮点
メモリ管理は、長時間の運用を考える上で非常に重要です。特に注意すべき点は:
- リソースの適切な解放
- 使用終了後の速やかな解放
- 循環参照の防止
- メモリ使用量の最適化
- 必要最小限のデータ保持
- 効率的なデータ構造の使用
EA実装時の注意事項
自動売買システム(EA)に組み込む場合は、追加の考慮が必要です:
- 処理のタイミング
- 重要な売買判断に影響を与えない
- システムの負荷が低い時間帯を選択
- リソースの共有
- 複数チャートでの同時使用への対応
- リソース競合の防止
EA実装時の初期化
// EAの初期化時に実行される関数
// 背景画像の初期設定を行う
int OnInit()
{
// 背景タイプが単色(COR)でない場合のみ処理
if(user03 != COR)
// 背景タイプに応じて画像またはロゴを設定
// IMAGEの場合はWallPapersフォルダから指定された画像
// LOGOの場合は通貨ペア名に対応するロゴ画像を使用
WallPaper.Init(user03 == IMAGE ? "WallPapers\\" + user02 : "WallPapers\\Logos\\" + _Symbol, (char)(100 - user01));
return INIT_SUCCEEDED;
}
// チャートイベント処理関数
// チャートのサイズ変更時に呼び出される
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
// チャートサイズ変更イベントの場合
if(id == CHARTEVENT_CHART_CHANGE)
WallPaper.Resize(); // 背景画像のリサイズを実行
}
まとめ:
チャート背景のカスタマイズは、適切に実装することで取引環境を大きく改善できます。本記事で解説した内容を参考に、自身のニーズに合わせた実装を行ってください。
補足:主要な専門用語の説明
- BMP形式:画像データを圧縮せずに保存する形式
- アスペクト比:画像の縦横の比率
- アルファチャンネル:画像の透明度を制御するための情報
- EA(Expert Advisor):MT5上で動作する自動売買プログラム
オンラインコミュニティ
こちらのコミュニティで、AIや機械学習をトレードに活かすために日々探求しています。
興味のある方は覗いてみてください。