記事「注文板に基づいた取引システムの開発(第1回):インジケーター」についてのディスカッション

 

新しい記事「注文板に基づいた取引システムの開発(第1回):インジケーター」はパブリッシュされました:

市場の厚みは、特に高頻度取引(HFT)アルゴリズムにおいて、高速な取引を実行するために不可欠な要素です。本連載では、多くの取引可能な銘柄に対してブローカー経由で取得できるこの種の取引イベントについて取り上げます。まずは、チャート上に直接表示されるヒストグラムのカラーパレット、位置、サイズをカスタマイズ可能なインジケーターから始めます。次に、特定の条件下でこのインジケーターをテストするためのBookEventイベントの生成方法について解説します。今後の記事では、価格分布データの保存方法や、そのデータをストラテジーテスターで活用する方法などのトピックも取り上げる予定です。

まず、「市場の厚み」(DOM)とは何かを改めて確認しましょう。それは、未決済の指値注文の一覧のことを指します。これらの注文は、市場参加者の売買意図を表しているものの、必ずしも実際の取引に至るわけではありません。なぜなら、トレーダーはさまざまな理由により、過去に発注した注文をキャンセルできるからです。たとえば、市場状況の変化や、当初指定した価格・数量での取引に対する関心の低下などが挙げられます。

関数SymbolInfoInteger(_Symbol, SYMBOL_TICKS_BOOKDEPTH)によって返される値は、注文板の深さを表すものであり、分析対象の価格レベルを格納する配列の半分を示します。この配列のうち、半分は指値売り注文に、残りの半分は指値買い注文に割り当てられます。ドキュメントによれば、注文キューを持たない銘柄の場合、このプロパティの値は0になります。以下の図はその一例として、深さ10の注文板を表示しており、すべての利用可能な価格レベルが視覚化されています。

例:深さ10の注文板

厚みは必ずしも市場の注文板から取得する必要はなく、銘柄情報から直接取得できることに注意が必要ですSymbolInfoInteger関数を使用するだけで該当プロパティの値を取得でき、OnBookEventハンドラやMarketBookAddなどの関連関数に依存する必要はありません。もちろん、後述するように、OnBookEventハンドラが更新するMqlBookInfo配列の要素数をカウントすることでも同じ結果を得ることが可能です。

作者: Daniel Santos

 
カスタムシンボルが 必要な理由はないと思います。通常のチャートの履歴(インジケータ表示用)でも、テスター(EAテスト用)でも、標準シンボル自体にブックイベントを保存して再生することは完全に可能です。
 

これは非常に短い記事で、コードもほとんどない。次のパートで、パート1、パート2、といったように意味があるかどうか見てみよう。

SYMBOL_TICKS_BOOKDEPTHは、Depth of Marketに表示されるリクエストの最大数を与える。このプロパティは、DOMのレベル数を数えるのと同じ結果を与えるというのは誤りです。正確な数ではなく、最大数を示します。

このスクリプトを使用することで、このような結果を得ることができます:

//+------------------------------------------------------------------+
//|TestOnderBook.mq5
//|著作権:2025年、サミュエル・マノエル・デ・スーザ
//|https://www.mql5.com/ja/users/samuelmnl|||.
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Samuel Manoel De Souza"
#property link      "https://www.mql5.com/ja/users/samuelmnl"
#property version   "1.00"
//+------------------------------------------------------------------+
//| スクリプト・プログラム開始機能|
//+------------------------------------------------------------------+
int OnInit(void)
  {
   MarketBookAdd(_Symbol);

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

   MarketBookRelease(_Symbol);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void OnTick(void)
  {

  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void OnBookEvent(const string& symbol)
  {
   double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
   MqlBookInfo book[];
   MarketBookGet(_Symbol, book);
   int total = ArraySize(book);
   if(total == 0)
     {
      Print("there is no order available on the book");
      ExpertRemove();
      return;
     }

   int buy_levels = 0, sell_levels = 0;
   int buy_gaps = 0, sell_gaps = 0, gaps = 0;
   for(int i = 0; i < total; i++)
     {
      Print("price: ", book[i].price, ", volume: ", book[i].volume, ", type: ", EnumToString(book[i].type));
      buy_levels += book[i].type == BOOK_TYPE_BUY ? 1 : 0;
      sell_levels += book[i].type == BOOK_TYPE_SELL ? 1 : 0;
      if(i > 0)
        {
         bool is_gap = fabs(book[i].price - book[i - 1].price) >= 2 * tick_size;
         gaps += is_gap ? 1 : 0;
         buy_gaps += is_gap && book[i].type == book[i - 1].type && book[i].type == BOOK_TYPE_BUY ? 1 : 0;
         sell_gaps += is_gap && book[i].type == book[i - 1].type && book[i].type == BOOK_TYPE_SELL ? 1 : 0;
        }
     }

   Print("max levels: ", SymbolInfoInteger(_Symbol, SYMBOL_TICKS_BOOKDEPTH));
   Print("levels: ", total);
   Print("buy levels: ", buy_levels);
   Print("sell levels: ", sell_levels);
   Print("gaps: ", gaps);
   Print("buy gaps: ", buy_gaps);
   Print("sell gap: ", sell_gaps);
   ExpertRemove();
  }
//+------------------------------------------------------------------+
 
このインジケーターを使って開発される予定だった取引システムはどうなったのですか?
 
Samuel Manoel De Souza #:

これは非常に短い記事で、コードもほとんどない。パート1、パート2......と続く意味があるかどうか、次のパートで見てみよう。

SYMBOL_TICKS_BOOKDEPTHは、Depth of Marketに表示されるリクエストの最大数を示します。このプロパティがDOMのレベル数をカウントするのと同じ結果を与えるのは誤りです。これは最大数を与えるものであり、正確な数を与えるものではありません。

このスクリプトでこれを行うことができます:

この記事は最高です!私はまた、スタックに関するTSを書きたかったのです!