DepthOfMarket

Тема в разделе "Примеры индикаторов", создана пользователем Support, 26 июл 2019.

  1. Support

    Support Администратор
    Команда форума

    Регистрация:
    5 сен 2015
    Сообщения:
    1 159
    Симпатии:
    261
    Код индикатора DepthOfMarket
    1. //------------------------------------------------------------------------------
    2. //
    3. // Индикатор DepthOfMarket. Copyright (c) 2019 Ilya Smirnov. All rights reserved.
    4. //
    5. //------------------------------------------------------------------------------
    6.  
    7. using System;
    8. using System.ComponentModel;
    9. using System.Runtime.Serialization;
    10. using System.Windows;
    11. using System.Windows.Media;
    12. using TigerTrade.Chart.Base;
    13. using TigerTrade.Chart.Indicators.Common;
    14. using TigerTrade.Chart.Indicators.Enums;
    15. using TigerTrade.Core.UI.Converters;
    16. using TigerTrade.Dx;
    17. using TigerTrade.Dx.Enums;
    18.  
    19. namespace TigerTrade.Chart.Indicators.Custom
    20. {
    21.     [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    22.     [DataContract(Name = "DepthOfMarketScaleAlignment", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    23.     public enum DepthOfMarketScaleAlignment
    24.     {
    25.         [EnumMember(Value = "Left"), Description("Слева")]
    26.         Left,
    27.         [EnumMember(Value = "Right"), Description("Справа")]
    28.         Right
    29.     }
    30.  
    31.     [DataContract(Name = "DepthOfMarketIndicator", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    32.     [Indicator("X_DepthOfMarket", "*DepthOfMarket", true, Type = typeof(DepthOfMarketIndicator))]
    33.     internal sealed class DepthOfMarketIndicator : IndicatorBase
    34.     {
    35.         private int _scaleWidth;
    36.  
    37.         [DataMember(Name = "ScaleWidth")]
    38.         [Category("Параметры"), DisplayName("Ширина шкалы")]
    39.         public int ScaleWidth
    40.         {
    41.             get => _scaleWidth;
    42.             set
    43.             {
    44.                 value = Math.Max(0, value);
    45.  
    46.                 if (value == _scaleWidth)
    47.                 {
    48.                     return;
    49.                 }
    50.  
    51.                 _scaleWidth = value;
    52.  
    53.                 OnPropertyChanged();
    54.             }
    55.         }
    56.  
    57.         private IndicatorNullIntParam _scaleVolumeParam;
    58.  
    59.         [DataMember(Name = "ScaleVolumeParam")]
    60.         public IndicatorNullIntParam ScaleVolumeParam
    61.         {
    62.             get => _scaleVolumeParam ?? (_scaleVolumeParam = new IndicatorNullIntParam(null));
    63.             set => _scaleVolumeParam = value;
    64.         }
    65.  
    66.         [DefaultValue(null)]
    67.         [Category("Параметры"), DisplayName("Объём шкалы")]
    68.         public int? ScaleVolume
    69.         {
    70.             get => ScaleVolumeParam.Get(SettingsShortKey);
    71.             set
    72.             {
    73.                 if (!ScaleVolumeParam.Set(SettingsShortKey, value, 1))
    74.                 {
    75.                     return;
    76.                 }
    77.  
    78.                 OnPropertyChanged();
    79.             }
    80.         }
    81.  
    82.         private DepthOfMarketScaleAlignment _scaleAlignment;
    83.      
    84.         [DataMember(Name = "DepthOfMarketScaleAlignment")]
    85.         [Category("Параметры"), DisplayName("Расположение шкалы")]
    86.         public DepthOfMarketScaleAlignment ScaleAlignment
    87.         {
    88.             get => _scaleAlignment;
    89.             set
    90.             {
    91.                 if (value == _scaleAlignment)
    92.                 {
    93.                     return;
    94.                 }
    95.  
    96.                 _scaleAlignment = value;
    97.  
    98.                 OnPropertyChanged();
    99.             }
    100.         }
    101.  
    102.         private bool _addMargins;
    103.      
    104.         [DataMember(Name = "AddMargins")]
    105.         [Category("Параметры"), DisplayName("Добавить отступы")]
    106.         public bool AddMargins
    107.         {
    108.             get => _addMargins;
    109.             set
    110.             {
    111.                 if (value == _addMargins)
    112.                 {
    113.                     return;
    114.                 }
    115.  
    116.                 _addMargins = value;
    117.  
    118.                 OnPropertyChanged();
    119.             }
    120.         }
    121.  
    122.         private bool _showValues;
    123.  
    124.         [DataMember(Name = "ShowValues")]
    125.         [Category("Параметры"), DisplayName("Отображать значения")]
    126.         public bool ShowValues
    127.         {
    128.             get => _showValues;
    129.             set
    130.             {
    131.                 if (value == _showValues)
    132.                 {
    133.                     return;
    134.                 }
    135.  
    136.                 _showValues = value;
    137.  
    138.                 OnPropertyChanged();
    139.             }
    140.         }
    141.  
    142.         private bool _minimizeValues;
    143.  
    144.         [DataMember(Name = "MinimizeValues")]
    145.         [Category("Параметры"), DisplayName("Минимизировать значения")]
    146.         public bool MinimizeValues
    147.         {
    148.             get => _minimizeValues;
    149.             set
    150.             {
    151.                 if (value == _minimizeValues)
    152.                 {
    153.                     return;
    154.                 }
    155.  
    156.                 _minimizeValues = value;
    157.  
    158.                 OnPropertyChanged();
    159.             }
    160.         }
    161.  
    162.         private IndicatorIntParam _roundValueParam;
    163.  
    164.         [DataMember(Name = "RoundValueParam")]
    165.         public IndicatorIntParam RoundValuesParam
    166.         {
    167.             get => _roundValueParam ?? (_roundValueParam = new IndicatorIntParam(0));
    168.             set => _roundValueParam = value;
    169.         }
    170.  
    171.         [DefaultValue(0)]
    172.         [Category("Параметры"), DisplayName("Округлять значения")]
    173.         public int RoundValues
    174.         {
    175.             get => RoundValuesParam.Get(SettingsLongKey);
    176.             set
    177.             {
    178.                 if (!RoundValuesParam.Set(SettingsLongKey, value, -4, 4))
    179.                 {
    180.                     return;
    181.                 }
    182.  
    183.                 OnPropertyChanged();
    184.             }
    185.         }
    186.  
    187.         private XBrush _bidQuoteBrush;
    188.  
    189.         private XColor _quoteBuyColor;
    190.  
    191.         [DataMember(Name = "BidQuoteColor")]
    192.         [Category("Стиль"), DisplayName("Заявка на покупку")]
    193.         public XColor BidQuoteColor
    194.         {
    195.             get => _quoteBuyColor;
    196.             set
    197.             {
    198.                 if (_quoteBuyColor == value)
    199.                 {
    200.                     return;
    201.                 }
    202.  
    203.                 _quoteBuyColor = value;
    204.  
    205.                 _bidQuoteBrush = new XBrush(value);
    206.  
    207.                 OnPropertyChanged();
    208.             }
    209.         }
    210.  
    211.         private XBrush _bestBidQuoteBrush;
    212.  
    213.         private XColor _quoteBestBuyColor;
    214.  
    215.         [DataMember(Name = "BestBidQuoteColor")]
    216.         [Category("Стиль"), DisplayName("Лучшая заявка на покупку")]
    217.         public XColor BestBidQuoteColor
    218.         {
    219.             get => _quoteBestBuyColor;
    220.             set
    221.             {
    222.                 if (_quoteBestBuyColor == value)
    223.                 {
    224.                     return;
    225.                 }
    226.  
    227.                 _quoteBestBuyColor = value;
    228.  
    229.                 _bestBidQuoteBrush = new XBrush(value);
    230.  
    231.                 OnPropertyChanged();
    232.             }
    233.         }
    234.  
    235.         private XBrush _askQuoteBrush;
    236.  
    237.         private XColor _quoteSellColor;
    238.  
    239.         [DataMember(Name = "AskQuoteColor")]
    240.         [Category("Стиль"), DisplayName("Заявка на продажу")]
    241.         public XColor AskQuoteColor
    242.         {
    243.             get => _quoteSellColor;
    244.             set
    245.             {
    246.                 if (_quoteSellColor == value)
    247.                 {
    248.                     return;
    249.                 }
    250.  
    251.                 _quoteSellColor = value;
    252.  
    253.                 _askQuoteBrush = new XBrush(value);
    254.  
    255.                 OnPropertyChanged();
    256.             }
    257.         }
    258.  
    259.         private XBrush _bestAskQuoteBrush;
    260.  
    261.         private XColor _quoteBestSellColor;
    262.  
    263.         [DataMember(Name = "BestAskQuoteColor")]
    264.         [Category("Стиль"), DisplayName("Лучшая заявка на прдажу")]
    265.         public XColor BestAskQuoteColor
    266.         {
    267.             get => _quoteBestSellColor;
    268.             set
    269.             {
    270.                 if (_quoteBestSellColor == value)
    271.                 {
    272.                     return;
    273.                 }
    274.  
    275.                 _quoteBestSellColor = value;
    276.  
    277.                 _bestAskQuoteBrush = new XBrush(value);
    278.  
    279.                 OnPropertyChanged();
    280.             }
    281.         }
    282.  
    283.         private XBrush _emptyQuoteBrush;
    284.  
    285.         private XColor _quoteEmptyColor;
    286.  
    287.         [Browsable(false)]
    288.         [DataMember(Name = "EmptyQuoteColor")]
    289.         [Category("Стиль"), DisplayName("Цена без заявок")]
    290.         public XColor EmptyQuoteColor
    291.         {
    292.             get => _quoteEmptyColor;
    293.             set
    294.             {
    295.                 if (_quoteEmptyColor == value)
    296.                 {
    297.                     return;
    298.                 }
    299.  
    300.                 _quoteEmptyColor = value;
    301.  
    302.                 _emptyQuoteBrush = new XBrush(value);
    303.  
    304.                 OnPropertyChanged();
    305.             }
    306.         }
    307.  
    308.         private XBrush _bidVolumeBrush;
    309.  
    310.         private XColor _quoteBuyVolumeColor;
    311.  
    312.         [DataMember(Name = "BidVolumeColor")]
    313.         [Category("Стиль"), DisplayName("Шкала покупок")]
    314.         public XColor BidVolumeColor
    315.         {
    316.             get => _quoteBuyVolumeColor;
    317.             set
    318.             {
    319.                 if (_quoteBuyVolumeColor == value)
    320.                 {
    321.                     return;
    322.                 }
    323.  
    324.                 _quoteBuyVolumeColor = value;
    325.  
    326.                 _bidVolumeBrush = new XBrush(value);
    327.  
    328.                 OnPropertyChanged();
    329.             }
    330.         }
    331.  
    332.         private XBrush _askVolumeBrush;
    333.  
    334.         private XColor _quoteSellVolumeColor;
    335.  
    336.         [DataMember(Name = "AskVolumeColor")]
    337.         [Category("Стиль"), DisplayName("Шкала продаж")]
    338.         public XColor AskVolumeColor
    339.         {
    340.             get => _quoteSellVolumeColor;
    341.             set
    342.             {
    343.                 if (_quoteSellVolumeColor == value)
    344.                 {
    345.                     return;
    346.                 }
    347.  
    348.                 _quoteSellVolumeColor = value;
    349.  
    350.                 _askVolumeBrush = new XBrush(value);
    351.  
    352.                 OnPropertyChanged();
    353.             }
    354.         }
    355.  
    356.         private XBrush _textBrush;
    357.  
    358.         private XColor _textColor;
    359.  
    360.         [DataMember(Name = "TextColor")]
    361.         [Category("Стиль"), DisplayName("Цвет текста")]
    362.         public XColor TextColor
    363.         {
    364.             get => _textColor;
    365.             set
    366.             {
    367.                 if (_textColor == value)
    368.                 {
    369.                     return;
    370.                 }
    371.  
    372.                 _textColor = value;
    373.  
    374.                 _textBrush = new XBrush(value);
    375.  
    376.                 OnPropertyChanged();
    377.             }
    378.         }
    379.  
    380.         private XBrush _backBrush;
    381.  
    382.         private XColor _backColor;
    383.  
    384.         [DataMember(Name = "BackColor")]
    385.         [Category("Стиль"), DisplayName("Цвет фона")]
    386.         public XColor BackColor
    387.         {
    388.             get => _backColor;
    389.             set
    390.             {
    391.                 if (_backColor == value)
    392.                 {
    393.                     return;
    394.                 }
    395.  
    396.                 _backColor = value;
    397.  
    398.                 _backBrush = new XBrush(value);
    399.  
    400.                 OnPropertyChanged();
    401.             }
    402.         }
    403.  
    404.         [Browsable(false)]
    405.         public override bool ShowIndicatorValues => false;
    406.  
    407.         [Browsable(false)]
    408.         public override bool ShowIndicatorLabels => false;
    409.  
    410.         [Browsable(false)]
    411.         public override IndicatorCalculation Calculation => IndicatorCalculation.OnEachTick;
    412.  
    413.         public DepthOfMarketIndicator()
    414.         {
    415.             ShowIndicatorTitle = false;
    416.  
    417.             ScaleWidth = 0;
    418.             ScaleAlignment = DepthOfMarketScaleAlignment.Right;
    419.             AddMargins = false;
    420.             ShowValues = true;
    421.             MinimizeValues = false;
    422.  
    423.             BidQuoteColor = Colors.Transparent;
    424.             BestBidQuoteColor = Colors.Transparent;
    425.             AskQuoteColor = Colors.Transparent;
    426.             BestAskQuoteColor = Colors.Transparent;
    427.             EmptyQuoteColor = Colors.Transparent;
    428.             BidVolumeColor = Color.FromArgb(255, 30, 144, 255);
    429.             AskVolumeColor = Color.FromArgb(255, 178, 34, 34);
    430.             TextColor = Colors.White;
    431.             BackColor = Colors.Transparent;
    432.         }
    433.  
    434.         protected override void Execute()
    435.         {
    436.         }
    437.  
    438.         public override void Render(DxVisualQueue visual)
    439.         {
    440.             var dp = DataProvider;
    441.             var step = dp.Step;
    442.             var symbol = dp.Symbol;
    443.  
    444.             var md = dp.GetRawMarketDepth();
    445.  
    446.             var r = Canvas.Rect;
    447.  
    448.             var maxWidth = ScaleWidth > 0 ? ScaleWidth : r.Width * 0.1;
    449.             var maxVolume = ScaleVolume > 0 ? symbol.CorrectSizeFilter(ScaleVolume.Value) : md.MaxSize;
    450.  
    451.             if (maxWidth < 5 || maxVolume < 1)
    452.             {
    453.                 return;
    454.             }
    455.  
    456.             var heightCorrect = AddMargins ? -1 : 0;
    457.  
    458.             var height = Math.Max(GetY(0.0) - GetY(step), 1);
    459.  
    460.             var fontSize = Math.Min(height + heightCorrect - 2, 18) * 96.0 / 72.0;
    461.  
    462.             fontSize = Math.Min(fontSize, Canvas.ChartFont.Size);
    463.  
    464.             var textFont = new XFont(Canvas.ChartFont.Name, fontSize);
    465.  
    466.             visual.FillRectangle(_backBrush, new Rect(r.Right - maxWidth, r.Y, maxWidth, r.Height));
    467.  
    468.             var asksY1 = (int)GetY(md.MaxAskPrice * step + step / 2.0);
    469.             var asksY2 = (int)GetY(md.MinAskPrice * step + step / 2.0);
    470.  
    471.             visual.FillRectangle(_askQuoteBrush,
    472.                 new Rect(new Point(r.Right - maxWidth, asksY1), new Point(r.Right, asksY2)));
    473.  
    474.             var bidsY1 = (int)GetY(md.MaxBidPrice * step - step / 2.0);
    475.             var bidsY2 = (int)GetY(md.MinBidPrice * step - step / 2.0);
    476.  
    477.             visual.FillRectangle(_bidQuoteBrush,
    478.                 new Rect(new Point(r.Right - maxWidth, bidsY1), new Point(r.Right, bidsY2)));
    479.  
    480.             var prevY = (int)GetY(md.MaxAskPrice * step + step / 2.0);
    481.  
    482.             var maxPrice = Math.Min((long)Math.Round(Canvas.GetValue(r.Top) / step), md.MaxAskPrice);
    483.             var minPrice = Math.Max((long)Math.Round(Canvas.GetValue(r.Bottom) / step), md.MinAskPrice);
    484.  
    485.             if (maxPrice - minPrice > 5000)
    486.             {
    487.                 return;
    488.             }
    489.  
    490.             var roundValues = RoundValues;
    491.  
    492.             for (var price = maxPrice; price >= minPrice; price--)
    493.             {
    494.                 var currY = (int)GetY(price * step - step / 2.0);
    495.  
    496.                 var currHeight = Math.Max(currY - prevY, 1);
    497.  
    498.                 var y = prevY;
    499.  
    500.                 prevY = currY;
    501.  
    502.                 if (!md.AskQuotes.ContainsKey(price) || currY < r.Top)
    503.                 {
    504.                     continue;
    505.                 }
    506.  
    507.                 if (price == md.MinAskPrice)
    508.                 {
    509.                     var quoteRect = new Rect(new Point(r.Right - maxWidth, y), new Point(r.Right, y + currHeight));
    510.  
    511.                     visual.FillRectangle(_bestAskQuoteBrush, quoteRect);
    512.                 }
    513.  
    514.                 var volume = md.AskQuotes[price];
    515.  
    516.                 var text = symbol.FormatRawSize(volume, roundValues, MinimizeValues);
    517.                 var textWidth = textFont.GetWidth(text);
    518.  
    519.                 var width = (int)Math.Min(volume * maxWidth / maxVolume, maxWidth);
    520.  
    521.                 if (ShowValues && height > 8)
    522.                 {
    523.                     width = (int)Math.Min(Math.Max(width, textWidth), maxWidth);
    524.                 }
    525.  
    526.                 var volumeRect = ScaleAlignment == DepthOfMarketScaleAlignment.Right
    527.                     ? new Rect(new Point(r.Right - width, y),
    528.                         new Point(r.Right, y + Math.Max(currHeight + heightCorrect, 1)))
    529.                     : new Rect(new Point(r.Right - maxWidth, y),
    530.                         new Point(r.Right - (maxWidth - width), y + Math.Max(currHeight + heightCorrect, 1)));
    531.  
    532.                 visual.FillRectangle(_askVolumeBrush, volumeRect);
    533.  
    534.                 if (ShowValues && height > 8)
    535.                 {
    536.                     visual.DrawString(text, textFont, _textBrush, volumeRect,
    537.                         ScaleAlignment == DepthOfMarketScaleAlignment.Right ? XTextAlignment.Right : XTextAlignment.Left);
    538.                 }
    539.             }
    540.  
    541.             prevY = (int)GetY(md.MaxBidPrice * step + step / 2.0);
    542.  
    543.             maxPrice = Math.Min((long)Math.Round(Canvas.GetValue(r.Top) / step), md.MaxBidPrice);
    544.             minPrice = Math.Max((long)Math.Round(Canvas.GetValue(r.Bottom) / step), md.MinBidPrice);
    545.  
    546.             if (maxPrice - minPrice > 5000)
    547.             {
    548.                 return;
    549.             }
    550.  
    551.             for (var price = maxPrice; price >= minPrice; price--)
    552.             {
    553.                 var currY = (int)GetY(price * step - step / 2.0);
    554.  
    555.                 var currHeight = Math.Max((currY - prevY), 1);
    556.  
    557.                 var y = prevY;
    558.  
    559.                 prevY = currY;
    560.  
    561.                 if (!md.BidQuotes.ContainsKey(price) || y > r.Bottom)
    562.                 {
    563.                     continue;
    564.                 }
    565.  
    566.                 if (price == md.MaxBidPrice)
    567.                 {
    568.                     var quoteRect = new Rect(new Point(r.Right - maxWidth, y), new Point(r.Right, y + currHeight));
    569.  
    570.                     visual.FillRectangle(_bestBidQuoteBrush, quoteRect);
    571.                 }
    572.  
    573.                 var volume = md.BidQuotes[price];
    574.  
    575.                 var text = symbol.FormatRawSize(volume, roundValues, MinimizeValues);
    576.                 var textWidth = textFont.GetWidth(text);
    577.  
    578.                 var width = (int)Math.Min(volume * maxWidth / maxVolume, maxWidth);
    579.  
    580.                 if (ShowValues && height > 8)
    581.                 {
    582.                     width = (int)Math.Min(Math.Max(width, textWidth), maxWidth);
    583.                 }
    584.  
    585.                 var volumeRect = ScaleAlignment == DepthOfMarketScaleAlignment.Right
    586.                     ? new Rect(new Point(r.Right - width, y),
    587.                         new Point(r.Right, y + Math.Max(currHeight + heightCorrect, 1)))
    588.                     : new Rect(new Point(r.Right - maxWidth, y),
    589.                         new Point(r.Right - (maxWidth - width), y + Math.Max(currHeight + heightCorrect, 1)));
    590.  
    591.                 visual.FillRectangle(_bidVolumeBrush, volumeRect);
    592.  
    593.                 if (ShowValues && height > 8)
    594.                 {
    595.                     visual.DrawString(text, textFont, _textBrush, volumeRect,
    596.                         ScaleAlignment == DepthOfMarketScaleAlignment.Right ? XTextAlignment.Right : XTextAlignment.Left);
    597.                 }
    598.             }
    599.         }
    600.  
    601.         public override void ApplyColors(IChartTheme theme)
    602.         {
    603.             BidVolumeColor = theme.PaletteColor6;
    604.             AskVolumeColor = theme.PaletteColor7;
    605.             TextColor = theme.ChartFontColor;
    606.  
    607.             base.ApplyColors(theme);
    608.         }
    609.  
    610.         public override void CopyTemplate(IndicatorBase indicator, bool style)
    611.         {
    612.             var i = (DepthOfMarketIndicator)indicator;
    613.  
    614.             ScaleWidth = i.ScaleWidth;
    615.             ScaleAlignment = i.ScaleAlignment;
    616.             AddMargins = i.AddMargins;
    617.             ShowValues = i.ShowValues;
    618.             MinimizeValues = i.MinimizeValues;
    619.  
    620.             ScaleVolumeParam.Copy(i.ScaleVolumeParam);
    621.             RoundValuesParam.Copy(i.RoundValuesParam);
    622.  
    623.             BidQuoteColor = i.BidQuoteColor;
    624.             BestBidQuoteColor = i.BestBidQuoteColor;
    625.             AskQuoteColor = i.AskQuoteColor;
    626.             BestAskQuoteColor = i.BestAskQuoteColor;
    627.             EmptyQuoteColor = i.EmptyQuoteColor;
    628.             BidVolumeColor = i.BidVolumeColor;
    629.             AskVolumeColor = i.AskVolumeColor;
    630.             TextColor = i.TextColor;
    631.             BackColor = i.BackColor;
    632.  
    633.             OnPropertyChanged(nameof(ScaleVolume));
    634.  
    635.             base.CopyTemplate(indicator, style);
    636.         }
    637.     }
    638. }
     
    #1 Support, 26 июл 2019
    Последнее редактирование: 26 июл 2019