Finish recursive price transform
This commit is contained in:
68
main.go
68
main.go
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user