Tiger.com Windows Wiki
English
English
  • 👋Welcome!
  • ⭐How to start?
    • Recommended system requirements
    • Register and setup
    • Licenses and login
  • ⚙️Settings
    • Workspace
    • Trading modes
    • Connections
      • Crypto exchanges
        • TigerX
        • Binance via Tiger.com Broker
        • Bybit via Tiger.com Broker
        • Binance
        • Bitfinex
        • BitMEX
        • Bybit
        • OKX
        • Gate.io
        • MEXC
      • Trading terminals
        • DataFeed
        • MetaTrader 5
        • OEC Trader (GAIN Capital)
        • Rithmic
        • QUIK
        • SmartCOM
        • Trader WorkStation (Interactive Brokers)
        • Transaq Connector
    • Basic setup
      • Selecting a symbol
      • Selecting a timeframe
      • Linking windows
      • Setting up exit strategies
      • Setting offsets
    • Terminal
      • Order volumes preset
      • Configuration
        • How to create public configuration
      • General settings
      • Email notifications
      • Telegram alerts
      • Hotkeys Manager
      • Sound alerts
      • Symbols manager
  • 🖥️Windows
    • Chart
      • Chart trading
      • Toolbar setup
      • Chart theme
      • Chart settings
      • Scaling and moving the chart
      • Cluster chart
      • Cluster presets
      • Graphical objects in Chart window
        • Text
        • Ruler
        • Volume profile
        • Trend angle
        • Elliott Correction Wave
        • Elliott Impulse Wave
        • Fibonacci Fan
        • Fibonacci Extensions
        • Fibonacci Retracement
        • Fibonacci Time Zones
        • Linear Regression
      • Main indicators in Chart window
        • Bar Search
        • Bar Timer
        • Bid Ask
        • Big Trades
        • BW MFI
        • Cluster Search
        • Cluster Statistic
        • Cumulative Delta
        • Delta
        • Depth Of Market
        • Dynamic Levels
        • Elders Force Index
        • External Chart
        • Gradient
        • Heatmap
        • High Low
        • Histogram
        • Ichimoku
        • Margin Zones
        • Maximum Levels
        • Open Interest
        • Price
        • Session Color
        • Trades Flow
        • Volume
        • Volume Profile
        • VWAP
        • Weis Wave Volume
        • ZigZag
    • DOM
      • Selecting a trading account
      • Ruler
      • Multiplier
      • DOM settings
        • Main
        • Cluster
        • Trading
      • Stop Loss
      • Take Profit
      • Trigger orders
    • Watchlist
      • How to filter watchlist
    • SmartTape
    • Statistics
    • Volume search
    • All prices
    • Options board
  • 📋Tables
    • Orders
    • Executions
    • Positions
    • XPositions
    • Accounts
    • Limits
    • Player
    • Signals
    • Log
  • 🔍Video Tutorials
    • Terminal Basics
    • Charts and technical analysis
    • Charts, Trade Tape and Player
    • Trading in Tiger.com Windows
  • 💡Platform Updates
    • Version 7.0 Beta
    • Version 6.9
    • Version 6.8
    • Version 6.7
    • Version 6.6
    • Version 6.5
    • Version 6.4
    • Version 6.3
    • Version 6.2
    • Version 6.1
    • Version 6.0.2
    • Version 6.0.1
    • Version 6.0.0
    • Version 5.0.7
    • Version 4.5.15
  • ⌨️Development for Tiger.com Windows
    • Indicator examples
      • DepthOfMarket
      • Trades Flow
      • Volume Profiles
      • Cluster Search
      • Bar Search
      • VWAP
      • Bar Timer
      • Volume
      • Trades
      • Session color
      • Open Interest
      • Dynamic Levels
      • Delta
      • Cumulative Delta
      • Cluster Statistic
      • Bid Ask
      • External Chart
      • High Low
      • Histogram
    • Source examples
      • Moving Average
      • Stock
    • Examples of graphical objects
      • Fibonacci Extensions
      • Fibonacci Retracement
      • Vertical Line
      • Horizontal Line
      • Volume Profile
      • Rectangle
  • ❓Frequently Asked Questions
    • Questions about licenses
    • Questions about indicators
    • Questions about connections
    • Questions about trading
    • Error "Connection lost" when launching the terminal
    • Why do I need to set commission in the terminal?
    • How does automatic account selection work?
    • How do I optimize the terminal to improve performance?
    • How to use the Crypto license to trade on Binance
    • Which order types are available in Tiger.com?
    • How to set up chart auto-refresh for QUIK connection?
    • How do I enable Take Profit orders on Binance?
    • How does autoselection of data type work?
    • Troubles installing the terminal
    • What are the system requirements for the terminal?
    • How to provide Tiger.com Windows app logs for investigation?
    • Fixing Network Issues: How to Adjust DNS Settings
  • 📬Technical support
  • 💭Suggest an improvement
