Histogram

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

  1. Support

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

    Регистрация:
    5 сен 2015
    Сообщения:
    1 023
    Симпатии:
    195
    Код индикатора Histogram
    1. //------------------------------------------------------------------------------
    2. //
    3. // Индикатор Histogram. Copyright (c) 2019 Ilya Smirnov. All rights reserved.
    4. //
    5. //------------------------------------------------------------------------------
    6.  
    7. using System;
    8. using System.Collections.Generic;
    9. using System.ComponentModel;
    10. using System.Runtime.Serialization;
    11. using System.Windows;
    12. using System.Windows.Media;
    13. using TigerTrade.Chart.Base.Enums;
    14. using TigerTrade.Chart.Data;
    15. using TigerTrade.Chart.Indicators.Common;
    16. using TigerTrade.Chart.Indicators.Enums;
    17. using TigerTrade.Core.UI.Converters;
    18. using TigerTrade.Core.Utils.Time;
    19. using TigerTrade.Dx;
    20.  
    21. namespace TigerTrade.Chart.Indicators.Custom
    22. {
    23.     [DataContract(Name = "HistogramPeriodType", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    24.     [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    25.     public enum HistogramPeriodType
    26.     {
    27.         [EnumMember(Value = "Minute"), Description("Минута")]
    28.         Minute,
    29.         [EnumMember(Value = "Hour"), Description("Час")]
    30.         Hour,
    31.         [EnumMember(Value = "Day"), Description("День")]
    32.         Day,
    33.         [EnumMember(Value = "Week"), Description("Неделя")]
    34.         Week,
    35.         [EnumMember(Value = "Month"), Description("Месяц")]
    36.         Month,
    37.         [EnumMember(Value = "AllBars"), Description("Все бары")]
    38.         AllBars,
    39.         [EnumMember(Value = "CustomDate"), Description("Свой интервал")]
    40.         CustomDate
    41.     }
    42.  
    43.     [DataContract(Name = "HistogramViewType", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    44.     [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    45.     public enum HistogramViewType
    46.     {
    47.         [EnumMember(Value = "Volume"), Description("Volume")]
    48.         Volume,
    49.         [EnumMember(Value = "Trades"), Description("Trades")]
    50.         Trades,
    51.         [EnumMember(Value = "Delta"), Description("Delta")]
    52.         Delta,
    53.         [EnumMember(Value = "BidAsk"), Description("Bid x Ask")]
    54.         BidAsk,
    55.     }
    56.  
    57.     [DataContract(Name = "HistogramCellViewType", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    58.     [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    59.     public enum HistogramCellViewType
    60.     {
    61.         [EnumMember(Value = "Solid"), Description("Без отступов")]
    62.         Solid,
    63.         [EnumMember(Value = "Bars"), Description("С отступами")]
    64.         Bars,
    65.         [EnumMember(Value = "BorderedBars"), Description("С границей")]
    66.         BorderedBars
    67.     }
    68.  
    69.     [DataContract(Name = "HistogramIndicator", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    70.     [Indicator("Z_Histogram", "*Histogram", true, Type = typeof(HistogramIndicator))]
    71.     internal sealed class HistogramIndicator : IndicatorBase
    72.     {
    73.         private HistogramPeriodType _periodType;
    74.  
    75.         [DataMember(Name = "PeriodType")]
    76.         [Category("Период"), DisplayName("Интервал")]
    77.         public HistogramPeriodType PeriodType
    78.         {
    79.             get => _periodType;
    80.             set
    81.             {
    82.                 if (value == _periodType)
    83.                 {
    84.                     return;
    85.                 }
    86.  
    87.                 _periodType = value;
    88.  
    89.                 _periodValue = _periodType == HistogramPeriodType.Minute ? 15 : 1;
    90.  
    91.                 Clear();
    92.  
    93.                 OnPropertyChanged();
    94.                 OnPropertyChanged(nameof(PeriodValue));
    95.                 OnPropertyChanged(nameof(PeriodRevers));
    96.                 OnPropertyChanged(nameof(StartDate));
    97.                 OnPropertyChanged(nameof(EndDate));
    98.             }
    99.         }
    100.  
    101.         private int _periodValue;
    102.  
    103.         [DataMember(Name = "PeriodValue")]
    104.         [Category("Период"), DisplayName("Значение")]
    105.         public int PeriodValue
    106.         {
    107.             get => _periodValue;
    108.             set
    109.             {
    110.                 value = Math.Max(1, value);
    111.  
    112.                 if (value == _periodValue)
    113.                 {
    114.                     return;
    115.                 }
    116.  
    117.                 _periodValue = value;
    118.  
    119.                 Clear();
    120.  
    121.                 OnPropertyChanged();
    122.             }
    123.         }
    124.  
    125.         private bool _periodRevers;
    126.  
    127.         [DataMember(Name = "PeriodRevers")]
    128.         [Category("Период"), DisplayName("От последнего бара")]
    129.         public bool PeriodRevers
    130.         {
    131.             get => _periodRevers;
    132.             set
    133.             {
    134.                 if (value == _periodRevers)
    135.                 {
    136.                     return;
    137.                 }
    138.  
    139.                 _periodRevers = value;
    140.  
    141.                 Clear();
    142.  
    143.                 OnPropertyChanged();
    144.             }
    145.         }
    146.  
    147.         private DateTime? _startDate;
    148.  
    149.         [DataMember(Name = "StartDate")]
    150.         [Category("Период"), DisplayName("Начальная дата")]
    151.         public DateTime? StartDate
    152.         {
    153.             get => _startDate;
    154.             set
    155.             {
    156.                 if (value.Equals(_startDate))
    157.                 {
    158.                     return;
    159.                 }
    160.  
    161.                 _startDate = value;
    162.  
    163.                 Clear();
    164.  
    165.                 OnPropertyChanged();
    166.             }
    167.         }
    168.  
    169.         private DateTime? _endDate;
    170.  
    171.         [DataMember(Name = "EndDate")]
    172.         [Category("Период"), DisplayName("Конечная дата")]
    173.         public DateTime? EndDate
    174.         {
    175.             get => _endDate;
    176.             set
    177.             {
    178.                 if (value.Equals(_endDate))
    179.                 {
    180.                     return;
    181.                 }
    182.  
    183.                 _endDate = value;
    184.  
    185.                 Clear();
    186.  
    187.                 OnPropertyChanged();
    188.             }
    189.         }
    190.  
    191.         private HistogramViewType _histogramViewType;
    192.  
    193.         [DataMember(Name = "HistogramViewType"), DefaultValue(HistogramViewType.Volume)]
    194.         [Category("Параметры"), DisplayName("Вид гистограммы")]
    195.         public HistogramViewType HistogramViewType
    196.         {
    197.             get => _histogramViewType;
    198.             set
    199.             {
    200.                 if (value == _histogramViewType)
    201.                 {
    202.                     return;
    203.                 }
    204.  
    205.                 _histogramViewType = value;
    206.  
    207.                 OnPropertyChanged();
    208.             }
    209.         }
    210.  
    211.         private HistogramCellViewType _histogramCellViewType;
    212.  
    213.         [DataMember(Name = "HistogramCellViewType"), DefaultValue(HistogramCellViewType.Solid)]
    214.         [Category("Параметры"), DisplayName("Вид ячейки")]
    215.         public HistogramCellViewType HistogramCellViewType
    216.         {
    217.             get => _histogramCellViewType;
    218.             set
    219.             {
    220.                 if (value == _histogramCellViewType)
    221.                 {
    222.                     return;
    223.                 }
    224.  
    225.                 _histogramCellViewType = value;
    226.  
    227.                 OnPropertyChanged();
    228.             }
    229.         }
    230.  
    231.         private bool _histogramGradient;
    232.  
    233.         [DataMember(Name = "HistogramGradient"), DefaultValue(true)]
    234.         [Category("Параметры"), DisplayName("Градиент")]
    235.         public bool HistogramGradient
    236.         {
    237.             get => _histogramGradient;
    238.             set
    239.             {
    240.                 if (value == _histogramGradient)
    241.                 {
    242.                     return;
    243.                 }
    244.  
    245.                 _histogramGradient = value;
    246.  
    247.                 OnPropertyChanged();
    248.             }
    249.         }
    250.  
    251.         private bool _histogramShowValues;
    252.  
    253.         [DataMember(Name = "HistogramShowValues"), DefaultValue(true)]
    254.         [Category("Параметры"), DisplayName("Отображать значения")]
    255.         public bool HistogramShowValues
    256.         {
    257.             get => _histogramShowValues;
    258.             set
    259.             {
    260.                 if (value == _histogramShowValues)
    261.                 {
    262.                     return;
    263.                 }
    264.  
    265.                 _histogramShowValues = value;
    266.  
    267.                 OnPropertyChanged();
    268.             }
    269.         }
    270.  
    271.         private bool _histogramMinimizeValues;
    272.  
    273.         [DataMember(Name = "HistogramMinimizeValues")]
    274.         [Category("Параметры"), DisplayName("Минимизировать значения")]
    275.         public bool HistogramMinimizeValues
    276.         {
    277.             get => _histogramMinimizeValues;
    278.             set
    279.             {
    280.                 if (value == _histogramMinimizeValues)
    281.                 {
    282.                     return;
    283.                 }
    284.  
    285.                 _histogramMinimizeValues = value;
    286.  
    287.                 OnPropertyChanged();
    288.             }
    289.         }
    290.  
    291.         private IndicatorIntParam _histogramRoundValueParam;
    292.  
    293.         [DataMember(Name = "HistogramRoundValuesParam")]
    294.         public IndicatorIntParam HistogramRoundValuesParam
    295.         {
    296.             get => _histogramRoundValueParam ?? (_histogramRoundValueParam = new IndicatorIntParam(0));
    297.             set => _histogramRoundValueParam = value;
    298.         }
    299.  
    300.         [DefaultValue(0)]
    301.         [Category("Параметры"), DisplayName("Округлять значения")]
    302.         public int HistogramRoundValues
    303.         {
    304.             get => HistogramRoundValuesParam.Get(SettingsLongKey);
    305.             set
    306.             {
    307.                 if (!HistogramRoundValuesParam.Set(SettingsLongKey, value, -4, 4))
    308.                 {
    309.                     return;
    310.                 }
    311.  
    312.                 OnPropertyChanged();
    313.             }
    314.         }
    315.  
    316.         private bool _histogramShowValueArea;
    317.  
    318.         [DataMember(Name = "HistogramShowValueArea"), DefaultValue(true)]
    319.         [Category("Параметры"), DisplayName("Отображать Value Area")]
    320.         public bool HistogramShowValueArea
    321.         {
    322.             get => _histogramShowValueArea;
    323.             set
    324.             {
    325.                 if (value == _histogramShowValueArea)
    326.                 {
    327.                     return;
    328.                 }
    329.  
    330.                 _histogramShowValueArea = value;
    331.  
    332.                 OnPropertyChanged();
    333.             }
    334.         }
    335.  
    336.         private bool _histogramExtendValueArea;
    337.  
    338.         [DataMember(Name = "HistogramExtendValueArea"), DefaultValue(false)]
    339.         [Category("Параметры"), DisplayName("Продлить Value Area")]
    340.         public bool HistogramExtendValueArea
    341.         {
    342.             get => _histogramExtendValueArea;
    343.             set
    344.             {
    345.                 if (value == _histogramExtendValueArea)
    346.                 {
    347.                     return;
    348.                 }
    349.  
    350.                 _histogramExtendValueArea = value;
    351.  
    352.                 OnPropertyChanged();
    353.             }
    354.         }
    355.  
    356.         private int _histogramValueAreaPercent;
    357.  
    358.         [DataMember(Name = "HistogramValueAreaPercent")]
    359.         [Category("Параметры"), DisplayName("ValueArea %")]
    360.         public int HistogramValueAreaPercent
    361.         {
    362.             get => _histogramValueAreaPercent;
    363.             set
    364.             {
    365.                 value = Math.Max(0, Math.Min(100, value));
    366.  
    367.                 if (value == 0)
    368.                 {
    369.                     value = 70;
    370.                 }
    371.  
    372.                 if (value == _histogramValueAreaPercent)
    373.                 {
    374.                     return;
    375.                 }
    376.  
    377.                 _histogramValueAreaPercent = value;
    378.  
    379.                 Clear();
    380.  
    381.                 OnPropertyChanged();
    382.             }
    383.         }
    384.  
    385.         private bool _histogramShowPoc;
    386.  
    387.         [DataMember(Name = "HistogramShowPoc"), DefaultValue(true)]
    388.         [Category("Параметры"), DisplayName("Отображать POC")]
    389.         public bool HistogramShowPoc
    390.         {
    391.             get => _histogramShowPoc;
    392.             set
    393.             {
    394.                 if (value == _histogramShowPoc)
    395.                 {
    396.                     return;
    397.                 }
    398.  
    399.                 _histogramShowPoc = value;
    400.  
    401.                 OnPropertyChanged();
    402.             }
    403.         }
    404.  
    405.         private bool _histogramExtendPoc;
    406.  
    407.         [DataMember(Name = "HistogramExtendPoc"), DefaultValue(false)]
    408.         [Category("Параметры"), DisplayName("Продлить POC")]
    409.         public bool HistogramExtendPoc
    410.         {
    411.             get => _histogramExtendPoc;
    412.             set
    413.             {
    414.                 if (value == _histogramExtendPoc)
    415.                 {
    416.                     return;
    417.                 }
    418.  
    419.                 _histogramExtendPoc = value;
    420.  
    421.                 OnPropertyChanged();
    422.             }
    423.         }
    424.  
    425.         private XBrush _volumeBrush;
    426.  
    427.         private XColor _volumeColor;
    428.  
    429.         [DataMember(Name = "VolumeColor")]
    430.         [Category("Стиль"), DisplayName("Volume")]
    431.         public XColor VolumeColor
    432.         {
    433.             get => _volumeColor;
    434.             set
    435.             {
    436.                 if (value == _volumeColor)
    437.                 {
    438.                     return;
    439.                 }
    440.  
    441.                 _volumeColor = value;
    442.  
    443.                 _volumeBrush = new XBrush(_volumeColor);
    444.  
    445.                 OnPropertyChanged();
    446.             }
    447.         }
    448.  
    449.         private XBrush _tradesBrush;
    450.  
    451.         private XColor _tradesColor;
    452.  
    453.         [DataMember(Name = "TradesColor")]
    454.         [Category("Стиль"), DisplayName("Trades")]
    455.         public XColor TradesColor
    456.         {
    457.             get => _tradesColor;
    458.             set
    459.             {
    460.                 if (value == _tradesColor)
    461.                 {
    462.                     return;
    463.                 }
    464.  
    465.                 _tradesColor = value;
    466.  
    467.                 _tradesBrush = new XBrush(_tradesColor);
    468.  
    469.                 OnPropertyChanged();
    470.             }
    471.         }
    472.  
    473.         private XBrush _deltaPlusBrush;
    474.  
    475.         private XColor _deltaPlusColor;
    476.  
    477.         [DataMember(Name = "DeltaPlusColor")]
    478.         [Category("Стиль"), DisplayName("Delta+")]
    479.         public XColor DeltaPlusColor
    480.         {
    481.             get => _deltaPlusColor;
    482.             set
    483.             {
    484.                 if (value == _deltaPlusColor)
    485.                 {
    486.                     return;
    487.                 }
    488.  
    489.                 _deltaPlusColor = value;
    490.  
    491.                 _deltaPlusBrush = new XBrush(_deltaPlusColor);
    492.  
    493.                 OnPropertyChanged();
    494.             }
    495.         }
    496.  
    497.         private XBrush _deltaMinusBrush;
    498.  
    499.         private XColor _deltaMinusColor;
    500.  
    501.         [DataMember(Name = "DeltaMinusColor")]
    502.         [Category("Стиль"), DisplayName("Delta-")]
    503.         public XColor DeltaMinusColor
    504.         {
    505.             get => _deltaMinusColor;
    506.             set
    507.             {
    508.                 if (value == _deltaMinusColor)
    509.                 {
    510.                     return;
    511.                 }
    512.  
    513.                 _deltaMinusColor = value;
    514.  
    515.                 _deltaMinusBrush = new XBrush(_deltaMinusColor);
    516.  
    517.                 OnPropertyChanged();
    518.             }
    519.         }
    520.  
    521.         private XBrush _bidBrush;
    522.  
    523.         private XColor _bidColor;
    524.  
    525.         [DataMember(Name = "BidColor")]
    526.         [Category("Стиль"), DisplayName("Bid")]
    527.         public XColor BidColor
    528.         {
    529.             get => _bidColor;
    530.             set
    531.             {
    532.                 if (value == _bidColor)
    533.                 {
    534.                     return;
    535.                 }
    536.  
    537.                 _bidColor = value;
    538.  
    539.                 _bidBrush = new XBrush(_bidColor);
    540.  
    541.                 OnPropertyChanged();
    542.             }
    543.         }
    544.  
    545.         private XBrush _askBrush;
    546.  
    547.         private XColor _askColor;
    548.  
    549.         [DataMember(Name = "AskColor")]
    550.         [Category("Стиль"), DisplayName("Ask")]
    551.         public XColor AskColor
    552.         {
    553.             get => _askColor;
    554.             set
    555.             {
    556.                 if (value == _askColor)
    557.                 {
    558.                     return;
    559.                 }
    560.  
    561.                 _askColor = value;
    562.  
    563.                 _askBrush = new XBrush(_askColor);
    564.  
    565.                 OnPropertyChanged();
    566.             }
    567.         }
    568.  
    569.         private XBrush _valueAreaBrush;
    570.  
    571.         private XColor _valueAreaColor;
    572.  
    573.         [DataMember(Name = "ValueAreaColor")]
    574.         [Category("Стиль"), DisplayName("Value Area")]
    575.         public XColor ValueAreaColor
    576.         {
    577.             get => _valueAreaColor;
    578.             set
    579.             {
    580.                 if (value == _valueAreaColor)
    581.                 {
    582.                     return;
    583.                 }
    584.  
    585.                 _valueAreaColor = value;
    586.  
    587.                 _valueAreaBrush = new XBrush(_valueAreaColor);
    588.  
    589.                 OnPropertyChanged();
    590.             }
    591.         }
    592.  
    593.         private XBrush _maximumBrush;
    594.  
    595.         private XColor _maximumColor;
    596.  
    597.         [DataMember(Name = "MaximumColor")]
    598.         [Category("Стиль"), DisplayName("POC")]
    599.         public XColor MaximumColor
    600.         {
    601.             get => _maximumColor;
    602.             set
    603.             {
    604.                 if (value == _maximumColor)
    605.                 {
    606.                     return;
    607.                 }
    608.  
    609.                 _maximumColor = value;
    610.  
    611.                 _maximumBrush = new XBrush(_maximumColor);
    612.  
    613.                 OnPropertyChanged();
    614.             }
    615.         }
    616.  
    617.         private XBrush _cellBorderBrush;
    618.  
    619.         private XPen _cellBorderPen;
    620.  
    621.         private XColor _cellBorderColor;
    622.  
    623.         [DataMember(Name = "CellBorderColor")]
    624.         [Category("Стиль"), DisplayName("Граница ячейки")]
    625.         public XColor CellBorderColor
    626.         {
    627.             get => _cellBorderColor;
    628.             set
    629.             {
    630.                 if (value == _cellBorderColor)
    631.                 {
    632.                     return;
    633.                 }
    634.  
    635.                 _cellBorderColor = value;
    636.  
    637.                 _cellBorderBrush = new XBrush(_cellBorderColor);
    638.                 _cellBorderPen = new XPen(_cellBorderBrush, 1);
    639.  
    640.                 OnPropertyChanged();
    641.             }
    642.         }
    643.  
    644.         private XBrush _textBrush;
    645.  
    646.         private XColor _textColor;
    647.  
    648.         [DataMember(Name = "TextColor")]
    649.         [Category("Стиль"), DisplayName("Текст")]
    650.         public XColor TextColor
    651.         {
    652.             get => _textColor;
    653.             set
    654.             {
    655.                 if (value == _textColor)
    656.                 {
    657.                     return;
    658.                 }
    659.  
    660.                 _textColor = value;
    661.  
    662.                 _textBrush = new XBrush(_textColor);
    663.  
    664.                 OnPropertyChanged();
    665.             }
    666.         }
    667.  
    668.         [Browsable(false)]
    669.         public override bool ShowIndicatorValues => false;
    670.  
    671.         [Browsable(false)]
    672.         public override IndicatorCalculation Calculation => IndicatorCalculation.OnEachTick;
    673.  
    674.         private List<IndicatorLabelInfo> _labels;
    675.  
    676.         private long _lastSequense;
    677.  
    678.         private RawCluster _histogram;
    679.  
    680.         public HistogramIndicator()
    681.         {
    682.             ShowIndicatorTitle = false;
    683.  
    684.             PeriodType = HistogramPeriodType.Day;
    685.             PeriodValue = 1;
    686.  
    687.             HistogramViewType = HistogramViewType.Volume;
    688.             HistogramCellViewType = HistogramCellViewType.Solid;
    689.  
    690.             HistogramGradient = true;
    691.             HistogramShowValues = true;
    692.             HistogramMinimizeValues = false;
    693.             HistogramShowValueArea = true;
    694.             HistogramValueAreaPercent = 70;
    695.             HistogramExtendValueArea = false;
    696.             HistogramShowPoc = true;
    697.             HistogramExtendPoc = false;
    698.  
    699.             VolumeColor = Color.FromArgb(255, 70, 130, 180);
    700.             TradesColor = Color.FromArgb(255, 70, 130, 180);
    701.             DeltaPlusColor = Color.FromArgb(255, 46, 139, 87);
    702.             DeltaMinusColor = Color.FromArgb(255, 178, 34, 34);
    703.             BidColor = Color.FromArgb(255, 178, 34, 34);
    704.             AskColor = Color.FromArgb(255, 70, 130, 180);
    705.             ValueAreaColor = Color.FromArgb(255, 128, 128, 128);
    706.             MaximumColor = Color.FromArgb(255, 178, 34, 34);
    707.             CellBorderColor = Color.FromArgb(255, 127, 127, 127);
    708.             TextColor = Color.FromArgb(255, 255, 255, 255);
    709.         }
    710.  
    711.         protected override void Execute()
    712.         {
    713.             if (_labels == null)
    714.             {
    715.                 _labels = new List<IndicatorLabelInfo>();
    716.             }
    717.  
    718.             if (_histogram == null)
    719.             {
    720.                 _histogram = new RawCluster(DateTime.MinValue);
    721.             }
    722.  
    723.             if (ClearData)
    724.             {
    725.                 Clear();
    726.             }
    727.  
    728.             if (PeriodType == HistogramPeriodType.CustomDate)
    729.             {
    730.                 if (_lastSequense == -1)
    731.                 {
    732.                     _histogram = new RawCluster(DateTime.MinValue);
    733.  
    734.                     for (var i = 0; i < DataProvider.Count; i++)
    735.                     {
    736.                         var cluster = DataProvider.GetRawCluster(i);
    737.  
    738.                         if (cluster.Time < StartDate || cluster.Time > EndDate)
    739.                         {
    740.                             continue;
    741.                         }
    742.  
    743.                         _histogram.AddCluster(cluster);
    744.                     }
    745.  
    746.                     _lastSequense = 1;
    747.                 }
    748.                 else
    749.                 {
    750.                     var ticks = DataProvider.GetRawTicks();
    751.  
    752.                     foreach (var tick in ticks)
    753.                     {
    754.                         _histogram.AddTick(tick, DataProvider.Scale);
    755.                     }
    756.                 }
    757.  
    758.                 _histogram.UpdateData();
    759.  
    760.                 return;
    761.             }
    762.  
    763.             if (PeriodRevers && PeriodType != HistogramPeriodType.AllBars)
    764.             {
    765.                 if (_lastSequense != DataProvider.Count)
    766.                 {
    767.                     var interval = GetTimeSeconds();
    768.  
    769.                     var lastBar = DataProvider.GetRawCluster(DataProvider.Count - 1);
    770.  
    771.                     var startTime = lastBar?.OpenTime ?? TimeHelper.GetCurrTime(DataProvider.Symbol.Exchange);
    772.  
    773.                     startTime = startTime.AddSeconds(-interval);
    774.  
    775.                     _histogram = new RawCluster(DateTime.MinValue);
    776.  
    777.                     for (var i = 0; i < DataProvider.Count; i++)
    778.                     {
    779.                         var cluster = DataProvider.GetRawCluster(i);
    780.  
    781.                         if (cluster.Time < startTime)
    782.                         {
    783.                             continue;
    784.                         }
    785.  
    786.                         _histogram.AddCluster(cluster);
    787.                     }
    788.  
    789.                     _lastSequense = DataProvider.Count;
    790.                 }
    791.                 else
    792.                 {
    793.                     var ticks = DataProvider.GetRawTicks();
    794.  
    795.                     foreach (var tick in ticks)
    796.                     {
    797.                         _histogram.AddTick(tick, DataProvider.Scale);
    798.                     }
    799.                 }
    800.  
    801.                 _histogram.UpdateData();
    802.  
    803.                 return;
    804.             }
    805.  
    806.             var timeOffset = TimeHelper.GetSessionOffset(DataProvider.Symbol.Exchange);
    807.  
    808.             var lastCluster = DataProvider.GetRawCluster(DataProvider.Count - 1);
    809.  
    810.             if (lastCluster == null)
    811.             {
    812.                 return;
    813.             }
    814.  
    815.             var currSequence = GetSequence(lastCluster.Time, timeOffset);
    816.  
    817.             if (_lastSequense != currSequence)
    818.             {
    819.                 _histogram = new RawCluster(DateTime.MinValue);
    820.  
    821.                 _lastSequense = currSequence;
    822.  
    823.                 for (var i = DataProvider.Count - 1; i >= 0; i--)
    824.                 {
    825.                     var cluster = DataProvider.GetRawCluster(i);
    826.  
    827.                     var newSequence = GetSequence(cluster.Time, timeOffset);
    828.  
    829.                     if (_lastSequense != newSequence)
    830.                     {
    831.                         break;
    832.                     }
    833.  
    834.                     _histogram.AddCluster(cluster);
    835.                 }
    836.             }
    837.             else
    838.             {
    839.                 var ticks = DataProvider.GetRawTicks();
    840.  
    841.                 foreach (var tick in ticks)
    842.                 {
    843.                     _histogram.AddTick(tick, DataProvider.Scale);
    844.                 }
    845.             }
    846.  
    847.             _histogram.UpdateData();
    848.         }
    849.  
    850.         private int GetSequence(DateTime date, double offset)
    851.         {
    852.             var cycleBase = ChartPeriodType.Hour;
    853.  
    854.             switch (PeriodType)
    855.             {
    856.                 case HistogramPeriodType.Minute:
    857.  
    858.                     cycleBase = ChartPeriodType.Minute;
    859.  
    860.                     break;
    861.  
    862.                 case HistogramPeriodType.Hour:
    863.  
    864.                     cycleBase = ChartPeriodType.Hour;
    865.  
    866.                     break;
    867.  
    868.                 case HistogramPeriodType.Day:
    869.  
    870.                     cycleBase = ChartPeriodType.Day;
    871.  
    872.                     break;
    873.  
    874.                 case HistogramPeriodType.Week:
    875.  
    876.                     cycleBase = ChartPeriodType.Week;
    877.  
    878.                     break;
    879.  
    880.                 case HistogramPeriodType.Month:
    881.  
    882.                     cycleBase = ChartPeriodType.Month;
    883.  
    884.                     break;
    885.  
    886.                 case HistogramPeriodType.AllBars:
    887.  
    888.                     return 0;
    889.             }
    890.  
    891.             return DataProvider.Period.GetSequence(cycleBase, PeriodValue, date, offset);
    892.         }
    893.  
    894.         public int GetTimeSeconds()
    895.         {
    896.             switch (PeriodType)
    897.             {
    898.                 case HistogramPeriodType.Minute:
    899.  
    900.                     return PeriodValue * 60;
    901.  
    902.                 case HistogramPeriodType.Hour:
    903.  
    904.                     return PeriodValue * 60 * 60;
    905.  
    906.                 case HistogramPeriodType.Day:
    907.  
    908.                     return PeriodValue * 60 * 60 * 24;
    909.  
    910.                 case HistogramPeriodType.Week:
    911.  
    912.                     return PeriodValue * 60 * 60 * 24 * 7;
    913.  
    914.                 case HistogramPeriodType.Month:
    915.  
    916.                     return PeriodValue * 60 * 60 * 24 * 30;
    917.  
    918.                 default:
    919.  
    920.                     return 0;
    921.             }
    922.         }
    923.  
    924.         private void Clear()
    925.         {
    926.             _lastSequense = -1;
    927.         }
    928.  
    929.         public override void Render(DxVisualQueue visual)
    930.         {
    931.             _labels.Clear();
    932.  
    933.             if (_histogram == null)
    934.             {
    935.                 return;
    936.             }
    937.  
    938.             var dp = DataProvider;
    939.             var step = dp.Step;
    940.             var symbol = dp.Symbol;
    941.  
    942.             var rect = Canvas.Rect;
    943.  
    944.             var width = rect.Width * 0.2;
    945.  
    946.             var heightCorrect = HistogramCellViewType == HistogramCellViewType.Bars ||
    947.                                 HistogramCellViewType == HistogramCellViewType.BorderedBars
    948.                 ? -1
    949.                 : 0;
    950.  
    951.             var height = Math.Max(GetY(0.0) - GetY(dp.Step), 1);
    952.  
    953.             var fontSize = Math.Min(height + heightCorrect - 2, 18) * 96.0 / 72.0;
    954.  
    955.             fontSize = Math.Min(fontSize, Canvas.ChartFont.Size);
    956.  
    957.             var textFont = new XFont(Canvas.ChartFont.Name, fontSize);
    958.  
    959.             var minPrice = (long)(Canvas.MinY / step) - 1;
    960.             var maxPrice = (long)(Canvas.MaxY / step) + 1;
    961.  
    962.             if (maxPrice - minPrice > 100000)
    963.             {
    964.                 return;
    965.             }
    966.  
    967.             var valueArea = HistogramShowValueArea ? _histogram.GetValueArea(HistogramValueAreaPercent) : null;
    968.  
    969.             maxPrice = Math.Min(_histogram.High, maxPrice + 1);
    970.             minPrice = Math.Max(_histogram.Low, minPrice - 1);
    971.  
    972.             var prevY = (int)GetY(maxPrice * step + step / 2.0);
    973.  
    974.             var roundValues = HistogramRoundValues;
    975.  
    976.             var maxValues = _histogram.MaxValues;
    977.  
    978.             for (var price = maxPrice; price >= minPrice; price--)
    979.             {
    980.                 var currY = (int)GetY(price * step - step / 2.0);
    981.  
    982.                 var currHeight = Math.Max((currY - prevY) + heightCorrect, 1);
    983.  
    984.                 var y = prevY;
    985.  
    986.                 prevY = currY;
    987.  
    988.                 var item = _histogram.GetItem(price);
    989.  
    990.                 if (item == null)
    991.                 {
    992.                     continue;
    993.                 }
    994.  
    995.                 var barWidth = 0.0;
    996.                 var valueText = "";
    997.  
    998.                 switch (HistogramViewType)
    999.                 {
    1000.                     case HistogramViewType.Volume:
    1001.                         {
    1002.                             barWidth = width / maxValues.MaxVolume * item.Volume;
    1003.  
    1004.                             var fillBrush = HistogramGradient
    1005.                                 ? new XBrush(VolumeColor.ChangeOpacity(item.Volume, maxValues.MaxVolume,
    1006.                                     Canvas.Theme.ChartBackColor))
    1007.                                 : _volumeBrush;
    1008.  
    1009.                             var fillRect = new Rect(rect.Left, y, barWidth, currHeight);
    1010.  
    1011.                             visual.FillRectangle(fillBrush, fillRect);
    1012.  
    1013.                             valueText = symbol.FormatRawSize(item.Volume, roundValues, HistogramMinimizeValues);
    1014.  
    1015.                             break;
    1016.                         }
    1017.  
    1018.                     case HistogramViewType.Trades:
    1019.                         {
    1020.                             barWidth = width / maxValues.MaxTrades * item.Trades;
    1021.  
    1022.                             var fillBrush = HistogramGradient
    1023.                                 ? new XBrush(TradesColor.ChangeOpacity(item.Trades, maxValues.MaxTrades,
    1024.                                     Canvas.Theme.ChartBackColor))
    1025.                                 : _tradesBrush;
    1026.  
    1027.                             var fillRect = new Rect(rect.Left, y, barWidth, currHeight);
    1028.  
    1029.                             visual.FillRectangle(fillBrush, fillRect);
    1030.  
    1031.                             valueText = symbol.FormatTrades(item.Trades, roundValues, HistogramMinimizeValues);
    1032.  
    1033.                             break;
    1034.                         }
    1035.                     case HistogramViewType.Delta:
    1036.                         {
    1037.                             var maxDelta = Math.Max(maxValues.MaxDelta, -maxValues.MinDelta);
    1038.  
    1039.                             barWidth = width / maxDelta * Math.Abs(item.Delta);
    1040.  
    1041.                             var fillBrush = item.Delta > 0
    1042.                                 ? (HistogramGradient
    1043.                                     ? new XBrush(DeltaPlusColor.ChangeOpacity(item.Delta, maxDelta,
    1044.                                         Canvas.Theme.ChartBackColor))
    1045.                                     : _deltaPlusBrush)
    1046.                                 : (HistogramGradient
    1047.                                     ? new XBrush(DeltaMinusColor.ChangeOpacity(-item.Delta, maxDelta,
    1048.                                         Canvas.Theme.ChartBackColor))
    1049.                                     : _deltaMinusBrush);
    1050.  
    1051.                             var fillRect = new Rect(rect.Left, y, barWidth, currHeight);
    1052.  
    1053.                             visual.FillRectangle(fillBrush, fillRect);
    1054.  
    1055.                             valueText = symbol.FormatRawSize(item.Delta, roundValues, HistogramMinimizeValues);
    1056.  
    1057.                             break;
    1058.                         }
    1059.                     case HistogramViewType.BidAsk:
    1060.                         {
    1061.                             barWidth = width / maxValues.MaxVolume * item.Volume;
    1062.  
    1063.                             var redWidth = barWidth / item.Volume * item.Bid;
    1064.  
    1065.                             var bidBrush = HistogramGradient
    1066.                                 ? new XBrush(BidColor.ChangeOpacity(item.Bid,
    1067.                                     Math.Max(maxValues.MaxBid, maxValues.MaxAsk), Canvas.Theme.ChartBackColor))
    1068.                                 : _bidBrush;
    1069.  
    1070.                             var bidRect = new Rect(rect.Left, y, redWidth, currHeight);
    1071.  
    1072.                             var askBrush = HistogramGradient
    1073.                                 ? new XBrush(AskColor.ChangeOpacity(item.Ask,
    1074.                                     Math.Max(maxValues.MaxBid, maxValues.MaxAsk), Canvas.Theme.ChartBackColor))
    1075.                                 : _askBrush;
    1076.  
    1077.                             var askRect = new Rect(rect.Left + redWidth, y, barWidth - redWidth, currHeight);
    1078.  
    1079.                             visual.FillRectangle(bidBrush, bidRect);
    1080.                             visual.FillRectangle(askBrush, askRect);
    1081.  
    1082.                             valueText = symbol.FormatRawSize(item.Volume, roundValues, HistogramMinimizeValues);
    1083.  
    1084.                             break;
    1085.                         }
    1086.                 }
    1087.  
    1088.                 if (HistogramCellViewType == HistogramCellViewType.BorderedBars &&
    1089.                     height + heightCorrect > 3)
    1090.                 {
    1091.                     visual.DrawRectangle(_cellBorderPen,
    1092.                         new Rect(rect.Left - 1, y, barWidth, currHeight - 1));
    1093.                 }
    1094.  
    1095.                 if (price == maxValues.Poc && HistogramShowPoc)
    1096.                 {
    1097.                     var pocRect = new Rect(rect.Left, y, width, currHeight);
    1098.  
    1099.                     if (HistogramExtendPoc)
    1100.                     {
    1101.                         visual.DrawLine(new XPen(_maximumBrush, 3),
    1102.                             new Point(rect.Left, y + currHeight / 2),
    1103.                             new Point(rect.Right, y + currHeight / 2));
    1104.  
    1105.                         _labels.Add(new IndicatorLabelInfo(price * step, MaximumColor));
    1106.                     }
    1107.                     else
    1108.                     {
    1109.                         visual.DrawLine(new XPen(_maximumBrush, 3),
    1110.                             new Point(rect.Left, y + currHeight / 2),
    1111.                             new Point(rect.Left + width, y + currHeight / 2));
    1112.                     }
    1113.  
    1114.                     var pocTextSize = Canvas.ChartFontBold.GetSize("POC");
    1115.  
    1116.                     visual.DrawString("POC", Canvas.ChartFontBold, _maximumBrush,
    1117.                         pocRect.Right - pocTextSize.Width, pocRect.Top - pocTextSize.Height - 4);
    1118.                 }
    1119.                 else if (valueArea != null && price == valueArea.Vah)
    1120.                 {
    1121.                     var vahRect = new Rect(rect.Left, y, width, currHeight);
    1122.  
    1123.                     if (HistogramExtendValueArea)
    1124.                     {
    1125.                         visual.DrawLine(new XPen(_valueAreaBrush, 3),
    1126.                             new Point(rect.Left, y + currHeight / 2),
    1127.                             new Point(rect.Right, y + currHeight / 2));
    1128.  
    1129.                         _labels.Add(new IndicatorLabelInfo(price * step, ValueAreaColor));
    1130.                     }
    1131.                     else
    1132.                     {
    1133.                         visual.DrawLine(new XPen(_valueAreaBrush, 3),
    1134.                             new Point(rect.Left, y + currHeight / 2),
    1135.                             new Point(rect.Left + width, y + currHeight / 2));
    1136.                     }
    1137.  
    1138.                     var vahTextSize = Canvas.ChartFontBold.GetSize("VAH");
    1139.  
    1140.                     visual.DrawString("VAH", Canvas.ChartFontBold, _valueAreaBrush,
    1141.                         vahRect.Right - vahTextSize.Width, vahRect.Top - vahTextSize.Height - 4);
    1142.                 }
    1143.                 else if (valueArea != null && price == valueArea.Val)
    1144.                 {
    1145.                     var valRect = new Rect(rect.Left, y, width, currHeight);
    1146.  
    1147.                     if (HistogramExtendValueArea)
    1148.                     {
    1149.                         visual.DrawLine(new XPen(_valueAreaBrush, 3),
    1150.                             new Point(rect.Left, y + currHeight / 2),
    1151.                             new Point(rect.Right, y + currHeight / 2));
    1152.  
    1153.                         _labels.Add(new IndicatorLabelInfo(price * step, ValueAreaColor));
    1154.                     }
    1155.                     else
    1156.                     {
    1157.                         visual.DrawLine(new XPen(_valueAreaBrush, 3),
    1158.                             new Point(rect.Left, y + currHeight / 2),
    1159.                             new Point(rect.Left + width, y + currHeight / 2));
    1160.                     }
    1161.  
    1162.                     var valTextSize = Canvas.ChartFontBold.GetSize("VAL");
    1163.  
    1164.                     visual.DrawString("VAL", Canvas.ChartFontBold, _valueAreaBrush,
    1165.                         valRect.Right - valTextSize.Width, valRect.Top - valTextSize.Height - 4);
    1166.                 }
    1167.  
    1168.                 if (HistogramShowValues && height > 7 && y > 15)
    1169.                 {
    1170.                     visual.DrawString(valueText, textFont, _textBrush,
    1171.                         new Rect(rect.Left + 2, y, width, currHeight));
    1172.                 }
    1173.             }
    1174.         }
    1175.  
    1176.         public override void GetLabels(ref List<IndicatorLabelInfo> labels)
    1177.         {
    1178.             labels.AddRange(_labels);
    1179.         }
    1180.  
    1181.         public override void CopyTemplate(IndicatorBase indicator, bool style)
    1182.         {
    1183.             var i = (HistogramIndicator)indicator;
    1184.  
    1185.             PeriodType = i.PeriodType;
    1186.             PeriodValue = i.PeriodValue;
    1187.             PeriodRevers = i.PeriodRevers;
    1188.             StartDate = i.StartDate;
    1189.             EndDate = i.EndDate;
    1190.  
    1191.             HistogramViewType = i.HistogramViewType;
    1192.             HistogramCellViewType = i.HistogramCellViewType;
    1193.             HistogramGradient = i.HistogramGradient;
    1194.             HistogramShowValues = i.HistogramShowValues;
    1195.             HistogramMinimizeValues = i.HistogramMinimizeValues;
    1196.             HistogramShowValueArea = i.HistogramShowValueArea;
    1197.             HistogramExtendValueArea = i.HistogramExtendValueArea;
    1198.             HistogramValueAreaPercent = i.HistogramValueAreaPercent;
    1199.             HistogramShowPoc = i.HistogramShowPoc;
    1200.             HistogramExtendPoc = i.HistogramExtendPoc;
    1201.  
    1202.             HistogramRoundValuesParam.Copy(i.HistogramRoundValuesParam);
    1203.  
    1204.             VolumeColor = i.VolumeColor;
    1205.             TradesColor = i.TradesColor;
    1206.             DeltaPlusColor = i.DeltaPlusColor;
    1207.             DeltaMinusColor = i.DeltaMinusColor;
    1208.             BidColor = i.BidColor;
    1209.             AskColor = i.AskColor;
    1210.             ValueAreaColor = i.ValueAreaColor;
    1211.             MaximumColor = i.MaximumColor;
    1212.             CellBorderColor = i.CellBorderColor;
    1213.             TextColor = i.TextColor;
    1214.  
    1215.             base.CopyTemplate(indicator, style);
    1216.         }
    1217.  
    1218.         public override bool GetPropertyVisibility(string propertyName)
    1219.         {
    1220.             switch (propertyName)
    1221.             {
    1222.                 case nameof(StartDate):
    1223.                 case nameof(EndDate):
    1224.  
    1225.                     return PeriodType == HistogramPeriodType.CustomDate;
    1226.  
    1227.                 case nameof(PeriodValue):
    1228.  
    1229.                     return PeriodType != HistogramPeriodType.CustomDate && PeriodType != HistogramPeriodType.AllBars;
    1230.  
    1231.                 case nameof(PeriodRevers):
    1232.  
    1233.                     return PeriodType != HistogramPeriodType.CustomDate && PeriodType != HistogramPeriodType.AllBars;
    1234.  
    1235.             }
    1236.  
    1237.             return base.GetPropertyVisibility(propertyName);
    1238.         }
    1239.     }
    1240. }
     
    #1 Support, 3 июл 2019
    Последнее редактирование: 6 июл 2019
    SmpMan нравится это.