Updated the application to use the AlphaVantage API.

This change may slow down the program, as the free API is rate-limited to 5 requests a minute.
This commit is contained in:
Adithya Chari
2020-05-11 19:10:31 -05:00
parent a498934181
commit 894c73d5b6
2 changed files with 29 additions and 25 deletions

View File

@@ -7,7 +7,7 @@ This application locates any stocks you have in your [ledger-cli](ledger-cli.org
Build the go file, and run as follows: Build the go file, and run as follows:
```bash ```bash
./[name of executable] -f=[ledger file] -p=[price database file (to create or update)] ./[name of executable] -f=[ledger file] -p=[price database file (to create or update)] -a=[Alpha Vantage API token] -b=[Name of ledger binary]
``` ```
This should spit out a price database file, which can then be used to calculate the market value in ledger as follows: This should spit out a price database file, which can then be used to calculate the market value in ledger as follows:

52
main.go
View File

@@ -13,8 +13,14 @@ import (
"time" "time"
) )
type Quote struct {
Data struct {
Price string `json:"05. price"`
} `json:"Global Quote"`
}
func main() { func main() {
apiToken := flag.String("a", "demo", "World Trading Data API Token") 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")
@@ -28,18 +34,28 @@ func main() {
} }
defer pricedb.Close() defer pricedb.Close()
for _, c := range commodities { start := time.Now()
for i, c := range commodities {
if i%5 == 0 {
elapsed := time.Now().Sub(start)
if elapsed < time.Minute {
time.Sleep(time.Minute - elapsed)
}
start = time.Now()
}
priceString, err := GetPriceString(c, *apiToken) priceString, err := GetPriceString(c, *apiToken)
if err != nil { if err != nil {
log.Println("Skipped " + c) log.Println("Skipped " + c)
continue continue
} }
pricedb.WriteString("P " + GetTimeString() + " " + c + " " + priceString + "\n") pricedb.WriteString("P " + GetTimeString() + " " + c + " " + priceString[:len(priceString)-2] + "\n")
} }
log.Println("Stock price update complete")
} }
func GetPriceString(ticker string, apiToken string) (string, error) { func GetPriceString(ticker string, apiToken string) (string, error) {
resp, err := http.Get("https://api.worldtradingdata.com/api/v1/stock?symbol=" + ticker + "&api_token=" + apiToken) resp, err := http.Get("https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=" + ticker + "&apikey=" + apiToken)
if err != nil { if err != nil {
return "", err return "", err
} }
@@ -50,28 +66,16 @@ func GetPriceString(ticker string, apiToken string) (string, error) {
return "", err return "", err
} }
var f interface{} var f Quote
json.Unmarshal(body, &f) err = json.Unmarshal(body, &f)
m, ok := f.(map[string]interface{}) if err != nil {
if !ok { return "", err
}
if f.Data.Price == "" {
return "", errors.New("Conversion Error") return "", errors.New("Conversion Error")
} }
dataInterface := m["data"] return "$" + f.Data.Price, nil
arr, ok := dataInterface.([]interface{})
if !ok {
return "", errors.New("Conversion Error")
}
elem := arr[0]
ma, ok := elem.(map[string]interface{})
if !ok {
return "", errors.New("Conversion Error")
}
priceInterface := ma["price"]
price, ok := priceInterface.(string)
if !ok {
return "", errors.New("Conversion Error")
}
return "$" + price, nil
} }
func GetTimeString() string { func GetTimeString() string {