113 lines
1.9 KiB
Go
113 lines
1.9 KiB
Go
|
package main
|
||
|
|
||
|
import "encoding/csv"
|
||
|
import "encoding/json"
|
||
|
import "time"
|
||
|
import "io"
|
||
|
import "log"
|
||
|
import "os"
|
||
|
import "strconv"
|
||
|
|
||
|
var COLUMNS []string
|
||
|
|
||
|
type FinancialData struct {
|
||
|
Date time.Time
|
||
|
Open, High, Low, Close, Adj_Close, Volume float64
|
||
|
}
|
||
|
|
||
|
func readCsvLine(line []string) *FinancialData {
|
||
|
data := new(FinancialData)
|
||
|
for i, col := range line {
|
||
|
switch COLUMNS[i] {
|
||
|
case "Date":
|
||
|
d, err := time.Parse("2006-01-02", col)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
} else {
|
||
|
data.Date = d
|
||
|
}
|
||
|
case "Open":
|
||
|
data.Open = toFloat(col)
|
||
|
case "High":
|
||
|
data.High = toFloat(col)
|
||
|
case "Low":
|
||
|
data.Low = toFloat(col)
|
||
|
case "Close":
|
||
|
data.Close = toFloat(col)
|
||
|
case "Adj Close":
|
||
|
data.Adj_Close = toFloat(col)
|
||
|
case "Volume":
|
||
|
data.Volume = toFloat(col)
|
||
|
}
|
||
|
}
|
||
|
return data
|
||
|
}
|
||
|
|
||
|
func toFloat(v string) float64 {
|
||
|
f, err := strconv.ParseFloat(v, 64)
|
||
|
if err != nil {
|
||
|
log.Fatalln(err)
|
||
|
}
|
||
|
return f
|
||
|
}
|
||
|
|
||
|
func readCsvHeader(line []string) {
|
||
|
for _, col := range line {
|
||
|
COLUMNS = append(COLUMNS, col)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func readCsv(in io.Reader) []FinancialData {
|
||
|
data := []FinancialData{}
|
||
|
csvReader := csv.NewReader(in)
|
||
|
for {
|
||
|
line, err := csvReader.Read()
|
||
|
if err == io.EOF {
|
||
|
break
|
||
|
} else if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
if len(COLUMNS) == 0 {
|
||
|
readCsvHeader(line)
|
||
|
} else {
|
||
|
data = append(data, *readCsvLine(line))
|
||
|
}
|
||
|
}
|
||
|
return data
|
||
|
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
if len(os.Args) < 2 {
|
||
|
log.Fatalln("Usage go-financial <file>")
|
||
|
}
|
||
|
|
||
|
// read input
|
||
|
csv, err := os.Open(os.Args[1])
|
||
|
if err != nil {
|
||
|
log.Fatalln("Error reading file", err)
|
||
|
}
|
||
|
defer csv.Close()
|
||
|
|
||
|
// parse data
|
||
|
data := readCsv(csv)
|
||
|
|
||
|
// convert JSON
|
||
|
var writer io.Writer
|
||
|
if len(os.Args) > 2 {
|
||
|
f, ferr := os.Create(os.Args[2])
|
||
|
if ferr != nil {
|
||
|
panic(ferr)
|
||
|
}
|
||
|
defer f.Close()
|
||
|
writer = f
|
||
|
} else {
|
||
|
writer = os.Stdout
|
||
|
}
|
||
|
err = json.NewEncoder(writer).Encode(data)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
}
|