python - 计算 smma(平滑移动平均线)
python - calculating smma (smoothed moving average)
我正在尝试在 Python 中编写 smma(平滑移动平均线)。我从 tradingview 中的 pine 脚本中获取公式。
smma = 0.0
smma := na(smma[1]) ? ta.sma(src, length) : (smma[1] * (length - 1) + src) / length
因此,当没有先前的 smma 值时,我们应该采用 (src,length) 的简单移动平均线。接下来的计算是根据 (smma[1] * (length - 1) + src) / length。 smmma[1] 是之前的 smma 值。
这是我的代码:
def smma(src, length):
smma = 0.0
dataLength = len(src)
lookbackPeriod = dataLength - length
#first value of smma is the sma of src and length
#Convert list to dataframe
df = pd.DataFrame(src, columns = ['hl2'])
smma = df.rolling(window=length).mean()
smma = float(smma.iloc[-1])
log.info(f"First smma value = {smma}")
lookbackPeriod = dataLength - length + 1 #calculate smma for the other values
while (lookbackPeriod < dataLength):
smma = (smma * (length - 1) + float(src[lookbackPeriod])) / length
log.info(f"lookback = {lookbackPeriod} src[lookbackPeriod] = {src[lookbackPeriod]} smma = {smma}")
lookbackPeriod = lookbackPeriod + 1
return smma
周期长度为 5 的输出如下所示:
[2021-11-07 12:26:21,701] First smma value = 61842.0
[2021-11-07 12:26:21,701] lookback = 196 src[lookbackPeriod] = 61817.25 smma = 61837.05
[2021-11-07 12:26:21,701] lookback = 197 src[lookbackPeriod] = 61883.5 smma = 61846.340000000004
[2021-11-07 12:26:21,701] lookback = 198 src[lookbackPeriod] = 61867.75 smma = 61850.621999999996
[2021-11-07 12:26:21,702] lookback = 199 src[lookbackPeriod] = 61838.0 smma = 61848.0976
src 在我的例子中是一个包含 200 个值的列表。
当我将第一个 smma 的值与 sma 进行比较时,它与 Tradingview 上的值相比是正确的。与我在 Tradingview 上看到的相比,smma 的最终值不正确。 (我在这种情况下将其作为源 (high+low)/2 而不是收盘价,但是当我将其作为 Tradingview 中的源时它仍然无法正确显示)
有人能看出我做错了什么吗?
非常感谢!
最近我一直在为同样的问题而苦苦挣扎 - 通过我的代码计算的 SMMA 值与图表上的 TradingView 值。
问题是您可以找到各种计算 SMMA 的公式,例如:
chartmill.com
fxcorporate.com
老实说,到目前为止我无法获得准确的 TradingView 结果,但我发现 chartmill 结果最接近 TradingView 的结果。
我尝试在 Java 中实施 SMMA 作为 ta4j library 的扩展。请在下面找到我最近的结果。希望您觉得它有帮助,我们将一起找到正确的实施方式:
public class SMMAIndicator extends RecursiveCachedIndicator<Num> {
/**
* N - Number of periods, over which the indicator is calculated.
*/
private final int barCount;
private final Num n;
/**
* Usually ClosePriceIndicator
*/
private final Indicator<Num> indicator;
/**
* SMA to calculate 1st SMMA period per index
*/
private final SMAIndicator smaIndicator;
public SMMAIndicator(Indicator<Num> indicator, int barCount) {
super(indicator.getBarSeries());
this.barCount = barCount;
this.n = numOf(barCount);
this.indicator = indicator;
this.smaIndicator = new SMAIndicator(indicator, barCount);
}
@Override
public Num calculate(int index) {
var i = max(0, index - barCount + 1);
if (i == 0) {
return smaIndicator.getValue(index);
}
if (i == 1) {
var nMinus1 = n.minus(numOf(1));
var smma0 = getValue(index - 1);
var input = indicator.getValue(index);
return smma0.multipliedBy(nMinus1).plus(input).dividedBy(n);
}
var prevSmma = getValue(index - 1);
var prevSum = prevSmma.multipliedBy(n);
return prevSum.minus(prevSmma).plus(indicator.getValue(index)).dividedBy(n);
}
}
我找到了解决办法。您只需要在足够大的样本量上进行计算。在我的例子中,计算周期为 5 的 smma 不应在 5 个数据点上 运行,但在 200 的大小上我有正确的值。
因此,计算前 5 个数据点的简单移动平均值,然后开始对剩余 195 个数据点进行 smma 计算。 smma 的最后一个值是与 Tradingview 中的值匹配的正确值。
我正在尝试在 Python 中编写 smma(平滑移动平均线)。我从 tradingview 中的 pine 脚本中获取公式。
smma = 0.0
smma := na(smma[1]) ? ta.sma(src, length) : (smma[1] * (length - 1) + src) / length
因此,当没有先前的 smma 值时,我们应该采用 (src,length) 的简单移动平均线。接下来的计算是根据 (smma[1] * (length - 1) + src) / length。 smmma[1] 是之前的 smma 值。
这是我的代码:
def smma(src, length):
smma = 0.0
dataLength = len(src)
lookbackPeriod = dataLength - length
#first value of smma is the sma of src and length
#Convert list to dataframe
df = pd.DataFrame(src, columns = ['hl2'])
smma = df.rolling(window=length).mean()
smma = float(smma.iloc[-1])
log.info(f"First smma value = {smma}")
lookbackPeriod = dataLength - length + 1 #calculate smma for the other values
while (lookbackPeriod < dataLength):
smma = (smma * (length - 1) + float(src[lookbackPeriod])) / length
log.info(f"lookback = {lookbackPeriod} src[lookbackPeriod] = {src[lookbackPeriod]} smma = {smma}")
lookbackPeriod = lookbackPeriod + 1
return smma
周期长度为 5 的输出如下所示:
[2021-11-07 12:26:21,701] First smma value = 61842.0
[2021-11-07 12:26:21,701] lookback = 196 src[lookbackPeriod] = 61817.25 smma = 61837.05
[2021-11-07 12:26:21,701] lookback = 197 src[lookbackPeriod] = 61883.5 smma = 61846.340000000004
[2021-11-07 12:26:21,701] lookback = 198 src[lookbackPeriod] = 61867.75 smma = 61850.621999999996
[2021-11-07 12:26:21,702] lookback = 199 src[lookbackPeriod] = 61838.0 smma = 61848.0976
src 在我的例子中是一个包含 200 个值的列表。 当我将第一个 smma 的值与 sma 进行比较时,它与 Tradingview 上的值相比是正确的。与我在 Tradingview 上看到的相比,smma 的最终值不正确。 (我在这种情况下将其作为源 (high+low)/2 而不是收盘价,但是当我将其作为 Tradingview 中的源时它仍然无法正确显示)
有人能看出我做错了什么吗?
非常感谢!
最近我一直在为同样的问题而苦苦挣扎 - 通过我的代码计算的 SMMA 值与图表上的 TradingView 值。
问题是您可以找到各种计算 SMMA 的公式,例如:
chartmill.com
fxcorporate.com
老实说,到目前为止我无法获得准确的 TradingView 结果,但我发现 chartmill 结果最接近 TradingView 的结果。
我尝试在 Java 中实施 SMMA 作为 ta4j library 的扩展。请在下面找到我最近的结果。希望您觉得它有帮助,我们将一起找到正确的实施方式:
public class SMMAIndicator extends RecursiveCachedIndicator<Num> {
/**
* N - Number of periods, over which the indicator is calculated.
*/
private final int barCount;
private final Num n;
/**
* Usually ClosePriceIndicator
*/
private final Indicator<Num> indicator;
/**
* SMA to calculate 1st SMMA period per index
*/
private final SMAIndicator smaIndicator;
public SMMAIndicator(Indicator<Num> indicator, int barCount) {
super(indicator.getBarSeries());
this.barCount = barCount;
this.n = numOf(barCount);
this.indicator = indicator;
this.smaIndicator = new SMAIndicator(indicator, barCount);
}
@Override
public Num calculate(int index) {
var i = max(0, index - barCount + 1);
if (i == 0) {
return smaIndicator.getValue(index);
}
if (i == 1) {
var nMinus1 = n.minus(numOf(1));
var smma0 = getValue(index - 1);
var input = indicator.getValue(index);
return smma0.multipliedBy(nMinus1).plus(input).dividedBy(n);
}
var prevSmma = getValue(index - 1);
var prevSum = prevSmma.multipliedBy(n);
return prevSum.minus(prevSmma).plus(indicator.getValue(index)).dividedBy(n);
}
}
我找到了解决办法。您只需要在足够大的样本量上进行计算。在我的例子中,计算周期为 5 的 smma 不应在 5 个数据点上 运行,但在 200 的大小上我有正确的值。 因此,计算前 5 个数据点的简单移动平均值,然后开始对剩余 195 个数据点进行 smma 计算。 smma 的最后一个值是与 Tradingview 中的值匹配的正确值。