From Newsgroup: comp.lang.awk
Hi folks, hope everyone is doing well.
Another experiment to mull over (notes below).
Very useful script for me at least. Hope it
posts without wordwrap (trying out 'Pan'
newsreader for the 1st time).
Must run, lots of irons in the fire these days...
Hope to check in with you guys down the road,
learn some new things.
Work hard & make your mother proud!
#!/bin/sh
:<<'ABOUT'
Michael Sanders - 2025
'Buying the dip' is an investment strategy where an investor purchases assets after their price has dropped, with the expectation that the value will rebound. The tactic is an application of the basic principle, 'buy low, sell high'.
This script fetches historical data within the specified range for the S&P 500 & determines if the price is down slightly within a broader upward trend. The result is that you'll save a nickel or two on the price. The rationale here is that, while its great to have cash on the side ready to invest, if a strong pullback in the market doesn't happen very frequently, then your cash misses out on potential gains...
Some popular ETFs that track the SPX index include:
VOO: Vanguard S&P 500
SPY: SPDR S&P 500
SPLG: SPDR Portfolio S&P 500
IVV: iShares Core S&P 500
FORMULA:
BUF IF SPX < SMA10 AND SPX > SMA30 AND RSI14 > 39 AND RSI14 < 51 ELSE WAIT
Condition Meaning
SPX < SMA10 Short-term pullback from recent highs
SPX > SMA30 Still trending upwards overall
RSI14 > 39 AND RSI14 < 51 Momentum is mild indicating healthy consolidation BUY / WAIT Buy if all conditions are true, otherwise wait
GLOSSARY:
SPX: S&P 500 index, representing the overall U.S. large-cap market.
SMA10: 10-day Simple Moving Average, average closing price over the last
10 trading days.
SMA30 30-day Simple Moving Average, average closing price over the last
30 trading days.
RSI14: 14-day Relative Strength Index, momentum indicator measuring
overbought/oversold conditions.
ABOUT
S=$(date -d "45 days ago" +%Y-%m-%d) # start date
E=$(date +%Y-%m-%d) # end date
URL="
https://fred.stlouisfed.org/graph/fredgraph.csv?id=SP500&cosd=$S&coed=$E"
curl -Ls "$URL" | awk -v mini=0 '
BEGIN { OFS = FS = "," }
# round to n decimals: 2.344 = 2.34, 2.345 = 2.35
function round(x, dec) {
factor = 10^dec
return int(x * factor + 0.5) / factor
}
# simple moving average
function SMA(len, i,sum) {
if (n < len) return ""
sum = 0
for(i = n - len + 1; i <= n; i++) sum += closes[i]
return sum / len
}
# relative strength index
function RSI(len, i,gain,loss,diff,rs) {
if (n <= len) return ""
gain = loss = 0
for(i = n - len + 1; i <= n; i++) {
diff = closes[i] - closes[i-1]
if (diff > 0) gain += diff
else loss -= diff
}
if (loss == 0) return 100
rs = gain / loss
return 100 - (100 / (1 + rs))
}
NR==1 { next } # skip CSV header
{
gsub(/"/,"",$2) # remove quotes from the CLOSE field
if ($2 ~ /^[0-9.]+$/) {
n++
closes[n] = $2 * 1 # convert string to number
dates[n] = $1 # store corresponding date
}
}
END {
if (n < 1) { print "No valid data"; exit }
last = closes[n]
sma10 = (n >= 10 ? SMA(10) : "")
sma30 = (n >= 30 ? SMA(30) : "")
rsi14 = (n >= 15 ? RSI(14) : "")
# buy/wait signal (no rounding here use full precision)
signal = "WAIT"
if (sma10 != "" && sma30 != "" && rsi14 != "") {
if (last < sma10 && last > sma30 && rsi14 > 39 && rsi14 < 51) signal="BUY"
}
# check if any computed field is missing or non-numeric
invalid = (sma10 == "" || sma30 == "" || rsi14 == "" || last == "")
# minimal output only...
if (mini) {
print dates[n] " SPX " (invalid ? "ERROR" : signal)
exit
}
# print header
print "DATE,INDEX,CLOSE,SMA10,SMA30,RSI14,SIGNAL"
# print last row (current day) directly with rounding expressions
if (invalid) {
print dates[n], "SPX", "", "", "", "", "", "ERROR"
} else {
print dates[n], "SPX",
round(last, 2),
round(sma10, 2),
round(sma30, 2),
round(rsi14, 1),
signal
}
}'
# eof
--- Synchronet 3.21a-Linux NewsLink 1.2