Экспоненциальная скользящая средняя проблема с EMA из предыдущего дня в начале - PullRequest
1 голос
/ 24 февраля 2020

Краткое описание:

Ниже приведены простые формулы скользящего среднего и экспоненциального скользящего среднего. ЕМА (предыдущий день) для первой свечи резко отличается. Это потому, что у меня нет данных для ЕМА предыдущего дня, и вместо этого в этой формуле используется SMA. Соответствующая строка: yesterdaysEMA = CalculateSimpleMovingAverage(numberOfDays, historicalDataList);. Я не совсем уверен, как Binance / TradingView получает первое значение.

Подробнее:

Я рассчитываю EMA (5) для вложенных свечей на рисунке ниже.

Фактические значения из Binance:

Candle 1: EMA(5) = 0.020547
Candle 2: EMA(5) = 0.020558
Candle 3: EMA(5) = 0.020529
Candle 4: EMA(5) = 0.020506
Candle 5: EMA(5) = 0.020441

Если я вручную установлю yesterdaysEMA, чтобы соответствовать значению binance 0.020580, я получу следующие значения:

Candle 1: EMA(5) = 0.0205466666666666666666666667
Candle 2: EMA(5) = 0.0205577777777777777777777778
Candle 3: EMA(5) = 0.0205285185185185185185185185
Candle 4: EMA(5) = 0.0205056790123456790123456790
Candle 5: EMA(5) = 0.0204404526748971193415637860

Что делает формулу я использую правильно. Расчетная SMA для yesterdaysEMA по моей формуле составляет 0,02046000. По сравнению с 0.020580 существует огромная разница.

Вопрос в том, как мне синхронизировать формулу с данными EMA (5) первой свечи Бинанса?

РЕДАКТИРОВАТЬ : я видел, что Binance использует значение закрытия, если нет данных для EMA предыдущего дня. Это заставляет меня задаться вопросом, сколько свечей я должен рассчитать, поэтому я могу приблизиться к их значениям.

enter image description here

Данные (TRX / USDT - интервал 30 минут ):

Open time (UTC): 2/23/2020 9:30:00 PM
Close time (UTC): 2/23/2020 9:59:59 PM
High: 0.02091000
Low: 0.02079000
Open: 0.02091000
Close: 0.02083000

Open time (UTC): 2/23/2020 10:00:00 PM
Close time (UTC): 2/23/2020 10:29:59 PM
High: 0.02086000
Low: 0.02076000
Open: 0.02084000
Close: 0.02077000

Open time (UTC): 2/23/2020 10:30:00 PM
Close time (UTC): 2/23/2020 10:59:59 PM
High: 0.02107000
Low: 0.02076000
Open: 0.02076000
Close: 0.02101000

Open time (UTC): 2/23/2020 11:00:00 PM
Close time (UTC): 2/23/2020 11:29:59 PM
High: 0.02124000
Low: 0.02100000
Open: 0.02101000
Close: 0.02122000

Open time (UTC): 2/23/2020 11:30:00 PM
Close time (UTC): 2/23/2020 11:59:59 PM
High: 0.02142000
Low: 0.02120000
Open: 0.02122000
Close: 0.02133000

Open time (UTC): 2/24/2020 12:00:00 AM
Close time (UTC): 2/24/2020 12:29:59 AM
High: 0.02136000
Low: 0.02117000
Open: 0.02133000
Close: 0.02131000

Open time (UTC): 2/24/2020 12:30:00 AM
Close time (UTC): 2/24/2020 12:59:59 AM
High: 0.02134000
Low: 0.02116000
Open: 0.02131000
Close: 0.02122000

Open time (UTC): 2/24/2020 1:00:00 AM
Close time (UTC): 2/24/2020 1:29:59 AM
High: 0.02123000
Low: 0.02107000
Open: 0.02122000
Close: 0.02112000

Open time (UTC): 2/24/2020 1:30:00 AM
Close time (UTC): 2/24/2020 1:59:59 AM
High: 0.02113000
Low: 0.02098000
Open: 0.02112000
Close: 0.02100000

Open time (UTC): 2/24/2020 2:00:00 AM
Close time (UTC): 2/24/2020 2:29:59 AM
High: 0.02112000
Low: 0.02096000
Open: 0.02101000
Close: 0.02099000

Open time (UTC): 2/24/2020 2:30:00 AM
Close time (UTC): 2/24/2020 2:59:59 AM
High: 0.02099000
Low: 0.02011000
Open: 0.02098000
Close: 0.02045000

Open time (UTC): 2/24/2020 3:00:00 AM
Close time (UTC): 2/24/2020 3:29:59 AM
High: 0.02058000
Low: 0.02035000
Open: 0.02047000
Close: 0.02041000

Open time (UTC): 2/24/2020 3:30:00 AM
Close time (UTC): 2/24/2020 3:59:59 AM
High: 0.02061000
Low: 0.02040000
Open: 0.02041000
Close: 0.02055000

Open time (UTC): 2/24/2020 4:00:00 AM
Close time (UTC): 2/24/2020 4:29:59 AM
High: 0.02055000
Low: 0.02040000
Open: 0.02054000
Close: 0.02044000

Open time (UTC): 2/24/2020 4:30:00 AM
Close time (UTC): 2/24/2020 4:59:59 AM
High: 0.02058000
Low: 0.02042000
Open: 0.02044000
Close: 0.02057000

