Tiger.com Windows Wiki
English
English
  • 👋Welcome!
  • ⭐How to start?
    • Recommended system requirements
    • Register and setup
    • Licenses and login
  • ⚙️Settings
    • Workspace
    • Trading modes
    • Connections
      • Crypto exchanges
        • TigerX
        • Binance via Tiger.com Broker
        • Bybit via Tiger.com Broker
        • Binance
        • Bitfinex
        • BitMEX
        • Bybit
        • OKX
        • Gate.io
        • MEXC
      • Trading terminals
        • DataFeed
        • MetaTrader 5
        • OEC Trader (GAIN Capital)
        • Rithmic
        • QUIK
        • SmartCOM
        • Trader WorkStation (Interactive Brokers)
        • Transaq Connector
    • Basic setup
      • Selecting a symbol
      • Selecting a timeframe
      • Linking windows
      • Setting up exit strategies
      • Setting offsets
    • Terminal
      • Order volumes preset
      • Configuration
        • How to create public configuration
      • General settings
      • Email notifications
      • Telegram alerts
      • Hotkeys Manager
      • Sound alerts
      • Symbols manager
  • 🖥️Windows
    • Chart
      • Chart trading
      • Toolbar setup
      • Chart theme
      • Chart settings
      • Scaling and moving the chart
      • Cluster chart
      • Cluster presets
      • Graphical objects in Chart window
        • Text
        • Ruler
        • Volume profile
        • Trend angle
        • Elliott Correction Wave
        • Elliott Impulse Wave
        • Fibonacci Fan
        • Fibonacci Extensions
        • Fibonacci Retracement
        • Fibonacci Time Zones
        • Linear Regression
      • Main indicators in Chart window
        • Bar Search
        • Bar Timer
        • Bid Ask
        • Big Trades
        • BW MFI
        • Cluster Search
        • Cluster Statistic
        • Cumulative Delta
        • Delta
        • Depth Of Market
        • Dynamic Levels
        • Elders Force Index
        • External Chart
        • Gradient
        • Heatmap
        • High Low
        • Histogram
        • Ichimoku
        • Margin Zones
        • Maximum Levels
        • Open Interest
        • Price
        • Session Color
        • Trades Flow
        • Volume
        • Volume Profile
        • VWAP
        • Weis Wave Volume
        • ZigZag
    • DOM
      • Selecting a trading account
      • Ruler
      • Multiplier
      • DOM settings
        • Main
        • Cluster
        • Trading
      • Stop Loss
      • Take Profit
      • Trigger orders
    • Watchlist
      • How to filter watchlist
    • SmartTape
    • Statistics
    • Volume search
    • All prices
    • Options board
  • 📋Tables
    • Orders
    • Executions
    • Positions
    • XPositions
    • Accounts
    • Limits
    • Player
    • Signals
    • Log
  • 🔍Video Tutorials
    • Terminal Basics
    • Charts and technical analysis
    • Charts, Trade Tape and Player
    • Trading in Tiger.com Windows
  • 💡Platform Updates
    • Version 7.0 Beta
    • Version 6.9
    • Version 6.8
    • Version 6.7
    • Version 6.6
    • Version 6.5
    • Version 6.4
    • Version 6.3
    • Version 6.2
    • Version 6.1
    • Version 6.0.2
    • Version 6.0.1
    • Version 6.0.0
    • Version 5.0.7
    • Version 4.5.15
  • ⌨️Development for Tiger.com Windows
    • Indicator examples
      • DepthOfMarket
      • Trades Flow
      • Volume Profiles
      • Cluster Search
      • Bar Search
      • VWAP
      • Bar Timer
      • Volume
      • Trades
      • Session color
      • Open Interest
      • Dynamic Levels
      • Delta
      • Cumulative Delta
      • Cluster Statistic
      • Bid Ask
      • External Chart
      • High Low
      • Histogram
    • Source examples
      • Moving Average
      • Stock
    • Examples of graphical objects
      • Fibonacci Extensions
      • Fibonacci Retracement
      • Vertical Line
      • Horizontal Line
      • Volume Profile
      • Rectangle
  • ❓Frequently Asked Questions
    • Questions about licenses
    • Questions about indicators
    • Questions about connections
    • Questions about trading
    • Error "Connection lost" when launching the terminal
    • Why do I need to set commission in the terminal?
    • How does automatic account selection work?
    • How do I optimize the terminal to improve performance?
    • How to use the Crypto license to trade on Binance
    • Which order types are available in Tiger.com?
    • How to set up chart auto-refresh for QUIK connection?
    • How do I enable Take Profit orders on Binance?
    • How does autoselection of data type work?
    • Troubles installing the terminal
    • What are the system requirements for the terminal?
    • How to provide Tiger.com Windows app logs for investigation?
    • Fixing Network Issues: How to Adjust DNS Settings
  • 📬Technical support
  • 💭Suggest an improvement
