英文:
How to fix EMA function not returning expected values in bash script?
问题
以下是您要翻译的代码部分:
function TA_EMA() {
local inReal=("$@")
local optInTimePeriod=$1
local num=${#inReal[@]}
local alpha=$(echo "2.0 / (${optInTimePeriod} + 1)" | bc -l)
local outReal=()
for ((i=0; i<num; i++)); do
if (( i < optInTimePeriod )); then
outReal+=("${inReal[i]}")
else
local ema=$(echo "${inReal[i]}*${alpha} + (1-${alpha})*${outReal[$((i-1))]}" | bc -l)
outReal+=("$ema")
fi
done
echo "${outReal[@]}"
}
inReal=(1 2 3 4 5)
optInTimePeriod=3
outReal=($(TA_EMA $optInTimePeriod "${inReal[@]}"))
echo "${outReal[@]}"
function TA_EMA() {
local inReal=("$@")
local optInTimePeriod=$1
local num=${#inReal[@]}
local alpha=$(echo "2 / (${optInTimePeriod} + 1)" | bc -l)
local outReal=()
for ((i=0; i<num; i++)); do
if (( i < optInTimePeriod )); then
outReal+=(0)
elif (( i == optInTimePeriod )); then
local sum=0
for ((j=0; j<optInTimePeriod; j++)); do
sum=$((sum+inReal[j]))
done
local sma=$((sum/optInTimePeriod))
outReal+=("$sma")
else
local ema=$(echo "${inReal[i]}*$alpha + (1-$alpha)*${outReal[$((i-1))]}" | bc -l)
outReal+=("$ema")
fi
done
echo "${outReal[@]}"
}
希望这对您有所帮助。
英文:
Hi i have created this function in bash
function TA_EMA() {
local inReal=("$@")
local optInTimePeriod=$1
local num=${#inReal[@]}
local alpha=$(echo "2.0 / (${optInTimePeriod} + 1)" | bc -l)
local outReal=()
for ((i=0; i<num; i++)); do
if (( i < optInTimePeriod )); then
outReal+=("${inReal[i]}")
else
local ema=$(echo "${inReal[i]}*${alpha} + (1-${alpha})*${outReal[$((i-1))]}" | bc -l)
outReal+=("$ema")
fi
done
echo "${outReal[@]}"
}
inReal=(1 2 3 4 5)
optInTimePeriod=3
outReal=($(TA_EMA $optInTimePeriod "${inReal[@]}"))
echo "${outReal[@]}"
if i calculate Ema in this site https://goodcalculators.com/exponential-moving-average-calculator/ return 1,1.5,2.25,3.125,4.063
but my code return
3 1 2 2.50000000000000000000 3.25000000000000000000 4.12500000000000000000
i try also in this mode
function TA_EMA() {
local inReal=("$@")
local optInTimePeriod=$1
local num=${#inReal[@]}
local alpha=$(echo "2 / (${optInTimePeriod} + 1)" | bc -l)
local outReal=()
for ((i=0; i<num; i++)); do
if (( i < optInTimePeriod )); then
outReal+=(0)
elif (( i == optInTimePeriod )); then
local sum=0
for ((j=0; j<optInTimePeriod; j++)); do
sum=$((sum+inReal[j]))
done
local sma=$((sum/optInTimePeriod))
outReal+=("$sma")
else
local ema=$(echo "${inReal[i]}*$alpha + (1-$alpha)*${outReal[$((i-1))]}" | bc -l)
outReal+=("$ema")
fi
done
echo "${outReal[@]}"
}
答案1
得分: 2
你可以将 optInTimePeriod
作为函数中 inReal
的一部分,如下所示:
local inReal=("$@")
local optInTimePeriod=$1
而不是:
local optInTimePeriod=$1
shift # 从$@中移除$1
local inReal=("$@")
第二个问题是,你在所有 i < 3
的值上都添加了当前值:
if (( i < optInTimePeriod )); then
outReal+=("${inReal[i]}")
应该只在 i == 0
时添加。
通过使用 readarray
进行了一些简化:
#!/bin/bash
TA_EMA() {
local optInTimePeriod=$1
shift
local inReal=( "$@" )
local num=${#inReal[@]}
local alpha
alpha=$(echo "2 / (${optInTimePeriod} + 1)" | bc -l)
local ema
for ((i=0; i<num; i++)); do
if (( i == 0 )); then
ema=${inReal[0]}
else
ema=$(echo "${inReal[i]}*${alpha} + (1-${alpha})*${ema}" | bc -l)
fi
echo "$ema"
done
}
inReal=(1 2 3 4 5)
optInTimePeriod=3
readarray -t outReal < <(TA_EMA $optInTimePeriod "${inReal[@]}")
for ema in "${outReal[@]}"
do
echo "$ema"
done
英文:
You make the optInTimePeriod
a part of inReal
in your function:
local inReal=("$@")
local optInTimePeriod=$1
instead do:
local optInTimePeriod=$1
shift # remove $1 from $@
local inReal=("$@")
The second problem is that you add the current value for all values where i < 3
:
if (( i < optInTimePeriod )); then
outReal+=("${inReal[i]}")
it should only be when i == 0
.
Somewhat simplified using readarray
instead:
#!/bin/bash
TA_EMA() {
local optInTimePeriod=$1
shift
local inReal=( "$@" )
local num=${#inReal[@]}
local alpha
alpha=$(echo "2 / (${optInTimePeriod} + 1)" | bc -l)
local ema
for ((i=0; i<num; i++)); do
if (( i == 0 )); then
ema=${inReal[0]}
else
ema=$(echo "${inReal[i]}*${alpha} + (1-${alpha})*${ema}" | bc -l)
fi
echo "$ema"
done
}
inReal=(1 2 3 4 5)
optInTimePeriod=3
readarray -t outReal < <(TA_EMA $optInTimePeriod "${inReal[@]}")
for ema in "${outReal[@]}"
do
echo "$ema"
done
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论