English Русский Deutsch
preview
初心者からエキスパートへ:MQL5での可視化による地理的市場認識の強化

初心者からエキスパートへ:MQL5での可視化による地理的市場認識の強化

MetaTrader 5 |
16 2
Clemence Benjamin
Clemence Benjamin

内容



はじめに

最近の市場セッション期間に関する私の公開記事の主な目的は、単に開閉時刻を示すだけでなく、各セッションの個性を明確に示すことにありました。多くの情報源では、シドニー、東京、ロンドン、ニューヨークの開閉時刻が説明されていますが、セッションを認識すること自体が取引心理を強化する方法に焦点を当てているものは少数です。どの地域がアクティブで、なぜ価格がその動きをしているかを知ることは、心を落ち着かせ、意思決定を鋭敏化します。

外国為替市場の24時間サイクルは、実際には地理的なシンフォニーです。しかし多くのトレーダーは、これを平坦なタイムラインとして経験しています。私たちは時間とローソク足を見ますが、シドニーが目覚める様子、ロンドンで朝の紅茶が注がれる様子、ニューヨークの午後のボラティリティ急上昇を目にすることはありません。時間ベースのチャートと、地理的に分布した流動性の間のこの断絶は、市場の心拍を真に見ることなく取引するようなものです。

本記事では、MQL5のビットマップ機能を用いてチャート自体をリアルタイム世界地図スライドプレイヤーに変換することで、このギャップを埋めます。静的な背景の代わりに、リアルタイムで現在アクティブなセッションをハイライトするインテリジェントな視覚レイヤーを構築します。ひと目でどのセッションが価格を牽引しているかがわかり、重なりも瞬時に認識でき、取引心理が市場のグローバルリズムに同期します。次に、実装の核心に移り、このセッション認識可視化を可能にするツールを開発します。

インテリジェントセッション地図

最終的に、画像上に表示されるテーマを制御するインテリジェントなエンジンが手に入る

歴史的観点:時代が現代の取引をどう形作ったか

取引セッションの概念は設計から生まれたのではなく、必要性から生まれました。1970年代、通貨が自由に変動し始めると、自然にパターンが現れました。シドニーのトレーダーが取引を終えると東京が目覚め、東京が閉まるとロンドンが開きます。この引き継ぎが現代のセッションサイクルを形成し、現在では1日あたり7.5兆ドルの取引を動かしています。

地理的必要性から始まったものは、やがて機会へと進化しました。プロのトレーダーはある重要なことに気づきました。セッションの重なりは単なる引き継ぎではなく、拡大要因だということです。ロンドンとニューヨークの3時間の重なりは取引日の12.5%に過ぎませんが、EURUSDの変動の40%を生み出します。これは偶然ではなく、価格を通して可視化された市場の地理的現実です。

数十年にわたり、トレーダーは精神的計算、複数タイムゾーン時計、または単純な色分けチャートを通じてセッション認識を管理してきました。しかし、これらの手法には共通の欠点があります。直感を生むのではなく、認知負荷を増やしてしまう点です。セッションについて考える必要があり、感じることができませんでした。

現代の取引心理学研究は重要な洞察を示します。プロは市場を分析するだけでなく、市場感覚を養っています。ロンドンのオープン直前を「感じ」、アジアの流動性が低下する時期を「察知」します。これは神秘的なことではなく、パターン認識によって意識的な知識を潜在意識の認識に変換しているのです。しかし、これを自然に身につけるには何年もかかります。では、これを加速できるとしたらどうでしょうか。

私たちの使命:目に見えないものを見えるようにする

ここから私たちの旅が始まります。私たちは単に画面上のデータを増やすインジケーターを作るのではありません。市場の地理的現実と時間ベースのチャートを結ぶ、視覚的翻訳レイヤーを作ります。

想像してみてください。取引プラットフォームが動的な世界地図に変わるのです。

  1. シドニーがアクティブなときオーストラリアが青く光ります。
  2. 東京が活動を始めると日本が点灯します。
  3. ロンドンのエネルギーでヨーロッパが活気づきます。
  4. ニューヨーク時間になるとアメリカ大陸が光ります。

金融可視化の研究によれば、時間データを空間的に表現すると意思決定の速度が30%、精度が22%向上します。セッションを地理的に可視化することで、通常は何年もかかる市場感覚を身につけることが可能です。

MQL5は、この可視化のためのペイントブラシです。私たちはその独自の機能を活用しています。

  • リソース埋め込みでシームレスな視覚体験を作成する
  • イベント駆動型アーキテクチャで市場リズムに自然に応答する
  • オブジェクト指向設計でクリーンかつ保守可能なコード
  • リアルタイム通知で情報を受け取りながら集中を妨げない