Powered by GitBook
On this page
  1. Development for Tiger.com Windows
  2. Indicator examples

DepthOfMarket

//------------------------------------------------------------------------------
//
// Indicator DepthOfMarket. Copyright (c) 2023 Tiger Trade Capital AG. All rights reserved.
//
//------------------------------------------------------------------------------
 
using System;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Windows;
using System.Windows.Media;
using TigerTrade.Chart.Base;
using TigerTrade.Chart.Indicators.Common;
using TigerTrade.Chart.Indicators.Enums;
using TigerTrade.Core.UI.Converters;
using TigerTrade.Dx;
using TigerTrade.Dx.Enums;
 
namespace TigerTrade.Chart.Indicators.Custom
{
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    [DataContract(Name = "DepthOfMarketScaleAlignment", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    public enum DepthOfMarketScaleAlignment
    {
        [EnumMember(Value = "Left"), Description("Слева")]
        Left,
        [EnumMember(Value = "Right"), Description("Справа")]
        Right
    }
 
    [DataContract(Name = "DepthOfMarketIndicator", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    [Indicator("X_DepthOfMarket", "*DepthOfMarket", true, Type = typeof(DepthOfMarketIndicator))]
    internal sealed class DepthOfMarketIndicator : IndicatorBase
    {
        private int _scaleWidth;
 
        [DataMember(Name = "ScaleWidth")]
        [Category("Параметры"), DisplayName("Ширина шкалы")]
        public int ScaleWidth
        {
            get => _scaleWidth;
            set
            {
                value = Math.Max(0, value);
 
                if (value == _scaleWidth)
                {
                    return;
                }
 
                _scaleWidth = value;
 
                OnPropertyChanged();
            }
        }
 
        private IndicatorNullIntParam _scaleVolumeParam;
 
        [DataMember(Name = "ScaleVolumeParam")]
        public IndicatorNullIntParam ScaleVolumeParam
        {
            get => _scaleVolumeParam ?? (_scaleVolumeParam = new IndicatorNullIntParam(null));
            set => _scaleVolumeParam = value;
        }
 
        [DefaultValue(null)]
        [Category("Параметры"), DisplayName("Объём шкалы")]
        public int? ScaleVolume
        {
            get => ScaleVolumeParam.Get(SettingsShortKey);
            set
            {
                if (!ScaleVolumeParam.Set(SettingsShortKey, value, 1))
                {
                    return;
                }
 
                OnPropertyChanged();
            }
        }
 
        private DepthOfMarketScaleAlignment _scaleAlignment;
     
        [DataMember(Name = "DepthOfMarketScaleAlignment")]
        [Category("Параметры"), DisplayName("Расположение шкалы")]
        public DepthOfMarketScaleAlignment ScaleAlignment
        {
            get => _scaleAlignment;
            set
            {
                if (value == _scaleAlignment)
                {
                    return;
                }
 
                _scaleAlignment = value;
 
                OnPropertyChanged();
            }
        }
 
        private bool _addMargins;
     
        [DataMember(Name = "AddMargins")]
        [Category("Параметры"), DisplayName("Добавить отступы")]
        public bool AddMargins
        {
            get => _addMargins;
            set
            {
                if (value == _addMargins)
                {
                    return;
                }
 
                _addMargins = value;
 
                OnPropertyChanged();
            }
        }
 
        private bool _showValues;
 
        [DataMember(Name = "ShowValues")]
        [Category("Параметры"), DisplayName("Отображать значения")]
        public bool ShowValues
        {
            get => _showValues;
            set
            {
                if (value == _showValues)
                {
                    return;
                }
 
                _showValues = value;
 
                OnPropertyChanged();
            }
        }
 
        private bool _minimizeValues;
 
        [DataMember(Name = "MinimizeValues")]
        [Category("Параметры"), DisplayName("Минимизировать значения")]
        public bool MinimizeValues
        {
            get => _minimizeValues;
            set
            {
                if (value == _minimizeValues)
                {
                    return;
                }
 
                _minimizeValues = value;
 
                OnPropertyChanged();
            }
        }
 
        private IndicatorIntParam _roundValueParam;
 
        [DataMember(Name = "RoundValueParam")]
        public IndicatorIntParam RoundValuesParam
        {
            get => _roundValueParam ?? (_roundValueParam = new IndicatorIntParam(0));
            set => _roundValueParam = value;
        }
 
        [DefaultValue(0)]
        [Category("Параметры"), DisplayName("Округлять значения")]
        public int RoundValues
        {
            get => RoundValuesParam.Get(SettingsLongKey);
            set
            {
                if (!RoundValuesParam.Set(SettingsLongKey, value, -4, 4))
                {
                    return;
                }
 
                OnPropertyChanged();
            }
        }
 
        private XBrush _bidQuoteBrush;
 
        private XColor _quoteBuyColor;
 
        [DataMember(Name = "BidQuoteColor")]
        [Category("Стиль"), DisplayName("Заявка на покупку")]
        public XColor BidQuoteColor
        {
            get => _quoteBuyColor;
            set
            {
                if (_quoteBuyColor == value)
                {
                    return;
                }
 
                _quoteBuyColor = value;
 
                _bidQuoteBrush = new XBrush(value);
 
                OnPropertyChanged();
            }
        }
 
        private XBrush _bestBidQuoteBrush;
 
        private XColor _quoteBestBuyColor;
 
        [DataMember(Name = "BestBidQuoteColor")]
        [Category("Стиль"), DisplayName("Лучшая заявка на покупку")]
        public XColor BestBidQuoteColor
        {
            get => _quoteBestBuyColor;
            set
            {
                if (_quoteBestBuyColor == value)
                {
                    return;
                }
 
                _quoteBestBuyColor = value;
 
                _bestBidQuoteBrush = new XBrush(value);
 
                OnPropertyChanged();
            }
        }
 
        private XBrush _askQuoteBrush;
 
        private XColor _quoteSellColor;
 
        [DataMember(Name = "AskQuoteColor")]
        [Category("Стиль"), DisplayName("Заявка на продажу")]
        public XColor AskQuoteColor
        {
            get => _quoteSellColor;
            set
            {
                if (_quoteSellColor == value)
                {
                    return;
                }
 
                _quoteSellColor = value;
 
                _askQuoteBrush = new XBrush(value);
 
                OnPropertyChanged();
            }
        }
 
        private XBrush _bestAskQuoteBrush;
 
        private XColor _quoteBestSellColor;
 
        [DataMember(Name = "BestAskQuoteColor")]
        [Category("Стиль"), DisplayName("Лучшая заявка на прдажу")]
        public XColor BestAskQuoteColor
        {
            get => _quoteBestSellColor;
            set
            {
                if (_quoteBestSellColor == value)
                {
                    return;
                }
 
                _quoteBestSellColor = value;
 
                _bestAskQuoteBrush = new XBrush(value);
 
                OnPropertyChanged();
            }
        }
 
        private XBrush _emptyQuoteBrush;
 
        private XColor _quoteEmptyColor;
 
        [Browsable(false)]
        [DataMember(Name = "EmptyQuoteColor")]
        [Category("Стиль"), DisplayName("Цена без заявок")]
        public XColor EmptyQuoteColor
        {
            get => _quoteEmptyColor;
            set
            {
                if (_quoteEmptyColor == value)
                {
                    return;
                }
 
                _quoteEmptyColor = value;
 
                _emptyQuoteBrush = new XBrush(value);
 
                OnPropertyChanged();
            }
        }
 
        private XBrush _bidVolumeBrush;
 
        private XColor _quoteBuyVolumeColor;
 
        [DataMember(Name = "BidVolumeColor")]
        [Category("Стиль"), DisplayName("Шкала покупок")]
        public XColor BidVolumeColor
        {
            get => _quoteBuyVolumeColor;
            set
            {
                if (_quoteBuyVolumeColor == value)
                {
                    return;
                }
 
                _quoteBuyVolumeColor = value;
 
                _bidVolumeBrush = new XBrush(value);
 
                OnPropertyChanged();
            }
        }
 
        private XBrush _askVolumeBrush;
 
        private XColor _quoteSellVolumeColor;
 
        [DataMember(Name = "AskVolumeColor")]
        [Category("Стиль"), DisplayName("Шкала продаж")]
        public XColor AskVolumeColor
        {
            get => _quoteSellVolumeColor;
            set
            {
                if (_quoteSellVolumeColor == value)
                {
                    return;
                }
 
                _quoteSellVolumeColor = value;
 
                _askVolumeBrush = new XBrush(value);
 
                OnPropertyChanged();
            }
        }
 
        private XBrush _textBrush;
 
        private XColor _textColor;
 
        [DataMember(Name = "TextColor")]
        [Category("Стиль"), DisplayName("Цвет текста")]
        public XColor TextColor
        {
            get => _textColor;
            set
            {
                if (_textColor == value)
                {
                    return;
                }
 
                _textColor = value;
 
                _textBrush = new XBrush(value);
 
                OnPropertyChanged();
            }
        }
 
        private XBrush _backBrush;
 
        private XColor _backColor;
 
        [DataMember(Name = "BackColor")]
        [Category("Стиль"), DisplayName("Цвет фона")]
        public XColor BackColor
        {
            get => _backColor;
            set
            {
                if (_backColor == value)
                {
                    return;
                }
 
                _backColor = value;
 
                _backBrush = new XBrush(value);
 
                OnPropertyChanged();
            }
        }
 
        [Browsable(false)]
        public override bool ShowIndicatorValues => false;
 
        [Browsable(false)]
        public override bool ShowIndicatorLabels => false;
 
        [Browsable(false)]
        public override IndicatorCalculation Calculation => IndicatorCalculation.OnEachTick;
 
        public DepthOfMarketIndicator()
        {
            ShowIndicatorTitle = false;
 
            ScaleWidth = 0;
            ScaleAlignment = DepthOfMarketScaleAlignment.Right;
            AddMargins = false;
            ShowValues = true;
            MinimizeValues = false;
 
            BidQuoteColor = Colors.Transparent;
            BestBidQuoteColor = Colors.Transparent;
            AskQuoteColor = Colors.Transparent;
            BestAskQuoteColor = Colors.Transparent;
            EmptyQuoteColor = Colors.Transparent;
            BidVolumeColor = Color.FromArgb(255, 30, 144, 255);
            AskVolumeColor = Color.FromArgb(255, 178, 34, 34);
            TextColor = Colors.White;
            BackColor = Colors.Transparent;
        }
 
        protected override void Execute()
        {
        }
 
        public override void Render(DxVisualQueue visual)
        {
            var dp = DataProvider;
            var step = dp.Step;
            var symbol = dp.Symbol;
 
            var md = dp.GetRawMarketDepth();
 
            var r = Canvas.Rect;
 
            var maxWidth = ScaleWidth > 0 ? ScaleWidth : r.Width * 0.1;
            var maxVolume = ScaleVolume > 0 ? symbol.CorrectSizeFilter(ScaleVolume.Value) : md.MaxSize;
 
            if (maxWidth < 5 || maxVolume < 1)
            {
                return;
            }
 
            var heightCorrect = AddMargins ? -1 : 0;
 
            var height = Math.Max(GetY(0.0) - GetY(step), 1);
 
            var fontSize = Math.Min(height + heightCorrect - 2, 18) * 96.0 / 72.0;
 
            fontSize = Math.Min(fontSize, Canvas.ChartFont.Size);
 
            var textFont = new XFont(Canvas.ChartFont.Name, fontSize);
 
            visual.FillRectangle(_backBrush, new Rect(r.Right - maxWidth, r.Y, maxWidth, r.Height));
 
            var asksY1 = (int)GetY(md.MaxAskPrice * step + step / 2.0);
            var asksY2 = (int)GetY(md.MinAskPrice * step + step / 2.0);
 
            visual.FillRectangle(_askQuoteBrush,
                new Rect(new Point(r.Right - maxWidth, asksY1), new Point(r.Right, asksY2)));
 
            var bidsY1 = (int)GetY(md.MaxBidPrice * step - step / 2.0);
            var bidsY2 = (int)GetY(md.MinBidPrice * step - step / 2.0);
 
            visual.FillRectangle(_bidQuoteBrush,
                new Rect(new Point(r.Right - maxWidth, bidsY1), new Point(r.Right, bidsY2)));
 
            var prevY = (int)GetY(md.MaxAskPrice * step + step / 2.0);
 
            var maxPrice = Math.Min((long)Math.Round(Canvas.GetValue(r.Top) / step), md.MaxAskPrice);
            var minPrice = Math.Max((long)Math.Round(Canvas.GetValue(r.Bottom) / step), md.MinAskPrice);
 
            if (maxPrice - minPrice > 5000)
            {
                return;
            }
 
            var roundValues = RoundValues;
 
            for (var price = maxPrice; price >= minPrice; price--)
            {
                var currY = (int)GetY(price * step - step / 2.0);
 
                var currHeight = Math.Max(currY - prevY, 1);
 
                var y = prevY;
 
                prevY = currY;
 
                if (!md.AskQuotes.ContainsKey(price) || currY < r.Top)
                {
                    continue;
                }
 
                if (price == md.MinAskPrice)
                {
                    var quoteRect = new Rect(new Point(r.Right - maxWidth, y), new Point(r.Right, y + currHeight));
 
                    visual.FillRectangle(_bestAskQuoteBrush, quoteRect);
                }
 
                var volume = md.AskQuotes[price];
 
                var text = symbol.FormatRawSize(volume, roundValues, MinimizeValues);
                var textWidth = textFont.GetWidth(text);
 
                var width = (int)Math.Min(volume * maxWidth / maxVolume, maxWidth);
 
                if (ShowValues && height > 8)
                {
                    width = (int)Math.Min(Math.Max(width, textWidth), maxWidth);
                }
 
                var volumeRect = ScaleAlignment == DepthOfMarketScaleAlignment.Right
                    ? new Rect(new Point(r.Right - width, y),
                        new Point(r.Right, y + Math.Max(currHeight + heightCorrect, 1)))
                    : new Rect(new Point(r.Right - maxWidth, y),
                        new Point(r.Right - (maxWidth - width), y + Math.Max(currHeight + heightCorrect, 1)));
 
                visual.FillRectangle(_askVolumeBrush, volumeRect);
 
                if (ShowValues && height > 8)
                {
                    visual.DrawString(text, textFont, _textBrush, volumeRect,
                        ScaleAlignment == DepthOfMarketScaleAlignment.Right ? XTextAlignment.Right : XTextAlignment.Left);
                }
            }
 
            prevY = (int)GetY(md.MaxBidPrice * step + step / 2.0);
 
            maxPrice = Math.Min((long)Math.Round(Canvas.GetValue(r.Top) / step), md.MaxBidPrice);
            minPrice = Math.Max((long)Math.Round(Canvas.GetValue(r.Bottom) / step), md.MinBidPrice);
 
            if (maxPrice - minPrice > 5000)
            {
                return;
            }
 
            for (var price = maxPrice; price >= minPrice; price--)
            {
                var currY = (int)GetY(price * step - step / 2.0);
 
                var currHeight = Math.Max((currY - prevY), 1);
 
                var y = prevY;
 
                prevY = currY;
 
                if (!md.BidQuotes.ContainsKey(price) || y > r.Bottom)
                {
                    continue;
                }
 
                if (price == md.MaxBidPrice)
                {
                    var quoteRect = new Rect(new Point(r.Right - maxWidth, y), new Point(r.Right, y + currHeight));
 
                    visual.FillRectangle(_bestBidQuoteBrush, quoteRect);
                }
 
                var volume = md.BidQuotes[price];
 
                var text = symbol.FormatRawSize(volume, roundValues, MinimizeValues);
                var textWidth = textFont.GetWidth(text);
 
                var width = (int)Math.Min(volume * maxWidth / maxVolume, maxWidth);
 
                if (ShowValues && height > 8)
                {
                    width = (int)Math.Min(Math.Max(width, textWidth), maxWidth);
                }
 
                var volumeRect = ScaleAlignment == DepthOfMarketScaleAlignment.Right
                    ? new Rect(new Point(r.Right - width, y),
                        new Point(r.Right, y + Math.Max(currHeight + heightCorrect, 1)))
                    : new Rect(new Point(r.Right - maxWidth, y),
                        new Point(r.Right - (maxWidth - width), y + Math.Max(currHeight + heightCorrect, 1)));
 
                visual.FillRectangle(_bidVolumeBrush, volumeRect);
 
                if (ShowValues && height > 8)
                {
                    visual.DrawString(text, textFont, _textBrush, volumeRect,
                        ScaleAlignment == DepthOfMarketScaleAlignment.Right ? XTextAlignment.Right : XTextAlignment.Left);
                }
            }
        }
 
        public override void ApplyColors(IChartTheme theme)
        {
            BidVolumeColor = theme.PaletteColor6;
            AskVolumeColor = theme.PaletteColor7;
            TextColor = theme.ChartFontColor;
 
            base.ApplyColors(theme);
        }
 
        public override void CopyTemplate(IndicatorBase indicator, bool style)
        {
            var i = (DepthOfMarketIndicator)indicator;
 
            ScaleWidth = i.ScaleWidth;
            ScaleAlignment = i.ScaleAlignment;
            AddMargins = i.AddMargins;
            ShowValues = i.ShowValues;
            MinimizeValues = i.MinimizeValues;
 
            ScaleVolumeParam.Copy(i.ScaleVolumeParam);
            RoundValuesParam.Copy(i.RoundValuesParam);
 
            BidQuoteColor = i.BidQuoteColor;
            BestBidQuoteColor = i.BestBidQuoteColor;
            AskQuoteColor = i.AskQuoteColor;
            BestAskQuoteColor = i.BestAskQuoteColor;
            EmptyQuoteColor = i.EmptyQuoteColor;
            BidVolumeColor = i.BidVolumeColor;
            AskVolumeColor = i.AskVolumeColor;
            TextColor = i.TextColor;
            BackColor = i.BackColor;
 
            OnPropertyChanged(nameof(ScaleVolume));
 
            base.CopyTemplate(indicator, style);
        }
    }
}
PreviousIndicator examplesNextTrades Flow

Last updated 2 years ago

⌨️