Bid Ask

//------------------------------------------------------------------------------
//
// Indicator BidAsk. 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.Indicators.Common;
using TigerTrade.Chart.Indicators.Enums;
using TigerTrade.Dx;
 
namespace TigerTrade.Chart.Indicators.Custom
{
    [DataContract(Name = "BidAskIndicator", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Indicators.Custom")]
    [Indicator("X_BidAsk", "*BidAsk", false, Type = typeof(BidAskIndicator))]
    internal sealed class BidAskIndicator : IndicatorBase
    {
        private XBrush _bidBrush;
 
        private XPen _bidPen;
 
        private XColor _bidColor;
 
        [DataMember(Name = "BidColor")]
        [Category("Стиль"), DisplayName("Цвет Bid")]
        public XColor BidColor
        {
            get => _bidColor;
            set
            {
                if (value == _bidColor)
                {
                    return;
                }
 
                _bidColor = value;
 
                _bidBrush = new XBrush(_bidColor);
                _bidPen = new XPen(_bidBrush, 1);
             
                OnPropertyChanged();
            }
        }
 
        private XBrush _askBrush;
 
        private XPen _askPen;
 
        private XColor _askColor;
 
        [DataMember(Name = "AskColor")]
        [Category("Стиль"), DisplayName("Цвет Ask")]
        public XColor AskColor
        {
            get => _askColor;
            set
            {
                if (value == _askColor)
                {
                    return;
                }
 
                _askColor = value;
 
                _askBrush = new XBrush(_askColor);
                _askPen = new XPen(_askBrush, 1);
             
                OnPropertyChanged();
            }
        }
 
        [Browsable(false)]
        public override IndicatorCalculation Calculation => IndicatorCalculation.OnEachTick;
 
        public override bool IntegerValues => true;
 
        public BidAskIndicator()
        {
            BidColor = Color.FromArgb(255, 178, 34, 34);
            AskColor = Color.FromArgb(255, 30, 144, 255);
        }
 
        protected override void Execute()
        {
        }
 
        public override void Render(DxVisualQueue visual)
        {
            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);
 
                var cluster = DataProvider.GetCluster(index);
 
                if (cluster == null)
                {
                    continue;
                }
 
                // Bid
 
                var x = Canvas.GetX(index);
                var y = GetY(-cluster.Bid);
                var h = (int)zeroPoint - (int)y;
 
                if (h < 0.0)
                {
                    y += h;
                    h = -h;
                }
 
                if (h < 1)
                {
                    y = (int)zeroPoint;
                    h = 1;
                }
 
                h = Math.Max(1, h);
 
                if (width > 1.0)
                {
                    visual.FillRectangle(_bidBrush, new Rect(x - width / 2.0, y, width, h));
                }
                else
                {
                    visual.DrawLine(_bidPen, x, y, x, y + h);
                }
 
                // Ask
 
                y = GetY(cluster.Ask);
                h = (int)zeroPoint - (int)y;
 
                if (h < 0.0)
                {
                    y += h;
                    h = -h;
                }
 
                if (h < 1)
                {
                    y = (int)zeroPoint - 1;
                    h = 1;
                }
 
                h = Math.Max(1, h);
 
                if (width > 1.0)
                {
                    visual.FillRectangle(_askBrush, new Rect(x - width / 2.0, y, width, h));
                }
                else
                {
                    visual.DrawLine(_askPen, x, y, x, y + h);
                }
            }
        }
 
        public override bool GetMinMax(out double min, out double max)
        {
            var bid = 0.0;
            var ask = 0.0;
 
            for (var i = 0; i < Canvas.Count; i++)
            {
                var index = Canvas.GetIndex(i);
 
                var cluster = DataProvider.GetCluster(index);
 
                if (cluster == null)
                {
                    continue;
                }
 
                bid = Math.Max(bid, (double)cluster.Bid);
                ask = Math.Max(ask, (double)cluster.Ask);
            }
 
            max = ask;
            min = -bid;
 
            return true;
        }
 
        public override List<IndicatorValueInfo> GetValues(int cursorPos)
        {
            var info = new List<IndicatorValueInfo>();
 
            var cluster = DataProvider.GetCluster(cursorPos);
 
            if (cluster == null)
            {
                return info;
            }
 
            info.Clear();
 
            var sBid = Canvas.FormatValue((double)cluster.Bid);
 
            info.Add(new IndicatorValueInfo(sBid, BidColor));
 
            var sAsk = Canvas.FormatValue((double)cluster.Ask);
 
            info.Add(new IndicatorValueInfo(sAsk, AskColor));
 
            return info;
        }
 
        public override void GetLabels(ref List<IndicatorLabelInfo> labels)
        {
            if (DataProvider.Count <= Canvas.Start)
            {
                return;
            }
 
            var cluster = DataProvider.GetCluster(DataProvider.Count - 1 - Canvas.Start);
 
            if (cluster == null)
            {
                return;
            }
 
            labels.Add(new IndicatorLabelInfo((double)cluster.Bid, BidColor));
            labels.Add(new IndicatorLabelInfo((double)cluster.Ask, AskColor));
        }
 
        public override bool CheckAlert(double value, int distance, ref int lastIndex, ref double lastValue)
        {
            if (DataProvider.Count == lastIndex && value == lastValue)
            {
                return false;
            }
 
            var cluster = DataProvider.GetCluster(DataProvider.Count - 1);
 
            if (cluster == null)
            {
                return false;
            }
 
            var result = false;
 
            if (value > 0 && (double)cluster.Ask >= value - distance)
            {
                result = true;
            }
            else if (value < 0 && (double)cluster.Bid <= value + distance)
            {
                result = true;
            }
 
            if (result == false)
            {
                return false;
            }
 
            lastIndex = DataProvider.Count;
            lastValue = value;
 
            return true;
        }
 
        public override void ApplyColors(IChartTheme theme)
        {
            BidColor = theme.PaletteColor7;
            AskColor = theme.PaletteColor6;
 
            base.ApplyColors(theme);
        }
 
        public override void CopyTemplate(IndicatorBase indicator, bool style)
        {
            var i = (BidAskIndicator)indicator;
 
            BidColor = i.BidColor;
            AskColor = i.AskColor;
 
            base.CopyTemplate(indicator, style);
        }
    }
}

Last updated