すべてのコードは、認知負荷を減らしながら、市場意識を高めるという目的を持っています。プロトレーダーが長年静かに利用してきた、リテールトレーダーにはほとんどアクセスされない機関投資家レベルのセッション可視化を構築しています。

取引の成功はしばしば微妙な認識力にかかっています。単に何が起こっているかを知るだけでなく、なぜ起こっているのかを理解することが重要です。アジア時間にEURUSDが停滞しているのを見ても、それは単なる「低ボラティリティ」ではなく、東京がJPYペアに集中しているという地理的現実なのです。GMT8時にGBPUSDが急伸する場合も、単なる「ニュース」ではなく、ロンドンの膨大な流動性プールが稼働し始めた結果であることを意味します。

このツールは、以下の間に存在するギャップを埋める役割を果たします。
  • 知識と直感
  • 分析と認識
  • 取引と市場参加

実装哲学

構築にあたっての指針は以下です。

  1. ビジュアル優先、データは二次:表示は即座に伝わる必要があります。
  2. 非侵襲的な設計:作業スペースを増やさず、機能を強化します。
  3. 設定可能なインテリジェンス:取引スタイルやブローカーに適応します。
  4. プロフェッショナルな堅牢性:エッジケースとエラーに柔軟に対応します。

次の章では、このビジョンを現実に変換していきます。まずセッション状態を計算するコアエンジンを構築し、その上に可視化レイヤーを重ね、さらにインテリジェント通知を追加します。各ステップは前のステップを補完し、単体以上の価値を持つツールが完成します。

しかしこれは単なるコーディングチュートリアルではありません。市場のリズムとの深い関係を育むことにあります。最終的に、単に新しいツールを手に入れるだけでなく、市場を見る新しい方法を手に入れることになるのです。



実装

初心者にも扱いやすいワークフローを維持するため、まずGoogle Imagesからクリエイティブ・コモンズ・ライセンスの基本的な世界地図を2種類入手しました。明るい青の海を持つライトテーマ用と、暗灰色のパレットを持つダークテーマ用です。各画像はGIMPで開き、一貫した横長のアスペクト比(例:1920×1080)に調整しました。これにより、ほとんどのMetaTrader 5チャートの背後に違和感なく配置できます。キーとなるアイデアは、これらの地図を「スライド背景」として扱うことです。装飾が過剰にならず、読みやすく、クリーンである必要があります。

元となる地図が整ったら、GIMPのテキストおよび図形ツールを使って、各取引セッションのラベルを画像上に直接追加しました。青い海の地図では、シドニー、東京、ロンドン、ニューヨークの地域をコード内のセッションカラーに合わせてハイライトし、ラベルを関連する地域近くに配置し、海岸線を覆わないようにしました。暗灰色地図でも同様の作業を行い、やや明るめのネオン風カラーを使ってラベルを際立たせました。目標は控えめなガイドです。チャート上のローソク足や価格動向を妨げず、どの地域を指しているかを瞬時に認識できるようにします。

その後、テーマごとの地図をGIMPから個別のBMPファイルとしてMQL5用にエクスポートしました。各セッションについて専用スライドを作成(例:world_sydney.bmp、world_tokyo.bmpなど)し、ライトテーマ用とダークテーマ用のファイルを作成しました。MetaTrader 5がリソースとして埋め込み可能なBMP形式でエクスポートし、MQL5\Imagesフォルダに配置しました。これによりエキスパートアドバイザー(EA)がアクセスし、アクティブな市場セッションに応じてリアルタイムで切り替え可能です。

ここまでで、抽象的な市場時間を視覚的直感に変換する準備が整いました。これは単なるインジケーターではなく、市場の心拍を視覚化するフルシステムです。より深く理解していただくために、各セクションの詳細な解説を進めます。まず既存のライブラリファイルを再利用して適応し、次にメインコードを開発します。

既存の基盤の上に構築する:SessionVisualizer.mqhの適応

メインEAロジックの構築に入る前に、重要なプロフェッショナル開発の原則を確認します。すべてのコンポーネントを一から作る必要はありません。世界地図画像を準備した後、価格チャート上にセッション境界をマークする手段も必要です。これをゼロから構築する代わりに、過去の記事で紹介した優れたリソースを再利用しました。

元のSessionVisualizer.mqhファイルは、OHLC矩形、ヒゲ、詳細ラベルを含む包括的なセッション可視化を提供していました。しかし今回のプロジェクトでは、より控えめな、世界地図スライドに馴染む視覚マーカーが必要でした。

ニーズに合わせた戦略的変更

このコンポーネントをスライドベース可視化向けに適応するための主要な修正は以下のとおりです。

1. モード切り替えの導入

シンプルながら強力なフラグを追加し、可視化アプローチ全体を切り替え可能にしました。

private:
   bool        m_markers_only;   // NEW: when true, only draw time markers

public:
   void SetMarkersOnly(bool markers_only) { m_markers_only = markers_only; }

