Documentation
¶
Overview ¶
Package bvb is a read-only client for the Bucharest Stock Exchange (Bursa de Valori București). It talks to two of the exchange's own public backends:
The TradingView UDF datafeed at https://wapi.bvb.ro/api, which serves the symbol config, per-symbol metadata, a (server-capped) symbol search, and historical OHLCV candles. These endpoints require no authentication token — a browser-like User-Agent and a bvb.ro Referer are sent defensively, nothing more.
The server-rendered market-list pages at https://www.bvb.ro, scraped to enumerate the full instrument universe (ticker + ISIN + name), because the datafeed search is capped and cannot list every symbol.
The client is read-only: BVB exposes no trading API. Redistributing BVB price data is the caller's responsibility under BVB's terms of use — this package ships code, not data.
Two quirks of the datafeed are handled for you: the daily candle resolution code is "1D" (bare "D" is rejected with HTTP 500), exposed here as the D1 constant; and the /history endpoint requires from, to, ajust, countback and currencyCode on every call, all supplied by History.
Index ¶
- Variables
- type APIError
- type Bar
- type Client
- func (c *Client) Config(ctx context.Context) (Config, error)
- func (c *Client) Fundamentals(ctx context.Context, ticker string) (Fundamentals, error)
- func (c *Client) History(ctx context.Context, ticker string, from, to time.Time, res Resolution, ...) ([]Bar, error)
- func (c *Client) Instruments(ctx context.Context, market Market) ([]Instrument, error)
- func (c *Client) Search(ctx context.Context, query string) ([]SearchResult, error)
- func (c *Client) ServerTime(ctx context.Context) (time.Time, error)
- func (c *Client) SymbolInfo(ctx context.Context, ticker string) (SymbolInfo, error)
- type Config
- type Fundamentals
- type Instrument
- type Market
- type Option
- type Resolution
- type SearchResult
- type Shareholder
- type SymbolInfo
- type SymbolType
Constants ¶
This section is empty.
Variables ¶
var ErrHistoryTruncated = errors.New("bvb: history window truncated")
ErrHistoryTruncated is wrapped when the requested span needs more bars than a single request can carry (maxCountback) and the delivered window does not reach back to from — so the series would be silently truncated. Match with errors.Is and retry with a coarser resolution or a later start. This only arises for long intraday spans; daily and coarser never hit the cap.
var ErrUnknownMarket = errors.New("bvb: unknown market")
ErrUnknownMarket is wrapped when Instruments is asked for a market that has no known list page. Match with errors.Is.
var ErrUnknownSymbol = errors.New("bvb: unknown symbol")
ErrUnknownSymbol is wrapped by SymbolInfo when the datafeed does not know a ticker. Match with errors.Is.
var ErrUnsupportedResolution = errors.New("bvb: unsupported resolution")
ErrUnsupportedResolution is wrapped when History is asked for a resolution outside the supported set. Match with errors.Is.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
Status int // HTTP status code
URL string // requested URL (no secrets are ever sent, so it is safe to surface)
Body string // truncated response body
}
APIError is a non-2xx HTTP response from a BVB backend.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a read-only Bucharest Stock Exchange client. Create it with New; the zero value is not usable.
func (*Client) Fundamentals ¶
Fundamentals fetches and parses the detail page for ticker. An unknown ticker (the page renders without an identity block) yields ErrUnknownSymbol.
func (*Client) History ¶
func (c *Client) History(ctx context.Context, ticker string, from, to time.Time, res Resolution, adjusted bool, currency string) ([]Bar, error)
History fetches OHLCV candles for ticker between from and to at resolution res. When adjusted is true, prices are corrected for splits (ajust=1). currency selects the pricing currency (e.g. "RON"); empty means "RON".
The datafeed bounds the window by to and by a countback derived from the requested span, so the returned bars end at or before to and reach back to at least from; trim to an exact range if needed. A "no_data" response yields an empty slice and no error.
func (*Client) Instruments ¶
Instruments enumerates the instruments listed on a market's page. It is the reliable way to list the universe, since the datafeed search is capped.
func (*Client) Search ¶
Search queries the datafeed symbol search. The endpoint caps results (about 30) for broad queries, so it is a lookup helper, not a way to enumerate the universe — use Instruments for that.
func (*Client) ServerTime ¶
ServerTime returns the datafeed's current time (GET /api/time).
func (*Client) SymbolInfo ¶
SymbolInfo resolves one ticker to its datafeed metadata. An unknown ticker is reported as ErrUnknownSymbol: the datafeed answers HTTP 200 with an all-empty body rather than an error status, so SymbolInfo treats an empty ticker in the response as "not found".
type Config ¶
type Config struct {
SupportsSearch bool `json:"supports_search"`
SupportsTime bool `json:"supports_time"`
SymbolTypes []SymbolType `json:"symbols_types"`
SupportedResolutions []string `json:"supported_resolutions"`
}
Config is the datafeed configuration (GET /api/config).
type Fundamentals ¶
type Fundamentals struct {
Ticker string
Name string // issuer name
ISIN string
Type string // e.g. "Actiuni"
Segment string // e.g. "Principal"
Category string // e.g. "Premium"
Status string // e.g. "Tranzactionabila"
// Indicatori bursieri (current valuation snapshot).
MarketCap float64 // Capitalizare
PER float64 // price/earnings
PBV float64 // price/book
EPS float64
DivYield float64 // DIVY, in percent
Dividend float64 // last dividend per share
DividendYear int // the year that dividend belongs to
// Issue info.
NominalValue float64 // Valoare Nominala
FirstTradeDate time.Time // Data start tranzactionare
Shareholders []Shareholder
}
Fundamentals is the company snapshot scraped from an instrument's detail page: identity, the "Indicatori bursieri" valuation ratios, issue info, and the ownership structure. BVB does not publish multi-year financial statements as structured data, so this is a current snapshot, not a historical track record.
Numeric indicators that the page omits (e.g. PER for a loss-maker, or a missing dividend) are left zero.
type Instrument ¶
type Instrument struct {
Ticker string
ISIN string
Name string // issuer / instrument name
Market Market
}
Instrument is one listed instrument from a market-list page. ISIN may be empty for the rare listing whose grid row omits it.
type Market ¶
type Market string
Market names a BVB market-list page. These five share the same server-rendered grid (symbol + ISIN + issuer), so Instruments can scrape them uniformly. Indices are not here: they are a different page shape and a different notion of "instrument"; index candles are still reachable through History/SymbolInfo by their datafeed symbol (e.g. "BET").
type Option ¶
type Option func(*Client)
Option configures a Client.
func WithDatafeedURL ¶
WithDatafeedURL overrides the wapi.bvb.ro datafeed origin (scheme+host, no trailing slash). Intended for tests.
func WithHTTPClient ¶
WithHTTPClient replaces the default HTTP client (30s timeout).
func WithUserAgent ¶
WithUserAgent overrides the User-Agent header.
func WithWebURL ¶
WithWebURL overrides the www.bvb.ro origin used for market-list scraping (scheme+host, no trailing slash). Intended for tests.
type Resolution ¶
type Resolution string
Resolution is a datafeed candle resolution. The constants carry the exact codes the /history endpoint accepts — note that daily is "1D", not the TradingView-style "D" advertised by SymbolInfo (bare "D" is rejected with HTTP 500).
const ( M1 Resolution = "1" M5 Resolution = "5" M15 Resolution = "15" M30 Resolution = "30" H1 Resolution = "60" D1 Resolution = "1D" W1 Resolution = "1W" Mo1 Resolution = "1M" )
func (Resolution) Valid ¶
func (r Resolution) Valid() bool
Valid reports whether r is a supported resolution.
type SearchResult ¶
type SearchResult struct {
Symbol string `json:"symbol"`
FullName string `json:"full_name"`
Description string `json:"description"`
Exchange string `json:"exchange"`
Ticker string `json:"ticker"`
Type string `json:"type"`
}
SearchResult is one hit from the datafeed symbol search. Description typically embeds the ISIN. Type is lowercase (share/bond/structured/...).
type SymbolInfo ¶
type SymbolInfo struct {
Name string `json:"name"`
Description string `json:"description"` // issuer/company name
Exchange string `json:"exchange"`
Type string `json:"type"`
Ticker string `json:"ticker"`
Session string `json:"session"`
Timezone string `json:"timezone"`
HasIntraday bool `json:"has_intraday"`
SupportedResolutions []string `json:"supported_resolutions"`
}
SymbolInfo is per-symbol metadata (GET /api/symbols?symbol=...).
type SymbolType ¶
SymbolType is one instrument class advertised by the datafeed config. Value is the single-letter code (S=shares, B=bonds, R=rights, U=fund units, T=structured, F=futures, I=indices); it is empty for the "all" pseudo-type.