Great Choice For Beginners!
Free Trading Education!
Free Demo Account 1000$!
Get Your Sign-Up Bonus Now!
Only For Experienced Traders!
How To Read Market Depth
This morning on Twitter, I went “OH MY GOODNESS” at this depth chart for the USDT/USD pair on the Kraken exchange, as at 0700 UTC:
Everyone went, “uh, OK … what am I looking at, and why is this important news?”
This is a picture of a market where lots of people want to sell tethers for dollars, almost nobody wants to buy tethers for dollars, and the price is hanging in the air like Wile E. Coyote about to get gravity lessons.
Why is this important? Because Tether is a lot of what appears to be holding the price of Bitcoin up.
So here’s how to read a depth chart — and what all this seems to mean!
Tether and audits
Reader Aranfan asks:
What I’m wondering is how a thing on a completely different blockchain boosts the price of bitcoin.
To recap: a Tether (USDT) is a dollar-substitute token, that you can move around more easily than an actual US dollar. It’s popular with exchanges that can’t or don’t want to deal in USD.
Tether, Inc. — which was set up by the people from the large crypto exchange Bitfinex, and remains closely associated — issue these as tokens running over other blockchains. They state that every USDT is backed by a US dollar on deposit. So far, the market has treated USDT as if they are indeed pegged to USD.
There have been a lot of questions about this — because Tether has been furiously issuing new USDT, coinciding with dips in the price of a bitcoin. This accelerated recently — over half a billion dollars’ worth of tethers have been issued just this month.
They maintain that all of these new USDT are backed by USD on deposit — that this isn’t just fictional reserve banking. Phil Potter from Bitfinex assured me of this in email, and Lao Mao, proprietor of the BigONE exchange, posted recently of how he discussed this with them, looked at the books and was reassured — but there has never been a proper audit of all of this.
Bitfinex/Tether promised a full audit was in progress — but a few days ago, their auditor, Friedman LLC, scoured their site of all mention of Bitfinex and Tether. Last night, Bitfinex confirmed that the two had ended their relationship:
Given the excruciatingly detailed procedures Friedman was undertaking for the relatively simple balance sheet of Tether, it became clear that an audit would be unattainable in a reasonable time frame.
The market has not responded well to this, and, overnight, seems to be pricing tethers at rather less than a dollar.
Great Choice For Beginners!
Free Trading Education!
Free Demo Account 1000$!
Get Your Sign-Up Bonus Now!
Only For Experienced Traders!
BTC is about $400 lower on GDAX/Coinbase than Bitfinex for once, because GDAX deals in actual dollars and Bitfinex in tokens that the market doesn’t quite so strongly believe are dollars any more — so traders are selling their not-USD on Bitfinex and buying BTC, which they can take elsewhere to sell for USD. This raises the “price” on Bitfinex and lowers it on the other exchange.
The other problem is that there are no reports of anyone ever successfully redeeming their USDT for USD from Tether themselves — actual money goes in, it doesn’t come out.
There is literally one USDT/USD trading pair that you can cash out of tethers in, on Kraken — go here and select “USDT/USD” at top-left. It’s not a very usable market, because there’s no depth to the order book — hardly anyone wants to buy tethers, certainly not as many as want actual money — so if you wanted to cash out 1,000,000 USDT then you’d be getting USD 0.30 each for the last ones. (Another example of “market cap” being a bad and meaningless number — you could tank a $2b market cap with a $1m sale.) Most of the activity on it looks very like bot-based wash trading around 1 USDT = 1 USD. (On that video, note the regular, repetitive transactions for the same amounts — up a bit, then down a bit.)
Now people are trying to use this tiny gateway to get real dollars out.
Reading a depth chart
Let’s look again at that tweet of Kraken USDT/USD around 0700 UTC:
Left to right is USD price, bottom to top is quantity of USDT. The red (left) is “buy” orders for USDT when the USD price goes down that far, and the black (right) is “sell” orders for when it goes up that far. The bottom chart is the orders themselves, the top chart is cumulative.
Here’s the bitcoin depth chart from GDAX at 1:16pm today, which is a bit more routine. This is a snapshot of the state of the market at a particular moment: 1316 UTC on 28 January 2020. The bit at the bottom, with the white line indicating it, is the last-traded price as of this moment.
This is a chart of the market makers — the people putting up offers to buy or sell. On the left there’s a pile of people who want to buy BTC from you, at what price they’ll pay. On the right are a pile who want to sell BTC to you, at what price they’ll accept.
(The term “market maker” is a bit different in security trading, but the crypto usage is often just “whoever puts up an offer.”)
The lines show how many BTC would need to be bought or sold to reach a given price point.
The green line (left) is cumulative “buy” orders below the current price — if you have coins to sell, they will buy them from you. The red line (right) is cumulative “sell” orders above that price — if you want to buy coins, they will sell them to you.
Orders are processed in order of price going down for buy orders, in order of price going up for sell orders. If you want to sell 10 BTC and there are buy orders for 2 BTC at $11,300, 3 BTC at $11,295 and 6.5 BTC at $11,290, you’ll fulfill all of the first two and most of the last, and you’ll receive $112,935 — minus the exchange’s trading fee, since GDAX charges the market taker (that’s you).
On the GDAX chart, you can also see vertical lines — these are “buy walls” and “sell walls”. For the price to keep going up or down through that wall, the order has to be fully satisfied. e.g., in the above chart, 150 BTC of sales would drop the price to $11,200, but it wouldn’t go lower until the 50 BTC order at that price had been filled.
In normal security or commodity trading, the order book — the set of all the buy and sell orders — has a fair bit of depth. So the market is reasonably robust and the order book isn’t thin and it’s hard to manipulate it very much.
But this is crypto. So the order books are super-thin, separated into one order book per exchange ‘cos the market’s structure is approximately the stupidest possible … and so the price is super-manipulable!
Look again at that GDAX chart. There’s a lot of information in there, in a compact at-a-glance format. You may get the feeling “wow, more people want to buy, Bitcoin’s on its way up. Maybe I should buy!”
But what if some of those orders … aren’t real? What if someone places some great big walls … but the orders are withdrawn as soon as the price gets anywhere near them?
This is called “spoofing” — where you put in orders you have no intention of letting go through, to manipulate other traders’ perceptions, and hence the market.
Spoofing is illegal in the US since the 2020 Dodd-Frank act — the precise wording (§747) is “bidding or offering with intent to cancel before execution.” For example, the CFTC just fined Deutsche Bank and HSBC for doing this in US futures markets.
It’s not frequently prosecuted, because doing so involves proving intent. Quite a lot of people — and high-frequency trading algorithms — put in orders they then withdraw.
Of course, like other market manipulations, it’s endemic in cryptos because that’s what “unregulated” means in practice. Bitfinex’ed’s post “Meet Spoofy” shows one apparent bot, Spoofy, in action. The crash a couple of weeks ago involved a lot of spoofed walls.
There aren’t enough USDT to just straight-up buy BTC — or place spoof orders — to prop up the price. But they can be used to fuel margin trading.
Margin trading is borrowing (from your broker or, in cryptos, the exchange) to multiply the effect of your trading — so rather than just having $100, you can borrow and trade with $200, using the $100 as collateral. If your trade pays off, you’ve done really well!
If your trade doesn’t pay off, or even if the price dips enough that it looks like it won’t, the lender forces you to liquidate the whole position and pay them back immediately, and you lose your collateral. The ratio of collateral to amount borrowed determines how far the market can dip from the price you bought in at before your position is liquidated.
In crypto, margin traders have a habit of borrowing a lot on margin. 5× or 10× is not uncommon. Bitmex offers up to 100× margin trading.
(It’s absolutely nuts to margin-trade cryptos, because they’re so volatile, but tell crypto gamblers that.)
So a small amount of USDT lent for margin trading can allow the creation of a large order.
(This is fine — as long as tethers are real.)
Which may not exist when the price gets there.
(This is not so fine, either way.)
Tether has dipped before — 1 USDT was 0.91 USD in April 2020, around the time the present massive crypto bubble was starting — and remember that, per chapter 8 of the book, this bubble was started by Bitfinex and Tether losing their US dollar banking — and it’s peaked at 1.07 USD in recent times. And more depth is showing up.
But last night, and today’s spread between USD and USDT exchanges, looks very like a worried market, trying to get out.
Your subscriptions keep this site going. Sign up today!
The Market Depth gadget provides you with an outline of best bid and ask quotes for a symbol from major exchanges. Like all other gadgets, the Market Depth can be displayed as a section of the left sidebar or a separate window (see the Left Sidebar article for details).
In order to view the Market Depth for a symbol, click on the Symbol Actions button and choose More info on and then Market Depth for. The Market Depth will be displayed on the Left Sidebar even if it wasn’t previously added there. You can view the Market Depth for multiple instruments or even an option spreads at the same time. When a spread is added, quotes are shown for each of its legs and the whole spread as well. If there are too many instruments in the Market Depth, consider collapsing some of them by clicking the ‘tick’ icon before the symbol name in the gadget, or even deleting them by clicking the ‘close’ button to the right.
By default, the Market Depth displays a watch list that contains the following columns: exchanges where the chosen symbol is available, its bid and ask values at this exchange, and bid and ask size values. This watch list can be customized and sorted (for details, refer to the Watch Lists article). When you click on bid or ask value in the table, the application automatically brings up the Order Entry dialog with order price equal to the chosen on the watch list. Clicking on a bid value creates a sell order, while clicking on an ask value creates the buy order.
The left sidebar is an area in the thinkorswim interface where you keep gadgets necessary for your work. These gadgets allow you to view some trading information immediately, watch news or even distract yourself by playing a couple of built-in games without needing to leave the main window of the platform. The content of the left sidebar is completely customizable. It is up to you to decide which gadgets to keep there; refer to pages in this section, to learn more about each of them.
To add a gadget, click the ‘plus’ button at the bottom of the sidebar. The Select gadget dialog will appear. Click on the name of the gadget you would like to display; it will be immediately added. Note that you can have up to 15 gadgets at a time on the left sidebar, however only a subset of these will be onscreen at any given time depending on their heights. The sidebar can be scrolled using the arrow buttons at the bottom. You can also resize the sidebar by dragging its right border to the width you like.
If you don’t need a previously added gadget anymore, you can remove it from the left sidebar. In order to do that, click the Show actions button in its top right corner and choose Delete gadget from the menu; the gadget will be removed. If you’ve added many gadgets and like to quickly delete several of them, consider using the Customize gadgets dialog (accessible via the ‘gear’ button at the bottom). This dialog displays a compact list of currently added gadgets; clicking the ‘x’ button next to a gadget name will delete the gadget from the sidebar. This menu also allows you to rearrange the order of your gadgets by clicking and dragging their names into a new order.
The Show actions menu (accessible from the button at the top-right corner of each gadget) also allows you to detach or switch the gadget. Detaching means displaying the gadget in a separate window with an option to keep it above all other windows (for this purpose, click the ‘pin’ button on top of the detached gadget). Switching means replacing a gadget with another: after clicking Switch gadget, you will see the Select gadget dialog where you can choose a gadget to replace the current one.
If you don’t need any of the gadgets at the moment, you can hide the whole sidebar. In order to do that, click the Hide gadgets button in the bottom left corner of the sidebar; the sidebar will be hidden. The button itself, however, will be kept where it belongs so that you can quickly unhide the sidebar once you need it again.
*tastytrade is no longer affiliated with TD Ameritrade.
The Quick Quote gadget allows you to view basic pricing data of a symbol. This data includes current last, bid, and ask prices and also the net change. For futures and forex, the net change is measured from the last transaction in the previous trading session; for other instruments, since morning. The Quick Quote is basically a watch list that only has one symbol in it. While you cannot customize this watch list, all other watch list functions are available: you can send orders, create alerts, and view more in-depth info on the symbol from the right-click menu.
Level II is a thinkorswim gadget that displays best ask and bid prices for each of the exchanges making markets in stocks, options, and futures. It is essentially a real-time ordered list of best bids and asks of an underlying that allows instant order placement. Like all other gadgets, Level II can be displayed as a section of the left sidebar or a separate window (see the Left Sidebar article for details).
In the gadget header you will see the following elements: the symbol selector, the ‘clip’ icon , the full name of the symbol, the current market price of the selected symbol, and its percentage and absolute change since midnight. The clip icon brings up a color-and-number selection menu; choosing a color in this menu will link Level II to all thinkorswim components with similar color. Consider linking Level II to a watch list so that clicking through the latter will immediately display the corresponding symbols in Level II.
For stocks and options, Level II is a color-coded display of best bid and ask prices from a given set of exchanges. Use the toggle in the upper right corner of the working area to switch between the pre-defined sets (books): Level II, NASDAQ Full Book, and BATS/EDGE Full Book. For futures, since they each trade on a single exchange, Level II displays first several layers of that exchange’s book.
When you specify the symbol in the symbol selector, you will see the real-time quotes in the working area. The working area is divided into two sets of columns: bid-related (to the left) and ask-related (to the right). These columns identify the marketplace or market maker at the given bid or ask price with respective number of shares to be bought or sold (ask/bid size). In both ask and bid size columns, the numbers represent hundreds of available shares or contracts: for example, 3 in the bid size column means that there are 300 shares or contracts ready to be bought at the respective bid price at the respective exchange.
Since the purpose of Level II is providing you with best bid ask prices, the columns are sorted accordingly. By default, the bid area of the gadget is sorted in descending order by the bid price column, so that highest prices are on top. As it might be expected, the ask side is sorted vice versa: the default sorting displays lowest prices on top. You can re-sort the columns in the reverse order by clicking on the Bid or Ask title, or sort the set by exchange name or bid/ask price by clicking the title of respective column.
Level II enables you to add orders instantly. Click on a bid price in Level II to add a sell order; clicking on an ask price will prompt you to add a buy order.
This is not an offer or solicitation in any jurisdiction where we are not authorized to do business or where such offer or solicitation would be contrary to the local laws and regulations of that jurisdiction, including, but not limited to persons residing in Australia, Canada, Hong Kong, Japan, Saudi Arabia, Singapore, UK, and the countries of the European Union.
Market volatility, volume and system availability may delay account access and trade executions.
Past performance of a security or strategy is no guarantee of future results or investing success.
Trading stocks, options, futures and forex involves speculation, and the risk of loss can be substantial. Clients must consider all relevant risk factors, including their own personal financial situation, before trading. Trading foreign exchange on margin carries a high level of risk, as well as its own unique risk factors.
Options are not suitable for all investors as the special risks inherent to options trading may expose investors to potentially rapid and substantial losses. Prior to trading options, you should carefully read Characteristics and Risks of Standardized Options.
Spreads, Straddles, and other multiple-leg option orders placed online will incur $0.65 fees per contract on each leg. Orders placed by other means will have additional transaction costs.
Futures and futures options trading is speculative and is not suitable for all investors. Please read the Risk Disclosure for Futures and Options prior to trading futures products.
Forex trading involves leverage, carries a high level of risk and is not suitable for all investors. Please read the Forex Risk Disclosure prior to trading forex products.
Futures and forex accounts are not protected by the Securities Investor Protection Corporation (SIPC).
Futures, futures options, and forex trading services provided by TD Ameritrade Futures & Forex LLC. Trading privileges subject to review and approval. Not all clients will qualify. Forex accounts are not available to residents of Ohio or Arizona.
Access to real-time market data is conditioned on acceptance of the exchange agreements. Professional access differs and subscription fees may apply. For details, see our Professional Rates & Fees.
Supporting documentation for any claims, comparison, statistics, or other technical data will be supplied upon request. TD Ameritrade does not make recommendations or determine the suitability of any security, strategy or course of action for you through your use of our trading tools. Any investment decision you make in your self-directed account is solely your responsibility.
TD Ameritrade, Inc., member FINRA/SIPC.
TD Ameritrade Inc., member FINRA/SIPC. TD Ameritrade is a trademark jointly owned by TD Ameritrade IP Company, Inc., and the Toronto-Dominion Bank © 2020 TD Ameritrade IP Company, Inc. All rights reserved. Used with Permission.
MQL5 Cookbook: Implementing Your Own Depth of Market
Table of Contents
MQL5 language is constantly evolving and offering more opportunities for operation with exchange information every year. One of such exchange data types is information about Depth of Market. It is a special table showing price levels and volumes of limit orders. MetaTrader 5 has a built-in Depth of Market for displaying limit orders, but it is not always sufficient. First of all, your Expert Advisor has to be given a simple and convenient access to Depth of Market. Certainly, MQL5 language has few special features for working with such information, but they are low-level features that require additional mathematical calculations.
However, all intermediate calculations can be avoided. All you have to do is to write a special class for working with Depth of Market. All complex calculations will be carried out within Depth of Market, and the class itself will provide convenient ways for operation with DOM prices and levels. This class will enable an easy creation of the efficient panel in a form of an indicator, which will be promptly reflecting the current state of prices in Depth of Market:
Fig. 1. Depth of Market displayed as a panel
This article demonstrates users how to utilize Depth of Market (DOM) programmatically and describes the operation principle of CMarketBook class, that can expand the Standard Library of MQL5 classes and offer convenient methods of using DOM.
After reading the first chapter of this article, it will become clear that the regular Depth of Market offered by MetaTrader 5 has impressive capabilities. We will not try to duplicate all these multiple opportunities in our indicator, as our task will be completely different. With a practical example of creating user-friendly Depth of Market trading panel we will show that the principles of object-oriented programming allow relatively easy handling of complex data structures. We will ensure that it won’t be difficult to gain access to Depth of Market directly from your Expert Advisor with MQL5 and, consequently, to visualize its representation as it is convenient for us.
Chapter 1. Standard Depth of Market in MetaTrader 5 and methods of using it
1.1. Standard Depth of Market in MetaTrader 5
MetaTrader 5 supports trading on centralized exchanges and provides standard tools for operation with Depth of Market. First of all, it is, certainly, a table of limit orders, that recently has been given an advanced mode of representation. To open Depth of Market it is necessary to connect to one of the exchanges that supports MetaTrader 5 and to select in the context menu “View” –> “Depth of Market” –> “Name of instrument.” A separate window that combines a tick price chart and a table of limit orders will appear:
Fig. 2. Standard Depth of Market in MetaTrader 5
Standard Depth of Market in MetaTrader 5 can boast a rich functionality. In particular, it allows to display the following:
- Buy and Sell limit orders, their price levels and volume (standard form of classical DOM);
- current spread level and price levels occupied by limit orders (advanced mode);
- tick chart and visualized Bid, Ask and last trade volumes;
- total level of Buy and Sell orders (displayed as two lines at the tick chart’s top and bottom, respectively).
The list provided confirms that Depth of Market features are more than impressive. Let’s find out how to operate with data by getting access to it programmatically. First of all, you need to get an idea about how is Depth of Market established and what is the key to its data organization. For more information read the article “Principles of Exchange Pricing through the Example of Moscow Exchange’s Derivatives Market” in chapter “13. Matching Sellers and Buyers. Exchange Depth of Market”. We will not be spending much time on this table description, assuming that the reader has already sufficient knowledge of the subject.
1.2. Event model for working with Depth of Market
Depth of Market has a very dynamic data table. On fast dynamic markets the table of limit orders may change dozens of times per second. Therefore, you must try to process only information that is actually needed for processing, otherwise the amount of transferred data and the central processor’s loading for processing this data may exceed all reasonable limits. This is the reason why MetaTrader 5 requires a special event model that prevents acquisition and processing of data that will not be actually used. Let’s have a thorough examination of this model.
Any event occurring on the market, such as the arrival of a new tick or the execution of a trading transaction, can be processed by calling the corresponding function associated with it. For example, with the arrival of a new tick in MQL5, a special OnTick() event handler function is called. Resizing the chart or its position calls the OnChartEvent() function. This event model also applies to Depth of Market changes. For example, if someone places Sell or Buy limit orders in Depth of Market, its status will change and call a special OnBookEvent() function.
Since there are tens or even hundreds of different symbols available on the terminal with their own Depth of Market, the number of calls of OnBookEvent function can be enormous and resource intensive. In order to avoid this, the terminal must be notified in advance when running an indicator or an Expert Advisor from which instruments in particular it is required to obtain information about second level quotations (information provided by Depth of Market is also called this way). A special system function MarketBookAdd is used for such purposes. For example, if we want to obtain information about Depth of Marked based on instrument Si-9.15 (futures contract for USD/RUR with expiration in September 2020), we need to write the following code in our Expert Advisor or an indicator of OnInit function:
With this function we have created the so-called “subscription” and notified the terminal, that the Expert Advisor or indicator has to be informed in the event of Depth of Market change based on the instrument Si-9.15. The Depth of Market changes for other instruments will be unavailable to us, which will considerably reduce the resources consumed by the program.
The opposite function of MarketBookAdd is MarketBookRelease function. On the contrary, it “unsubscribes” us from the notifications of Depth of Market changes. It is advisable for a programmer to unsubscribe in OnDeinit section, thus closing access to data for closing the Expert Advisor or indicator:
The call of MarketBookAdd function basically implies that at the moment of change in Depth of Market for a required instrument, a special event handling OnBookEvent() function will be called. This way a simple Expert Advisor or an indicator operating with Depth of Market will contain three system functions:
- OnInit – Expert Advisor or indicator initialization function for subscribing to receive an update in case of DOM change for the required instrument.
- OnDeinit – deinitialization of Expert Advisor or indicator function for unsubscribing from receiving information in the event of Depth of Market change for the required instrument.
- OnBookEvent – function called after a change in Depth of Market to signal that Depth of Market has changed.
Our first simple Expert Advisor will contain these three functions. As seen from the example below, for every Depth of Market change the following message will be typed: “Depth of Market for Si-9.15 was changed”:
Key instructions in the code are highlighted with yellow marker.
1.3. Receiving second level quotes with MarketBookGet functions and MqlBookInfo structure
Now that we have learned to receive notifications for Depth of Market changes, it’s time to learn how to access DOM information by using the MarketBookGet function. Let’s examine its prototype and usage.
As already mentioned, Depth of Market is presented with a special table consisting of two parts to display Sell and Buy limit orders. Like any other table, it is the easiest way to display Depth of Market in the form of array, where the array index is the table’s line number, and the array value is a certain line or sequence of data that includes volume, price and application type. Let’s also imagine Depth of Market as a table showing the index of each line:
|Line index||Order type||Volume||Price|
Table 1. Depth of Market presented in a table
To make it easier to navigate across the table, Sell Orders are marked with pink, and Buy Orders with blue colors. The Depth of Market table is basically a two-dimensional array. The first dimension indicates a line number and the second dimension – one of the three table factors (order type – 0, order volume – 1 and order price – 2). However, to avoid working with multidimensional arrays, a special MqlBookInfo structure is used in MQL5. It includes all the necessary values. This way every Depth of Market index contains a MqlBookInfo structure, which in turn carries information about the order type, its volume and price. Let’s give a definition of this structure:
Now the method of working with Depth of Market should be clear to us. MarketBookGet function returns an array of MqlBookInfo structures. Array index indicates the line of price table, and the index structure contains information about volume, price and order type. Knowing this, we will try to get access to the first DOM order, and for this reason we will slightly modify the OnBookEvent function of our Expert Advisor from the previous example:
When running an Expert Advisor on any of the charts, we will receive the reports about the first DOM and its parameters:
Looking at our previous table, it is easy to guess that the level available for zero index of DOM corresponds to the worst Ask price (BOOK_TYPE_SELL). And on the contrary, the lowest Bid price takes the last index in the obtained array. Best Ask and Bid prices are positioned approximately in the middle of Depth of Market. The first disadvantage of the obtained prices is that the calculation in Depth of Market is normally performed using the best prices that are usually placed in the middle of the table. The lowest Ask and Bid prices have a secondary importance. In the future, when analyzing the CMarketBook class we will solve this issue by providing specific indexers convenient for working with Depth of Market.
Chapter 2. CMarketBook class for easy access and operation with Depth of Market
2.1. Designing CMarketInfoBook class
In the first chapter we got acquainted with the system functions for operating with Depth of Market and found out the particular features of the event model for arranging access to the second level quotations. In this chapter we will create a special class CMarketBook for a convenient use of a standard Depth of Market. Based on the knowledge gained from the first chapter, we can discuss the properties our class should have to work with this type of data.
So the first thing that must be considered in designing this class is a resource intensity of received data. Depth of Market can be updated dozens of times per second, in addition to that, it contains dozens of MqlBookInfo type elements. Therefore, our class must initially work only with one instrument. When processing several Depth of Market from different instruments, it is sufficient to create multiple copies of our class with a specific instrument indication:
The second aspect we need to take care of is the organization of an easy access to data. Since the limit orders generate a high-frequency stream of price levels, it is impossible to copy Depth of Market to a secure object-oriented table. Therefore, our class will provide a direct, albeit not as secure, access to the MqlBookInfo array provided by MarketBookGet system function. For example, to access a zero index of DOM with our class, the following has to be written:
MarketBook is an array that is directly obtained using the MarketBookGet function. However, the convenience of using our class will be primarily based on the fact that besides the direct access to an array of limit orders, our class will allow targeted access to the most commonly used Depth of Market prices. For example, to obtain the best Ask price, it is enough to write the following:
It is more convenient than calculating the best Ask index in your expert and then getting the price value based on this index. From the above code it is obvious that CMarketBook, as well as many other MQL5 system functions such as SymbolInfoDouble or OrderHistoryInteger, use their own set of modifiers and InfoGetInteger and InfoGetDouble methods to access integer and double values respectively. To obtain the required properties we must specify a certain modifier of this property. Let’s thoroughly describe the modifiers of these properties:
Certainly, in addition to the methods of InfoGet. group, our class will contain Refresh method triggering the Depth of Market update. Due to the fact that our class requires information update by calling Refresh() method, we will use a resource intensive class update only when it is required.
2.2. Index calculation of most frequently used Depth of Market levels
CMarketBook class is a wrapper for the MqlBookInfo array. Its main purpose is to provide quick and convenient access to the most frequently requested information from this array. Consequently, there are only two basic resource-intensive operations enabled by the class:
- copying of MqlBookInfo array with MarketBookGet system function;
- index calculation of most commonly used prices.
We can’t speed up the operation of your MarketBookGet system function, but it is not necessary, since all system functions of MQL5 language have maximum optimization. But we can produce the fastest calculation of the required indexes. Once again we will refer to ENUM_MBOOK_INFO_INTEGER and ENUM_MBOOK_INFO_DOUBLE property modifiers. As you can see, almost all available properties are based on the calculation of four indexes:
- index of best Ask price;
- index of best Bid price;
- index of worst Bid price;
- index of worst Ask price.
Also three integer-valued properties are used:
- number of Sell price levels or Depth of Market for Sell (Ask depth);
- number of Buy price levels or Depth of Market for Buy (Bid depth);
- total Depth of Market equal to the total number of elements in DOM.
It is obvious that the index of the worst Ask price will always be zero, since the array produced using MarketBookGet function begins with the worst Ask price. Finding the worst Bid price index is trivial – it will always have the last index in the obtained MqlInfoBook array (we would like to remind you, that the last element index in the array is less than the total number of elements of this array per unit):
index of worst Ask price = 0
index of worst Bid price = total number of elements in Depth of Market – 1
Indexes of integer-valued properties are also easy to calculate. Thus, the total Depth of Market always equals the number of elements in the MqlBookInfo array. Depth of Market from the Ask side is the following:
Ask depth = index of best Ask price – index of worst Ask price + 1
We always add one, as the numbering in the array starts with zero and to determine the number of elements it is required to add one to a better index. However, by adding one to the index of best Ask price we already obtain the index of best Bid price. For example, if in the Table 1 we add one to the line with the second number, we will move from the best Sell Limit order at the price 56 842 to the best Buy Limit order at the price 56 836. We have also found out that the index of worst Ask price is always zero. Therefore, we can reduce the formula to find the Ask depth accordingly:
Ask depth = index of best Bid price
Calculation of Bid depth is somewhat different. It is obvious that the number of Buy orders equals the total number of orders minus the number of Sell orders or Ask depth. Since in the previous formula we have learned that the Ask depth equals the index of best Bid price, it won’t be difficult to make the formula to determine the number of Buy orders or the Bid depth:
Bid depth = total Depth of Market – index of best Ask price
Total Depth of Market always equals the total of Bid and Ask depth, and therefore equals the total number of elements in the Depth of Market:
total Depth of Market = total number of elements in Depth of Market
Analytically, we have found almost all frequently used indexes. Using the mathematical reductions, we have replaced the index calculation with the direct indexation. This is very important in CMarketBook class, since the fastest possible access to Depth of Market properties and indexes is required.
Apart from the actual indexes, it is often needed to know the average spread level for the current instrument. Spread is a difference between the best Bid and Ask prices. CMarketBook class allows to obtain the average value of this parameter using the InfoGetDouble method by calling it with the MBOOK_AVERAGE_SPREAD modifier. CMarketBook calculates the current spread in the Refresh method as well as its average value by memorizing the number of this method’s calls.
However, we haven’t yet found the main indexes of the best Bid and Ask prices, so we move on to the next section.
2.3. Predicting indexes of best Bid and Ask prices based on previous values of these indexes
Calculation of the best Ask and Bid prices is a more difficult task that we have yet to complete. For example, in Table 1 the index of the best Ask price will be index with number 2, and the index of the best Bid price will be index number 3. A simplified Depth of Market consisting from only 6 levels is presented in this table. In reality, Depth of Market may be considerably bigger and contain up to 64 Sell and Buy levels. This is a significant value, considering that the DOM update can occur several times per second.
The easiest solution would be to use a “divide in two” method here. Indeed, if we take the total number of levels in Table 1, which is 6, and divide it in two, the obtained figure (3) is the index of the best Bid price. Therefore, its preceding index is the index of the best Ask price (2). However, this method only works if the number of Sell levels equals the number of Buy levels in DOM. This normally occurs on the liquid markets, however, on the illiquid markets Depth of Market may be partially full, and on one of the sides there may be no levels at all.
Our CMarketBook class has to operate on any markets and with any Depth of Market, so the method of dividing in two is not suitable for us. To illustrate the situation when the dividing in two method may not work, we refer to the following figure:
Fig. 3. The number of Bid price levels is not always equal to the number of Ask price levels
Two Depth of Market are shown on Figure 3. The first of them is a futures contract DOM for two-year federal loan bonds (OFZ2-9.15). The second is a EUR/USD futures contract (ED-9.15). It shows that for OFZ2-9.15 the number of Buy price levels is four, while the number of Sell price levels is eight. On a more liquid ED-9.15 market the amount of both Buy and Sell levels is 12 for each of the parties. In case with ED-9.15 the method of determining indexes by diving in two would have worked, and with OFZ2 – it wouldn’t.
A more reliable way to find the index would be to use the DOM iteration until the first order occurrence with BOOK_TYPE_BUY type. The previous index would automatically become the index of the best Ask price. This is the method that a CMarketBook class has. We will refer to it for illustration of the above:
The main purpose of this method lies in the iteration of DOM by for operator. Once a first order with the BOOK_TYPE_BUY type is encountered in Depth of Market, the indexes of best Bid and Ask prices are set, and the iteration is interrupted. Full Depth of Market iteration for each update would be an extremely resource-intensive solution.
Instead of having iteration for every update, there is an option to remember earlier obtained indexes of the best Bid and Ask prices. Indeed, Depth of Market normally contains a fixed amount of Buy and Sell levels. Therefore, it is not required to iterate Depth of Market each time in order to find new indexes. It is sufficient to refer to the previously found indexes and to understand whether they are still indexes of the best Bid and Ask prices. FindBestBid private method is used to solve such issue. Let’s see its content:
It is easy to operate it. Firstly, the method confirms that the current index of the best Ask price still complies with the index of Ask price. It then resets the index of the best Bid price and tries to find it again, referring to the element that follows the index of the best Ask price:
If the found element is indeed the best index of Bid price, then the previous state of DOM had the same number of Buy and Sell levels as the present state. Because of that, DOM iteration can be avoided, since in the SetBestAskAndBidIndex method a FindBestBid method is called before iteration. Thus, DOM iteration is executed only at the first function calling, as well as in case of changing the number of Sell and/or Buy levels.
Although the resulting source code came out bigger and more complex than a simple Depth of Market, in fact it will operate faster. The benefit in performance will be especially noticeable on big DOM of liquid markets. Simple instructions to check the conditions are fulfilled very quickly, and the quantity of these checks is much smaller than the loops of for operator. Therefore, the performance of this method aimed at finding best price indexes will be higher than the normal iteration.
2.4. Determining maximum slippage with GetDeviationByVol method
Often Depth of Market is used by traders to determine the current market liquidity, i.e. Depth of Market is used as an additional instrument to control risks. If market liquidity is low, entering market through market orders can cause high slippage. Slippage always implies additional losses that may be of significant value.
To avoid such situations, the additional methods for controlling the market entry have to be used. For more information please read the article “How to Secure Your Expert Advisor While Trading on the Moscow Exchange”. Therefore, we will not describe these methods in detail and will only mention, that by getting access to Depth of Market we can estimate the value of a potential slippage before entering a market. The size of a slippage depends on two factors:
- current liquidity of Bid side (sell orders) and Ask side (buy orders);
- volume of a deal.
Having access to Depth of Market allows us to see at what volume and prices our order will be executed. If we know the volume of our order, we can calculate the weighted average price for market entry. The difference between this price and the best Bid or Ask price (depending on the entrance direction) will be our slippage.
It is impossible to calculate the weighted average of the entry price manually, as it is required to produce a large volume of calculations in a very short space of time (let me remind you, that the state of DOM may change several times per second). Thus, it is natural to delegate this task to an Expert Advisor or indicator.
CMarketBook class includes a special method to calculate this characteristic – GetDeviationByVol. Since the deal’s volume effects the slippage size, it is required to pass the volume expected to be executed on the market to the method. Since this method uses integer-valued arithmetic of volumes, as adopted on the Moscow Exchange futures market, the method takes volume as a long type value. In addition to that, the method needs to know for which side of liquidity the calculation has to be performed, therefore a special ENUM_MBOOK_SIDE enumeration is used:
Now let’s introduce a source code of the GetDeviationByVol method:
As you can see, the code has a significant volume, but the principle of its calculation is not complex at all. Firstly, Depth of Market iteration is performed from the best towards the worst price. The iteration is executed to the relevant side for each direction. During iteration the current volume is added to the total volume. If the total volume is called and it matches the required volume, then the exit from the loop occurs. Then the average entry price for a given volume is calculated. And finally, the difference between the average entry price and the best Bid/Ask prices are calculated. The absolute difference will be an estimated deviation.
This method is required to calculate the direct iteration of DOM. Although only one out of two DOM parts is iterated, and most of the times only partially, nevertheless, such calculation needs more time than calculation of frequently used indexes of DOM. Therefore, this calculation is implemented directly in a separate method and is produced on demand, i.e. only in those cases when it is required to obtain this information in a clear form.
2.5. Examples for operating with CMarketBook class
So we covered the basic methods of CMarketBook class, and it’s time to practice a little using it. Our test example is fairly simple and understandable even for beginners to programming. Let’s write a test Expert Advisor for executing one-off information output based on DOM. Certainly, for these purposes a script would fit better, but the access to Depth of Market through a script is not possible, and either an Expert Advisor or an indicator has to be used. The source code for our EA is given below:
When running this test Expert Advisor on OFZ2 chart we get the following report:
Let’s compare the obtained report with DOM screenshot for this instrument:
Fig. 4. Depth of Market for OFZ2 when running a test report
We have confirmed that the received indexes and prices fully comply with the current Depth of Market.
Chapter 3. Writing your own Depth of Market as a panel indicator
3.1. General principles of designing the Depth of Market panel. Creating an indicator
With access to the CMarketBook class, it is relatively simple to create a special panel that displays current Depth of Market directly on the chart. We will create our panel on the basis of the user’s indicator. Using an indicator as a base was selected due to the fact that just one Expert Advisor can be located on every chart, while there can be an unlimited number of indicators. If we take an Expert Advisor as a base of the panel, then trading with an expert on the same chart would no longer be possible, and that would be inconvenient.
We will provide our Depth of Market with the ability to appear and hide on the chart, just as it is implemented in a standard trading panel for each chart. We will use the same button for showing or hiding it:
Fig. 5. Standard trading panel in MetaTrader 5
Our Depth of Market will be placed in the upper left corner of the chart, in the same place where the trading panel is located. This is due to the fact that on the chart with Depth of Market indicator a trading Expert Advisor has been launched. In order not to block its icon located in the top right corner, we will move our panel to the left.
When creating an indicator it is required to use one out of two system functions OnCalculate. Since our panel does not use the information received from these functions, we will leave these methods empty. Also, the indicator will not use any graphic series, so indicator_plots property in this case will equal zero.
OnBookEvent system function will be the main function that our indicator will use, thus we will need to sign the current chart symbol in order to receive information about Depth of Market changes. We will subscribe using MarketBookAdd function already known to us.
Depth of Market panel will be implemented in a form of a special CBookPanel class. Now, without going into further details about this class, we will provide the code of the most starting indicator file:
Now CBookPanel class contains only the basic elements for its operation: the arrow which you click for Depth of Market to appear, and the “MarketBook” label for signing our future DOM. When running our indicator, the chart will look the following way:
Fig. 6. Location of future MarketBook panel on the chart
Each element of this class is also an independent class derived from a basic CNode class. This class contains basic methods, such as Show and Hide, which can be overridden in descendant classes. CNode class also generates a unique name for each instance, which makes it more convenient to use standard functions for creating graphical objects and setting their properties.
3.2. Processing of click events and creating Depth of Market form
Currently our indicator does not react to clicking the arrow, so we will continue to work on it. The first thing we should do for our panel is to enter the OnChartEvent event handler. We will call this method as Event. It will take the parameters obtained from OnChartEvent. Also, we will extend the CNode basic class providing it with CArrayObj array, which will contain other graphical elements of CNode type. In the future it will help us to create many same type elements – Depth of Market cells.
Now we are going to provide a source code of the CBookPanel class and its parent class CNode:
Refresh method that updates the state of DOM is not yet full. We will create it a bit later. Current functionality already enables to show the first prototype of our Depth of Market. So far when clicking the arrow, only the standard gray canvas is displayed. When clicked again, it disappears:
Fig. 7. Appearance of future Depth of Market
Depth of Market doesn’t look very convincing yet, but we will continue to improve it.
3.3. Depth of Market cells.
Cells create the base for Depth of Market. Each cell is a table’s element that contains information about volume or price. Also, cells can be distinguished by color: for Buy limit orders it is painted blue, for Sell limit orders – pink. The number of cells may be different for each Depth of Market, therefore, all cells need to be created dynamically on demand and stored in a special data container CArrayObj. Since all cells, regardless of what they show, have the same size and type, the class that implements various types of cells will be the same for all types of cells.
For the cells showing volume and for the cells showing price, a special CBookCeil class will be used. The cell type will be specified when creating an object of this class, so each class instance will know what kind of information from Depth of Market it will be necessary to show, and what color should the background be painted. CBookCeil will use two graphics primitives: text label OBJ_TEXT_LABEL and rectangular label OBJ_RECTANBLE_LABEL. The first will display the text, the second – the actual Depth of Market cell.
Here is a source code of the CBookCeil class:
The main operation of this class is performed using methods Show and Refresh. The latter, depending on the transmitted cell type, colors it in a relevant color and displays the volume or price in it. To create a cell, you must specify its type, location on the X axis, location on the Y axis, DOM index that corresponds to this cell, and Depth of Market from where the cell will receive the information.
A special private method CreateCeils will create cells in a class that implements a substrate of DOM. Here is the source code:
It will be called by clicking the arrow that expands Depth of Market.
Now everything is ready to create our new version of Depth of Market. After making changes and compiling the project, our indicator has acquired a new form:
Fig. 8. The first version of Depth of Market as an indicator
3.4. Displaying volume histogram in Depth of Market
The obtained Depth of Market already performs the basic function – it shows trading levels, volume and prices of Sell and Buy limit orders. Thus, every change of values in Depth of Market also changes the values in the corresponding cells. However, visually it is not easy to keep track of volumes in the obtained table. For example, in a standard MetaTrader 5 DOM volume is displayed on the histogram’s background, which shows the relative magnitude of the current volume in regards to the maximum volume in Depth of Market. Also, it wouldn’t hurt to implement similar functionality to our Depth of Market.
There are different ways to solve this issue. The easiest solution would be to make all the necessary calculations directly in the CBookCeil class. Therefore it is required to write the following in its Refresh method:
In the complete DOM iteration method there is a maximum volume of DOM, then the current volume is divided by the maximum. The obtained share is multiplied by the maximum width of a volume table cell (it is represented by a constant of 50 pixels). The obtained width of a canvas will be a required histogram:
Fig. 9. Depth of Market with histogram volumes
However, the problem with this code is that the DOM iteration is done in each cell every time Refresh is being called. For Depth of Market that is 40 elements deep it means 800 iterations of for loop per each Depth of Market update. Each cell iterates Depth of Market only for its own side, therefore iteration within each cell consists of twenty iterations (Depth of Market divided in half). Although modern computers handle this task, it is a very inefficient operation method, especially given the fact that it is necessary working with Depth of Market using the quickest and most efficient algorithms.
3.5. Quick calculation of maximum volumes in Depth of Market, optimization of iteration
Unfortunately, it is impossible to eliminate full iteration of Depth of Market. After each Depth of Market update the maximum volume and its price level can drastically change. However, we can try to minimize the number of iterations. For this purpose you should learn to make DOM iteration no more than one time between two Refresh calls. The second thing you have to do is to minimize the number of full iteration calls. For this purpose you must use the deferred calculation or, in other words, to carry out this calculation only at the explicit demand. We will transfer all calculations directly to the Depth of Market CMarketBook class, and write a special calculation subclass CBookCalculation located inside the CMarketBook. Please find its source code below:
All Depth of Market iteration and resource-intensive calculations are hidden inside the Calculate private method. It is called only if the calculation flag m_calculate is reset to false condition. Resetting this flag happens only in the Reset method. Since this class is designed exclusively to operate within CMarketBook class, only this class has access to it.
After updating Depth of Market Refresh method CMarketBook class resets the condition of the calculating module by calling its Reset method. Due to this the complete iteration of Depth of Market occurs not more than once between its two upgrades. Also a pending execution is used. In other words, the Calculate method of CBookCalcultae class is called only when there is a clear call from one out of six publicly available methods.
In addition to finding volume, the class that performs a full iteration of Depth of Market had fields added containing the total amount of Sell and Buy limit orders. Additional time to calculate these parameters is not required, since the total cycle of the array is calculated.
Now, instead of a constant Depth of Market iteration a smart iteration on demand is used. This greatly reduces the resources used, making operation with Depth of Market extremely efficient and fast.
3.6. Finishing touches: a volume histogram and a dividing line
We have almost completed our task of creating an indicator. The practical need to find the maximum volume has helped us create an effective method of economical calculation of the required indicators. If in the future we will want to add new calculation parameters to our Depth of Market, it will be easy to do so. For this purpose it will be sufficient to extend our CBookCalculate class with relevant methods and enter the appropriate modifiers to ENUM_MBOOK_INFO_INTEGER and ENUM_MBOOK_INFO_DOUBLE enumerations.
Now we have to make use of the work we have done and to rewrite the Refresh method for each cell:
Visually our panel indicator works the same as in the preceding version, but in reality the histogram’s calculation speed has significantly increased. This is what the art of programming is about – creating effective and easy-to-use algorithms, hiding the complexity of their implementation within private methods of the corresponding modules (classes).
With the appearance of volume histogram it became very vague where the dividing line between volumes of Bid and Ask prices is. Therefore, we will create such line adding to CBookPanel class the CBookLine special subclass implementing this feature:
This is a very simple class which, basically, just determines its position. The line position on Y-axis must be calculated at the time of its creation in the Show method. Knowing the index of best Ask price it is relatively easy to do this:
In this case, the index of best_bid cell is multiplied by the width of each cell (15 pixels), and an additional constant of 19 pixels is added to it.
Our Depth of Market has finally acquired that minimum appearance and functionality to make the experience of using it enjoyable. Certainly, much more could still be done. If desired, our indicator could be made much closer in functionality to the standard MetaTrader 5 Depth of Market.
But the main purpose of this article is not about this. The Depth of Market panel was created with a sole purpose of showing the possibilities of CMarketBook class. It helped to make this class faster, better and more functional, and therefore has fully achieved its goal. We will show you a short video, which will reveal all our work that we have done so far. Below is our DOM panel in dynamics:
3.7. Adding properties of DOM with information about the total number of limit orders for trading instrument
One distinguishing feature of the Moscow Exchange is a transmission of information about the total number of limit orders in real time. This article highlights the operation of Depth of Market as such, without being addressed to any specific market. However, this information despite being specific (peculiar to a specific trading platform), is available at the terminal’s system level. Moreover, it expands data provided by Depth of Market. It was therefore decided to extend the enumeration of property modifiers and to include the support of these properties directly to the Depth of Market CMarketBook class.
The Moscow Stock Exchange provides the following real-time information:
- number of Sell limit orders placed for instrument at the current time;
- number of all Buy limit orders placed for instrument at the current time;
- total volume of all Sell limit orders placed for instrument at the current time;
- total amount of all Buy limit orders placed for instrument at the current time;
- number of open positions and open interest (only for futures markets).
While open interest is not directly related to the number of limit orders on the market (i.e. with its current liquidity), nevertheless, this information is often required in conjunction with the information about the limit orders, so the access to it through the CMarketBook class also looks appropriate. To access this information you must use SymbolInfoInteger and SymbolInfoDouble functions. However, in order for data to be accessible from a single location, we will expand our Depth of Market class by introducing additional enumeration and changes in InfoGetInteger and InfoGetDouble functions:
As you can see, the code is quite simple. In fact, it duplicates the standard functionality of MQL. But the point of adding it to the CMarketBook class is to provide users with a convenient and centralized module for accessing information on limit orders and their price levels.
Chapter 4. Documentation for CMarketBook class
We have completed the description and creation of the class for operation with CMarketBook Depth of Market. The fourth chapter contains documentation for its public methods. Using these documents the class operation becomes simple and straightforward, even for entry-level programmers. Also, this chapter is convenient for being used as a small guidebook for working with the class.
4.1. Methods of obtaining basic information from Depth of Market and operation with it
It updates Depth of Market condition. For every call of OnBookEvent system event (Depth of Market has changed), it is also required to call this method.
Find the example of usage in the relevant section of the fourth chapter.
Returns one of the Depth of Market properties corresponding to the ENUM_MBOOK_INFO_INTEGER modifier. A complete list of supported features can be found in the Description of the ENUM_MBOOK_INFO_INTEGER listing.
Integer-valued property of Depth of Market long type. In case of failure returns -1.
Find the example of usage in the relevant section of the fourth chapter.
It returns one of the Depth of Market properties corresponding to the ENUM_MBOOK_INFO_DOUBLE modifier. A complete list of supported features can be found in the description of the ENUM_MBOOK_INFO_DOUBLE listing.
Property of Depth of Market double type. In case of failure, it returns -1.0.
Find the example of usage in the relevant section of the fourth chapter.
Returns true, if the information on Depth of Market is available, and false if otherwise. This method must be called before operating with Depth of Market class for checking the possibility of working with this type of information.
True, if Depth of Market is available for further operation, and false if otherwise.
Sets the symbol, whose Depth of Market we will be required to work with. It is also possible to set a symbol of Depth of Market when creating an instance of CMarketBook class, clearly stating the name of used symbol in the constructor.
True, if ‘symbol’ is available for trading, false if otherwise.
It returns the symbol of an instrument, for whose operation with Depth of Market the current instance of the class is set.
Name of the instrument whose Depth of Market displays the current instance of the class. NULL, if an instrument is not selected or not available.
Returns the value of a potential slippage at the market entrance with a market order. This value has an estimated character and the obtained slippage may differ from what has been calculated by this function, if the state of Depth of Market at the point of entry has changed. However, this feature provides a fairly accurate assessment of slippage, which will take place at the market entry, and can be used as a source of additional information.
The method takes two parameters: the amount of the proposed deal and iteration indicating the type of liquidity used at closing a deal. For example, the liquidity of Sell limit orders will be used to Buy and, in this case the type of MBOOK_ASK will have to be specified as side. To Sell, on the contrary, MBOOK_BID will have to be indicated. For more information on the DOM side, please read a description of ENUM_BOOK_SIDE enumeration.
- [in] vol — volume of the proposed deal;
- [in] side — Depth of Market side which will be used for making a deal.
The amount of potential slippage in the instrument’s points.
4.2. Enumerations and modifiers of CMarketBook class
Enumeration of ENUM_MBOOK_SIDE
ENUM_BOOK_SIDE enumeration contains modifiers that indicate the type of liquidity. Enumeration and description fields are listed below:
|MBOOK_ASK||Indicates the liquidity provided by Sell limit orders.|
|MBOOK_BID||Indicates the liquidity provided by Buy limit orders.|
Every market order can be executed by limit orders. Depending on the direction of the order, Buy or Sell limit orders are used. The downside of the Buy deal will be one or few Sell limit orders. The downside of the Sell deal will be one or few Buy limit orders. This way the modifier indicates one out of two Depth of Market parts: Buy side or Sell side. The modifier is used by the GetDeviationByVol function, for operation of which you are required to know which side of liquidity will be used by the expected market deal.
Enumeration of ENUM_MBOOK_INFO_INTEGER
Enumeration ENUM_MBOOK_INFO_INTEGER contains property modifiers, which have to be obtained using InfoGetInteger method. Enumeration and description fields are listed below:
|MBOOK_BEST_ASK_INDEX||Index of best Ask price|
|MBOOK_BEST_BID_INDEX||Index of best Bid price|
|MBOOK_LAST_ASK_INDEX||Index of worst or last Ask price|
|MBOOK_LAST_BID_INDEX||Index of worst or last Bid price|
|MBOOK_DEPTH_ASK||Depth of Market from the Ask side or its total number of trade levels|
|MBOOK_DEPTH_BID||Depth of Market from the Bid side or its total number of trade levels|
|MBOOK_DEPTH_TOTAL||Total Depth of Market or the number of Buy and Sell trading levels|
|MBOOK_MAX_ASK_VOLUME||Maximum Ask volume|
|MBOOK_MAX_ASK_VOLUME_INDEX||Level index of maximum Ask volume|
|MBOOK_MAX_BID_VOLUME||Maximum Bid volume|
|MBOOK_MAX_BID_VOLUME_INDEX||Level index of maximum Bid level|
|MBOOK_ASK_VOLUME_TOTAL||Total volume of Sell limit orders available in the current Depth of Market|
|MBOOK_BID_VOLUME_TOTAL||Total volume of Buy limit orders available in the current Depth of Market|
|MBOOK_BUY_ORDERS||Total volume of Buy limit orders currently available on the stock market|
|MBOOK_SELL_ORDERS||Total volume of Sell limit orders currently available on the stock market|
Enumeration of ENUM_MBOOK_INFO_DOUBLE
Enumeration ENUM_MBOOK_INFO_DOUBLE contains property modifiers, which have to be obtained using InfoGetDouble method. Enumeration and description fields are listed below:
|MBOOK_BEST_ASK_PRICE||Best Ask price|
|MBOOK_BEST_BID_PRICE||Best Bid price|
|MBOOK_LAST_ASK_PRICE||Worst or last Ask price|
|MBOOK_LAST_BID_PRICE||Worst or last Bid price|
|MBOOK_AVERAGE_SPREAD||Average difference between the best Bid and Ask, or a spread|
|MBOOK_BUY_ORDERS_VOLUME||Number of Buy orders|
|MBOOK_SELL_ORDERS_VOLUME||Number of Sell orders|
4.3. Example for using CMarketBook class
This example contains a source code in the form of an Expert Advisor that displays basic Depth of Market information at the point of starting:
The article turned out to be rather dynamic. We have analyzed Depth of Market from a technical perspective and proposed a high-performance class-container to work with it. As an example, we have created a Depth of Market indicator based on this class-container, which can be compactly displayed on the instrument’s price chart.
Our Depth of Market indicator is very basic and it still lacks a number of things. However, the main objective was achieved – we made sure that with a CMarketBook class that we have created we can relatively quickly build complex Expert Advisors and indicators for analyzing current liquidity with the instrument. When designing the CMarketBook class a lot of attention has been paid to performance, since Depth of Market has a very dynamic table that changes hundreds of times per minute.
The class described in the article can become a solid base for your scalper or a high-frequency system. Feel free to add functionality specific to your system. To do this, simply create your Depth of Market class derived from CMarketBook, and write extension methods you will need. We do hope, however, that even those basic properties provided by Depth of Market will make your work easier and more reliable.
Great Choice For Beginners!
Free Trading Education!
Free Demo Account 1000$!
Get Your Sign-Up Bonus Now!
Only For Experienced Traders!