ClusterStatistic

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

  1. Support

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

    Регистрация:
    5 сен 2015
    Сообщения:
    984
    Симпатии:
    185
    Код индикатора ClusterStatistic
    1. //------------------------------------------------------------------------------
    2. //
    3. // Индикатор ClusterStatistic. 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.Linq;
    11. using System.Runtime.Serialization;
    12. using System.Windows;
    13. using TigerTrade.Chart.Base.Enums;
    14. using TigerTrade.Chart.Indicators.Common;
    15. using TigerTrade.Chart.Indicators.Enums;
    16. using TigerTrade.Core.UI.Converters;
    17. using TigerTrade.Core.Utils.Time;
    18. using TigerTrade.Dx;
    19.  
    20. namespace TigerTrade.Chart.Indicators.Custom
    21. {
    22.     [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    23.     [DataContract(Name = "ClusterStatisticPeriodType", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    24.     public enum ClusterStatisticPeriodType
    25.     {
    26.         [EnumMember(Value = "Day"), Description("День")]
    27.         Day,
    28.         [EnumMember(Value = "Week"), Description("Неделя")]
    29.         Week,
    30.         [EnumMember(Value = "Month"), Description("Месяц")]
    31.         Month,
    32.         [EnumMember(Value = "VisibleBars"), Description("Видимые бары")]
    33.         VisibleBars,
    34.         [EnumMember(Value = "AllBars"), Description("Все бары")]
    35.         AllBars
    36.     }
    37.  
    38.     [DataContract(Name = "ClusterStatisticIndicator", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    39.     [Indicator("X_ClusterStatistic", "*ClusterStatistic", false, Type = typeof(ClusterStatisticIndicator))]
    40.     internal sealed class ClusterStatisticIndicator : IndicatorBase
    41.     {
    42.         private ClusterStatisticPeriodType _period;
    43.  
    44.         [DataMember(Name = "Period")]
    45.         [Category("Параметры"), DisplayName("Период")]
    46.         public ClusterStatisticPeriodType Period
    47.         {
    48.             get => _period;
    49.             set
    50.             {
    51.                 if (value == _period)
    52.                 {
    53.                     return;
    54.                 }
    55.  
    56.                 _period = value;
    57.  
    58.                 OnPropertyChanged();
    59.             }
    60.         }
    61.  
    62.         private bool _minimizeValues;
    63.  
    64.         [DataMember(Name = "MinimizeValues")]
    65.         [Category("Параметры"), DisplayName("Минимизировать значения")]
    66.         public bool MinimizeValues
    67.         {
    68.             get => _minimizeValues;
    69.             set
    70.             {
    71.                 if (value == _minimizeValues)
    72.                 {
    73.                     return;
    74.                 }
    75.  
    76.                 _minimizeValues = value;
    77.  
    78.                 OnPropertyChanged();
    79.             }
    80.         }
    81.  
    82.         private IndicatorIntParam _roundValuesParam;
    83.  
    84.         [DataMember(Name = "RoundValueParam")]
    85.         public IndicatorIntParam RoundValuesParam
    86.         {
    87.             get => _roundValuesParam ?? (_roundValuesParam = new IndicatorIntParam(0));
    88.             set => _roundValuesParam = value;
    89.         }
    90.  
    91.         [DefaultValue(0)]
    92.         [Category("Параметры"), DisplayName("Округлять значения")]
    93.         public int RoundValues
    94.         {
    95.             get => RoundValuesParam.Get(SettingsLongKey);
    96.             set
    97.             {
    98.                 if (!RoundValuesParam.Set(SettingsLongKey, value, -4, 4))
    99.                 {
    100.                     return;
    101.                 }
    102.  
    103.                 OnPropertyChanged();
    104.             }
    105.         }
    106.  
    107.         private bool _ask;
    108.  
    109.         [DataMember(Name = "ShowAsk")]
    110.         [Category("Вывод данных"), DisplayName("Ask")]
    111.         public bool ShowAsk
    112.         {
    113.             get => _ask;
    114.             set
    115.             {
    116.                 if (value == _ask)
    117.                 {
    118.                     return;
    119.                 }
    120.  
    121.                 _ask = value;
    122.              
    123.                 OnPropertyChanged();
    124.             }
    125.         }
    126.  
    127.         private bool _bid;
    128.  
    129.         [DataMember(Name = "ShowBid")]
    130.         [Category("Вывод данных"), DisplayName("Bid")]
    131.         public bool ShowBid
    132.         {
    133.             get => _bid;
    134.             set
    135.             {
    136.                 if (value == _bid)
    137.                 {
    138.                     return;
    139.                 }
    140.  
    141.                 _bid = value;
    142.              
    143.                 OnPropertyChanged();
    144.             }
    145.         }
    146.  
    147.         private bool _delta;
    148.  
    149.         [DataMember(Name = "ShowDelta")]
    150.         [Category("Вывод данных"), DisplayName("Delta")]
    151.         public bool ShowDelta
    152.         {
    153.             get => _delta;
    154.             set
    155.             {
    156.                 if (value == _delta)
    157.                 {
    158.                     return;
    159.                 }
    160.  
    161.                 _delta = value;
    162.              
    163.                 OnPropertyChanged();
    164.             }
    165.         }
    166.  
    167.         private bool _volume;
    168.  
    169.         [DataMember(Name = "ShowVolume")]
    170.         [Category("Вывод данных"), DisplayName("Volume")]
    171.         public bool ShowVolume
    172.         {
    173.             get => _volume;
    174.             set
    175.             {
    176.                 if (value == _volume)
    177.                 {
    178.                     return;
    179.                 }
    180.  
    181.                 _volume = value;
    182.              
    183.                 OnPropertyChanged();
    184.             }
    185.         }
    186.  
    187.         private bool _trades;
    188.  
    189.         [DataMember(Name = "ShowTrades")]
    190.         [Category("Вывод данных"), DisplayName("Trades")]
    191.         public bool ShowTrades
    192.         {
    193.             get => _trades;
    194.             set
    195.             {
    196.                 if (value == _trades)
    197.                 {
    198.                     return;
    199.                 }
    200.  
    201.                 _trades = value;
    202.  
    203.                 OnPropertyChanged();
    204.             }
    205.         }
    206.  
    207.         [Browsable(false)]
    208.         public override bool ShowIndicatorValues => false;
    209.  
    210.         [Browsable(false)]
    211.         public override bool ShowIndicatorLabels => false;
    212.  
    213.         [Browsable(false)]
    214.         public override IndicatorCalculation Calculation => IndicatorCalculation.OnEachTick;
    215.  
    216.         public ClusterStatisticIndicator()
    217.         {
    218.             ShowIndicatorTitle = false;
    219.  
    220.             Period = ClusterStatisticPeriodType.Day;
    221.  
    222.             MinimizeValues = false;
    223.  
    224.             ShowAsk = true;
    225.             ShowBid = true;
    226.             ShowDelta = true;
    227.             ShowVolume = true;
    228.             ShowTrades = true;
    229.         }
    230.  
    231.         protected override void Execute()
    232.         {
    233.         }
    234.  
    235.         public override void Render(DxVisualQueue visual)
    236.         {
    237.             var labels = new List<string>();
    238.  
    239.             if (ShowVolume)
    240.             {
    241.                 labels.Add("Volume");
    242.             }
    243.  
    244.             if (ShowTrades)
    245.             {
    246.                 labels.Add("Trades");
    247.             }
    248.  
    249.             if (ShowDelta)
    250.             {
    251.                 labels.Add("Delta");
    252.             }
    253.  
    254.             if (ShowBid)
    255.             {
    256.                 labels.Add("Bid");
    257.             }
    258.  
    259.             if (ShowAsk)
    260.             {
    261.                 labels.Add("Ask");
    262.             }
    263.  
    264.             if (labels.Count == 0)
    265.             {
    266.                 return;
    267.             }
    268.  
    269.             var symbol = DataProvider.Symbol;
    270.  
    271.             var linePen = new XPen(new XBrush(Canvas.Theme.ChartAxisColor), 1);
    272.  
    273.             var lastSequence = -1;
    274.  
    275.             var maxVolume = 0m;
    276.             var maxTrades = 0L;
    277.             var maxDelta = 0m;
    278.  
    279.             var updateMaxValues = true;
    280.  
    281.             switch (Period)
    282.             {
    283.                 case ClusterStatisticPeriodType.AllBars:
    284.                 {
    285.                     updateMaxValues = false;
    286.  
    287.                     var count = DataProvider.Count;
    288.  
    289.                     for (var i = 0; i < count; i++)
    290.                     {
    291.                         var cluster = DataProvider.GetCluster(i);
    292.  
    293.                         if (cluster == null)
    294.                         {
    295.                             continue;
    296.                         }
    297.  
    298.                         var maxValues = cluster.MaxValues;
    299.  
    300.                         maxVolume = Math.Max(maxVolume, cluster.Volume);
    301.                         maxTrades = Math.Max(maxTrades, cluster.Trades);
    302.                         maxDelta = Math.Max(maxDelta, Math.Max(maxValues.MaxDelta, -maxValues.MinDelta));
    303.                     }
    304.  
    305.                     break;
    306.                 }
    307.                 case ClusterStatisticPeriodType.VisibleBars:
    308.                 {
    309.                     updateMaxValues = false;
    310.  
    311.                     for (var i = 0; i < Canvas.Count; i++)
    312.                     {
    313.                         var cluster = DataProvider.GetCluster(Canvas.GetIndex(i));
    314.  
    315.                         if (cluster == null)
    316.                         {
    317.                             continue;
    318.                         }
    319.  
    320.                         var maxValues = cluster.MaxValues;
    321.  
    322.                         maxVolume = Math.Max(maxVolume, cluster.Volume);
    323.                         maxTrades = Math.Max(maxTrades, cluster.Trades);
    324.                         maxDelta = Math.Max(maxDelta, Math.Max(maxValues.MaxDelta, -maxValues.MinDelta));
    325.                     }
    326.  
    327.                     break;
    328.                 }
    329.             }
    330.  
    331.             var baseHeight = (int)Canvas.ChartFont.GetHeight() + 4;
    332.  
    333.             var height = labels.Count * baseHeight + 2;
    334.  
    335.             var prevLeft = 0.0;
    336.  
    337.             var columnWidth = Canvas.ColumnWidth;
    338.             var r = Canvas.Rect;
    339.  
    340.             var roundValues = RoundValues;
    341.  
    342.             var timeOffset = TimeHelper.GetSessionOffset(DataProvider.Symbol.Exchange);
    343.  
    344.             for (var i = 0; i < Canvas.Count; i++)
    345.             {
    346.                 var x = Canvas.GetXX(i);
    347.  
    348.                 var left = x - columnWidth * .5;
    349.  
    350.                 if (i == 0)
    351.                 {
    352.                     prevLeft = left + columnWidth;
    353.  
    354.                     var backRect = new Rect(new Point(r.Left, r.Bottom - baseHeight*labels.Count - 2),
    355.                         new Point(prevLeft, r.Bottom));
    356.  
    357.                     visual.FillRectangle(XBrush.White, backRect);
    358.                     visual.FillRectangle(Canvas.Theme.ChartBackBrush, backRect);
    359.  
    360.                     for (var j = 1; j <= labels.Count; j++)
    361.                     {
    362.                         var h = baseHeight * j + 2;
    363.  
    364.                         visual.DrawLine(linePen,
    365.                             new Point(r.Left, r.Bottom - h),
    366.                             new Point(x + columnWidth * .5, r.Bottom - h));
    367.                     }
    368.                 }
    369.  
    370.                 visual.DrawLine(linePen,
    371.                     new Point(left + columnWidth, r.Bottom - height),
    372.                     new Point(left + columnWidth, r.Bottom));
    373.  
    374.                 var index = Canvas.GetIndex(i);
    375.  
    376.                 var cluster = DataProvider.GetCluster(index);
    377.  
    378.                 if (cluster == null)
    379.                 {
    380.                     continue;
    381.                 }
    382.  
    383.                 if (updateMaxValues)
    384.                 {
    385.                     var sequence = 1;
    386.  
    387.                     switch (Period)
    388.                     {
    389.                         case ClusterStatisticPeriodType.Day:
    390.  
    391.                             sequence = DataProvider.Period.GetSequence(ChartPeriodType.Day, 1, cluster.Time, timeOffset);
    392.  
    393.                             break;
    394.  
    395.                         case ClusterStatisticPeriodType.Week:
    396.  
    397.                             sequence = DataProvider.Period.GetSequence(ChartPeriodType.Week, 1, cluster.Time, timeOffset);
    398.  
    399.                             break;
    400.  
    401.                         case ClusterStatisticPeriodType.Month:
    402.  
    403.                             sequence = DataProvider.Period.GetSequence(ChartPeriodType.Month, 1, cluster.Time, timeOffset);
    404.  
    405.                             break;
    406.                     }
    407.  
    408.                     if (sequence != lastSequence)
    409.                     {
    410.                         lastSequence = sequence;
    411.  
    412.                         maxVolume = 0;
    413.                         maxTrades = 0;
    414.                         maxDelta = 0;
    415.  
    416.                         for (var j = index; j >= 0; j--)
    417.                         {
    418.                             var cl = DataProvider.GetCluster(j);
    419.  
    420.                             if (cl == null)
    421.                             {
    422.                                 continue;
    423.                             }
    424.  
    425.                             var newSequence = 1;
    426.  
    427.                             switch (Period)
    428.                             {
    429.                                 case ClusterStatisticPeriodType.Day:
    430.  
    431.                                     newSequence = DataProvider.Period.GetSequence(ChartPeriodType.Day, 1, cl.Time, timeOffset);
    432.  
    433.                                     break;
    434.  
    435.                                 case ClusterStatisticPeriodType.Week:
    436.  
    437.                                     newSequence = DataProvider.Period.GetSequence(ChartPeriodType.Week, 1, cl.Time, timeOffset);
    438.  
    439.                                     break;
    440.  
    441.                                 case ClusterStatisticPeriodType.Month:
    442.  
    443.                                     newSequence = DataProvider.Period.GetSequence(ChartPeriodType.Month, 1, cl.Time, timeOffset);
    444.  
    445.                                     break;
    446.                             }
    447.  
    448.                             if (newSequence != sequence)
    449.                             {
    450.                                 break;
    451.                             }
    452.  
    453.                             var maxValues = cl.MaxValues;
    454.  
    455.                             maxVolume = Math.Max(maxVolume, cl.Volume);
    456.                             maxTrades = Math.Max(maxTrades, cl.Trades);
    457.                             maxDelta = Math.Max(maxDelta, Math.Max(maxValues.MaxDelta, -maxValues.MinDelta));
    458.                         }
    459.                     }
    460.                 }
    461.  
    462.                 var deltaBrush = new XBrush(
    463.                         (cluster.Delta > 0
    464.                             ? Canvas.Theme.ClusterDeltaPlusColor
    465.                             : Canvas.Theme.ClusterDeltaMinusColor).ChangeOpacity(Math.Abs(cluster.Delta), maxDelta));
    466.  
    467.                 var volumeBrush = new XBrush(Canvas.Theme.ClusterVolumeColor.ChangeOpacity(cluster.Volume, maxVolume));
    468.                 var tradesBrush = new XBrush(Canvas.Theme.ClusterTradesColor.ChangeOpacity(cluster.Trades, maxTrades));
    469.                 var textBrush = new XBrush(Canvas.Theme.ClusterTextColor);
    470.  
    471.                 for (var j = 1; j <= labels.Count; j++)
    472.                 {
    473.                     var label = labels[j - 1];
    474.  
    475.                     var h = baseHeight * j + 2;
    476.  
    477.                     var cellRect = new Rect(new Point((int)left, r.Bottom - h + 1),
    478.                         new Point((int)prevLeft, r.Bottom - (h - baseHeight) + (j == 1 ? 2 : 0)));
    479.  
    480.                     var cellTextRect = new Rect(new Point(left + 2, r.Bottom - h),
    481.                         new Point(left + columnWidth - 2, r.Bottom - (h - baseHeight)));
    482.  
    483.                     var value = "";
    484.  
    485.                     switch (label)
    486.                     {
    487.                         case "Volume":
    488.  
    489.                             value = symbol.FormatSize(cluster.Volume, roundValues, MinimizeValues);
    490.  
    491.                             break;
    492.  
    493.                         case "Trades":
    494.  
    495.                             value = symbol.FormatTrades(cluster.Trades, roundValues, MinimizeValues);
    496.  
    497.                             break;
    498.  
    499.                         case "Delta":
    500.  
    501.                             value = symbol.FormatSize(cluster.Delta, roundValues, MinimizeValues);
    502.  
    503.                             break;
    504.  
    505.                         case "Bid":
    506.  
    507.                             value = symbol.FormatSize(cluster.Bid, roundValues, MinimizeValues);
    508.  
    509.                             break;
    510.  
    511.                         case "Ask":
    512.  
    513.                             value = symbol.FormatSize(cluster.Ask, roundValues, MinimizeValues);
    514.  
    515.                             break;
    516.                     }
    517.  
    518.                     if (!string.IsNullOrEmpty(value))
    519.                     {
    520.                         visual.FillRectangle(
    521.                             label == "Volume" ? volumeBrush : (label == "Trades" ? tradesBrush : deltaBrush), cellRect);
    522.  
    523.                         visual.DrawString(value, Canvas.ChartFont, textBrush, cellTextRect);
    524.                     }
    525.                 }
    526.  
    527.                 prevLeft = left;
    528.             }
    529.  
    530.             // labels
    531.  
    532.             var labelMaxWidth = labels.Aggregate(0,
    533.                 (current, label) => (int)Math.Max(current, Canvas.ChartFont.GetWidth(label))) + 5;
    534.  
    535.             visual.FillRectangle(Canvas.Theme.ChartBackBrush,
    536.                 new Rect(new Point(r.Left, r.Bottom - height), new Point(r.Left + labelMaxWidth, r.Bottom)));
    537.  
    538.             visual.DrawLine(linePen,
    539.                 new Point(r.Left + labelMaxWidth, r.Bottom - height),
    540.                 new Point(r.Left + labelMaxWidth, r.Bottom));
    541.  
    542.             var labelHeight = 2;
    543.  
    544.             foreach (var label in labels)
    545.             {
    546.                 labelHeight += baseHeight;
    547.  
    548.                 visual.DrawLine(linePen, new Point(r.Left, r.Bottom - labelHeight),
    549.                     new Point(r.Left + labelMaxWidth, r.Bottom - labelHeight));
    550.  
    551.                 var labelTextRect = new Rect(new Point(r.Left + 2, r.Bottom - labelHeight),
    552.                         new Point(r.Left + labelMaxWidth - 2, r.Bottom - (labelHeight - baseHeight)));
    553.  
    554.                 visual.DrawString(label, Canvas.ChartFont, Canvas.Theme.ChartFontBrush, labelTextRect);
    555.             }
    556.         }
    557.  
    558.         public override void CopyTemplate(IndicatorBase indicator, bool style)
    559.         {
    560.             var i = (ClusterStatisticIndicator)indicator;
    561.  
    562.             Period = i.Period;
    563.  
    564.             MinimizeValues = i.MinimizeValues;
    565.  
    566.             RoundValuesParam.Copy(i.RoundValuesParam);
    567.  
    568.             ShowAsk = i.ShowAsk;
    569.             ShowBid = i.ShowBid;
    570.             ShowDelta = i.ShowDelta;
    571.             ShowVolume = i.ShowVolume;
    572.             ShowTrades = i.ShowTrades;
    573.  
    574.             base.CopyTemplate(indicator, style);
    575.         }
    576.     }
    577. }
     
    #1 Support, 6 июл 2019
    Последнее редактирование: 6 июл 2019