package pipeline import ( "context" "encoding/json" "fmt" "net/http" ) type yahooChart struct { Chart struct { Result []struct { Meta struct { RegularMarketPrice float64 `json:"regularMarketPrice"` Currency string `json:"currency"` } `json:"meta"` } `json:"result"` Error *struct{ Description string } `json:"error"` } `json:"chart"` } // FetchYahooPrice récupère le dernier prix connu pour un ticker Yahoo Finance. func FetchYahooPrice(ctx context.Context, ticker string) (float64, error) { url := fmt.Sprintf( "https://query1.finance.yahoo.com/v8/finance/chart/%s?interval=1d&range=1d", ticker) req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return 0, err } req.Header.Set("User-Agent", "Mozilla/5.0") resp, err := http.DefaultClient.Do(req) if err != nil { return 0, err } defer resp.Body.Close() var chart yahooChart if err := json.NewDecoder(resp.Body).Decode(&chart); err != nil { return 0, fmt.Errorf("decode yahoo response: %w", err) } if chart.Chart.Error != nil { return 0, fmt.Errorf("yahoo error: %s", chart.Chart.Error.Description) } if len(chart.Chart.Result) == 0 { return 0, fmt.Errorf("no result for ticker %s", ticker) } price := chart.Chart.Result[0].Meta.RegularMarketPrice if price == 0 { return 0, fmt.Errorf("zero price for ticker %s", ticker) } return price, nil }