如何使用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
相关产品推荐
相关产品推荐

