c# - 从前一天开始的EMA指数移动平均线问题
问题描述
简要描述;简介:
我得到了下面的简单移动平均线和指数移动平均线公式。第一根蜡烛的 EMA(前一天)差异很大。那是因为我没有前一天 EMA 的数据,而这个公式使用的是 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 的 value 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
这使得我使用的公式是正确的。根据我的公式计算的 SMAyesterdaysEMA
是 0.02046000。与0.020580相比,有很大的不同。
问题是如何将公式与币安的第一个蜡烛 EMA(5) 数据同步?
编辑:如果前一天的 EMA 没有数据,我看到 Binance 正在使用收盘价。这让我想知道我应该计算多少蜡烛,这样我才能接近它们的值。
数据(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;
}
}
编辑:我读了这篇不错的文章,显然不可能像 Binance 那样计算 100% 准确,因为我没有计算整个周期,而只计算了几根蜡烛。据我了解,EMA 通常取第一个元素的收盘价(今天的价格),但这只是在我们计算整个周期时。由于我没有这样做,因此计算第一个元素的 SMA 会更准确。在下图中,您可以看到我计算了第一个元素的 SMA,而不是前一天我没有的 EMA。通过这种方式,这些值会更准确一些。我想知道我必须计算多少个 EMA,所以它的准确率接近 99.9%。有人可以证实这一点或提出一些建议吗?代码如下。您可以使用Binance 进行测试。.
// 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;
}
解决方案
推荐阅读
- amazon-web-services - dynamoDB 是否对受限制的请求收费?
- python - 将电子邮件发送到带有附件的电子邮件
- html - 如何在悬停时更改跨度 ID 文本?(CSS)
- javascript - 表单无效时停止向表单动态添加字段
- python - Python AttributeError:“序列”对象没有属性“序列”
- html - 使用容器流体在引导程序中填充
- sql - Oracle 返回 ORA-00904: 添加外键时出现无效标识符错误
- r - tidyverse:替换字符串中的特殊字符
- amazon-web-services - android中的aws-sdk反应本机设置
- swift - 为什么它在 SwiftUI 中总是说“无法将类型''的值转换为预期的参数类型''”