Algo2

Algo2

namespace ATAS.Indicators.Technical
{
using ATAS.Indicators.Drawing;
using OFT.Attributes;
using OFT.Localization;
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using CrossColor = System.Windows.Media.Color;

public enum Side
{
Buy,
Sell
}

[DisplayName(“COT High/LowAtas”)]
[Display(ResourceType = typeof(Strings), Description = nameof(Strings.RatioDescription))]
[HelpLink(“https://help.atas.net/en/support/solutions/articles/72000602282”)]
public class CotHighAtas : Indicator
{
#region Nested types

private class RatioSign
{
public readonly int Bar;
public readonly int Direction;
public readonly double Price;
public readonly double Ratio;

public RatioSign(int bar, int direction, double ratio, double price)
{
Bar = bar;
Direction = direction;
Ratio = ratio;
Price = price;
}
}

#endregion

#region Static and constants

public const int Call = 1;
public const int Put = -1;
public const int Wait = 0;

#endregion

#region Fields

private CrossColor _bgColor = DefaultColors.Yellow.Convert();
private int _days = 20;
private int _fontSize = 10;
private CrossColor _highColor = DefaultColors.Blue.Convert();
private CrossColor _lowColor = DefaultColors.Green.Convert();
private decimal _lowRatio = 0.71m;
private CrossColor _neutralColor = DefaultColors.Gray.Convert();
private decimal _neutralRatio = 29m;
private int _targetBar;
public int CallPutCount;

#endregion

#region Properties

[Display(ResourceType = typeof(Strings), GroupName = nameof(Strings.Settings), Name = nameof(Strings.LowRatio), Description = nameof(Strings.LowRatioDescription), Order = 20)]
public decimal LowRatio
{
get => _lowRatio;
set
{
_lowRatio = value;
ReDraw();
}
}

[Display(ResourceType = typeof(Strings), GroupName = nameof(Strings.Settings), Name = nameof(Strings.NeutralRatio), Description = nameof(Strings.HighRatioDescription), Order = 21)]
public decimal NeutralRatio
{
get => _neutralRatio;
set
{
_neutralRatio = value;
ReDraw();
}
}

[Display(ResourceType = typeof(Strings), GroupName = nameof(Strings.Calculation), Name = nameof(Strings.DaysLookBack), Order = int.MaxValue, Description = nameof(Strings.DaysLookBackDescription))]
[Range(0, 1000)]
public int Days
{
get => _days;
set
{
if (value < 0) return; _days = value; RecalculateValues(); } } [Display(ResourceType = typeof(Strings), GroupName = nameof(Strings.Colors), Name = nameof(Strings.LowColor), Description = nameof(Strings.LowRatioColorDescription), Order = 10)] public CrossColor LowColor { get => _lowColor;
set
{
_lowColor = value;
ReDraw();
}
}

[Display(ResourceType = typeof(Strings), GroupName = nameof(Strings.Colors), Name = nameof(Strings.NeutralColor), Description = nameof(Strings.NeutralRatioColorDescription), Order = 11)]
public CrossColor NeutralColor
{
get => _neutralColor;
set
{
_neutralColor = value;
ReDraw();
}
}

[Display(ResourceType = typeof(Strings), GroupName = nameof(Strings.Colors), Name = nameof(Strings.HighColor), Description = nameof(Strings.HighRatioColorDescription), Order = 12)]
public CrossColor HighColor
{
get => _highColor;
set
{
_highColor = value;
ReDraw();
}
}

[Display(ResourceType = typeof(Strings), GroupName = nameof(Strings.Colors), Name = nameof(Strings.BackGround), Description = nameof(Strings.FillColorDescription), Order = 13)]
public CrossColor BackgroundColor
{
get => _bgColor;
set
{
_bgColor = value;
ReDraw();
}
}

[Display(ResourceType = typeof(Strings), GroupName = nameof(Strings.Colors), Name = nameof(Strings.FontSize), Description = nameof(Strings.FontSizeDescription), Order = 22)]
[Range(1, 10000)]
public int FontSize
{
get => _fontSize;
set
{
_fontSize = value;
ReDraw();
}
}

#endregion

#region ctor

public CotHighAtas()
: base(true)
{
DataSeries[0].IsHidden = true;
DenyToChangePanel = true;
}

#endregion

#region Protected methods

protected override void OnCalculate(int bar, decimal value)
{
if (bar == 0)
{
return;
}

var candle = GetCandle(bar);
var cotBar = new CommitmentOfTradersBar();

decimal cotHigh = 0;
decimal cotLow = 0;
decimal highestPrice = candle.High;
decimal lowestPrice = candle.Low;

decimal totalBuyVolume = 0;
decimal totalSellVolume = 0;

decimal previousPrice = candle.Open;

for (var price = candle.Low; price <= candle.High; price += InstrumentInfo.TickSize) { var volumeInfo = candle.GetPriceVolumeInfo(price); if (volumeInfo == null) continue; var buySize = volumeInfo.Ask; var sellSize = volumeInfo.Bid; totalBuyVolume += buySize; totalSellVolume += sellSize; if (price > highestPrice)
{
highestPrice = price;
cotHigh = 0;
}
else
{
cotHigh += (price > previousPrice) ? buySize : -sellSize; // ????????? ???????? ????
}

if (price < lowestPrice) { lowestPrice = price; cotLow = 0; } else { cotLow += (price < previousPrice) ? -sellSize : buySize; // ?????????? ??? Low } previousPrice = price; Console.WriteLine($"Price: {price}, CotHigh: {cotHigh}, CotLow: {cotLow}, Buy: {totalBuyVolume}, Sell: {totalSellVolume}"); cotBar.Calculate((double)price, (double)(buySize + sellSize), buySize > sellSize ? Side.Buy : Side.Sell);
}

if (candle.Close == candle.High) cotHigh = 0;
if (candle.Close == candle.Low) cotLow = 0;

AddLabel(new RatioSign(bar, cotHigh > cotLow ? Call : Put,
(double)(cotHigh – cotLow),
cotHigh > cotLow ? (double)highestPrice : (double)lowestPrice));
}

#endregion

#region Private methods

Log($”{bar}: ????: {price}, COT High: {cotHigh}, COT Low: {cotLow}”);

private void AddLabel(RatioSign rs)
{
var bg = System.Drawing.Color.FromArgb(_bgColor.A, _bgColor.R, _bgColor.G, _bgColor.B);
var price = (decimal)rs.Price; // ?????????????? ? double
var labelName = “BAR_” + rs.Bar;

// ??????? ?????????? ????? ? ????? ?? ??????, ???? ??? ??????????
if (Labels.ContainsKey(labelName))
{
Labels.Remove(labelName);
}

var sRatio = rs.Ratio.ToString(“N2”).Replace(“,00”, “”);

// ????????? ????????? ????? ?? ??????
AddText(labelName, sRatio, true, rs.Bar, price, 0, 0,
System.Drawing.Color.FromArgb(_highColor.A, _highColor.R, _highColor.G, _highColor.B),
System.Drawing.Color.Transparent, bg, _fontSize, DrawingText.TextAlign.Center, _fontSize == 0);
}

private void ReDraw()
{
try
{
foreach (var label in Labels)
{
decimal ratio = 0;

// ??????? ????????????? ????? ????? ? ?????
if (decimal.TryParse(label.Value.Text, out var parsedRatio))
{
ratio = parsedRatio;
}

// ????????? ?????????? ?????
label.Value.AutoSize = _fontSize == 0;
label.Value.FontSize = _fontSize;
label.Value.XOffset = 0;
label.Value.FillColor = System.Drawing.Color.FromArgb(_bgColor.A, _bgColor.R, _bgColor.G, _bgColor.B);

// ????????? ????? ?????? ? ??????????? ?? ???????? ratio
if (ratio <= _lowRatio) { label.Value.Textcolor = System.Drawing.Color.FromArgb(_lowColor.A, _lowColor.R, _lowColor.G, _lowColor.B); } else if (ratio <= _neutralRatio) { label.Value.Textcolor = System.Drawing.Color.FromArgb(_neutralColor.A, _neutralColor.R, _neutralColor.G, _neutralColor.B); } else { label.Value.Textcolor = System.Drawing.Color.FromArgb(_highColor.A, _highColor.R, _highColor.G, _highColor.B); } } } catch (Exception ex) { // ??????????? ?????? (???? ??????????) Console.WriteLine($"?????? ? ReDraw: {ex.Message}"); } } #endregion } internal class CommitmentOfTradersBar { private double _highPrice = double.MinValue; private double _lowPrice = double.MaxValue; public double High { get; private set; } public double Low { get; private set; } public double HighPrice => _highPrice;
public double LowPrice => _lowPrice;

public void Calculate(double price, double size, Side side)
{
// ?????? High
if (_highPrice < price || _highPrice == double.MinValue) { _highPrice = price; High = 0; } if (side == Side.Buy) High += size; else High -= size; // ?????? Low if (_lowPrice > price || _lowPrice == double.MaxValue)
{
_lowPrice = price;
Low = 0;
}

if (side == Side.Buy)
Low -= size;
else
Low += size;
}
}

}