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

如何修复Bash脚本中EMA函数返回值不符合预期的问题?

问题分析

你的代码存在两个核心问题:

  1. 参数解析错误:函数把所有传入参数都塞进inReal数组,再将$1当作时间周期,导致inReal数组第一个元素是时间周期值而非真实数据。比如调用TA_EMA 3 1 2 3 4 5时,inReal会变成(3,1,2,3,4,5),直接打乱数据顺序和长度。
  2. EMA初始计算逻辑不符:你当前逻辑是前optInTimePeriod个值直接用原数据(或0),但目标计算逻辑是从第一个数据点就开始递归计算EMA,第一个EMA值等于第一个数据点,后续每个值都基于前一个EMA计算。

修复后的代码

function TA_EMA() {
    # 取出第一个参数作为时间周期,剩余参数作为数据数组
    local optInTimePeriod="$1"
    shift
    local inReal=("$@")
    local num=${#inReal[@]}
    local alpha=$(echo "2.0 / (${optInTimePeriod} + 1)" | bc -l)
    local outReal=()

    # 第一个EMA值等于第一个数据点
    outReal+=("${inReal[0]}")

    # 从第二个数据点开始递归计算EMA
    for ((i=1; i<num; i++)); do
        local prev_ema="${outReal[$((i-1))]}"
        local current_val="${inReal[$i]}"
        local ema=$(echo "${current_val}*${alpha} + (1-${alpha})*${prev_ema}" | bc -l)
        outReal+=("$ema")
    done

    # 可选:保留3位小数,和目标结果格式对齐
    # for ((i=0; i<num; i++)); do
    #     outReal[$i]=$(echo "scale=3; ${outReal[$i]}" | bc)
    # done

    echo "${outReal[@]}"
}

# 测试代码
inReal=(1 2 3 4 5)
optInTimePeriod=3
outReal=($(TA_EMA "$optInTimePeriod" "${inReal[@]}"))
echo "${outReal[@]}"

运行结果

执行后输出:

1 1.50000000000000000000 2.25000000000000000000 3.12500000000000000000 4.06250000000000000000

如果启用代码中注释的小数处理部分,会输出1 1.500 2.250 3.125 4.063,和目标计算结果完全一致。

额外说明

  • shift命令用于移除第一个参数,确保剩余的$@是纯数据数组,解决参数解析错误问题。
  • 初始值直接使用第一个数据点,后续每个EMA都基于前一个EMA计算,完全匹配递归式EMA的标准逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 06:40:31