Compare commits

...

1 Commits

Author SHA1 Message Date
62d11abb9d Keep existing event CSVs when a download carries no events of that kind
Yahoo stopped returning capitalGain events for some funds (2026); a blind
os.Create + write of an empty event set overwrote the only copy of that
history. When the new download has zero rows of an event kind and the
existing CSV has data rows, keep the existing file. (gmp/f data.py also
falls back to overrides/event-backup/ as a second line of defense.)
2026-08-31 21:29:29 -04:00

78
main.go
View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"os" "os"
"sort" "sort"
"strings"
"time" "time"
) )
@ -219,47 +220,52 @@ func Conv(name string) {
adjclose[k], vol)) adjclose[k], vol))
} }
if dividends != nil { if dividends != nil {
out, err = os.Create(name + "-dividend.csv") writeEvents(name, name+"-dividend.csv", "Date,Dividends",
if err != nil { eventRows(name, "dividend", dividends, loc),
fmt.Printf("%s: %s\n", name, err) func(r eventRow) string { return fmt.Sprintf("%s,%f", r.date, r.amount) })
os.Exit(-1)
}
defer out.Close()
out.WriteString("Date,Dividends\n")
for _, r := range eventRows(name, "dividend", dividends, loc) {
out.WriteString(fmt.Sprintf("%s,%f\n", r.date, r.amount))
}
} }
if capgains != nil { if capgains != nil {
out, err = os.Create(name + "-capitalGain.csv") writeEvents(name, name+"-capitalGain.csv", "Date,Capital Gains",
if err != nil { eventRows(name, "capital gain", capgains, loc),
fmt.Printf("%s: %s\n", name, err) func(r eventRow) string { return fmt.Sprintf("%s,%f", r.date, r.amount) })
os.Exit(-1)
}
defer out.Close()
out.WriteString("Date,Capital Gains\n")
for _, r := range eventRows(name, "capital gain", capgains, loc) {
out.WriteString(fmt.Sprintf("%s,%f\n", r.date, r.amount))
}
} }
if splits != nil { if splits != nil {
out, err = os.Create(name + "-split.csv") writeEvents(name, name+"-split.csv", "Date,Stock Splits",
if err != nil { eventRows(name, "split", splits, loc),
fmt.Printf("%s: %s\n", name, err) func(r eventRow) string { return fmt.Sprintf("%s,%s", r.date, r.ratio) })
os.Exit(-1) }
} }
defer out.Close() // fileHasDataRows reports whether path exists and has a row beyond the header.
func fileHasDataRows(path string) bool {
out.WriteString("Date,Stock Splits\n") b, err := os.ReadFile(path)
for _, r := range eventRows(name, "split", splits, loc) { if err != nil {
out.WriteString(fmt.Sprintf("%s,%s\n", r.date, r.ratio)) return false
} }
lines := strings.Split(strings.TrimSpace(string(b)), "\n")
return len(lines) > 1 && strings.TrimSpace(lines[1]) != ""
}
// writeEvents writes the event rows to path, unless the download carries no
// rows of this kind while an existing populated file is present: Yahoo has
// stopped returning capitalGain events for some funds (2026), and a blind
// overwrite would wipe the only copy of that history. (The consumer side,
// gmp/f data.py, additionally falls back to a backup directory.)
func writeEvents(name, path, header string, rows []eventRow, format func(eventRow) string) {
if len(rows) == 0 && fileHasDataRows(path) {
fmt.Printf("%s: no %s events in download; keeping existing %s\n", name, header, path)
return
}
out, err := os.Create(path)
if err != nil {
fmt.Printf("%s: %s\n", name, err)
os.Exit(-1)
}
defer out.Close()
out.WriteString(header + "\n")
for _, r := range rows {
out.WriteString(format(r) + "\n")
} }
} }