この単一のブール値で、完全なOHLC可視化(元の動作)と、最小限の境界マーカー表示(本プロジェクト用)を切り替えます。

2. ミニマリスト描画メソッドの作成

新しいDrawSessionMarkers()メソッドを実装し、必要な機能を提供します。

void DrawSessionMarkers(const SessionInfo &sess,
                        datetime t_open, datetime t_close,
                        bool is_current)
{
   // Creates clean vertical lines at session boundaries
   // with minimal labels showing session abbreviations
}

このメソッドにより、以下を実現します。

  • セッション開始と終了を示す控えめな縦線
  • チャートを圧迫しない小さなテキストラベル(SYD、TOK、LON、NY)
  • 現在セッション(実線)と過去セッション(点線)の視覚的区別

3. スマートな条件分岐

既存のDrawSessionVisuals()メソッドを修正し、適切な場合に新方式を使用します。

void DrawSessionVisuals(const SessionInfo &sess,
                        datetime t_open, datetime t_close,
                        double o,double h,double l,double c,
                        bool is_current)
{
   // --- markers-only mode: keep chart minimal
   if(m_markers_only)
   {
      DrawSessionMarkers(sess, t_open, t_close, is_current);
      return;
   }
   // ... original comprehensive drawing logic
}

この条件分岐により、後方互換性を維持しつつ、出力を簡素化できます。

この変更は、いくつかの専門的な開発の実践を示しています。

  1. リソース効率:既存のテスト済みコードを有効活用することで、新たに一から作る必要を減らしています。
  2.  目的志向の設計:プロジェクト固有の要件に合わせて機能を適応させています。
  3. 非破壊的拡張:既存機能を壊さずに新しい機能を追加しています。元のコンポーネントは、他のアプリケーションでも完全に機能したままです。
  4. ユーザー体験重視:今回の適応により、視覚的な煩雑さを減らしつつ重要な情報は維持しているため、世界地図可視化を使用するトレーダーにとってより良い体験を提供しています。

修正版のSessionVisualizer.mqhファイルはこの記事下部に添付されており、元のファイルは包括的な可視化が必要な開発者向けにMQL5のリンクから参照可能です。このアプローチは、再構築するのではなく適応させる方法を選ぶことで、プロジェクト固有の要素に開発リソースを集中させることを可能にしました。

これで、視覚資産が準備され、セッションマーカーコンポーネントも適応済みとなったため、これらの要素を統合して一つの包括的な取引ツールに仕上げる、メインのWorldSessionSlides EAの構築準備が整いました。

WorldSessionSlides EA

1. 基盤の設定:プロパティとリソース

まず#property strictから始めます。プロフェッショナルなコードは手を抜かず、強い型付けを強制し、エラーを早期に検出できるようにしています。 

本当の魔法は#resourceディレクティブにあります。実行時にディスクから画像を読み込む代わりに(ユーザーがファイルを移動した場合に失敗する可能性があります)、画像を直接EX5ファイルに埋め込みます。ケーキに材料を混ぜ込むようなイメージです。外部依存はなく、ファイル欠損の心配もありません。ライトテーマとダークテーマの両方を提供しているのは、真剣なトレーダーが異なる環境で作業するためです。昼間は明るいチャートを好む人もいれば、夜間セッションにはダークテーマを必要とする人もいます。

//+------------------------------------------------------------------+
//|                                           WorldSessionSlides.mq5 |
//|   Session-based world map slideshow + session time markers       |
//|   with terminal & push notifications on session changes          |
//+------------------------------------------------------------------+
#property strict
#property copyright "Clemence Benjamin"
#property link      "https://mql5.com"
#property version   "1.00"

//--- Embed BLUE OCEAN bitmaps as resources
#resource "\\Images\\world_idle.bmp"
#resource "\\Images\\world_sydney.bmp"
#resource "\\Images\\world_tokyo.bmp"
#resource "\\Images\\world_london.bmp"
#resource "\\Images\\world_newyork.bmp"

//--- Embed DARK GRAY theme bitmaps as resources
#resource "\\Images\\world_idle_dark.bmp"
#resource "\\Images\\world_sydney_dark.bmp"
#resource "\\Images\\world_tokyo_dark.bmp"
#resource "\\Images\\world_london_dark.bmp"
#resource "\\Images\\world_newyork_dark.bmp"

2. ユーザー設定の構成:入力セクション

セッション時間をハードコーディングしないのは、ブローカーによって開始時刻が異なるためです。たとえば、シドニーが21:00に開く場合もあれば22:00に開く場合もあります。 ユーザー入力として設定可能にすることで、ツールが世界中で機能するようにしています。

 ユーザーには3段階のアラートを提供しています。静かに作業したいトレーダー向けのNOTIFY_OFF、すべてのセッション変更を把握したいトレーダー向けの通知、そして本格的なボラティリティトレーダー向けに、実際のアクションが起こる重なりだけを通知する設定です。プッシュ通知のオプションはデフォルトでfalseに設定しています。モバイル通知はオプトイン方式とし、煩わしさにならないようにしています。

