BarSearch

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

  1. Support

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

    Регистрация:
    5 сен 2015
    Сообщения:
    1 047
    Симпатии:
    203
    Код индикатора BarSearch
    1.  
    2. //------------------------------------------------------------------------------
    3. //
    4. // Индикатор BarSearch. Copyright (c) 2019 Ilya Smirnov. All rights reserved.
    5. //
    6. //------------------------------------------------------------------------------
    7.  
    8. using System;
    9. using System.Collections.Generic;
    10. using System.ComponentModel;
    11. using System.Runtime.CompilerServices;
    12. using System.Runtime.Serialization;
    13. using TigerTrade.Chart.Alerts;
    14. using TigerTrade.Chart.Annotations;
    15. using TigerTrade.Chart.Base;
    16. using TigerTrade.Chart.Indicators.Common;
    17. using TigerTrade.Chart.Indicators.Enums;
    18. using TigerTrade.Chart.Indicators.Sources;
    19. using TigerTrade.Core.UI.Common;
    20. using TigerTrade.Core.UI.Converters;
    21. using TigerTrade.Core.Utils.Time;
    22. using TigerTrade.Dx;
    23.  
    24. namespace TigerTrade.Chart.Indicators.Custom
    25. {
    26.     [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    27.     [DataContract(Name = "BarSearchConditions", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    28.     public enum BarSearchConditions
    29.     {
    30.         [EnumMember(Value = "GreaterThenSource"), Description("Источник 1 > Источник 2")]
    31.         GreaterThenSource,
    32.         [EnumMember(Value = "GreaterThenValue"), Description("Источник 1 >= Значение")]
    33.         GreaterThenValue,
    34.         [EnumMember(Value = "LessThenSource"), Description("Источник 1 < Источник 2")]
    35.         LessThenSource,
    36.         [EnumMember(Value = "LessThenValue"), Description("Источник 1 <= Значение")]
    37.         LessThenValue,
    38.         [EnumMember(Value = "EqualSource"), Description("Источник 1 = Источник 2")]
    39.         EqualSource,
    40.         [EnumMember(Value = "EqualValue"), Description("Источник 1 = Значение")]
    41.         EqualValue,
    42.     }
    43.  
    44.     [TypeConverter(typeof(ExpandableObjectConverter)), ReadOnly(true)]
    45.     [DataContract(Name = "BarSearchCondition", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    46.     internal sealed class BarSearchCondition : INotifyPropertyChanged, IDynamicProperty
    47.     {
    48.         private BarSearchConditions _conditions;
    49.  
    50.         [DataMember(Name = "Condition")]
    51.         [DisplayName("Условие")]
    52.         public BarSearchConditions Condition
    53.         {
    54.             get => _conditions;
    55.             set
    56.             {
    57.                 if (Equals(value, _conditions))
    58.                 {
    59.                     return;
    60.                 }
    61.  
    62.                 _conditions = value;
    63.  
    64.                 OnPropertyChanged();
    65.                 OnPropertyChanged(nameof(Source2));
    66.                 OnPropertyChanged(nameof(Value));
    67.             }
    68.         }
    69.  
    70.         private IndicatorSourceBase _source1;
    71.        
    72.         [DataMember(Name = "Source1")]
    73.         [DisplayName("Источник 1")]
    74.         public IndicatorSourceBase Source1
    75.         {
    76.             get => _source1 ?? (_source1 = new StockSource());
    77.             set
    78.             {
    79.                 if (value == _source1)
    80.                 {
    81.                     return;
    82.                 }
    83.  
    84.                 _source1 = value;
    85.  
    86.                 OnPropertyChanged();
    87.             }
    88.         }
    89.  
    90.         private IndicatorSourceBase _source2;
    91.  
    92.         [DataMember(Name = "Source2")]
    93.         [DisplayName("Источник 2")]
    94.         public IndicatorSourceBase Source2
    95.         {
    96.             get => _source2 ?? (_source2 = new StockSource());
    97.             set
    98.             {
    99.                 if (value == _source2)
    100.                 {
    101.                     return;
    102.                 }
    103.  
    104.                 _source2 = value;
    105.  
    106.                 OnPropertyChanged();
    107.             }
    108.         }
    109.  
    110.         private decimal _value;
    111.        
    112.         [DataMember(Name = "Value")]
    113.         [DisplayName("Значение")]
    114.         public decimal Value
    115.         {
    116.             get => _value;
    117.             set
    118.             {
    119.                 if (value == _value)
    120.                 {
    121.                     return;
    122.                 }
    123.  
    124.                 _value = value;
    125.  
    126.                 OnPropertyChanged();
    127.             }
    128.         }
    129.  
    130.         private double[] _source1Cache;
    131.         private double[] _source2Cache;
    132.  
    133.         public void Clear()
    134.         {
    135.             _source1Cache = null;
    136.             _source2Cache = null;
    137.         }
    138.  
    139.         private double[] GetSource1(IndicatorsHelper helper, int barIndex)
    140.         {
    141.             if (_source1Cache != null && _source1Cache.Length - 1 > barIndex)
    142.             {
    143.                 return _source1Cache;
    144.             }
    145.  
    146.             _source1Cache = Source1.GetSeries(helper);
    147.  
    148.             if (_source1Cache == null || _source1Cache.Length < barIndex)
    149.             {
    150.                 return null;
    151.             }
    152.  
    153.             return _source1Cache;
    154.         }
    155.  
    156.         private double[] GetSource2(IndicatorsHelper helper, int barIndex)
    157.         {
    158.             if (_source2Cache != null && _source2Cache.Length - 1 > barIndex)
    159.             {
    160.                 return _source2Cache;
    161.             }
    162.  
    163.             _source2Cache = Source2.GetSeries(helper);
    164.  
    165.             if (_source2Cache == null || _source2Cache.Length < barIndex)
    166.             {
    167.                 return null;
    168.             }
    169.  
    170.             return _source2Cache;
    171.         }
    172.  
    173.         public bool Check(IndicatorsHelper helper, int barIndex)
    174.         {
    175.             var source1 = GetSource1(helper, barIndex);
    176.  
    177.             switch (Condition)
    178.             {
    179.                 case BarSearchConditions.GreaterThenSource:
    180.                 {
    181.                     var source2 = GetSource2(helper, barIndex);
    182.  
    183.                     if (source2 == null)
    184.                     {
    185.                         return false;
    186.                     }
    187.  
    188.                     if (source1[barIndex] > source2[barIndex])
    189.                     {
    190.                         return true;
    191.                     }
    192.  
    193.                     break;
    194.                 }
    195.                 case BarSearchConditions.GreaterThenValue:
    196.                 {
    197.                     if (source1[barIndex] >= (double)Value)
    198.                     {
    199.                         return true;
    200.                     }
    201.  
    202.                     break;
    203.                 }
    204.                 case BarSearchConditions.LessThenSource:
    205.                 {
    206.                     var source2 = GetSource2(helper, barIndex);
    207.  
    208.                     if (source2 == null)
    209.                     {
    210.                         return false;
    211.                     }
    212.  
    213.                     if (source1[barIndex] < source2[barIndex])
    214.                     {
    215.                         return true;
    216.                     }
    217.  
    218.                     break;
    219.                 }
    220.                 case BarSearchConditions.LessThenValue:
    221.                 {
    222.                     if (source1[barIndex] <= (double)Value)
    223.                     {
    224.                         return true;
    225.                     }
    226.  
    227.                     break;
    228.                 }
    229.                 case BarSearchConditions.EqualSource:
    230.                 {
    231.                     var source2 = GetSource2(helper, barIndex);
    232.  
    233.                     if (source2 == null)
    234.                     {
    235.                         return false;
    236.                     }
    237.  
    238.                     if (source1[barIndex] == source2[barIndex])
    239.                     {
    240.                         return true;
    241.                     }
    242.  
    243.                     break;
    244.                 }
    245.                 case BarSearchConditions.EqualValue:
    246.                 {
    247.                     if (source1[barIndex] == (double)Value)
    248.                     {
    249.                         return true;
    250.                     }
    251.  
    252.                     break;
    253.                 }
    254.             }
    255.  
    256.             return false;
    257.         }
    258.  
    259.         public void Copy(BarSearchCondition condition)
    260.         {
    261.             Source1 = condition.Source1.CloneSource();
    262.             Source2 = condition.Source2.CloneSource();
    263.  
    264.             Value = condition.Value;
    265.         }
    266.  
    267.         [Browsable(false)]
    268.         public bool Updated { get; set; }
    269.  
    270.         public event PropertyChangedEventHandler PropertyChanged;
    271.  
    272.         [NotifyPropertyChangedInvocator]
    273.         private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    274.         {
    275.             Updated = true;
    276.  
    277.             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    278.         }
    279.  
    280.         public override string ToString()
    281.         {
    282.             return "Условие";
    283.         }
    284.  
    285.         public bool GetPropertyHasStandardValues(string propertyName)
    286.         {
    287.             return false;
    288.         }
    289.  
    290.         public bool GetPropertyReadOnly(string propertyName)
    291.         {
    292.             return false;
    293.         }
    294.  
    295.         public IEnumerable<object> GetPropertyStandardValues(string propertyName)
    296.         {
    297.             return null;
    298.         }
    299.  
    300.         public bool GetPropertyVisibility(string propertyName)
    301.         {
    302.             switch (propertyName)
    303.             {
    304.                 case "Source2":
    305.  
    306.                     return Condition == BarSearchConditions.GreaterThenSource ||
    307.                            Condition == BarSearchConditions.LessThenSource ||
    308.                            Condition == BarSearchConditions.EqualSource;
    309.  
    310.                 case "Value":
    311.  
    312.                     return Condition == BarSearchConditions.GreaterThenValue ||
    313.                            Condition == BarSearchConditions.LessThenValue ||
    314.                            Condition == BarSearchConditions.EqualValue;
    315.             }
    316.  
    317.             return true;
    318.         }
    319.     }
    320.  
    321.     internal sealed class AlertData
    322.     {
    323.         public int LastIndex { get; set; }
    324.         public DateTime LastTime { get; set; }
    325.  
    326.         public AlertData()
    327.         {
    328.             Clear();
    329.         }
    330.  
    331.         public void Clear()
    332.         {
    333.             LastIndex = -1;
    334.             LastTime = DateTime.MinValue;
    335.         }
    336.     }
    337.  
    338.     [DataContract(Name = "BarSearchIndicator", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    339.     [Indicator("X_BarSearch", "*BarSearch", true, Type = typeof(BarSearchIndicator))]
    340.     internal sealed class BarSearchIndicator : IndicatorBase, IContainsConditions
    341.     {
    342.         private XBrush _selectionBrush;
    343.  
    344.         private XPen _selectionPen;
    345.  
    346.         private XColor _selectionColor;
    347.  
    348.         [DataMember(Name = "SelectionColor")]
    349.         [Category("Стиль"), DisplayName("Цвет выделения")]
    350.         public XColor SelectionColor
    351.         {
    352.             get => _selectionColor;
    353.             set
    354.             {
    355.                 if (value == _selectionColor)
    356.                 {
    357.                     return;
    358.                 }
    359.  
    360.                 _selectionColor = value;
    361.  
    362.                 _selectionBrush = new XBrush(_selectionColor);
    363.                 _selectionPen = new XPen(_selectionBrush, 1);
    364.  
    365.                 OnPropertyChanged();
    366.             }
    367.         }
    368.  
    369.         private List<BarSearchCondition> _conditions;
    370.  
    371.         [DataMember(Name = "Conditions")]
    372.         [Category("Параметры"), DisplayName("Условия")]
    373.         public List<BarSearchCondition> Conditions
    374.         {
    375.             get => _conditions ?? (_conditions = new List<BarSearchCondition>());
    376.             set => _conditions = value;
    377.         }
    378.  
    379.         private ChartAlertSettings _alert;
    380.  
    381.         [DataMember(Name = "Alert"), Browsable(true)]
    382.         [Category("Параметры"), DisplayName("Оповещение")]
    383.         public ChartAlertSettings Alert
    384.         {
    385.             get => _alert ?? (_alert = new ChartAlertSettings());
    386.             set
    387.             {
    388.                 if (Equals(value, _alert))
    389.                 {
    390.                     return;
    391.                 }
    392.  
    393.                 _alert = value;
    394.  
    395.                 OnPropertyChanged();
    396.             }
    397.         }
    398.  
    399.         [Browsable(false)]
    400.         public override bool ShowIndicatorValues => false;
    401.  
    402.         [Browsable(false)]
    403.         public override bool ShowIndicatorLabels => false;
    404.  
    405.         [Browsable(false)]
    406.         public override IndicatorCalculation Calculation => IndicatorCalculation.OnBarClose;
    407.  
    408.         private int _lastFullID;
    409.  
    410.         private Dictionary<int, bool> _bars;
    411.         private Dictionary<int, bool> Bars => _bars ?? (_bars = new Dictionary<int, bool>());
    412.  
    413.         private AlertData _alertData;
    414.  
    415.         private void Clear()
    416.         {
    417.             _lastFullID = 0;
    418.  
    419.             Bars.Clear();
    420.  
    421.             foreach (var condition in Conditions)
    422.             {
    423.                 condition.Clear();
    424.             }
    425.  
    426.             _alertData?.Clear();
    427.         }
    428.  
    429.         protected override void Execute()
    430.         {
    431.             var clear = false;
    432.  
    433.             foreach (var condition in Conditions)
    434.             {
    435.                 if (!condition.Updated)
    436.                 {
    437.                     continue;
    438.                 }
    439.  
    440.                 condition.Updated = false;
    441.  
    442.                 clear = true;
    443.             }
    444.  
    445.             if (clear || ClearData)
    446.             {
    447.                 Clear();
    448.             }
    449.  
    450.             for (var i = _lastFullID; i < DataProvider.Count; i++)
    451.             {
    452.                 if (!Bars.ContainsKey(i))
    453.                 {
    454.                     Bars.Add(i, false);
    455.                 }
    456.  
    457.                 var result = Conditions.Count > 0;
    458.  
    459.                 foreach (var condition in Conditions)
    460.                 {
    461.                     if (!condition.Check(Helper, i))
    462.                     {
    463.                         result = false;
    464.  
    465.                         break;
    466.                     }
    467.                 }
    468.  
    469.                 Bars[i] = result;
    470.  
    471.                 if (result && _lastFullID > 0)
    472.                 {
    473.                     AddAlert(i);
    474.                 }
    475.             }
    476.  
    477.             _lastFullID = Math.Max(DataProvider.Count - 2, 0);
    478.         }
    479.  
    480.         private void AddAlert(int index)
    481.         {
    482.             if (_alertData == null)
    483.             {
    484.                 _alertData = new AlertData();
    485.             }
    486.  
    487.             if (!Alert.IsActive || _alertData.LastIndex >= index)
    488.             {
    489.                 return;
    490.             }
    491.  
    492.             var currTime = TimeHelper.LocalTime;
    493.  
    494.             _alertData.LastIndex = index;
    495.             _alertData.LastTime = currTime;
    496.  
    497.             AddAlert(Alert, "BarSearch Alert");
    498.         }
    499.  
    500.         public override void ApplyColors(IChartTheme theme)
    501.         {
    502.             SelectionColor = theme.GetNextColor();
    503.  
    504.             base.ApplyColors(theme);
    505.         }
    506.  
    507.         public override void CopyTemplate(IndicatorBase indicator, bool style)
    508.         {
    509.             var i = (BarSearchIndicator)indicator;
    510.  
    511.             SelectionColor = i.SelectionColor;
    512.  
    513.             Conditions.Clear();
    514.  
    515.             if (!style)
    516.             {
    517.                 foreach (var condition in i.Conditions)
    518.                 {
    519.                     var newCondition = new BarSearchCondition();
    520.  
    521.                     newCondition.Copy(condition);
    522.  
    523.                     Conditions.Add(newCondition);
    524.                 }
    525.             }
    526.  
    527.             Alert.Copy(i.Alert, !style);
    528.  
    529.             OnPropertyChanged(nameof(Alert));
    530.  
    531.             base.CopyTemplate(indicator, style);
    532.         }
    533.  
    534.         public XBrush GetBrush(int index, bool isUp)
    535.         {
    536.             if (index > 0 && index < Bars.Count)
    537.             {
    538.                 if (Bars[index])
    539.                 {
    540.                     return _selectionBrush;
    541.                 }
    542.             }
    543.  
    544.             return null;
    545.         }
    546.     }
    547. }
    548.  
     
    #1 Support, 6 июл 2019
    Последнее редактирование: 26 июл 2019