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

Spring+MySQL计算最优简单移动平均耗时过长优化求助

简单移动平均最优参数计算程序优化问题

背景

  • 已搭建对接MySQL数据库的简易Spring应用,库中存储了20年的股票行情数据,共5694条记录,示例数据如下:
    股票示例数据
  • 核心需求:基于全部交易日的收盘价,计算该数据集对应的最优简单移动平均周期参数N:
    • 移动平均值随N取值变化,例如当N=3时,交易日t对应的移动平均值计算公式为((t-1日收盘价)+(t-2日收盘价)+(t-3日收盘价))/N
    • 最终输出内容为最优N取值,以及该N值下模拟全量买卖交易得到的总收益

现有实现

未找到公开适配算法,自行实现逻辑为遍历取值区间内所有N(测试区间2-250共249次循环),单次循环执行以下步骤:

  • 执行SQL查询,计算当前N对应的移动平均值并返回结果列表
  • 模拟买卖交易流程,计算当前N对应的总收益
  • 将当前收益与历史最优收益对比,更新最优参数与最优收益
  • 进入下一个N值的计算

Repository层代码

@Repository
public interface StockRepository extends CrudRepository<Stock, Integer> {
    /*
     * 计算传入n值对应的移动平均值
     */
    @Query(value = "SELECT a.date, a.close, Round( ( SELECT SUM(b.close) / COUNT(b.close) FROM stock AS b WHERE DATEDIFF(a.date, b.date) BETWEEN 0 AND ?1 ), 2 ) AS 'avg' FROM stock AS a ORDER BY a.date", nativeQuery = true)
    List<AverageDTO> calculateAverage(int n); 
}

Controller层代码

@RestController
public class ApiController {
    @Autowired
    private StockRepository stockRepository;


    @CrossOrigin(origins = "*")
    @GetMapping("/getBestValue")
    /*
     * 遍历[min,max]区间所有可能取值,计算每个取值对应的移动均线与模拟交易收益,选出最优参数
     */
    public ResultDTO getBestValue(@PathParam("min") int min, @PathParam("max") int max) {
        Double best = 0.0;
        int value = 0;

        for (int i = min; i <= max; i++) {
            Double result = simulate(stockRepository.calculateAverage(i));
            if (result > best) {
                value = i;
                best = result;
            }
        }
        return new ResultDTO(value, best);
    }

    /*
     * 传入股票收盘价与对应移动平均值列表,模拟买卖交易流程计算总收益
     */
    public Double simulate(List<AverageDTO> list) {
        Double result = 0.0;
        Double lastPrice = list.get(0).getClose();
        for (int i = 1; i < list.size(); i++) {
            if (list.get(i - 1).getClose() < list.get(i - 1).getAvg()
                    && list.get(i).getClose() > list.get(i).getAvg()) {
                // 金叉买入
                lastPrice = list.get(i).getClose();
            } else if (list.get(i - 1).getClose() > list.get(i - 1).getAvg()
                    && list.get(i).getClose() < list.get(i).getAvg()) {
                // 死叉卖出
                result += (list.get(i).getClose() - lastPrice);
                lastPrice = list.get(i).getClose();
            }
        }
        return result;
    }
}

问题描述

当设置参数区间为Min=2、Max=250时,程序完整执行需要45分钟。作为Java与Spring初学者,需要针对这段逻辑的执行效率优化建议。


内容的提问来源于stack exchange,提问作者judo_ürgens

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:27:25