//--- Inputs: session times in broker time (hours 0..23)
input int  InpSydneyOpen    = 22;
input int  InpSydneyClose   = 7;
// ... (other session inputs)

//--- Timer period in seconds
input int  InpCheckPeriod   = 15;

//--- Theme toggle: false = blue ocean, true = dark gray
input bool InpUseDarkTheme  = false;

//--- Marker control
input bool InpShowSessionMarkers = true;
input int  InpMarkersGMTOffset   = 0;

//--- Notification control
enum ENUM_NOTIFY_MODE
  {
   NOTIFY_OFF = 0,
   NOTIFY_SESSION_CHANGES,
   NOTIFY_OVERLAPS_ONLY
  };

input ENUM_NOTIFY_MODE InpNotifyMode        = NOTIFY_SESSION_CHANGES;
input bool             InpTerminalAlerts    = true;
input bool             InpPushNotifications = false;

3. コアロジック:時間計算とビットマスクの魔法

HourInRange()は少し厄介な現実に対応しています。いくつかのセッションは日付をまたいでいます。たとえばシドニーセッション(22:00~07:00)は日を跨ぐため、単純な範囲チェックではなく「22時以降または7時前」という論理を理解する必要があります。

GetSessionMaskFromTime()関数では、より効率的な処理をおこなっています。各セッションを別々の変数で追跡するのではなく、ビットマスクを使用しています。ビットマスクとは、各ビットがセッションの状態を表す単一の整数です。ビット0がシドニー、ビット1が東京、というように割り当てます。これにより複数のセッションを同時に確認できたり(重なり判定)、状態を素早く比較できたり、メモリ使用量を最小限に抑えたりする利点があります。たとえば「mask |= (1 << SESSION_SYDNEY)」という処理では、他のビットに影響を与えずにシドニーのビットを立てることができます。

bool HourInRange(int start_hour,int end_hour,int h)
  {
   if(start_hour < end_hour)
      return (h >= start_hour && h < end_hour);
   if(start_hour > end_hour)
      return (h >= start_hour || h < end_hour);
   return(false);
  }

int GetSessionMaskFromTime(datetime t)
  {
   MqlDateTime st;
   TimeToStruct(t,st);
   int h    = st.hour;
   int mask = 0;

   if(HourInRange(InpSydneyOpen,InpSydneyClose,h))
      mask |= (1 << SESSION_SYDNEY);
   // ... other sessions
   return(mask);
  }

4. セッションインテリジェンス:重なり検出と優先度

複数のセッションが重なった場合、どの地図を表示するかを決める必要があります。私たちの優先度システム(ニューヨーク>ロンドン>東京>シドニー)は、市場の重要性を反映しています。たとえば、ニューヨークとロンドンが重なる時間帯ではニューヨークを表示し、ロンドンと東京の重なりではロンドンを表示します。これは、流動性が最も多く流れる地域を優先して示すためです。

ラベル生成機能はすべての組み合わせに対応しています。単一セッションでは「LONDON SESSION (LIVE)」と表示し、重なりでは「LONDON + NEW YORK SESSIONS (OVERLAP)」と表示します。この即時の視覚的フィードバックにより、どのセッションがアクティブか、また高流動性時間帯にいるかを瞬時に把握できます。

//+------------------------------------------------------------------+
//| Build a bitmask of all active sessions at time t                 |
//| bit 0: Sydney, bit 1: Tokyo, bit 2: London, bit 3: New York      |
//+------------------------------------------------------------------+
int GetSessionMaskFromTime(datetime t)
  {
   MqlDateTime st;
   TimeToStruct(t,st);
   int h    = st.hour;
   int mask = 0;

   if(HourInRange(InpSydneyOpen,InpSydneyClose,h))
      mask |= (1 << SESSION_SYDNEY);
   if(HourInRange(InpTokyoOpen,InpTokyoClose,h))
      mask |= (1 << SESSION_TOKYO);
   if(HourInRange(InpLondonOpen,InpLondonClose,h))
      mask |= (1 << SESSION_LONDON);
   if(HourInRange(InpNewYorkOpen,InpNewYorkClose,h))
      mask |= (1 << SESSION_NEWYORK);

   return(mask);
  }

//+------------------------------------------------------------------+
//| Count how many sessions are active in mask (for overlaps)        |
//+------------------------------------------------------------------+
int CountActiveSessions(int mask)
  {
   int count = 0;
   for(int i=0; i<4; ++i)
     {
      if(mask & (1<<i))
         count++;
     }
   return(count);
  }

