price

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2026 License: AGPL-3.0 Imports: 15 Imported by: 0

Documentation

Overview

Package price values assets on a given day, in a given currency, from free public market data: Binance and OKX daily candles for crypto, justETF's daily quotes for stocks and ETFs by ISIN (Yahoo Finance as a fallback), the European Central Bank's reference rates (through Frankfurter) between currencies. No account or key is needed. Prices are kept in memory and, with a Cache, across restarts: each day is asked once.

p := price.New(nil, http.DefaultClient) // memory only
eur, err := p.Price(ctx, model.CryptoOrFiat("BTC"), day, "EUR")

UnitPrice adapts a Service to what pkg/portfolio expects; any other source of prices with that signature works too.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoPrice = errors.New("no price known")

ErrNoPrice is returned when no provider knows the asset that day.

Functions

This section is empty.

Types

type Cache

type Cache interface {
	PriceSeries(ctx context.Context, pair string) (map[string]string, error)
	PriceWindows(ctx context.Context, pair string) ([]Window, error)
	PutPrices(ctx context.Context, pair string, w Window, closes map[string]string) error
}

Cache keeps closes between runs. Pairs are a provider and a market ("binance:BTCEUR", "fx:USDEUR"); days are YYYY-MM-DD and closes decimal strings. Fundarr's store is one.

type Service

type Service struct {
	Cache Cache // nil: memory only
	HTTP  *http.Client
	Now   func() time.Time
	// Provider endpoints, replaceable in tests.
	BinanceURL, OKXURL, FXURL, JustETFURL string
	YahooURLs                             []string // tried in turn
	// Market, when set, answers instead of the providers (no network): the
	// closes of pair ("binance:BTCEUR", "fx:USDEUR"…) from from to to. A
	// market it does not know has no closes.
	Market func(pair string, from, to time.Time) map[string]decimal.Decimal
	// contains filtered or unexported fields
}

Service answers "what was this worth that day". Safe for concurrent use.

func New

func New(cache Cache, client *http.Client) *Service

New makes a service asking the public providers; cache may be nil.

func (*Service) Price

func (s *Service) Price(ctx context.Context, a model.Asset, at time.Time, ccy string) (decimal.Decimal, error)

Price of one unit of asset on the day of at, in ccy (a fiat code).

func (*Service) UnitPrice

func (s *Service) UnitPrice(ctx context.Context, ccy string) func(a model.Asset, at time.Time) (decimal.Decimal, bool)

UnitPrice prices one unit of an asset on the day of at, in ccy, never failing: ok is false when no price is known. It fits portfolio.Price.

func (*Service) Valuer

func (s *Service) Valuer(ctx context.Context, ccy string) model.Valuer

Valuer returns a model.Valuer in ccy that never fails: unknown prices are reported as not ok.

type Window

type Window struct {
	From, To string // YYYY-MM-DD
	Fetched  time.Time
}

Window is a range of days already asked to a provider for a market.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL