package main import ( "encoding/json" "fmt" "log" "net/http" "sort" "time" ) func main() { // Read VOO's file (one GET, no key), naming your own project req, err := http.NewRequest("GET", "https://tickerinside.com/api/v1/fund/voo.json", nil) if err != nil { log.Fatal(err) } req.Header.Set("User-Agent", "MyProject/1.0 (+https://example.com)") client := &http.Client{Timeout: 30 * time.Second} resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { log.Fatalf("HTTP %d", resp.StatusCode) } // Decode the fields this example uses var fund struct { HoldingsAsOf string `json:"holdings_as_of"` Holdings map[string]float64 `json:"holdings"` CiteAs string `json:"cite_as"` } if err := json.NewDecoder(resp.Body).Decode(&fund); err != nil { log.Fatal(err) } // The date of the issuer's file the weights come from fmt.Println("VOO holdings_as_of", fund.HoldingsAsOf) // holdings maps each ticker to its weight in percent. A Go map has no // order: sort the tickers, largest weight first, then by name tickers := make([]string, 0, len(fund.Holdings)) for t := range fund.Holdings { tickers = append(tickers, t) } sort.Slice(tickers, func(i, j int) bool { wi, wj := fund.Holdings[tickers[i]], fund.Holdings[tickers[j]] if wi != wj { return wi > wj } return tickers[i] < tickers[j] }) fmt.Println(len(tickers), "holdings, largest first") for _, t := range tickers { fmt.Println(t, fund.Holdings[t]) } // The line to print under any figure you quote fmt.Println(fund.CiteAs) }