使用Java计算船体移动平均值

问题描述 投票:0回答:1

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;
    }

我有什么误解吗?

java algorithmic-trading moving-average technical-indicator
1个回答
0
投票

我做了一个计算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();
}
}

希望对你有帮助

© www.soinside.com 2019 - 2024. All rights reserved.