package util import ( "encoding/json" "fmt" "io" "net/http" "time" ) type YahooChartResponse struct { Chart struct { Result []struct { Meta struct { Symbol string `json:"symbol"` RegularMarketPrice float64 `json:"regularMarketPrice"` Exchange string `json:"exchangeName"` Currency string `json:"currency"` Instrument string `json:"instrumentType"` FirstTrade int64 `json:"firstTradeDate"` GMTOffset int64 `json:"gmtoffset"` Timezone string `json:"exchangeTimezoneName"` ShortName string `json:"shortName"` LongName string `json:"longName"` Range string `json:"range"` DataGranularity string `json:"dataGranularity"` PriceHint int `json:"priceHint"` PreviousClose float64 `json:"previousClose"` Scale int `json:"scale"` HasPrePostMarket bool `json:"hasPrePostMarketData"` TradingPeriods [][]struct { Timezone string `json:"timezone"` Start int64 `json:"start"` End int64 `json:"end"` GMTOffset int64 `json:"gmtoffset"` } `json:"tradingPeriods"` ValidRanges []string `json:"validRanges"` } `json:"meta"` Timestamp []int64 `json:"timestamp"` Indicators struct { Quote []struct { Open []float64 `json:"open"` High []float64 `json:"high"` Low []float64 `json:"low"` Close []float64 `json:"close"` Volume []int64 `json:"volume"` } `json:"quote"` Adjclose []struct { Adjclose []float64 `json:"adjclose"` } `json:"adjclose,omitempty"` } `json:"indicators"` Events struct { Dividends map[string]struct { Amount float64 `json:"amount"` Date int64 `json:"date"` } `json:"dividends,omitempty"` Splits map[string]struct { Date int64 `json:"date"` Numerator float64 `json:"numerator"` Denominator float64 `json:"denominator"` SplitRatio string `json:"splitRatio"` } `json:"splits,omitempty"` } `json:"events,omitempty"` } `json:"result"` Error interface{} `json:"error"` } `json:"chart"` } func StockSearch(query string) (string, error) { url := fmt.Sprintf("https://query2.finance.yahoo.com/v1/finance/search?q=%s", query) req, err := http.NewRequest("GET", url, nil) if err != nil { return "", fmt.Errorf("Fehler beim Erstellen der Anfrage: %v", err) } req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15") client := &http.Client{} resp, err := client.Do(req) if err != nil { return "", fmt.Errorf("Fehler beim Abrufen der URL: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return "", fmt.Errorf("Fehler: HTTP Status %s", resp.Status) } body, err := io.ReadAll(resp.Body) if err != nil { return "", fmt.Errorf("Fehler beim Lesen der Antwort: %v", err) } return string(body), nil } func FetchYahooFinanceData(stock string) (string, error) { url := fmt.Sprintf( "https://query2.finance.yahoo.com/v8/finance/chart/%s?range=1y&interval=1d&events=history", stock, ) req, err := http.NewRequest("GET", url, nil) if err != nil { return "", fmt.Errorf("Fehler beim Erstellen der Anfrage: %v", err) } req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15") client := &http.Client{} resp, err := client.Do(req) if err != nil { return "", fmt.Errorf("Fehler beim Abrufen der URL: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return "", fmt.Errorf("Fehler: HTTP Status %s", resp.Status) } body, err := io.ReadAll(resp.Body) if err != nil { return "", fmt.Errorf("Fehler beim Lesen der Antwort: %v", err) } return string(body), nil } func FetchYahooFinanceDataMax(stock string) (string, error) { url := fmt.Sprintf( "https://query2.finance.yahoo.com/v8/finance/chart/%s?range=max&interval=1mo&events=div", stock, ) req, err := http.NewRequest("GET", url, nil) if err != nil { return "", fmt.Errorf("Fehler beim Erstellen der Anfrage: %v", err) } req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15") client := &http.Client{} resp, err := client.Do(req) if err != nil { return "", fmt.Errorf("Fehler beim Abrufen der URL: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return "", fmt.Errorf("Fehler: HTTP Status %s", resp.Status) } body, err := io.ReadAll(resp.Body) if err != nil { return "", fmt.Errorf("Fehler beim Lesen der Antwort: %v", err) } return string(body), nil } // Neu: Daten für das Chart extrahieren func ExtractChartData(jsonStr string) ([]string, []float64, error) { var data YahooChartResponse err := json.Unmarshal([]byte(jsonStr), &data) if err != nil { return nil, nil, fmt.Errorf("Fehler beim Parsen des JSON: %v", err) } if len(data.Chart.Result) == 0 { return nil, nil, fmt.Errorf("Keine Daten gefunden") } timestamps := data.Chart.Result[0].Timestamp closes := data.Chart.Result[0].Indicators.Quote[0].Close labels := make([]string, len(timestamps)) for i, ts := range timestamps { labels[i] = time.Unix(ts, 0).Format("2006-01-02") } return labels, closes, nil }