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