Finish recursive price transform

This commit is contained in:
2022-05-25 14:31:55 +08:00
parent d8b0e4c5db
commit 9a5884d4dd

68
main.go
View File

@@ -30,15 +30,21 @@ type Quote struct {
const API = "https://query1.finance.yahoo.com/v7/finance/spark?symbols=%s&range=1m" const API = "https://query1.finance.yahoo.com/v7/finance/spark?symbols=%s&range=1m"
type Price struct {
Commodity string
Currency string
Price float64
}
func main() { func main() {
apiToken := flag.String("a", "demo", "Alpha Vantage API Token")
ledgerBinary := flag.String("b", "ledger", "Ledger Binary") ledgerBinary := flag.String("b", "ledger", "Ledger Binary")
ledgerFile := flag.String("f", "ledger.ledger", "Ledger File") ledgerFile := flag.String("f", "ledger.ledger", "Ledger File")
priceDbFile := flag.String("p", "prices.db", "Price Database File") priceDbFile := flag.String("p", "prices.db", "Price Database File")
mappingFile := flag.String("m", "mapping", "Commodities Name Mapping File") mappingFile := flag.String("m", "mapping", "Commodities Name Mapping File")
flag.Parse() flag.Parse()
commodities := GetCommodities(*ledgerFile, *ledgerBinary, *mappingFile) mappings := GetMapping(*mappingFile)
commodities := GetCommodities(*ledgerFile, *ledgerBinary)
pricedb, err := os.OpenFile(*priceDbFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) pricedb, err := os.OpenFile(*priceDbFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil { if err != nil {
@@ -46,6 +52,10 @@ func main() {
} }
defer pricedb.Close() defer pricedb.Close()
currency := mappings["$"]
log.Println("Currency", currency)
prices := make(map[string]Price)
start := time.Now() start := time.Now()
for i, c := range commodities { for i, c := range commodities {
if i+1%5 == 0 { if i+1%5 == 0 {
@@ -56,45 +66,73 @@ func main() {
} }
start = time.Now() start = time.Now()
} }
if c == "$" {
continue
}
priceString, err := GetPriceString(c, *apiToken) ticker := c
if value, ok := mappings[c]; ok {
ticker = value
}
price, err := GetPriceString(c, ticker)
if err != nil { if err != nil {
log.Println("Skipped " + c) log.Println("Skipped " + c)
continue continue
} }
pricedb.WriteString("P " + GetTimeString() + " " + c + " " + priceString[:len(priceString)-2] + "\n") prices[c] = price
}
for c, p := range prices {
result := fmt.Sprintf("P %s %s $%f\n", GetTimeString(), c, p.GetPrice(currency, prices))
pricedb.WriteString(result)
} }
log.Println("Stock price update complete") log.Println("Stock price update complete")
} }
func GetPriceString(ticker string, apiToken string) (string, error) { func (p Price) GetPrice(currency string, prices map[string]Price) float64 {
if p.Commodity == currency {
return 1
}
if p.Currency == currency {
return p.Price
}
if altCurrency, ok := prices[p.Currency]; ok {
return p.Price * altCurrency.GetPrice(currency, prices)
}
return 0
}
func GetPriceString(commodity, ticker string) (price Price, err error) {
resp, err := http.Get(fmt.Sprintf(API, ticker)) resp, err := http.Get(fmt.Sprintf(API, ticker))
if err != nil { if err != nil {
return "", err return
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return "", err return
} }
var f Quote var f Quote
err = json.Unmarshal(body, &f) err = json.Unmarshal(body, &f)
if err != nil { if err != nil {
return "", err return
} }
log.Println(f) price = Price{
Commodity: commodity,
return fmt.Sprintf("$%f", f.Spark.Result[0].Response[0].Meta.RegularMarketPrice), nil Price: f.Spark.Result[0].Response[0].Meta.RegularMarketPrice,
Currency: f.Spark.Result[0].Response[0].Meta.Currency,
}
return
} }
func GetTimeString() string { func GetTimeString() string {
return time.Now().Format("2006-01-02 15:04:05") return time.Now().Format("2006-01-02 15:04:05")
} }
func GetCommodities(ledger string, binary string, mappingFile string) []string { func GetCommodities(ledger string, binary string) []string {
cmd := exec.Command(binary, "-f", ledger, "commodities") cmd := exec.Command(binary, "-f", ledger, "commodities")
out, err := cmd.Output() out, err := cmd.Output()
if err != nil { if err != nil {
@@ -102,17 +140,12 @@ func GetCommodities(ledger string, binary string, mappingFile string) []string {
} }
a := strings.Split(string(out), "\n") a := strings.Split(string(out), "\n")
sliceOut := a[:len(a)-1] sliceOut := a[:len(a)-1]
mapping := GetMapping(mappingFile)
commodities := make([]string, 0) commodities := make([]string, 0)
for _, e := range sliceOut { for _, e := range sliceOut {
e = strings.Trim(e, `"`) e = strings.Trim(e, `"`)
if value, ok := mapping[e]; ok {
e = value
}
commodities = append(commodities, e) commodities = append(commodities, e)
} }
log.Println(commodities)
return commodities return commodities
} }
@@ -132,7 +165,6 @@ func GetMapping(mappingFile string) map[string]string {
result[arr[0]] = strings.Trim(arr[1], "\n") result[arr[0]] = strings.Trim(arr[1], "\n")
} }
} }
log.Println(result)
return result return result
} }