Выход индикатора True True Range (ATR) по некоторым причинам отличается от выходов TradingView. Я сделал это, следуя их расчетам и до сих пор не точным. Кстати, я рассчитываю это для последних 500 свечей, так что проблема наверняка в формулах.
Если вы посмотрите здесь: https://www.binance.com/en/trade/pro/TRX_USDT, Binance имеет реализации графика TradingView , Результаты вывода, которые я опубликовал, относятся к интервалу 1 ч.
Формулы ATR из вики TradingView здесь: https://www.tradingview.com/wiki/Average_True_Range_ (ATR) # РАСЧЕТ
Текущий максимум периода минус (-) Низкий текущий период
Абсолютное значение (abs) максимума текущего периода минус (-) Закрытие предыдущего периода
Абсолютное значение (abs) минимума текущего периода минус (-) Закрытие предыдущего периода
истинный диапазон = max [(максимум - минимум), abs (максимум - предыдущее закрытие), abs (минимум - предыдущее закрытие)]
ATR является Экспоненциальная скользящая средняя истинного диапазона
Какие-либо предложения, которые я мог бы изменить, чтобы достичь того же результата? Я попытался использовать SMA для ATR, но все равно другой вывод.
Вывод (последние несколько цифр):
0.000099
0.000110
0.000112
Какой он должен быть:
0.000111
0.000116
0.000117
// Usage
var candles = Client.GetKlines("TRXUSDT", KlineInterval.OneHour, limit: 500).Data.ToList();
ATR atr = new ATR(14);
var atr = atr.Calculate(candles.Select(e => (e.High, e.Low, e.Close)).ToList());
for (int i = 0; i < atr.Length - 1; i++)
{
Console.WriteLine($"{atr[i]:f6}");
}
/// <summary>
/// Average True Range indicator.
/// </summary>
public class ATR
{
/// <summary>
/// Indicator period.
/// </summary>
private readonly int _period;
/// <summary>
/// Initialization.
/// </summary>
/// <param name="period">Indicator period.</param>
public ATR(int period)
{
_period = period;
}
/// <summary>
/// Calculates the indicator.
/// https://www.tradingview.com/wiki/Average_True_Range_(ATR)#CALCULATION
/// </summary>
/// <param name="prices">Price series.</param>
/// <returns>Calculated indicator series.</returns>
public decimal[] Calculate(IReadOnlyList<(decimal High, decimal Low, decimal Close)> prices)
{
var temp = new decimal[prices.Count];
temp[0] = 0;
for (var i = 1; i < prices.Count; i++)
{
var trueHigh = Math.Abs(prices[i].High - prices[i - 1].Close);
var trueLow = Math.Abs(prices[i].Low - prices[i - 1].Close);
var trueRange = prices[i].High - prices[i].Low;
var max = trueHigh > trueLow ? trueHigh : trueLow;
temp[i] = max > trueRange ? max : trueRange;
}
var atr = new EMA(_period).Calculate(temp);
return atr;
}
}
/// <summary>
/// Exponential Moving Average indicator.
/// </summary>
public class EMA
{
/// <summary>
/// Indicator period.
/// </summary>
private readonly int _period;
/// <summary>
/// Initialization.
/// </summary>
/// <param name="period">Indicator period.</param>
public EMA(int period)
{
_period = period;
}
/// <summary>
/// Calculates the indicator.
/// </summary>
/// <param name="prices">Price series.</param>
/// <returns>Calculated indicator series.</returns>
public decimal[] Calculate(decimal[] prices)
{
var ema = new decimal[prices.Length];
decimal sum = prices[0];
decimal smoothingFactor = 2m / (_period + 1m);
for (int i = 0; i < prices.Length; i++)
{
sum = smoothingFactor * prices[i] + (1m - smoothingFactor) * sum;
ema[i] = sum;
}
return ema;
}
}