OpenInterest

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

  1. Support

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

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