Shortcuts

libfinance#

[ English | 中文 ]

Conclusions in quantitative research rest on historical data, and historical data is distorted in three common ways: security codes are renamed, reused, and collide across markets; financial statements are revised after release, so a backtest that reads the latest version uses information nobody had at the time; and corporate actions such as dividends and splits break price comparability, so inconsistent adjustment distorts returns. Research and production also tend to run in different languages, Python and C++, and small differences between two interfaces make the same strategy produce different results once it is ported.

libfinance is a financial data client for quantitative research and backtesting, covering Chinese A-shares and US equities, with implementations in Python and C++. It organizes prices, the security catalog, trading calendars, corporate actions, shares, financials, industry / index / theme constituents and daily factors around unified security identifiers, point-in-time data versions and event-by-event adjustment factors. Both markets and both languages follow one interface contract: queries are written the same way, and differences come only from the data.

The data design rests on four conventions:

  • Unified security identifiers: <trading_code>.<namespace>, such as 600000.XSHG, 000001.XSHE and AAPL.US. The namespace separates equal codes in different markets, and codes resolve at a point in time, so renames and reused codes never land on another security.

  • Point-in-time queries with as_of: rebuild the security universe of a past date and select the financial statements disclosed by then, avoiding look-ahead and survivorship bias.

  • High-quality adjustment factors, exfactor: computed event by event from corporate actions, with unadjusted, forward-adjusted and backward-adjusted prices; get_ex_factor returns each event’s factor and the cumulative factor, so every adjustment can be traced.

  • One function design for Python and C++: both clients implement one contract – function names, parameter order and defaults, validation and errors, returned columns; the same calls are sent through both clients to one server and compared item by item.

See Unified security identifiers <trading_code>.<namespace>, Point-in-time mechanism: as_of, High-quality adjustment factors: exfactor and One function design for Python and C++.

from libfinance import get_price

# One call, both markets: each code carries its market
bars = get_price(["600000.XSHG", "AAPL.US"], "2024-03-01", "2024-03-05", adjust_type="none")

What this returns and how to read it: Quickstart.

A-shares and US equities share one vocabulary#

The unification holds at three layers.

Layer

What is shared

Example

Security identifiers

Both are written <trading_code>.<namespace>; the granularity of the namespace follows the scope needed to remove ambiguity in that market

600000.XSHG, AAPL.US

Functions and arguments

Both markets go through the same functions with the same argument names; as_of and adjust_type carry the same meaning

get_price, instruments, get_dividends

Result shape

The same columns and the same index; a field that does not apply to a market, or that a deployment does not provide, comes back as NaN rather than as a separate table

turnover, limit_up, limit_down for US equities

Only queries that do not name a security need the market stated: trading calendars, the full security master, and coverage ranges. When you query by security, the namespace already carries the market, and one list may mix the two.

from libfinance import instruments, get_trading_dates

instruments(["000001.XSHE", "AAPL.US"])            # the namespace carries the market
get_trading_dates("2024-01-01", "2024-01-31", market="us")   # no security named

What is shared is the vocabulary and the calling convention; the differences in the data remain. Allotments are China only, spin-offs US only, and the theme catalogue (THS) China only; US bars have no price limits, and turnover is not provided for them. See Working with US stocks for the picture function by function.

What data is here#

Data

Markets

Main function

Notes

Trading calendar

CN · US

get_trading_dates()

Sessions, ranges, N sessions forward or back

Security master

CN · US

all_instruments()

Code, name, type, listing and delisting dates

Daily bars

CN · US

get_price()

OHLC, volume, turnover; adjustable

Adjustment factors

CN · US

get_ex_factor()

Event and cumulative factors by ex-date

Share capital

CN · US

get_shares()

Per-session total and floating shares

Dividends / splits / allotments

CN · US

get_dividends()

Ex-rights events — the source of price gaps; allotments are China only

Spin-offs

US

get_spinoffs()

A-shares do not produce this kind of event

Financial statements (PIT)

CN · US

get_pit_financials_ex()

Quarterly, with full revision history

Financial metrics

CN · US

get_financial_metrics()

Derived financial metrics, per trading day

Industry classification

CN · US

get_instrument_industry()

Shenwan, GICS and more; members and weights via get_industry_constituents()

Index constituents

CN · US

get_index_constituents()

CSI, S&P and more; weights via get_index_weights()

Themes

CN

get_theme_constituents()

THS themes; weights via get_theme_weights()

Daily factors

CN

get_factor_exposure()

alpha158, qlib, Barra CNE5 style / industry factors, CNE5 and CNE6 descriptors; see Factor data and Factor dictionary

Live quotes

CN

QuoteApi

Streaming subscription

How far back the history goes and how recent it is depend on the service you connect to. Do not copy dates out of these docs — ask the service, as shown in How recent the data is.

Where to start#

I just want some prices

Install, connect, run your first query. Then read Fetching the last N sessions, which walks through every trap in “give me the last N sessions”.

Quickstart
I am building a backtest

Start with Point-in-time mechanism: as_of and High-quality adjustment factors: exfactor. Together they decide whether your backtest sees numbers that did not exist at the time.

Point-in-time mechanism: as_of
I want live data

Snapshot queries and streaming subscriptions are two different paths. Receiving live quotes has a program you can run as-is.

Live market data

Already using it and something looks wrong? Go straight to Troubleshooting — it is organised by symptom.

Three things worth knowing up front#

These are not advanced topics. They are defaults. Not knowing them means your code runs fine and your numbers are wrong.

Without adjust_type, you get forward-adjusted prices

Same stock, same day: forward-adjusted close 8.81, unadjusted 10.49 — a 16% difference. Use adjust_type to select the price convention explicitly. See Prices and adjustment.

end_date cannot be today

The calendar is published ahead of time (it reaches the end of the year); price data only reaches the last closed session. Passing today is rejected outright rather than silently returning a shorter table. See How recent the data is.

Financial statements get restated

One company’s Q2 2024 net profit exists here in five versions, the latest published in 2026. Omit as_of in a backtest and you are using numbers from the future. See Restatements and as_of.