Powered by GitBook
On this page
  1. Development for Tiger.com Windows
  2. Indicator examples

Bar Search

//------------------------------------------------------------------------------
//
// Indicator BarSearch. Copyright (c) 2023 Tiger Trade Capital AG. All rights reserved.
//
//------------------------------------------------------------------------------
 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using TigerTrade.Chart.Alerts;
using TigerTrade.Chart.Annotations;
using TigerTrade.Chart.Base;
using TigerTrade.Chart.Indicators.Common;
using TigerTrade.Chart.Indicators.Enums;
using TigerTrade.Chart.Indicators.Sources;
using TigerTrade.Core.UI.Common;
using TigerTrade.Core.UI.Converters;
using TigerTrade.Core.Utils.Time;
using TigerTrade.Dx;
 
namespace TigerTrade.Chart.Indicators.Custom
{
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    [DataContract(Name = "BarSearchConditions", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    public enum BarSearchConditions
    {
        [EnumMember(Value = "GreaterThenSource"), Description("Источник 1 > Источник 2")]
        GreaterThenSource,
        [EnumMember(Value = "GreaterThenValue"), Description("Источник 1 >= Значение")]
        GreaterThenValue,
        [EnumMember(Value = "LessThenSource"), Description("Источник 1 < Источник 2")]
        LessThenSource,
        [EnumMember(Value = "LessThenValue"), Description("Источник 1 <= Значение")]
        LessThenValue,
        [EnumMember(Value = "EqualSource"), Description("Источник 1 = Источник 2")]
        EqualSource,
        [EnumMember(Value = "EqualValue"), Description("Источник 1 = Значение")]
        EqualValue,
    }
 
    [TypeConverter(typeof(ExpandableObjectConverter)), ReadOnly(true)]
    [DataContract(Name = "BarSearchCondition", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    internal sealed class BarSearchCondition : INotifyPropertyChanged, IDynamicProperty
    {
        private BarSearchConditions _conditions;
 
        [DataMember(Name = "Condition")]
        [DisplayName("Условие")]
        public BarSearchConditions Condition
        {
            get => _conditions;
            set
            {
                if (Equals(value, _conditions))
                {
                    return;
                }
 
                _conditions = value;
 
                OnPropertyChanged();
                OnPropertyChanged(nameof(Source2));
                OnPropertyChanged(nameof(Value));
            }
        }
 
        private IndicatorSourceBase _source1;
       
        [DataMember(Name = "Source1")]
        [DisplayName("Источник 1")]
        public IndicatorSourceBase Source1
        {
            get => _source1 ?? (_source1 = new StockSource());
            set
            {
                if (value == _source1)
                {
                    return;
                }
 
                _source1 = value;
 
                OnPropertyChanged();
            }
        }
 
        private IndicatorSourceBase _source2;
 
        [DataMember(Name = "Source2")]
        [DisplayName("Источник 2")]
        public IndicatorSourceBase Source2
        {
            get => _source2 ?? (_source2 = new StockSource());
            set
            {
                if (value == _source2)
                {
                    return;
                }
 
                _source2 = value;
 
                OnPropertyChanged();
            }
        }
 
        private decimal _value;
       
        [DataMember(Name = "Value")]
        [DisplayName("Значение")]
        public decimal Value
        {
            get => _value;
            set
            {
                if (value == _value)
                {
                    return;
                }
 
                _value = value;
 
                OnPropertyChanged();
            }
        }
 
        private double[] _source1Cache;
        private double[] _source2Cache;
 
        public void Clear()
        {
            _source1Cache = null;
            _source2Cache = null;
        }
 
        private double[] GetSource1(IndicatorsHelper helper, int barIndex)
        {
            if (_source1Cache != null && _source1Cache.Length - 1 > barIndex)
            {
                return _source1Cache;
            }
 
            _source1Cache = Source1.GetSeries(helper);
 
            if (_source1Cache == null || _source1Cache.Length < barIndex)
            {
                return null;
            }
 
            return _source1Cache;
        }
 
        private double[] GetSource2(IndicatorsHelper helper, int barIndex)
        {
            if (_source2Cache != null && _source2Cache.Length - 1 > barIndex)
            {
                return _source2Cache;
            }
 
            _source2Cache = Source2.GetSeries(helper);
 
            if (_source2Cache == null || _source2Cache.Length < barIndex)
            {
                return null;
            }
 
            return _source2Cache;
        }
 
        public bool Check(IndicatorsHelper helper, int barIndex)
        {
            var source1 = GetSource1(helper, barIndex);
 
            switch (Condition)
            {
                case BarSearchConditions.GreaterThenSource:
                {
                    var source2 = GetSource2(helper, barIndex);
 
                    if (source2 == null)
                    {
                        return false;
                    }
 
                    if (source1[barIndex] > source2[barIndex])
                    {
                        return true;
                    }
 
                    break;
                }
                case BarSearchConditions.GreaterThenValue:
                {
                    if (source1[barIndex] >= (double)Value)
                    {
                        return true;
                    }
 
                    break;
                }
                case BarSearchConditions.LessThenSource:
                {
                    var source2 = GetSource2(helper, barIndex);
 
                    if (source2 == null)
                    {
                        return false;
                    }
 
                    if (source1[barIndex] < source2[barIndex])
                    {
                        return true;
                    }
 
                    break;
                }
                case BarSearchConditions.LessThenValue:
                {
                    if (source1[barIndex] <= (double)Value)
                    {
                        return true;
                    }
 
                    break;
                }
                case BarSearchConditions.EqualSource:
                {
                    var source2 = GetSource2(helper, barIndex);
 
                    if (source2 == null)
                    {
                        return false;
                    }
 
                    if (source1[barIndex] == source2[barIndex])
                    {
                        return true;
                    }
 
                    break;
                }
                case BarSearchConditions.EqualValue:
                {
                    if (source1[barIndex] == (double)Value)
                    {
                        return true;
                    }
 
                    break;
                }
            }
 
            return false;
        }
 
        public void Copy(BarSearchCondition condition)
        {
            Source1 = condition.Source1.CloneSource();
            Source2 = condition.Source2.CloneSource();
 
            Value = condition.Value;
        }
 
        [Browsable(false)]
        public bool Updated { get; set; }
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        [NotifyPropertyChangedInvocator]
        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            Updated = true;
 
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
 
        public override string ToString()
        {
            return "Условие";
        }
 
        public bool GetPropertyHasStandardValues(string propertyName)
        {
            return false;
        }
 
        public bool GetPropertyReadOnly(string propertyName)
        {
            return false;
        }
 
        public IEnumerable<object> GetPropertyStandardValues(string propertyName)
        {
            return null;
        }
 
        public bool GetPropertyVisibility(string propertyName)
        {
            switch (propertyName)
            {
                case "Source2":
 
                    return Condition == BarSearchConditions.GreaterThenSource ||
                           Condition == BarSearchConditions.LessThenSource ||
                           Condition == BarSearchConditions.EqualSource;
 
                case "Value":
 
                    return Condition == BarSearchConditions.GreaterThenValue ||
                           Condition == BarSearchConditions.LessThenValue ||
                           Condition == BarSearchConditions.EqualValue;
            }
 
            return true;
        }
    }
 
    internal sealed class AlertData
    {
        public int LastIndex { get; set; }
        public DateTime LastTime { get; set; }
 
        public AlertData()
        {
            Clear();
        }
 
        public void Clear()
        {
            LastIndex = -1;
            LastTime = DateTime.MinValue;
        }
    }
 
    [DataContract(Name = "BarSearchIndicator", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    [Indicator("X_BarSearch", "*BarSearch", true, Type = typeof(BarSearchIndicator))]
    internal sealed class BarSearchIndicator : IndicatorBase, IContainsConditions
    {
        private XBrush _selectionBrush;
 
        private XPen _selectionPen;
 
        private XColor _selectionColor;
 
        [DataMember(Name = "SelectionColor")]
        [Category("Стиль"), DisplayName("Цвет выделения")]
        public XColor SelectionColor
        {
            get => _selectionColor;
            set
            {
                if (value == _selectionColor)
                {
                    return;
                }
 
                _selectionColor = value;
 
                _selectionBrush = new XBrush(_selectionColor);
                _selectionPen = new XPen(_selectionBrush, 1);
 
                OnPropertyChanged();
            }
        }
 
        private List<BarSearchCondition> _conditions;
 
        [DataMember(Name = "Conditions")]
        [Category("Параметры"), DisplayName("Условия")]
        public List<BarSearchCondition> Conditions
        {
            get => _conditions ?? (_conditions = new List<BarSearchCondition>());
            set => _conditions = value;
        }
 
        private ChartAlertSettings _alert;
 
        [DataMember(Name = "Alert"), Browsable(true)]
        [Category("Параметры"), DisplayName("Оповещение")]
        public ChartAlertSettings Alert
        {
            get => _alert ?? (_alert = new ChartAlertSettings());
            set
            {
                if (Equals(value, _alert))
                {
                    return;
                }
 
                _alert = value;
 
                OnPropertyChanged();
            }
        }
 
        [Browsable(false)]
        public override bool ShowIndicatorValues => false;
 
        [Browsable(false)]
        public override bool ShowIndicatorLabels => false;
 
        [Browsable(false)]
        public override IndicatorCalculation Calculation => IndicatorCalculation.OnBarClose;
 
        private int _lastFullID;
 
        private Dictionary<int, bool> _bars;
        private Dictionary<int, bool> Bars => _bars ?? (_bars = new Dictionary<int, bool>());
 
        private AlertData _alertData;
 
        private void Clear()
        {
            _lastFullID = 0;
 
            Bars.Clear();
 
            foreach (var condition in Conditions)
            {
                condition.Clear();
            }
 
            _alertData?.Clear();
        }
 
        protected override void Execute()
        {
            var clear = false;
 
            foreach (var condition in Conditions)
            {
                if (!condition.Updated)
                {
                    continue;
                }
 
                condition.Updated = false;
 
                clear = true;
            }
 
            if (clear || ClearData)
            {
                Clear();
            }
 
            for (var i = _lastFullID; i < DataProvider.Count; i++)
            {
                if (!Bars.ContainsKey(i))
                {
                    Bars.Add(i, false);
                }
 
                var result = Conditions.Count > 0;
 
                foreach (var condition in Conditions)
                {
                    if (!condition.Check(Helper, i))
                    {
                        result = false;
 
                        break;
                    }
                }
 
                Bars[i] = result;
 
                if (result && _lastFullID > 0)
                {
                    AddAlert(i);
                }
            }
 
            _lastFullID = Math.Max(DataProvider.Count - 2, 0);
        }
 
        private void AddAlert(int index)
        {
            if (_alertData == null)
            {
                _alertData = new AlertData();
            }
 
            if (!Alert.IsActive || _alertData.LastIndex >= index)
            {
                return;
            }
 
            var currTime = TimeHelper.LocalTime;
 
            _alertData.LastIndex = index;
            _alertData.LastTime = currTime;
 
            AddAlert(Alert, "BarSearch Alert");
        }
 
        public override void ApplyColors(IChartTheme theme)
        {
            SelectionColor = theme.GetNextColor();
 
            base.ApplyColors(theme);
        }
 
        public override void CopyTemplate(IndicatorBase indicator, bool style)
        {
            var i = (BarSearchIndicator)indicator;
 
            SelectionColor = i.SelectionColor;
 
            Conditions.Clear();
 
            if (!style)
            {
                foreach (var condition in i.Conditions)
                {
                    var newCondition = new BarSearchCondition();
 
                    newCondition.Copy(condition);
 
                    Conditions.Add(newCondition);
                }
            }
 
            Alert.Copy(i.Alert, !style);
 
            OnPropertyChanged(nameof(Alert));
 
            base.CopyTemplate(indicator, style);
        }
 
        public XBrush GetBrush(int index, bool isUp)
        {
            if (index > 0 && index < Bars.Count)
            {
                if (Bars[index])
                {
                    return _selectionBrush;
                }
            }
 
            return null;
        }
    }
}
 
PreviousCluster SearchNextVWAP

Last updated 2 years ago

⌨️