Open time (UTC): 2/24/2020 5:00:00 AM
Close time (UTC): 2/24/2020 5:29:59 AM
High: 0.02056000
Low: 0.02046000
Open: 0.02056000
Close: 0.02048000

Open time (UTC): 2/24/2020 5:30:00 AM
Close time (UTC): 2/24/2020 5:59:59 AM
High: 0.02061000
Low: 0.02047000
Open: 0.02048000
Close: 0.02058000

Open time (UTC): 2/24/2020 6:00:00 AM
Close time (UTC): 2/24/2020 6:29:59 AM
High: 0.02060000
Low: 0.02047000
Open: 0.02060000
Close: 0.02047000

Open time (UTC): 2/24/2020 6:30:00 AM
Close time (UTC): 2/24/2020 6:59:59 AM
High: 0.02054000
Low: 0.02039000
Open: 0.02048000
Close: 0.02046000

Open time (UTC): 2/24/2020 7:00:00 AM
Close time (UTC): 2/24/2020 7:29:59 AM
High: 0.02044000
Low: 0.02019000
Open: 0.02044000
Close: 0.02031000
public class ExponentialMovingAverage
{
    public static decimal CalculateSimpleMovingAverage(int numberOfDays, List<BinanceKline> historicalDataList)
    {
        if (historicalDataList.Count >= numberOfDays)
        {
            decimal sumOfAllOnClose = 0;
            for (int i = 0; i < numberOfDays; i++)
            {
                sumOfAllOnClose = sumOfAllOnClose + historicalDataList[i].Close;
            }

            return sumOfAllOnClose / numberOfDays;
        }
        else
            return 0;
    }

    public static decimal ExponentialMovingAverageFormula(decimal todaysPrice, decimal yesterdaysEMA, decimal numberOfDays)
    {
        decimal multiplier = (2 / (numberOfDays + 1));
        return (todaysPrice - yesterdaysEMA) * multiplier + yesterdaysEMA;
    }

    public static decimal CalculateExponentialMovingAverage(int numberOfDays, List<BinanceKline> historicalDataList)
    {
        decimal yesterdaysEMA = 0;
        if (historicalDataList.Count >= numberOfDays)
        {
            decimal sumOfEMA = 0;
            for (int i = 0; i < numberOfDays; i++)
            {
                if (i == 0)
                {
                    yesterdaysEMA = CalculateSimpleMovingAverage(numberOfDays, historicalDataList);
                }
                decimal eMA = ExponentialMovingAverageFormula(historicalDataList[i].Close, yesterdaysEMA, numberOfDays);
                sumOfEMA += eMA;
                yesterdaysEMA = eMA;
            }

            return sumOfEMA / numberOfDays;
        }
        else
            return 0;
    }
}

Редактировать : я прочитал эту замечательную статью и, по-видимому, невозможно рассчитать ее на 100% точно, как это сделал Бинанс, потому что я Я не рассчитываю весь цикл, а только несколько свечей назад. Насколько я понимаю, EMA обычно принимает значение закрытия (цена на сегодня) для первого элемента, но это только тогда, когда мы рассчитываем весь цикл. Поскольку я этого не делаю, более точно рассчитать SMA для первого элемента. На рисунке ниже вы можете видеть, что я вычислил SMA для первого элемента вместо EMA для предыдущего дня, которого у меня нет. Значения немного более точны в этом смысле. Интересно, сколько EMA мне нужно рассчитать, чтобы получить точность 99,9%. Может кто-то подтвердить это или предложить что-то? Код ниже. Вы можете проверить с помощью Binance. Net Пакет NuGet .

enter image description here

// Usage
var klines = _client.GetKlines("TRXUSDT", KlineInterval.ThirtyMinutes, limit: 11).Data.ToList();
var previousCandles = klines.Skip(1).Take(5).ToList();
var candles = klines.SkipLast(1).TakeLast(5).ToList();

// Code
public static decimal SMA(int period, List<BinanceKline> candles)
{
    if (candles.Count >= period)
    {
        decimal sum = 0;
        for (int i = 0; i < period; i++)
        {
            sum += candles[i].Close;
        }
        return sum / period;
    }
    return 0;
}

public static decimal EMA(decimal close, decimal previousDayEMA, decimal period)
{
    decimal multiplier = 2 / (period + 1);
    return (close - previousDayEMA) * multiplier + previousDayEMA;
}

public static decimal Calculate(int period, List<BinanceKline> candles, List<BinanceKline> previousCandles)
{
    decimal previousDayEMA = 0;
    if (candles.Count >= period)
    {
        decimal sum = 0;
        for (int i = 0; i < period; i++)
        {
            if (i == 0)
            {
                previousDayEMA = SMA(period, previousCandles); // candles[i].Close; // SMA(period, candles);

                Console.WriteLine($"SMA = {Math.Round(previousDayEMA, 6, MidpointRounding.AwayFromZero)}");
            }

            decimal EMA = ExponentialMovingAverage.EMA(candles[i].Close, previousDayEMA, period);

            Console.WriteLine($"EMA(5) = {Math.Round(EMA, 6, MidpointRounding.AwayFromZero)} | EMA5 = {EMA}");

            sum += EMA;
            previousDayEMA = EMA;
        }
        return sum / period;
    }
    return 0;
}
...