package main import ( "encoding/json" "fmt" "log" "net/http" "strings" "time" ) // The fields of a fund file this example uses type fund struct { HoldingsAsOf string `json:"holdings_as_of"` Holdings map[string]float64 `json:"holdings"` CiteAs string `json:"cite_as"` } func main() { // Read both funds' files; each has the date of its own issuer's file client := &http.Client{Timeout: 30 * time.Second} tickers := []string{"VOO", "QQQ"} funds := map[string]fund{} for _, ticker := range tickers { req, err := http.NewRequest("GET", "https://tickerinside.com/api/v1/fund/"+ strings.ToLower(ticker)+".json", nil) if err != nil { log.Fatal(err) } req.Header.Set("User-Agent", "MyProject/1.0 (+https://example.com)") resp, err := client.Do(req) if err != nil { log.Fatal(err) } if resp.StatusCode != http.StatusOK { log.Fatalf("HTTP %d for %s", resp.StatusCode, ticker) } var f fund err = json.NewDecoder(resp.Body).Decode(&f) resp.Body.Close() if err != nil { log.Fatal(err) } funds[ticker] = f fmt.Println(ticker, "holdings_as_of", f.HoldingsAsOf) } // Overlap by weight, as the site computes it: for every ticker both // funds hold, add the smaller of its two weights a, b := funds["VOO"].Holdings, funds["QQQ"].Holdings overlap, shared := 0.0, 0 for t, wa := range a { if wb, ok := b[t]; ok { overlap += min(wa, wb) shared++ } } fmt.Printf("overlap by weight %.1f%%, %d companies in both\n", overlap, shared) // The lines to print under the figure, one per fund file for _, ticker := range tickers { fmt.Println(funds[ticker].CiteAs) } }