StackOverflow 上的第一个问题,如果我的问题不清楚,我深表歉意。
我正在尝试使用 Java 创建赫尔移动平均线,但显然我陷入了困境。
我在互联网上能找到的唯一公式如下(n == 天数):
HMA = WMA(2 * WMA(n/2) − WMA(n)), sqrt(n))
在 TradingView 的 PineScript 编辑器上,我有一个可用的 HMA,尽管我个人并不理解它是如何工作的:
f_hma(_src, _length)=>
//HMA = WMA(2*WMA(n/2) − WMA(n)),sqrt(n))
_return = wma((2 * wma(_src, _length / 2)) - wma(_src, _length), round(sqrt(_length)))
src = input(close)
length = input(250)
hma = f_hma(src, length)
plot(series=hma, title='250 HMA', color=#F39C12)
好吧,不知何故我已经走到这一步了。
现在我正在尝试用 Java 创建它,但这就是一切都向南的地方。
如何计算输入为 1 且长度为周期平方根的 WMA?
例如:
public double hma(String crypto, int period) {
// Fetching data from JPA
Pageable paging = PageRequest.of(0, period, Sort.by("dateTime").descending());
Page<CryptoData> dataPage = cryptoRepo.findCryptoDataByName(crypto, paging);
List<Double> prices = new ArrayList<>();
// Sorting data
for (int i = dataPage.getSize(); i > 0; i--) {
prices.add(dataPage.getContent().get(i - 1).getClose());
}
// hma calculations start here:
double wma1 = 2 * wma(prices, (int)Math.round(period / 2.0));
double wma2 = wma(prices, period);
// According to the internet formula, this should be the 'smoothing wma', but it makes no sense to me.
return wma(List.of(wma1 - wma2), (int)Math.round(sqrt(period)));
}
我当前创建的帮助 wma 函数:
public double wma(List<Double> prices, int period) {
List<Double> updatedList = new ArrayList<>();
// For wma1, only use the last half of the prices list
if (period == prices.size() / 2) {
for (int i = 0; i < prices.size(); i++) {
if (i >= period) {
updatedList.add(prices.get(i));
}
}
}
// For the hma's returning wma value
else if (period > prices.size()) {
// I have no idea what to do here.
// prices.size() == 1 so there's nothing to calculate the wma with.
}
// For wma2, use the whole prices list
else {
updatedList = prices;
}
// WMA calculations, this part is a-okay.
double totalWeight = ((double)period * (period + 1)) / 2;
double pricePoint = 0;
double weightCounter = 1;
for (Double value: updatedList) {
// https://blog.earn2trade.com/weighted-moving-average/
double wma = value * (weightCounter / totalWeight);
pricePoint += wma;
weightCounter++;
}
return pricePoint;
}
我有什么误解吗?
我做了一个计算wma的库,我和你分享
package com.personal.tools;
public class WMA {
private int period;
public WMA(int period) {
this.period = period;
}
public double[] calculate(final double[] prizes) {
double[] results = new double[prizes.length - period + 1];
double wma;
int j = 0;
for (int i = period - 1; i < prizes.length; i++) {
double[] prizesAux = new double[period];
System.arraycopy(prizes, i - period + 1, prizesAux, 0, period);
wma = calculateWMA(prizesAux);
results[j++] = wma;
}
return results;
}
private double calculateWMA(final double[] prizes){
double wma=0.0;
int total = 0;
for (int i = 0; i < prizes.length; i++) {
wma += prizes[i]*(i+1);
total+= i+1;
}
wma= wma/(double)total;
return wma;
}
}
我也分享你如何使用它:
package com.personal.pruebas;
import com.personal.tools.WMA;
import java.util.Arrays;
public class PruebaWMA {
public PruebaWMA() {
double[] precios = {32.52,35.19,48.63,45.54,31.17,41.77,25.07,-1.67,25.60,8.42,4.07,10.05,11.60,12.80,9.24,-1.95,5.30,15.70};
WMA wma =new WMA(10);
double[] wmaTable = wma.calculate(precios);
Arrays.stream(wmaTable).forEach(System.out::println);
}
public static void main(String[] args) {
new PruebaWMA();
}
}
希望对你有帮助