You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Java正确实现赫尔移动平均线(HMA)计算逻辑

Java实现赫尔移动平均线(HMA)的逻辑误区提问

这是我首次在Stack Overflow提问,若问题表述不够清晰还请谅解。

我目前尝试使用Java实现赫尔移动平均线(Hull Moving Average, HMA),但在实现过程中遇到了逻辑卡点。

我在全网查到的唯一HMA计算公式如下(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时出现了问题,核心疑问是:当WMA的输入序列长度为1、计算周期为原周期的平方根时,应当如何完成WMA计算?

我当前编写的Java版HMA实现代码如下:

public double hma(String crypto, int period) {
        // 从JPA拉取数据
        Pageable paging = PageRequest.of(0, period, Sort.by("dateTime").descending());
        Page<CryptoData> dataPage = cryptoRepo.findCryptoDataByName(crypto, paging);
        List<Double> prices = new ArrayList<>();
        
        // 对数据做时间正序排序
        for (int i = dataPage.getSize(); i > 0; i--) {
            prices.add(dataPage.getContent().get(i - 1).getClose());
        }
        
        // HMA计算流程
        double wma1 = 2 * wma(prices, (int)Math.round(period / 2.0));
        double wma2 = wma(prices, period);

        // 按照公开公式这里应该传入差值序列做平滑WMA计算,但我完全想不通实现逻辑
        return wma(List.of(wma1 - wma2), (int)Math.round(Math.sqrt(period)));
    }

我编写的辅助WMA计算函数代码如下:

public double wma(List<Double> prices, int period) {
        List<Double> updatedList = new ArrayList<>();

        // 计算半周期WMA时,仅取价格列表后半段数据
        if (period == prices.size() / 2) {
            for (int i = 0; i < prices.size(); i++) {
                if (i >= period) {
                    updatedList.add(prices.get(i));
                }
            }
        }
        // 处理最终HMA平滑WMA的场景
        else if (period > prices.size()) {
            // 此处暂无处理逻辑
            // 此时传入的价格列表长度为1,没有足够数据完成WMA计算
        }
        // 计算全周期WMA时,使用完整价格列表
        else {
            updatedList = prices;
        }

        // WMA核心计算逻辑,这部分确认无问题
        double totalWeight = ((double)period * (period + 1)) / 2;

        double pricePoint = 0;
        double weightCounter = 1;
        for (Double value: updatedList) {
            double wmaVal = value * (weightCounter / totalWeight);
            pricePoint += wmaVal;

            weightCounter++;
        }
        return pricePoint;
    }

想请问我当前的实现思路存在哪些认知误区?


内容的提问来源于stack exchange,提问作者AroenvR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 12:39:15