add correct backfile

Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
GnomeZworc 2026-06-14 13:41:42 +02:00
commit 28e082f0fc
Signed by: nicolas.boufideline
GPG key ID: 4406BBBF8845D632
8 changed files with 317 additions and 35 deletions

View file

@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"strings"
"time"
)
// ResolveCryptoID résout un ticker crypto (ex: "BTC") en ID CoinGecko (ex: "bitcoin").
@ -46,6 +47,48 @@ func ResolveCryptoID(ctx context.Context, apiKey, ticker string) (string, error)
return "", fmt.Errorf("no coingecko match for ticker %s", ticker)
}
// FetchCoinGeckoHistory récupère les prix EUR journaliers entre from et to pour un coin.
func FetchCoinGeckoHistory(ctx context.Context, apiKey, coinID string, from, to time.Time) ([]PricePoint, error) {
baseURL := "https://api.coingecko.com/api/v3"
if apiKey != "" {
baseURL = "https://pro-api.coingecko.com/api/v3"
}
url := fmt.Sprintf("%s/coins/%s/market_chart/range?vs_currency=eur&from=%d&to=%d",
baseURL, coinID, from.Unix(), to.Unix())
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, err
}
if apiKey != "" {
req.Header.Set("x-cg-pro-api-key", apiKey)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
// Réponse : {"prices": [[timestamp_ms, price], ...]}
var raw struct {
Prices [][2]float64 `json:"prices"`
}
if err := json.NewDecoder(resp.Body).Decode(&raw); err != nil {
return nil, fmt.Errorf("decode coingecko history: %w", err)
}
points := make([]PricePoint, 0, len(raw.Prices))
for _, p := range raw.Prices {
points = append(points, PricePoint{
At: time.UnixMilli(int64(p[0])).UTC(),
Price: p[1],
})
}
return points, nil
}
// FetchCoinGeckoPrices récupère les prix EUR pour une liste d'IDs CoinGecko.
// Le ticker stocké dans instrument_ticker_cache doit être l'ID CoinGecko (ex: "bitcoin", "ethereum").
func FetchCoinGeckoPrices(ctx context.Context, apiKey string, coinIDs []string) (map[string]float64, error) {