BarTimer

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

  1. Support

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

    Регистрация:
    5 сен 2015
    Сообщения:
    1 023
    Симпатии:
    195
    Код индикатора BarTimer
    1. //------------------------------------------------------------------------------
    2. //
    3. // Индикатор BarTimer. Copyright (c) 2019 Ilya Smirnov. All rights reserved.
    4. //
    5. //------------------------------------------------------------------------------
    6.  
    7. using System;
    8. using System.ComponentModel;
    9. using System.Runtime.Serialization;
    10. using System.Windows;
    11. using System.Windows.Media;
    12. using TigerTrade.Chart.Alerts;
    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. using TigerTrade.Dx.Enums;
    21.  
    22. namespace TigerTrade.Chart.Indicators.Custom
    23. {
    24.     [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    25.     [DataContract(Name = "BarTimerLocation", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    26.     public enum BarTimerLocation
    27.     {
    28.         [EnumMember(Value = "LeftTop"), Description("Слева сверху")]
    29.         LeftTop,
    30.         [EnumMember(Value = "LeftMiddle"), Description("Слева посередине")]
    31.         LeftMiddle,
    32.         [EnumMember(Value = "LeftBottom"), Description("Слева снизу")]
    33.         LeftBottom,
    34.         [EnumMember(Value = "CenterTop"), Description("По центру сверху")]
    35.         CenterTop,
    36.         [EnumMember(Value = "CenterMiddle"), Description("По центру посередине")]
    37.         CenterMiddle,
    38.         [EnumMember(Value = "CenterBottom"), Description("По центру снизу")]
    39.         CenterBottom,
    40.         [EnumMember(Value = "RightTop"), Description("Справа сверху")]
    41.         RightTop,
    42.         [EnumMember(Value = "RightMiddle"), Description("Справа посередине")]
    43.         RightMiddle,
    44.         [EnumMember(Value = "RightBottom"), Description("Справа снизу")]
    45.         RightBottom,
    46.     }
    47.  
    48.     [DataContract(Name = "BarTimerIndicator", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    49.     [Indicator("X_BarTimer", "*BarTimer", true, Type = typeof(BarTimerIndicator))]
    50.     internal sealed class BarTimerIndicator : IndicatorBase
    51.     {
    52.         private BarTimerLocation _location;
    53.  
    54.         [DataMember(Name = "Location"), DefaultValue(BarTimerLocation.RightBottom)]
    55.         [Category("Параметры"), DisplayName("Расположение")]
    56.         public BarTimerLocation Location
    57.         {
    58.             get => _location;
    59.             set
    60.             {
    61.                 if (value == _location)
    62.                 {
    63.                     return;
    64.                 }
    65.  
    66.                 _location = value;
    67.  
    68.                 OnPropertyChanged();
    69.             }
    70.         }
    71.  
    72.         private int _offsetX;
    73.  
    74.         [DataMember(Name = "OffsetX")]
    75.         [Category("Параметры"), DisplayName("Отступ по X")]
    76.         public int OffsetX
    77.         {
    78.             get => _offsetX;
    79.             set
    80.             {
    81.                 value = Math.Max(0, Math.Min(1000, value));
    82.  
    83.                 if (value == _offsetX)
    84.                 {
    85.                     return;
    86.                 }
    87.  
    88.                 _offsetX = value;
    89.  
    90.                 OnPropertyChanged();
    91.             }
    92.         }
    93.  
    94.         private int _offsetY;
    95.  
    96.         [DataMember(Name = "OffsetY")]
    97.         [Category("Параметры"), DisplayName("Отступ по Y")]
    98.         public int OffsetY
    99.         {
    100.             get => _offsetY;
    101.             set
    102.             {
    103.                 value = Math.Max(0, Math.Min(1000, value));
    104.  
    105.                 if (value == _offsetY)
    106.                 {
    107.                     return;
    108.                 }
    109.  
    110.                 _offsetY = value;
    111.  
    112.                 OnPropertyChanged();
    113.             }
    114.         }
    115.  
    116.         private ChartAlertSettings _alert;
    117.  
    118.         [DataMember(Name = "Alert"), Browsable(true)]
    119.         [Category("Параметры"), DisplayName("Оповещение")]
    120.         public ChartAlertSettings Alert
    121.         {
    122.             get => _alert ?? (_alert = new ChartAlertSettings());
    123.             set
    124.             {
    125.                 if (Equals(value, _alert))
    126.                 {
    127.                     return;
    128.                 }
    129.  
    130.                 _alert = value;
    131.  
    132.                 OnPropertyChanged();
    133.             }
    134.         }
    135.  
    136.         private XBrush _backBrush;
    137.  
    138.         private XColor _backColor;
    139.  
    140.         [DataMember(Name = "BackColor")]
    141.         [Category("Стиль"), DisplayName("Цвет фона")]
    142.         public XColor BackColor
    143.         {
    144.             get => _backColor;
    145.             set
    146.             {
    147.                 if (value == _backColor)
    148.                 {
    149.                     return;
    150.                 }
    151.  
    152.                 _backColor = value;
    153.  
    154.                 _backBrush = new XBrush(_backColor);
    155.  
    156.                 OnPropertyChanged();
    157.             }
    158.         }
    159.  
    160.         private XBrush _borderBrush;
    161.  
    162.         private XPen _borderPen;
    163.  
    164.         private XColor _borderColor;
    165.  
    166.         [DataMember(Name = "BorderColor")]
    167.         [Category("Стиль"), DisplayName("Цвет границы")]
    168.         public XColor BorderColor
    169.         {
    170.             get => _borderColor;
    171.             set
    172.             {
    173.                 if (value == _borderColor)
    174.                 {
    175.                     return;
    176.                 }
    177.  
    178.                 _borderColor = value;
    179.  
    180.                 _borderBrush = new XBrush(_borderColor);
    181.                 _borderPen = new XPen(_borderBrush, 1);
    182.  
    183.                 OnPropertyChanged();
    184.             }
    185.         }
    186.  
    187.         private XBrush _textBrush;
    188.  
    189.         private XColor _textColor;
    190.  
    191.         [DataMember(Name = "TextColor")]
    192.         [Category("Стиль"), DisplayName("Цвет текста")]
    193.         public XColor TextColor
    194.         {
    195.             get => _textColor;
    196.             set
    197.             {
    198.                 if (value == _textColor)
    199.                 {
    200.                     return;
    201.                 }
    202.  
    203.                 _textColor = value;
    204.  
    205.                 _textBrush = new XBrush(_textColor);
    206.  
    207.                 OnPropertyChanged();
    208.             }
    209.         }
    210.  
    211.         private int _textSize;
    212.  
    213.         [DataMember(Name = "TextSize")]
    214.         [Category("Стиль"), DisplayName("Размер текста")]
    215.         public int TextSize
    216.         {
    217.             get => _textSize;
    218.             set
    219.             {
    220.                 value = Math.Max(8, Math.Min(50, value));
    221.  
    222.                 if (value == _textSize)
    223.                 {
    224.                     return;
    225.                 }
    226.  
    227.                 _textSize = value;
    228.  
    229.                 OnPropertyChanged();
    230.             }
    231.         }
    232.  
    233.         [Browsable(false)]
    234.         public override bool ShowIndicatorValues => false;
    235.  
    236.         [Browsable(false)]
    237.         public override bool ShowIndicatorLabels => false;
    238.  
    239.         [Browsable(false)]
    240.         public override IndicatorCalculation Calculation => IndicatorCalculation.OnEachTick;
    241.  
    242.         private DateTime _lastDateTime;
    243.         private long _lastDiff = long.MinValue;
    244.        
    245.         public BarTimerIndicator()
    246.         {
    247.             ShowIndicatorTitle = false;
    248.  
    249.             Location = BarTimerLocation.RightBottom;
    250.  
    251.             OffsetX = 10;
    252.             OffsetY = 10;
    253.  
    254.             BackColor = Colors.Black;
    255.             BorderColor = Colors.Silver;
    256.             TextColor = Colors.White;
    257.             TextSize = 16;
    258.         }
    259.  
    260.         protected override void Execute()
    261.         {
    262.             if (ClearData)
    263.             {
    264.                 _lastDiff = long.MinValue;
    265.             }
    266.  
    267.             _lastDateTime = DateTime.Now;
    268.         }
    269.  
    270.         public override void Render(DxVisualQueue visual)
    271.         {
    272.             var lastCluster = DataProvider.GetCluster(DataProvider.Count - 1);
    273.  
    274.             if (lastCluster == null)
    275.             {
    276.                 return;
    277.             }
    278.  
    279.             var period = DataProvider.Period;
    280.  
    281.             var alert = false;
    282.  
    283.             string text;
    284.  
    285.             switch (period.Type)
    286.             {
    287.                 case ChartPeriodType.Second:
    288.                 case ChartPeriodType.Minute:
    289.                 case ChartPeriodType.Hour:
    290.  
    291.                     string format;
    292.  
    293.                     switch (period.Type)
    294.                     {
    295.                         case ChartPeriodType.Second:
    296.  
    297.                             format = @"ss";
    298.  
    299.                             break;
    300.  
    301.                         case ChartPeriodType.Minute:
    302.  
    303.                             format = @"mm\:ss";
    304.  
    305.                             break;
    306.  
    307.                         default:
    308.  
    309.                             format = @"hh\:mm\:ss";
    310.  
    311.                             break;
    312.                     }
    313.  
    314.                     var interval = GetTimeSeconds();
    315.  
    316.                     var closeTime = lastCluster.Time.AddSeconds(interval);
    317.                     var currentTime = TimeHelper.GetCurrTime(DataProvider.Symbol.Exchange);
    318.  
    319.                     while (closeTime < currentTime)
    320.                     {
    321.                         closeTime = closeTime.AddSeconds(interval);
    322.                     }
    323.  
    324.                     var timeDiff = closeTime - currentTime;
    325.  
    326.                     if (_lastDiff != long.MinValue && timeDiff > TimeSpan.FromTicks(_lastDiff))
    327.                     {
    328.                         alert = true;
    329.                     }
    330.  
    331.                     _lastDiff = timeDiff.Ticks;
    332.  
    333.                     text = timeDiff.ToString(format);
    334.  
    335.                     break;
    336.  
    337.                 case ChartPeriodType.Day:
    338.                 case ChartPeriodType.Week:
    339.                 case ChartPeriodType.Month:
    340.                 case ChartPeriodType.Year:
    341.  
    342.                     // not working
    343.  
    344.                     return;
    345.  
    346.                 case ChartPeriodType.Tick:
    347.  
    348.                     var ticksDiff = period.Interval - lastCluster.Trades;
    349.  
    350.                     if (_lastDiff != long.MinValue && ticksDiff > _lastDiff)
    351.                     {
    352.                         alert = true;
    353.                     }
    354.  
    355.                     _lastDiff = ticksDiff;
    356.  
    357.                     text = (ticksDiff > 0 ? ticksDiff : period.Interval).ToString("N0");
    358.  
    359.                     break;
    360.  
    361.                 case ChartPeriodType.Volume:
    362.  
    363.                     var volumeDiff = period.Interval - (long)lastCluster.Volume;
    364.  
    365.                     if (_lastDiff != long.MinValue && volumeDiff > _lastDiff)
    366.                     {
    367.                         alert = true;
    368.                     }
    369.  
    370.                     _lastDiff = volumeDiff;
    371.  
    372.                     text = (volumeDiff > 0 ? volumeDiff : period.Interval).ToString("N0");
    373.  
    374.                     break;
    375.  
    376.                 case ChartPeriodType.Delta:
    377.  
    378.                     var deltaDiff = period.Interval - (long)Math.Abs(lastCluster.Delta);
    379.  
    380.                     if (_lastDiff != long.MinValue && deltaDiff > _lastDiff)
    381.                     {
    382.                         alert = true;
    383.                     }
    384.  
    385.                     _lastDiff = deltaDiff;
    386.  
    387.                     text = (deltaDiff > 0 ? deltaDiff : period.Interval).ToString("N0");
    388.  
    389.                     break;
    390.  
    391.                 case ChartPeriodType.Range:
    392.  
    393.                     var rangeDiff = period.Interval - (long)((lastCluster.High - lastCluster.Low) / (decimal)DataProvider.Step);
    394.  
    395.                     if (_lastDiff != long.MinValue && rangeDiff > _lastDiff)
    396.                     {
    397.                         alert = true;
    398.                     }
    399.  
    400.                     _lastDiff = rangeDiff;
    401.  
    402.                     text = (rangeDiff > 0 ? rangeDiff : period.Interval).ToString("N0");
    403.  
    404.                     break;
    405.  
    406.                 default:
    407.  
    408.                     return;
    409.             }
    410.  
    411.             var font = new XFont(Canvas.ChartFont.Name, TextSize);
    412.  
    413.             var textSize = font.GetSize(text);
    414.  
    415.             var x = 0.0;
    416.             var y = 0.0;
    417.  
    418.             var width = textSize.Width + 10;
    419.             var height = textSize.Height + 10;
    420.  
    421.             var rect = Canvas.Rect;
    422.  
    423.             switch (Location)
    424.             {
    425.                 case BarTimerLocation.LeftTop:
    426.                 case BarTimerLocation.CenterTop:
    427.                 case BarTimerLocation.RightTop:
    428.  
    429.                     y = rect.Top + OffsetY - 1;
    430.  
    431.                     break;
    432.  
    433.                 case BarTimerLocation.LeftMiddle:
    434.                 case BarTimerLocation.CenterMiddle:
    435.                 case BarTimerLocation.RightMiddle:
    436.  
    437.                     y = (rect.Top + rect.Bottom - height) / 2.0;
    438.  
    439.                     break;
    440.  
    441.                 case BarTimerLocation.LeftBottom:
    442.                 case BarTimerLocation.CenterBottom:
    443.                 case BarTimerLocation.RightBottom:
    444.  
    445.                     y = rect.Bottom - OffsetY - height - 1;
    446.  
    447.                     break;
    448.             }
    449.  
    450.             switch (Location)
    451.             {
    452.                 case BarTimerLocation.LeftTop:
    453.                 case BarTimerLocation.LeftMiddle:
    454.                 case BarTimerLocation.LeftBottom:
    455.  
    456.                     x = rect.X + OffsetX - 1;
    457.  
    458.                     break;
    459.  
    460.                 case BarTimerLocation.CenterTop:
    461.                 case BarTimerLocation.CenterMiddle:
    462.                 case BarTimerLocation.CenterBottom:
    463.  
    464.                     x = rect.Right - (rect.Width + width) / 2.0;
    465.  
    466.                     x = Math.Max(x, rect.Left);
    467.  
    468.                     break;
    469.  
    470.                 case BarTimerLocation.RightTop:
    471.                 case BarTimerLocation.RightMiddle:
    472.                 case BarTimerLocation.RightBottom:
    473.  
    474.                     x = rect.Right - width - OffsetX;
    475.  
    476.                     x = Math.Max(x, rect.Left);
    477.  
    478.                     break;
    479.             }
    480.  
    481.             var rect1 = new Rect(x, y, width, height);
    482.  
    483.             visual.FillRectangle(_backBrush, rect1);
    484.             visual.DrawRectangle(_borderPen, rect1);
    485.  
    486.             visual.DrawString(text, new XFont(Canvas.ChartFont.Name, TextSize), _textBrush, rect1,
    487.                 XTextAlignment.Center);
    488.  
    489.             if (alert && Alert.IsActive)
    490.             {
    491.                 AddAlert(Alert, "BarTimer");
    492.             }
    493.         }
    494.  
    495.         public int GetTimeSeconds()
    496.         {
    497.             switch (DataProvider.Period.Type)
    498.             {
    499.                 case ChartPeriodType.Second:
    500.  
    501.                     return DataProvider.Period.Interval;
    502.  
    503.                 case ChartPeriodType.Minute:
    504.  
    505.                     return DataProvider.Period.Interval * 60;
    506.  
    507.                 case ChartPeriodType.Hour:
    508.  
    509.                     return DataProvider.Period.Interval * 60 * 60;
    510.  
    511.                 case ChartPeriodType.Day:
    512.  
    513.                     return DataProvider.Period.Interval * 60 * 60 * 24;
    514.  
    515.                 case ChartPeriodType.Week:
    516.  
    517.                     return DataProvider.Period.Interval * 60 * 60 * 24 * 7;
    518.  
    519.                 case ChartPeriodType.Month:
    520.  
    521.                     return DataProvider.Period.Interval * 60 * 60 * 24 * 30;
    522.  
    523.                 default:
    524.  
    525.                     return 0;
    526.             }
    527.         }
    528.  
    529.         public override bool CheckNeedRedraw()
    530.         {
    531.             if (DataProvider == null)
    532.             {
    533.                 return false;
    534.             }
    535.  
    536.             switch (DataProvider.Period.Type)
    537.             {
    538.                 case ChartPeriodType.Day:
    539.                 case ChartPeriodType.Week:
    540.                 case ChartPeriodType.Month:
    541.                 case ChartPeriodType.Year:
    542.                 case ChartPeriodType.Tick:
    543.                 case ChartPeriodType.Volume:
    544.                 case ChartPeriodType.Delta:
    545.                 case ChartPeriodType.Range:
    546.  
    547.                     return false;
    548.             }
    549.  
    550.             if (DateTime.Now - _lastDateTime < TimeSpan.FromSeconds(1))
    551.             {
    552.                 return false;
    553.             }
    554.  
    555.             _lastDateTime = DateTime.Now;
    556.  
    557.             return true;
    558.  
    559.         }
    560.  
    561.         public override void ApplyColors(IChartTheme theme)
    562.         {
    563.             BackColor = theme.ChartBackColor;
    564.             BorderColor = theme.ChartAxisColor;
    565.             TextColor = theme.ChartFontColor;
    566.  
    567.             base.ApplyColors(theme);
    568.         }
    569.  
    570.         public override void CopyTemplate(IndicatorBase indicator, bool style)
    571.         {
    572.             var i = (BarTimerIndicator)indicator;
    573.  
    574.             Location = i.Location;
    575.  
    576.             OffsetX = i.OffsetX;
    577.             OffsetY = i.OffsetY;
    578.  
    579.             Alert.Copy(i.Alert, !style);
    580.  
    581.             OnPropertyChanged(nameof(Alert));
    582.  
    583.             BackColor = i.BackColor;
    584.             BorderColor = i.BorderColor;
    585.             TextColor = i.TextColor;
    586.             TextSize = i.TextSize;
    587.  
    588.             base.CopyTemplate(indicator, style);
    589.         }
    590.     }
    591. }
     
    #1 Support, 6 июл 2019
    Последнее редактирование: 6 июл 2019