CumulativeDelta

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

  1. Support

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

    Регистрация:
    5 сен 2015
    Сообщения:
    1 086
    Симпатии:
    219
    Код индикатора CumulativeDelta
    1. //------------------------------------------------------------------------------
    2. //
    3. // Индикатор CumulativeDelta. 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;
    14. using TigerTrade.Chart.Base.Enums;
    15. using TigerTrade.Chart.Indicators.Common;
    16. using TigerTrade.Chart.Indicators.Enums;
    17. using TigerTrade.Core.Utils.Time;
    18. using TigerTrade.Dx;
    19.  
    20. namespace TigerTrade.Chart.Indicators.Custom
    21. {
    22.     [DataContract(Name = "CumulativeDeltaIndicator", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    23.     [Indicator("X_CumulativeDelta", "*CumulativeDelta", false, Type = typeof(CumulativeDeltaIndicator))]
    24.     internal sealed class CumulativeDeltaIndicator : IndicatorBase
    25.     {
    26.         private IndicatorPeriodType _period;
    27.      
    28.         [DataMember(Name = "Period")]
    29.         [Category("Параметры"), DisplayName("Период")]
    30.         public IndicatorPeriodType Period
    31.         {
    32.             get => _period;
    33.             set
    34.             {
    35.                 if (value == _period)
    36.                 {
    37.                     return;
    38.                 }
    39.  
    40.                 _period = value;
    41.  
    42.                 Clear();
    43.  
    44.                 OnPropertyChanged();
    45.             }
    46.         }
    47.  
    48.         private IndicatorViewType _type;
    49.      
    50.         [DataMember(Name = "Type")]
    51.         [Category("Параметры"), DisplayName("Тип")]
    52.         public IndicatorViewType Type
    53.         {
    54.             get => _type;
    55.             set
    56.             {
    57.                 if (value == _type)
    58.                 {
    59.                     return;
    60.                 }
    61.  
    62.                 _type = value;
    63.              
    64.                 OnPropertyChanged();
    65.                 OnPropertyChanged(nameof(UpColor));
    66.                 OnPropertyChanged(nameof(DownColor));
    67.                 OnPropertyChanged(nameof(LineColor));
    68.                 OnPropertyChanged(nameof(LineWidth));
    69.             }
    70.         }
    71.  
    72.         private XBrush _upBrush;
    73.  
    74.         private XPen _upPen;
    75.  
    76.         private XColor _upColor;
    77.      
    78.         [DataMember(Name = "UpColor")]
    79.         [Category("Стиль"), DisplayName("Цвет при росте")]
    80.         public XColor UpColor
    81.         {
    82.             get => _upColor;
    83.             set
    84.             {
    85.                 if (value == _upColor)
    86.                 {
    87.                     return;
    88.                 }
    89.  
    90.                 _upColor = value;
    91.  
    92.                 _upBrush = new XBrush(_upColor);
    93.                 _upPen = new XPen(_upBrush, 1);
    94.              
    95.                 OnPropertyChanged();
    96.             }
    97.         }
    98.  
    99.         private XBrush _downBrush;
    100.  
    101.         private XPen _downPen;
    102.  
    103.         private XColor _downColor;
    104.      
    105.         [DataMember(Name = "DownColor")]
    106.         [Category("Стиль"), DisplayName("Цвет при падении")]
    107.         public XColor DownColor
    108.         {
    109.             get => _downColor;
    110.             set
    111.             {
    112.                 if (value == _downColor)
    113.                 {
    114.                     return;
    115.                 }
    116.  
    117.                 _downColor = value;
    118.  
    119.                 _downBrush = new XBrush(_downColor);
    120.                 _downPen = new XPen(_downBrush, 1);
    121.  
    122.                 OnPropertyChanged();
    123.             }
    124.         }
    125.  
    126.         private XBrush _lineBrush;
    127.  
    128.         private XPen _linePen;
    129.  
    130.         private XColor _lineColor;
    131.  
    132.         [DataMember(Name = "LineColor")]
    133.         [Category("Стиль"), DisplayName("Цвет линии")]
    134.         public XColor LineColor
    135.         {
    136.             get => _lineColor;
    137.             set
    138.             {
    139.                 if (value == _lineColor)
    140.                 {
    141.                     return;
    142.                 }
    143.  
    144.                 _lineColor = value;
    145.  
    146.                 _lineBrush = new XBrush(_lineColor);
    147.                 _linePen = new XPen(_lineBrush, LineWidth);
    148.  
    149.                 OnPropertyChanged();
    150.             }
    151.         }
    152.  
    153.         private int _lineWidth;
    154.  
    155.         [DataMember(Name = "LineWidth")]
    156.         [Category("Стиль"), DisplayName("Толщина линии")]
    157.         public int LineWidth
    158.         {
    159.             get => _lineWidth;
    160.             set
    161.             {
    162.                 value = Math.Max(1, Math.Min(9, value));
    163.  
    164.                 if (value == _lineWidth)
    165.                 {
    166.                     return;
    167.                 }
    168.  
    169.                 _lineWidth = value;
    170.  
    171.                 _linePen = new XPen(_lineBrush, _lineWidth);
    172.  
    173.                 OnPropertyChanged();
    174.             }
    175.         }
    176.  
    177.         [Browsable(false)]
    178.         public override IndicatorCalculation Calculation => IndicatorCalculation.OnEachTick;
    179.  
    180.         public override bool IntegerValues => true;
    181.  
    182.         private class CumDeltaItem
    183.         {
    184.             public long Open;
    185.             public long High;
    186.             public long Low;
    187.             public long Close;
    188.             public int Seq = -1;
    189.         }
    190.  
    191.         private int _lastFullID;
    192.  
    193.         private List<CumDeltaItem> _items;
    194.         private List<CumDeltaItem> Items => _items ?? (_items = new List<CumDeltaItem>());
    195.  
    196.         private void Clear()
    197.         {
    198.             _lastFullID = 0;
    199.  
    200.             Items.Clear();
    201.         }
    202.  
    203.         public CumulativeDeltaIndicator()
    204.         {
    205.             Period = IndicatorPeriodType.Day;
    206.             Type = IndicatorViewType.Columns;
    207.  
    208.             UpColor = Color.FromArgb(255, 30, 144, 255);
    209.             DownColor = Color.FromArgb(255, 178, 34, 34);
    210.  
    211.             LineColor = Color.FromArgb(255, 30, 144, 255);
    212.             LineWidth = 1;
    213.         }
    214.  
    215.         protected override void Execute()
    216.         {
    217.             if (ClearData)
    218.             {
    219.                 Clear();
    220.             }
    221.  
    222.             var timeOffset = TimeHelper.GetSessionOffset(DataProvider.Symbol.Exchange);
    223.  
    224.             for (var i = _lastFullID; i < DataProvider.Count; i++)
    225.             {
    226.                 var cluster = DataProvider.GetRawCluster(i);
    227.  
    228.                 if (Items.Count < i + 1)
    229.                 {
    230.                     Items.Add(new CumDeltaItem());
    231.                 }
    232.  
    233.                 var item = Items[i];
    234.                 var prevItem = Items.Count > 1 ? Items[i - 1] : new CumDeltaItem();
    235.  
    236.                 var sequence = 1;
    237.  
    238.                 switch (Period)
    239.                 {
    240.                     case IndicatorPeriodType.Day:
    241.  
    242.                         sequence = DataProvider.Period.GetSequence(ChartPeriodType.Day, 1, cluster.Time, timeOffset);
    243.  
    244.                         break;
    245.  
    246.                     case IndicatorPeriodType.Week:
    247.  
    248.                         sequence = DataProvider.Period.GetSequence(ChartPeriodType.Week, 1, cluster.Time, timeOffset);
    249.  
    250.                         break;
    251.  
    252.                     case IndicatorPeriodType.Month:
    253.  
    254.                         sequence = DataProvider.Period.GetSequence(ChartPeriodType.Month, 1, cluster.Time, timeOffset);
    255.  
    256.                         break;
    257.                 }
    258.  
    259.                 var cumDeltaValue = 0L;
    260.  
    261.                 if (sequence == prevItem.Seq)
    262.                 {
    263.                     cumDeltaValue = prevItem.Close;
    264.                 }
    265.  
    266.                 item.Seq = sequence;
    267.  
    268.                 item.Open = cumDeltaValue;
    269.  
    270.                 cumDeltaValue += cluster.Delta;
    271.  
    272.                 item.Close = cumDeltaValue;
    273.  
    274.                 item.High = cumDeltaValue + (cluster.DeltaHigh - cluster.Delta);
    275.                 item.Low = cumDeltaValue + (cluster.DeltaLow - cluster.Delta);
    276.             }
    277.  
    278.             _lastFullID = Math.Max(DataProvider.Count - 2, 0);
    279.         }
    280.  
    281.         public override bool GetMinMax(out double min, out double max)
    282.         {
    283.             min = double.MaxValue;
    284.             max = double.MinValue;
    285.  
    286.             if (Items.Count == 0)
    287.             {
    288.                 return false;
    289.             }
    290.  
    291.             var longMin = long.MaxValue;
    292.             var longMax = long.MinValue;
    293.  
    294.             if (Type == IndicatorViewType.Candles)
    295.             {
    296.                 for (var i = 0; i < Canvas.Count; i++)
    297.                 {
    298.                     var index = Canvas.GetIndex(i);
    299.  
    300.                     if (index < 0 || index >= Items.Count)
    301.                     {
    302.                         continue;
    303.                     }
    304.  
    305.                     var item = Items[index];
    306.  
    307.                     if (longMin > item.Low)
    308.                     {
    309.                         longMin = item.Low;
    310.                     }
    311.  
    312.                     if (longMax < item.High)
    313.                     {
    314.                         longMax = item.High;
    315.                     }
    316.                 }
    317.             }
    318.             else
    319.             {
    320.                 for (var i = 0; i < Canvas.Count; i++)
    321.                 {
    322.                     var index = Canvas.GetIndex(i);
    323.  
    324.                     if (index < 0 || index >= Items.Count)
    325.                     {
    326.                         continue;
    327.                     }
    328.  
    329.                     var item = Items[index];
    330.  
    331.                     if (longMin > item.Close)
    332.                     {
    333.                         longMin = item.Close;
    334.                     }
    335.  
    336.                     if (longMax < item.Close)
    337.                     {
    338.                         longMax = item.Close;
    339.                     }
    340.                 }
    341.             }
    342.  
    343.             if (longMin > longMax)
    344.             {
    345.                 return false;
    346.             }
    347.  
    348.             min = (double) DataProvider.Symbol.GetSize(longMin);
    349.             max = (double) DataProvider.Symbol.GetSize(longMax);
    350.  
    351.             return true;
    352.         }
    353.  
    354.         public override void Render(DxVisualQueue visual)
    355.         {
    356.             var symbol = DataProvider.Symbol;
    357.  
    358.             switch (Type)
    359.             {
    360.                 case IndicatorViewType.Candles:
    361.                     {
    362.                         var width = (int)(Canvas.ColumnWidth * Canvas.ColumnPercent + 0.4);
    363.                         var halfWith = Math.Max((int)(width / 2.0), 1.0);
    364.  
    365.                         for (var i = 0; i < Canvas.Count; i++)
    366.                         {
    367.                             var index = Canvas.GetIndex(i);
    368.  
    369.                             if (index < 0 || index >= Items.Count)
    370.                             {
    371.                                 continue;
    372.                             }
    373.  
    374.                             var item = Items[index];
    375.  
    376.                             var isUp = item.Close > item.Open;
    377.  
    378.                             var centerX = (int)Canvas.GetX(index);
    379.                             var openY = (int)GetY(symbol.GetSize(item.Open));
    380.                             var highY = (int)GetY(symbol.GetSize(item.High));
    381.                             var lowY = (int)GetY(symbol.GetSize(item.Low));
    382.                             var closeY = (int)GetY(symbol.GetSize(item.Close));
    383.  
    384.                             var topY = Math.Min(openY, closeY);
    385.                             var bottomY = Math.Max(openY, closeY);
    386.  
    387.                             var height = bottomY - topY;
    388.  
    389.                             var backBrush = isUp ? _upBrush : _downBrush;
    390.                             var backPen = isUp ? _upPen : _downPen;
    391.  
    392.                             if (height == 0 || width <= 1)
    393.                             {
    394.                                 if (highY == lowY)
    395.                                 {
    396.                                     lowY++;
    397.                                 }
    398.  
    399.                                 visual.DrawLine(backPen,
    400.                                     new Point(centerX, highY),
    401.                                     new Point(centerX, lowY));
    402.                             }
    403.                             else
    404.                             {
    405.                                 visual.DrawLine(backPen,
    406.                                     new Point(centerX, highY),
    407.                                     new Point(centerX, topY));
    408.  
    409.                                 visual.DrawLine(backPen,
    410.                                     new Point(centerX, bottomY),
    411.                                     new Point(centerX, lowY));
    412.                             }
    413.  
    414.                             if (width > 1)
    415.                             {
    416.                                 if (height == 0)
    417.                                 {
    418.                                     visual.DrawLine(backPen,
    419.                                         new Point(centerX - halfWith, topY),
    420.                                         new Point(centerX + halfWith + 1, topY));
    421.                                 }
    422.                                 else
    423.                                 {
    424.                                     visual.FillRectangle(backBrush,
    425.                                         new Rect(centerX - halfWith, topY, halfWith * 2 + 1, height));
    426.                                 }
    427.                             }
    428.                         }
    429.                     }
    430.                     break;
    431.  
    432.                 case IndicatorViewType.Columns:
    433.                     {
    434.                         var zeroPoint = GetY(0.0);
    435.  
    436.                         var width = Math.Max(Canvas.ColumnWidth - 1, 1);
    437.  
    438.                         for (var i = 0; i < Canvas.Count; i++)
    439.                         {
    440.                             var index = Canvas.GetIndex(i);
    441.  
    442.                             if (index < 0 || index >= Items.Count)
    443.                             {
    444.                                 continue;
    445.                             }
    446.  
    447.                             var item = Items[index];
    448.  
    449.                             var x = Canvas.GetX(index);
    450.                             var y = GetY(symbol.GetSize(item.Open));
    451.                             var h = (int)zeroPoint - (int)y;
    452.  
    453.                             var isUp = h > 0;
    454.  
    455.                             if (h < 0.0)
    456.                             {
    457.                                 y += h;
    458.                                 h = -h;
    459.                             }
    460.  
    461.                             h = Math.Max(1, h);
    462.  
    463.                             if (width > 1.0)
    464.                             {
    465.                                 var rect = new Rect(x - width / 2.0, y, width, h);
    466.  
    467.                                 visual.FillRectangle(isUp ? _upBrush : _downBrush, rect);
    468.                             }
    469.                             else
    470.                             {
    471.                                 visual.DrawLine(isUp ? _upPen : _downPen, x, y, x, y + h);
    472.                             }
    473.                         }
    474.                     }
    475.                     break;
    476.  
    477.                 case IndicatorViewType.Line:
    478.                     {
    479.                         if (Items.Count < 2)
    480.                         {
    481.                             return;
    482.                         }
    483.  
    484.                         var points = new Point[Canvas.Count];
    485.  
    486.                         for (var i = 0; i < Canvas.Count; i++)
    487.                         {
    488.                             var index = Canvas.GetIndex(i);
    489.  
    490.                             if (index < 0 || index >= Items.Count)
    491.                             {
    492.                                 continue;
    493.                             }
    494.  
    495.                             var item = Items[index];
    496.  
    497.                             var x = Canvas.GetX(index);
    498.                             var y = GetY(symbol.GetSize(item.Open));
    499.  
    500.                             points[i] = new Point(x, y);
    501.                         }
    502.  
    503.                         visual.DrawLines(_linePen, points);
    504.                     }
    505.                     break;
    506.             }
    507.         }
    508.  
    509.         public override List<IndicatorValueInfo> GetValues(int cursorPos)
    510.         {
    511.             var info = new List<IndicatorValueInfo>();
    512.  
    513.             if (cursorPos >= 0 && cursorPos < Items.Count)
    514.             {
    515.                 var s = Canvas.FormatValue((double)DataProvider.Symbol.GetSize(Items[cursorPos].Close));
    516.  
    517.                 info.Add(new IndicatorValueInfo(s,
    518.                     Type == IndicatorViewType.Line ? _lineBrush : Canvas.Theme.ChartFontBrush));
    519.             }
    520.  
    521.             return info;
    522.         }
    523.  
    524.         public override void GetLabels(ref List<IndicatorLabelInfo> labels)
    525.         {
    526.             if (Items.Count == 0)
    527.             {
    528.                 return;
    529.             }
    530.  
    531.             if (DataProvider.Count <= Canvas.Start)
    532.             {
    533.                 return;
    534.             }
    535.  
    536.             var index = DataProvider.Count - 1 - Canvas.Start;
    537.  
    538.             if (index < 0 && index >= Items.Count)
    539.             {
    540.                 return;
    541.             }
    542.  
    543.             var item = Items[index];
    544.  
    545.             var lastValue = (double)DataProvider.Symbol.GetSize(item.Close);
    546.  
    547.             if (Type == IndicatorViewType.Line)
    548.             {
    549.                 labels.Add(new IndicatorLabelInfo(lastValue, _lineColor));
    550.  
    551.                 return;
    552.             }
    553.  
    554.             var isUp = false;
    555.  
    556.             switch (Type)
    557.             {
    558.                 case IndicatorViewType.Line:
    559.                 case IndicatorViewType.Columns:
    560.  
    561.                     isUp = !double.IsNaN(lastValue) && lastValue > 0;
    562.  
    563.                     break;
    564.  
    565.                 case IndicatorViewType.Candles:
    566.  
    567.                     isUp = !double.IsNaN(lastValue) && item.Close > item.Open;
    568.  
    569.                     break;
    570.             }
    571.  
    572.             labels.Add(new IndicatorLabelInfo(lastValue, isUp ? UpColor : DownColor));
    573.         }
    574.  
    575.         public override void ApplyColors(IChartTheme theme)
    576.         {
    577.             UpColor = theme.PaletteColor6;
    578.             DownColor = theme.PaletteColor7;
    579.  
    580.             LineColor = theme.GetNextColor();
    581.  
    582.             base.ApplyColors(theme);
    583.         }
    584.  
    585.         public override void CopyTemplate(IndicatorBase indicator, bool style)
    586.         {
    587.             var i = (CumulativeDeltaIndicator)indicator;
    588.  
    589.             Period = i.Period;
    590.             Type = i.Type;
    591.  
    592.             UpColor = i.UpColor;
    593.             DownColor = i.DownColor;
    594.  
    595.             LineColor = i.LineColor;
    596.             LineWidth = i.LineWidth;
    597.  
    598.             base.CopyTemplate(indicator, style);
    599.         }
    600.  
    601.         public override string ToString()
    602.         {
    603.             return $"{Name} ({Period})";
    604.         }
    605.  
    606.         public override bool GetPropertyVisibility(string propertyName)
    607.         {
    608.             switch (propertyName)
    609.             {
    610.                 case "LineWidth":
    611.                 case "LineColor":
    612.  
    613.                     return Type == IndicatorViewType.Line;
    614.  
    615.                 case "UpColor":
    616.                 case "DownColor":
    617.  
    618.                     return Type != IndicatorViewType.Line;
    619.             }
    620.  
    621.             return true;
    622.         }
    623.     }
    624. }
     
    #1 Support, 6 июл 2019
    Последнее редактирование: 6 июл 2019