自定义软件复现TradingView EMA计算结果不符问题排查
复现TradingView EMA计算结果不一致的问题解决
问题背景
尝试在自定义软件中复现TradingView的EMA计算逻辑,但结果与TradingView存在偏差,例如2024-01-09的EMA预期值为84.99,自行计算结果为83.919...,后续数值也全部偏离。
原始代码
var closePrices = new List<(string, decimal)> { ("2024-01-03 00:00:00.0000000" , 84.0600000000m), ("2024-01-04 00:00:00.0000000" , 96.8900000000m), ("2024-01-05 00:00:00.0000000" , 89.6400000000m), ("2024-01-06 00:00:00.0000000" , 80.4300000000m), ("2024-01-07 00:00:00.0000000" , 73.1800000000m), ("2024-01-08 00:00:00.0000000" , 85.3900000000m), ("2024-01-09 00:00:00.0000000" , 85.3400000000m), ("2024-01-10 00:00:00.0000000" , 97.9800000000m), ("2024-01-11 00:00:00.0000000" , 108.0600000000m) }; var emas = CalculateEMA(closePrices, 7); foreach(var ema in emas) { Console.WriteLine(ema); } static List<(string, decimal)> CalculateEMA(List<(string,decimal)> prices, int period) { List<(string, decimal)> ema = new List<(string, decimal)>(); decimal alpha = 2m / (period + 1); ema.Add(prices[0]); for (int i = 1; i < prices.Count; i++) { decimal value = alpha * prices[i].Item2 + (1 - alpha) * ema[i - 1].Item2; ema.Add((prices[i].Item1, value)); } return ema; }
原始输出
(2024-01-03 00:00:00.0000000, 84,0600000000) (2024-01-04 00:00:00.0000000, 87,267500000000) (2024-01-05 00:00:00.0000000, 87,86062500000000) (2024-01-06 00:00:00.0000000, 86,0029687500000000) (2024-01-07 00:00:00.0000000, 82,797226562500000000) (2024-01-08 00:00:00.0000000, 83,44541992187500000000) (2024-01-09 00:00:00.0000000, 83,9190649414062500000000) <- should be 84,99 (2024-01-10 00:00:00.0000000, 87,434298706054687500000000) (2024-01-11 00:00:00.0000000, 92,59072402954101562500000000)
核心问题
TradingView的EMA计算并非以第一个价格作为初始值,而是先计算前period个价格的简单移动平均线(SMA)作为第一个EMA值,之后再用EMA公式迭代计算后续值。你的代码直接将第一个价格作为初始EMA,这是导致结果偏差的根本原因。
修改后的代码
调整CalculateEMA方法,先计算周期长度的SMA作为初始EMA:
static List<(string, decimal)> CalculateEMA(List<(string, decimal)> prices, int period) { List<(string, decimal)> ema = new List<(string, decimal)>(); decimal alpha = 2m / (period + 1); // 填充周期前的数据(TradingView会显示无数据,这里保留原始价格对齐索引) for (int i = 0; i < period - 1; i++) { ema.Add((prices[i].Item1, prices[i].Item2)); } // 计算前period个价格的SMA作为初始EMA decimal initialSma = prices.Take(period).Sum(p => p.Item2) / period; ema.Add((prices[period - 1].Item1, initialSma)); // 从第period个数据开始迭代计算EMA for (int i = period; i < prices.Count; i++) { decimal value = alpha * prices[i].Item2 + (1 - alpha) * ema[i - 1].Item2; ema.Add((prices[i].Item1, value)); } return ema; }
验证结果
修改后,2024-01-09的EMA值会和预期一致:
- 前7个价格的SMA计算:
(84.06+96.89+89.64+80.43+73.18+85.39+85.34)/7 = 594.93/7 ≈ 84.99,正好是你预期的数值。后续迭代计算会基于这个初始值,结果将完全匹配TradingView的输出。
内容的提问来源于stack exchange,提问作者Steffx115
相关产品推荐
相关产品推荐

