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

Open Interest

//------------------------------------------------------------------------------
//
// Indicator OpenInterest. Copyright (c) 2023 Tiger Trade Capital AG. All rights reserved.
//
//------------------------------------------------------------------------------
 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Windows;
using System.Windows.Media;
using TigerTrade.Chart.Base;
using TigerTrade.Chart.Base.Enums;
using TigerTrade.Chart.Indicators.Common;
using TigerTrade.Chart.Indicators.Enums;
using TigerTrade.Core.UI.Converters;
using TigerTrade.Core.Utils.Time;
using TigerTrade.Dx;
 
namespace TigerTrade.Chart.Indicators.Custom
{
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    [DataContract(Name = "OpenInterestDataType", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    public enum OpenInterestDataType
    {
        [EnumMember(Value = "All"), Description("Все")]
        All,
        [EnumMember(Value = "Buys"), Description("Покупки")]
        Buys,
        [EnumMember(Value = "Sells"), Description("Продажи")]
        Sells
    }
 
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    [DataContract(Name = "OpenInterestPeriodType", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    public enum OpenInterestPeriodType
    {
        [EnumMember(Value = "Bar"), Description("Бар")]
        Bar,
        [EnumMember(Value = "Day"), Description("День")]
        Day,
        [EnumMember(Value = "Week"), Description("Неделя")]
        Week,
        [EnumMember(Value = "Month"), Description("Месяц")]
        Month,
        [EnumMember(Value = "AllBars"), Description("Все бары")]
        AllBars
    }
 
    [DataContract(Name = "OpenInterestIndicator", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    [Indicator("X_OpenInterest", "*OpenInterest", false, Type = typeof(OpenInterestIndicator))]
    internal sealed class OpenInterestIndicator : IndicatorBase
    {
        private OpenInterestDataType _dataType;
 
        [DataMember(Name = "DataType")]
        [Category("Параметры"), DisplayName("Тип сделок")]
        public OpenInterestDataType DataType
        {
            get => _dataType;
            set
            {
                if (value == _dataType)
                {
                    return;
                }
 
                _dataType = value;
 
                Clear();
 
                OnPropertyChanged();
                OnPropertyChanged(nameof(Title));
            }
        }
 
        private OpenInterestPeriodType _period;
 
        [DataMember(Name = "Period")]
        [Category("Параметры"), DisplayName("Период")]
        public OpenInterestPeriodType Period
        {
            get => _period;
            set
            {
                if (value == _period)
                {
                    return;
                }
 
                _period = value;
 
                Clear();
 
                OnPropertyChanged();
                OnPropertyChanged(nameof(Title));
            }
        }
 
        private IndicatorViewType _type;
 
        [DataMember(Name = "Type")]
        [Category("Параметры"), DisplayName("Тип")]
        public IndicatorViewType Type
        {
            get => _type;
            set
            {
                if (value == _type)
                {
                    return;
                }
 
                _type = value;
 
                OnPropertyChanged();
                OnPropertyChanged(nameof(UpColor));
                OnPropertyChanged(nameof(DownColor));
                OnPropertyChanged(nameof(LineColor));
                OnPropertyChanged(nameof(LineWidth));
            }
        }
 
        private XBrush _upBrush;
 
        private XPen _upPen;
 
        private XColor _upColor;
 
        [DataMember(Name = "UpColor")]
        [Category("Стиль"), DisplayName("Цвет при росте")]
        public XColor UpColor
        {
            get => _upColor;
            set
            {
                if (value == _upColor)
                {
                    return;
                }
 
                _upColor = value;
 
                _upBrush = new XBrush(_upColor);
                _upPen = new XPen(_upBrush, 1);
 
                OnPropertyChanged();
            }
        }
 
        private XBrush _downBrush;
 
        private XPen _downPen;
 
        private XColor _downColor;
 
        [DataMember(Name = "DownColor")]
        [Category("Стиль"), DisplayName("Цвет при падении")]
        public XColor DownColor
        {
            get => _downColor;
            set
            {
                if (value == _downColor)
                {
                    return;
                }
 
                _downColor = value;
 
                _downBrush = new XBrush(_downColor);
                _downPen = new XPen(_downBrush, 1);
 
                OnPropertyChanged();
            }
        }
 
        private XBrush _lineBrush;
 
        private XPen _linePen;
 
        private XColor _lineColor;
 
        [DataMember(Name = "LineColor")]
        [Category("Стиль"), DisplayName("Цвет линии")]
        public XColor LineColor
        {
            get => _lineColor;
            set
            {
                if (value == _lineColor)
                {
                    return;
                }
 
                _lineColor = value;
 
                _lineBrush = new XBrush(_lineColor);
                _linePen = new XPen(_lineBrush, LineWidth);
 
                OnPropertyChanged();
            }
        }
 
        private int _lineWidth;
 
        [DataMember(Name = "LineWidth")]
        [Category("Стиль"), DisplayName("Толщина линии")]
        public int LineWidth
        {
            get => _lineWidth;
            set
            {
                value = Math.Max(1, Math.Min(9, value));
 
                if (value == _lineWidth)
                {
                    return;
                }
 
                _lineWidth = value;
 
                _linePen = new XPen(_lineBrush, _lineWidth);
 
                OnPropertyChanged();
            }
        }
 
        [Browsable(false)]
        public override IndicatorCalculation Calculation => IndicatorCalculation.OnEachTick;
 
        public override bool IntegerValues => true;
 
        private class OpenIntItem
        {
            public int Open;
            public int High;
            public int Low;
            public int Close;
            public int Seq = -1;
            public int OpenInt;
            public int StartOpenInt;
        }
 
        private int _lastFullID;
 
        private List<OpenIntItem> _items;
        private List<OpenIntItem> Items => _items ?? (_items = new List<OpenIntItem>());
 
        private void Clear()
        {
            _lastFullID = 0;
 
            Items.Clear();
        }
 
        public OpenInterestIndicator()
        {
            DataType = OpenInterestDataType.All;
            Period = OpenInterestPeriodType.Bar;
            Type = IndicatorViewType.Columns;
 
            UpColor = Color.FromArgb(255, 30, 144, 255);
            DownColor = Color.FromArgb(255, 178, 34, 34);
 
            LineColor = Color.FromArgb(255, 30, 144, 255);
            LineWidth = 1;
        }
 
        protected override void Execute()
        {
            if (ClearData)
            {
                Clear();
            }
 
            var timeOffset = TimeHelper.GetSessionOffset(DataProvider.Symbol.Exchange);
 
            for (var i = _lastFullID; i < DataProvider.Count; i++)
            {
                var cluster = DataProvider.GetRawCluster(i);
 
                if (Items.Count < i + 1)
                {
                    Items.Add(new OpenIntItem());
                }
 
                var item = Items[i];
 
                var prevItem = i > 0 && Items.Count > 1
                    ? Items[i - 1]
                    : new OpenIntItem
                    {
                        OpenInt = cluster.OpenPos,
                        StartOpenInt = cluster.OpenPos
                    };
 
                var sequence = 1;
 
                switch (Period)
                {
                    case OpenInterestPeriodType.Bar:
 
                        sequence = i;
 
                        break;
 
                    case OpenInterestPeriodType.Day:
 
                        sequence = DataProvider.Period.GetSequence(ChartPeriodType.Day, 1, cluster.Time, timeOffset);
 
                        break;
 
                    case OpenInterestPeriodType.Week:
 
                        sequence = DataProvider.Period.GetSequence(ChartPeriodType.Week, 1, cluster.Time, timeOffset);
 
                        break;
 
                    case OpenInterestPeriodType.Month:
 
                        sequence = DataProvider.Period.GetSequence(ChartPeriodType.Month, 1, cluster.Time, timeOffset);
 
                        break;
 
                    case OpenInterestPeriodType.AllBars:
 
                        sequence = -1;
 
                        break;
                }
 
                switch (DataType)
                {
                    case OpenInterestDataType.All:
                    {
                        if (Period == OpenInterestPeriodType.AllBars)
                        {
                            item.Close = cluster.OpenPos;
                            item.Open = prevItem.Close;
                            item.High = cluster.OpenPosHigh;
                            item.Low = cluster.OpenPosLow;
 
                            if (item.Open == 0)
                            {
                                item.Open = item.Close;
                            }
                        }
                        else
                        {
                            var startOpenPosValue = prevItem.StartOpenInt;
 
                            var prevClose = prevItem.OpenInt - startOpenPosValue;
                            var close = cluster.OpenPos - startOpenPosValue;
 
                            if (sequence != prevItem.Seq)
                            {
                                startOpenPosValue = prevItem.OpenInt;
 
                                prevClose = 0;
                                close = cluster.OpenPos - prevItem.OpenInt;
 
                                if (close == 0)
                                {
                                    close = cluster.OpenPosChg;
                                    startOpenPosValue -= cluster.OpenPosChg;
                                }
                            }
 
                            item.Seq = sequence;
                            item.OpenInt = cluster.OpenPos;
                            item.StartOpenInt = startOpenPosValue;
 
                            item.Close = close;
                            item.Open = prevClose;
                            item.High = cluster.OpenPosHigh - startOpenPosValue;
                            item.Low = cluster.OpenPosLow - startOpenPosValue;
                        }
 
                        break;
                    }
                    case OpenInterestDataType.Buys:
                    {
                        if (sequence != prevItem.Seq)
                        {
                            prevItem.OpenInt = 0;
                        }
 
                        item.Seq = sequence;
 
                        item.Open = prevItem.OpenInt;
                        item.Close = prevItem.OpenInt + cluster.OpenPosAskChg;
                        item.High = Math.Max(item.Open, item.Close);
                        item.Low = Math.Min(item.Open, item.Close);
 
                        item.OpenInt = item.Close;
 
                        break;
                    }
                    case OpenInterestDataType.Sells:
                    {
                        if (sequence != prevItem.Seq)
                        {
                            prevItem.OpenInt = 0;
                        }
 
                        item.Seq = sequence;
 
                        item.Open = prevItem.OpenInt;
                        item.Close = prevItem.OpenInt + cluster.OpenPosBidChg;
                        item.High = Math.Max(item.Open, item.Close);
                        item.Low = Math.Min(item.Open, item.Close);
 
                        item.OpenInt = item.Close;
 
                        break;
                    }
                }
            }
 
            _lastFullID = Math.Max(DataProvider.Count - 2, 0);
        }
 
        public override bool GetMinMax(out double min, out double max)
        {
            min = double.MaxValue;
            max = double.MinValue;
 
            if (Items.Count == 0)
            {
                return false;
            }
 
            var longMin = long.MaxValue;
            var longMax = long.MinValue;
 
            if (Type == IndicatorViewType.Candles)
            {
                for (var i = 0; i < Canvas.Count; i++)
                {
                    var index = Canvas.GetIndex(i);
 
                    if (index < 0 || index >= Items.Count)
                    {
                        continue;
                    }
 
                    var item = Items[index];
 
                    if (longMin > item.Low)
                    {
                        longMin = item.Low;
                    }
 
                    if (longMax < item.High)
                    {
                        longMax = item.High;
                    }
                }
            }
            else
            {
                for (var i = 0; i < Canvas.Count; i++)
                {
                    var index = Canvas.GetIndex(i);
 
                    if (index < 0 || index >= Items.Count)
                    {
                        continue;
                    }
 
                    var item = Items[index];
 
                    if (longMin > item.Close)
                    {
                        longMin = item.Close;
                    }
 
                    if (longMax < item.Close)
                    {
                        longMax = item.Close;
                    }
                }
            }
 
            if (longMin > longMax)
            {
                return false;
            }
 
            min = longMin;
            max = longMax;
 
            return true;
        }
 
        public override void Render(DxVisualQueue visual)
        {
            switch (Type)
            {
                case IndicatorViewType.Candles:
                    {
                        var width = (int)(Canvas.ColumnWidth * Canvas.ColumnPercent + 0.4);
                        var halfWith = Math.Max((int)(width / 2.0), 1.0);
 
                        for (var i = 0; i < Canvas.Count; i++)
                        {
                            var index = Canvas.GetIndex(i);
 
                            if (index < 0 || index >= Items.Count)
                            {
                                continue;
                            }
 
                            var item = Items[index];
 
                            var isUp = item.Close > item.Open;
 
                            var centerX = (int)Canvas.GetX(index);
                            var openY = (int)GetY((double)item.Open);
                            var highY = (int)GetY((double)item.High);
                            var lowY = (int)GetY((double)item.Low);
                            var closeY = (int)GetY((double)item.Close);
 
                            var topY = Math.Min(openY, closeY);
                            var bottomY = Math.Max(openY, closeY);
 
                            var height = bottomY - topY;
 
                            var backBrush = isUp ? _upBrush : _downBrush;
                            var backPen = isUp ? _upPen : _downPen;
 
                            if (height == 0 || width <= 1)
                            {
                                if (highY == lowY)
                                {
                                    lowY++;
                                }
 
                                visual.DrawLine(backPen,
                                    new Point(centerX, highY),
                                    new Point(centerX, lowY));
                            }
                            else
                            {
                                visual.DrawLine(backPen,
                                    new Point(centerX, highY),
                                    new Point(centerX, topY));
 
                                visual.DrawLine(backPen,
                                    new Point(centerX, bottomY),
                                    new Point(centerX, lowY));
                            }
 
                            if (width > 1)
                            {
                                if (height == 0)
                                {
                                    visual.DrawLine(backPen,
                                        new Point(centerX - halfWith, topY),
                                        new Point(centerX + halfWith + 1, topY));
                                }
                                else
                                {
                                    visual.FillRectangle(backBrush,
                                        new Rect(centerX - halfWith, topY, halfWith * 2 + 1, height));
                                }
                            }
                        }
                    }
                    break;
 
                case IndicatorViewType.Columns:
                    {
                        var zeroPoint = GetY(0.0);
 
                        var width = Math.Max(Canvas.ColumnWidth - 1, 1);
 
                        for (var i = 0; i < Canvas.Count; i++)
                        {
                            var index = Canvas.GetIndex(i);
 
                            if (index < 0 || index >= Items.Count)
                            {
                                continue;
                            }
 
                            var item = Items[index];
 
                            var x = Canvas.GetX(index);
                            var y = GetY((double)item.Close);
                            var h = (int)zeroPoint - (int)y;
 
                            var isUp = h > 0;
 
                            if (h < 0.0)
                            {
                                y += h;
                                h = -h;
                            }
 
                            h = Math.Max(1, h);
 
                            if (width > 1.0)
                            {
                                var rect = new Rect(x - width / 2.0, y, width, h);
 
                                visual.FillRectangle(isUp ? _upBrush : _downBrush, rect);
                            }
                            else
                            {
                                visual.DrawLine(isUp ? _upPen : _downPen, x, y, x, y + h);
                            }
                        }
                    }
                    break;
 
                case IndicatorViewType.Line:
                    {
                        if (Items.Count < 2)
                        {
                            return;
                        }
 
                        var points = new Point[Canvas.Count];
 
                        for (var i = 0; i < Canvas.Count; i++)
                        {
                            var index = Canvas.GetIndex(i);
 
                            if (index < 0 || index >= Items.Count)
                            {
                                continue;
                            }
 
                            var item = Items[index];
 
                            var x = Canvas.GetX(index);
                            var y = GetY((double)item.Close);
 
                            points[i] = new Point(x, y);
                        }
 
                        visual.DrawLines(_linePen, points);
                    }
                    break;
            }
        }
 
        public override List<IndicatorValueInfo> GetValues(int cursorPos)
        {
            var info = new List<IndicatorValueInfo>();
 
            if (cursorPos >= 0 && cursorPos < Items.Count)
            {
                var s = Canvas.FormatValue(Items[cursorPos].Close);
 
                info.Add(new IndicatorValueInfo(s,
                    Type == IndicatorViewType.Line ? _lineBrush : Canvas.Theme.ChartFontBrush));
            }
 
            return info;
        }
 
        public override void GetLabels(ref List<IndicatorLabelInfo> labels)
        {
            if (Items.Count == 0)
            {
                return;
            }
 
            if (DataProvider.Count <= Canvas.Start)
            {
                return;
            }
 
            var index = DataProvider.Count - 1 - Canvas.Start;
 
            if (index < 0 && index >= Items.Count)
            {
                return;
            }
 
            var item = Items[index];
 
            var lastValue = item.Close;
 
            if (Type == IndicatorViewType.Line)
            {
                labels.Add(new IndicatorLabelInfo(lastValue, _lineColor));
 
                return;
            }
 
            var isUp = false;
 
            switch (Type)
            {
                case IndicatorViewType.Line:
                case IndicatorViewType.Columns:
 
                    isUp = !double.IsNaN(lastValue) && lastValue > 0;
 
                    break;
 
                case IndicatorViewType.Candles:
 
                    isUp = !double.IsNaN(lastValue) && item.Close > item.Open;
 
                    break;
            }
 
            labels.Add(new IndicatorLabelInfo(lastValue, isUp ? UpColor : DownColor));
        }
 
        public override void ApplyColors(IChartTheme theme)
        {
            UpColor = theme.PaletteColor6;
            DownColor = theme.PaletteColor7;
 
            LineColor = theme.GetNextColor();
 
            base.ApplyColors(theme);
 
        }
        public override void CopyTemplate(IndicatorBase indicator, bool style)
        {
            var i = (OpenInterestIndicator)indicator;
 
            DataType = i.DataType;
            Period = i.Period;
            Type = i.Type;
 
            UpColor = i.UpColor;
            DownColor = i.DownColor;
 
            LineColor = i.LineColor;
            LineWidth = i.LineWidth;
 
            base.CopyTemplate(indicator, style);
        }
 
        public override string ToString()
        {
            return $"{Name} ({Period}, {DataType})";
        }
 
        public override bool GetPropertyVisibility(string propertyName)
        {
            switch (propertyName)
            {
                case "LineWidth":
                case "LineColor":
 
                    return Type == IndicatorViewType.Line;
 
                case "UpColor":
                case "DownColor":
 
                    return Type != IndicatorViewType.Line;
            }
 
            return true;
        }
    }
}
PreviousSession colorNextDynamic Levels

Last updated 2 years ago

⌨️