//+------------------------------------------------------------------+
//| Pick one "dominant" session from a mask (for bitmap selection)   |
//| Priority: New York > London > Tokyo > Sydney                     |
//+------------------------------------------------------------------+
int DominantSessionFromMask(int mask)
  {
   if((mask & (1 << SESSION_NEWYORK)) != 0)
      return SESSION_NEWYORK;
   if((mask & (1 << SESSION_LONDON)) != 0)
      return SESSION_LONDON;
   if((mask & (1 << SESSION_TOKYO)) != 0)
      return SESSION_TOKYO;
   if((mask & (1 << SESSION_SYDNEY)) != 0)
      return SESSION_SYDNEY;

   return SESSION_NONE;
  }

//+------------------------------------------------------------------+
//| Build human-readable label from mask (handles overlaps)          |
//+------------------------------------------------------------------+
string BuildSessionLabel(int mask)
  {
   if(mask == 0)
      return "NO MAJOR SESSION (IDLE MAP)";

   string label = "";
   int    count = 0;

   if((mask & (1 << SESSION_SYDNEY)) != 0)
     {
      if(count > 0) label += " + ";
      label += "SYDNEY";
      count++;
     }

   if((mask & (1 << SESSION_TOKYO)) != 0)
     {
      if(count > 0) label += " + ";
      label += "TOKYO";
      count++;
     }

   if((mask & (1 << SESSION_LONDON)) != 0)
     {
      if(count > 0) label += " + ";
      label += "LONDON";
      count++;
     }

   if((mask & (1 << SESSION_NEWYORK)) != 0)
     {
      if(count > 0) label += " + ";
      label += "NEW YORK";
      count++;
     }

   if(count > 1)
      label += " SESSIONS (OVERLAP)";
   else
      label += " SESSION (LIVE)";

   return(label);
  }

5. プロフェッショナルな可視化:チャートオブジェクトの正しい扱い

多くのトレーダーはチャートオブジェクトを適切に管理せずに作成してしまいます。EnsureBackgroundObject()パターンでは、オブジェクトを作成する前に既に存在するかを確認し、重複を防ぎます。OBJPROP_BACK, trueの設定は非常に重要で、地図を価格ローソク足の背面に配置することで、チャートを妨げずに強化することができます。

CenterBackgroundToChart()ではプロフェッショナルな細部へのこだわりが表れています。リソースから実際の画像寸法を読み取り、数学的に中央に配置します。チャートが地図より小さい場合でも、負のオフセットを許容し、画像を左右対称にクロップします。これにより、歪みなく視覚品質を維持することができます。

//+------------------------------------------------------------------+
//| Create background bitmap label if missing                        |
//+------------------------------------------------------------------+
void EnsureBackgroundObject()
  {
   // Make sure chart is NOT in foreground mode so BACK objects sit behind candles
   ChartSetInteger(0,CHART_FOREGROUND,false);

   if(ObjectFind(0,g_bg_name) < 0)
     {
      if(!ObjectCreate(0,g_bg_name,OBJ_BITMAP_LABEL,0,0,0))
        {
         Print(__FUNCTION__,": failed to create bitmap label, error=",GetLastError());
         return;
        }

      ObjectSetInteger(0,g_bg_name,OBJPROP_CORNER,CORNER_LEFT_UPPER);
      ObjectSetInteger(0,g_bg_name,OBJPROP_BACK,true);   // draw behind candles
     }
  }

//+------------------------------------------------------------------+
//| Center the bitmap in the chart, using its original size          |
//| - No scaling; symmetric cropping when chart is smaller           |
//+------------------------------------------------------------------+
void CenterBackgroundToChart(const string file)
  {
   if(ObjectFind(0,g_bg_name) < 0)
      return;

   // Chart size in pixels
   int chartW = (int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
   int chartH = (int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
   if(chartW <= 0 || chartH <= 0)
      return;

   // Read image size from resource
   uint imgW = 0, imgH = 0;
   uint data[];

   if(!ResourceReadImage(file,data,imgW,imgH))
     {
      // Fallback: put object at (0,0) and stretch object to chart
      ObjectSetInteger(0,g_bg_name,OBJPROP_XDISTANCE,0);
      ObjectSetInteger(0,g_bg_name,OBJPROP_YDISTANCE,0);
      ObjectSetInteger(0,g_bg_name,OBJPROP_XSIZE,chartW);
      ObjectSetInteger(0,g_bg_name,OBJPROP_YSIZE,chartH);
      return;
     }

   if(imgW == 0 || imgH == 0)
      return;

   int imgWi = (int)imgW;
   int imgHi = (int)imgH;

   // Object size = image size (no scaling)
   ObjectSetInteger(0,g_bg_name,OBJPROP_XSIZE,imgWi);
   ObjectSetInteger(0,g_bg_name,OBJPROP_YSIZE,imgHi);

   // Compute offset so that image center aligns with chart center
   int xOffset = (chartW - imgWi) / 2;
   int yOffset = (chartH - imgHi) / 2;

   // Negative offsets are allowed (chart will crop symmetrically)
   ObjectSetInteger(0,g_bg_name,OBJPROP_XDISTANCE,xOffset);
   ObjectSetInteger(0,g_bg_name,OBJPROP_YDISTANCE,yOffset);
  }

6. 通知システム:スマートアラート

if (InpNotifyMode == NOTIFY_OVERLAPS_ONLY && active < 2)というチェックにより、ボラティリティ期間のみを気にするユーザーには不要な通知が送られないようになっています。メッセージには銘柄と時間足の両方を含めているため、複数のチャートで実行している場合でも、どのチャートで変更があったのかを正確に把握できます。

void NotifySessionChange(int old_mask,int new_mask)
  {
   if(InpNotifyMode == NOTIFY_OFF) return;
   int active = CountActiveSessions(new_mask);
   if(InpNotifyMode == NOTIFY_OVERLAPS_ONLY && active < 2) return;
   
   string msg = "WorldSessionSlides: " + BuildSessionLabel(new_mask) +
                " on " + _Symbol + " [" + EnumToString((ENUM_TIMEFRAMES)_Period) + "]";
   
   if(InpTerminalAlerts) Alert(msg);
   if(InpPushNotifications) SendNotification(msg);
  }

7. イベント駆動アーキテクチャ:メインループ

常にチェックする方式はCPUを無駄に消費するため、OnTimer()を使い、適切な間隔(デフォルト15秒)でサンプリングしています。実際に変更があったときのみ更新するため、ビットマスクの比較も非常に高速です。

OnChartEvent()ハンドラでは先見性が示されています。ユーザーがチャートサイズを変更した場合でも、地図は自動的に中央に再配置されます。これにより、グリッチや手動調整の必要がなくなります。

void OnTimer()
  {
   int mask_now = GetSessionMaskFromTime(TimeCurrent());
   if(mask_now != g_current_session_mask)
     {
      int old_mask = g_current_session_mask;
      g_current_session_mask = mask_now;
      ShowSessionSlideByMask(g_current_session_mask);
      NotifySessionChange(old_mask, g_current_session_mask);
     }
  }

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
  {
   if(id == CHARTEVENT_CHART_CHANGE)
     {
      EnsureBackgroundObject();
      if(g_last_bitmap_file != "")
         CenterBackgroundToChart(g_last_bitmap_file);
     }
  }

8. クリーンな初期化と終了処理

 OnInit()では、初回実行時にすべてを正しく設定します。タイマー周期は最低でも5秒に制限しており、ユーザーが誤って1秒ごとのチェックを設定してCPUを消費しすぎることを防いでいます。

OnDeinit()も同様に重要です。タイマーを停止し、チャート上のオブジェクトを削除し、セッションマーカーをクリーンアップします。これにより、メモリリークやチャート上に孤立したオブジェクトが残ることを防ぎます。

int OnInit()
  {
   g_current_session_mask = GetSessionMaskFromTime(TimeCurrent());
   ShowSessionSlideByMask(g_current_session_mask);
   
   if(InpShowSessionMarkers)
     {
      g_sess_vis.SetGMTOffset(InpMarkersGMTOffset);
      g_sess_vis.SetShowWicks(false);
      g_sess_vis.SetMarkersOnly(true);
      g_sess_vis.RefreshSessions(1);
     }
     
   g_check_period = (InpCheckPeriod < 5 ? 5 : InpCheckPeriod);
   EventSetTimer(g_check_period);
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   EventKillTimer();
   ObjectDelete(0,g_bg_name);
   ObjectDelete(0,g_text_name);
   if(InpShowSessionMarkers) g_sess_vis.ClearAll();
  }

 

テスト

MetaTrader 5ターミナルおよび統合ストラテジーテスターで実行した包括的なテストプロトコルにより、システムのコア機能が高精度で検証されました。セッション検出アルゴリズムは常に正しい視覚的遷移をトリガーし、レンダリングエンジンはメモリリークやグラフィックの異常を発生させることなく安定したパフォーマンスを維持しました。

ライトテーマセッションテスト

WorldSessionSlidesのテスト

添付のGIFが決定的な証拠を示しています。

  1. セッション別地図:シドニー、東京、ロンドン、ニューヨークの各セッションが、それぞれ対応するハイライト領域を正しく表示します。
  2. 動的遷移:タイムスタンプ付きシーケンスにより、セッション間のスムーズな切り替えが確認できます。
  3. 重なりシナリオ:複数のアクティブセッションが正しく組み合わせラベルで表示されます。
  4. テーマ適応:ライトテーマとダークテーマの両方で、一貫した描画がおこなわれます。
  5. 通知連携:セッション境界でターミナルアラートが正確に生成されます。

これらの結果により、トレーダーはグローバル市場の動きをリアルタイムで視覚的に追跡でき、時間データを空間的な認識に変換できることが確認されました。ストラテジーテスターのジャーナルでは、セッションアラートも受信可能であることがログスニペットから確認できます。

2025.12.03 11:33:55.238 2025.12.01 07:00:00   Alert: WorldSessionSlides: TOKYO SESSION (LIVE) on EURUSD [PERIOD_M5]
2025.12.03 11:33:59.696 2025.12.01 08:00:00   Alert: WorldSessionSlides: TOKYO + LONDON SESSIONS (OVERLAP) on EURUSD [PERIOD_M5]
2025.12.03 11:34:06.315 2025.12.01 09:00:00   Alert: WorldSessionSlides: LONDON SESSION (LIVE) on EURUSD [PERIOD_M5]
2025.12.03 11:34:21.396 2025.12.01 13:00:00   Alert: WorldSessionSlides: LONDON + NEW YORK SESSIONS (OVERLAP) on EURUSD [PERIOD_M5]
2025.12.03 11:34:39.553 2025.12.01 17:00:00   Alert: WorldSessionSlides: NEW YORK SESSION (LIVE) on EURUSD [PERIOD_M5]
2025.12.03 11:34:55.388 2025.12.01 22:00:00   Alert: WorldSessionSlides: SYDNEY SESSION (LIVE) on EURUSD [PERIOD_M5]



結論

本記事では、抽象的な市場時間を直感的な地理的感覚に変換する、シンプルながら実用的なビジュアル取引ツールを無事に開発できました。インテリジェントなセッション検出システムと動的な世界地図可視化を組み合わせることで、グローバル市場における時間的な方向感覚の喪失という重大な問題を解決しています。このソリューションは、プロフェッショナルなMQL5開発が技術的精度と実践的な取引心理を橋渡しし、情報を表示するだけでなく、市場認識を根本的に向上させるツールを生み出すことを示しています。

技術的には、ビットマスクによる効率的なセッション追跡、リソース埋め込み型グラフィック、イベント駆動型アーキテクチャといった業界のベストプラクティスを取り入れた実装となっています。厳格なテスト検証により、ライブ環境および履歴環境の双方でシステムの信頼性が確認され、セッション遷移やテーマの適応レンダリングも完璧に機能しました。このプロジェクトは、適切なメモリ管理、エラー処理、ユーザー中心の設計を含む堅牢なコーディング手法が、プロフェッショナルな取引環境にふさわしいツールを生み出すことを実証しています。

最終的に、このツールは単なるインジケーター以上の意味を持ちます。取引ワークフローにおける視覚的インテリジェンスへのシフトを示しており、市場の地理的リズムを直感的に把握できることで、トレーダーはより深いマーケットセンスを養いながら認知負荷を軽減できます。このプロジェクトは、技術的卓越性と取引のインサイトが融合することで、トレーダーがグローバル市場の連続的な流れを理解し、操作する方法を根本的に変えることを実証しました。

ただし、テスト中にいくつか異常な現象も観察されました。ほとんどのスライドの表示は明確でしたが、一部で軽い「シャワー」やグリッチが発生しました。当初はRAM容量の問題かと考えましたが、ログにはエラーが報告されていないため、単に一部の画像が処理に重すぎた可能性もあります。現在も原因を調査中であり、今後のアップデートで調査結果を共有する予定です。

プロジェクトで使用したすべてのソースファイルおよび画像は、下記の添付表に説明付きで添付しています。コメント欄でのディスカッションへの参加も歓迎します。次回の公開まで、どうぞご期待ください。

重要な学び

重要な学び説明
ビットマスク状態管理ビット演算を用いた効率的なセッション追跡を習得します。複数のセッション状態を単一の整数に格納することで、重なり判定を高速化し、メモリ使用量を最小限に抑えつつ、高度な市場分析を可能にします。
イベント駆動型アーキテクチャOnTimer()を用いた定期チェックやOnChartEvent()によるレスポンシブなUI更新を設計することで、リソースを大量に消費するポーリングループなしで、セッション可視化をシームレスに実行できる効率的なシステムを構築します。
日跨ぎ対応の時間計算日をまたぐセッションを正しく扱う堅牢な時間範囲計算を実装します。これは、異なるタイムゾーンにおけるグローバル市場分析で正確性を確保するために不可欠なスキルです。
リソース埋め込みと管理#resourceディレクティブを使用してビットマップファイルをEX5実行ファイルに直接埋め込む方法を学びます。これにより、異なる取引環境でも移植性を維持したプロフェッショナルなビジュアルツールを作成できます。
セッション固有の戦略適合セッションの特性に応じたプログラミングを理解します。たとえば、東京はJPYペアのテクニカル精度、ロンドンはEUR/GBPの方向性モメンタム、重なり時間帯はボラティリティ戦略に最適です。
重なりチャンスの検出流動性が急増する重要な重なり時間帯(東京-ロンドン、ロンドン-ニューヨーク)を特定しハイライトするロジックを実装し、複数の取引スタイルにおけるプレミアムな取引機会を捉えます。
プロフェッショナルなチャートオブジェクト管理描画レイヤー(BACKとFRONT)の扱いに注意しつつ、チャートオブジェクトの作成、位置決め、クリーンアップを適切に行う方法を習得し、価格分析を妨げることなく視覚的明瞭性を確保します。
セッションベースのリスク管理重なり時の高活動や単独セッション・休止時間帯のリスク低下など、セッションごとのボラティリティパターンに基づき自動的に取引パラメータを調整するシステムを開発します。
モジュール式コードの再利用性既存コンポーネント(SessionVisualizer.mqh)を専門的なモードで適応しつつ、元の機能を維持することで、将来のプロジェクトにも応用可能なプロフェッショナルな開発手法を適用します。
設定可能な通知システム保守的な重なりのみのアラートから包括的なセッション変更通知まで、異なる取引スタイルに合わせた柔軟な通知システムを構築します。


添付ファイル

ソースファイル バージョン説明
WorldSessionSlides.mq51.01コアとなるEAファイルで、セッション可視化ロジック、通知システム、チャートイベントハンドラを含みます。このファイルは、リアルタイムでセッションを追跡しながら、動的な世界地図表示を実装します。
SessionVisualizer.mqh1.03補助用のインクルードファイルで、価格チャート上にセッション時間マーカーを描画します。セッション境界や重なりを示す視覚的指標を提供し、GMTオフセットや表示設定を調整可能です。
Light_theme.zip1.00ライトテーマのグラフィックアセットで、すべての取引セッション用の世界地図ビットマップを含みます。ライトテーマの可視化を有効にするため、MQL5/Imagesフォルダに展開する必要があります。
Dark_theme.zip1.00ダークテーマのグラフィックアセットで、すべての取引セッション用の世界地図ビットマップを含みます。ダークテーマの可視化を有効にするため、MQL5/Imagesフォルダに展開する必要があります。

MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/20417

添付されたファイル |
Light_theme.zip (13315.35 KB)
Dark_theme.zip (7889.04 KB)
最後のコメント | ディスカッションに移動 (2)
Chacha Ian Maroa
Chacha Ian Maroa | 5 12月 2025 において 14:51
あなたの努力と考えに本当に感謝している。そして、とても役に立つものを提供してくれてありがとう!
Rasoul Mojtahedzadeh
Rasoul Mojtahedzadeh | 5 12月 2025 において 17:23
素晴らしい仕事だ!仕事を教えてくれてありがとう!
多通貨エキスパートアドバイザーの開発(第24回):新しい戦略の追加(II) 多通貨エキスパートアドバイザーの開発(第24回):新しい戦略の追加(II)
本記事では、引き続き、作成済みの自動最適化システムに新しい戦略を連携する方法を見ていきます。最適化プロジェクト作成EAと、第2ステージおよび第3ステージのEAにどのような変更を加える必要があるかを見てみましょう。
MQL5 MVCパラダイムのテーブルのビューコンポーネント:基本グラフィック要素 MQL5 MVCパラダイムのテーブルのビューコンポーネント:基本グラフィック要素
本記事では、MQL5におけるMVC (Model-View-Controller)パラダイムでのテーブル実装の一環として、ビューコンポーネント向けの基本的なグラフィック要素を開発するプロセスを扱います。本記事はビューコンポーネントに関する最初の記事であり、MetaTrader 5クライアントターミナル向けテーブル作成に関する連載の第3回目です。
中心力最適化(CFO)アルゴリズム 中心力最適化(CFO)アルゴリズム
本記事では、重力の法則にヒントを得た中心力最適化(Central Force Optimization, CFO)アルゴリズムを紹介します。このアルゴリズムは、物理的引力の原理を用いて最適化問題を解決する手法を探究するものです。ここでは、「より重い」解が、成功度の低い解を引き寄せる仕組みを扱います。
初心者からエキスパートへ:時間フィルタ付き取引 初心者からエキスパートへ:時間フィルタ付き取引
ティックが常に流入しているからといって、すべての瞬間が取引チャンスであるわけではありません。本記事では「タイミングの技術」に焦点を当て、トレーダーが最も有利な市場時間帯を特定し、その中で取引をおこなうための時間分離アルゴリズムの構築について詳しく検討します。この規律を身につけることで、個人トレーダーは機関投資家のタイミングとより密接に同期できるようになり、成功を左右することの多い正確さと忍耐力を発揮できるようになります。MQL5の分析機能を通じて、タイミングと選択的取引の科学を探求しましょう。