Python-facing financial market data access library powered by Rust.
Project description
fincore
fincore is a developer-first financial data library.
The package is designed for software and data engineers who understand systems, streams, schemas, and downstream storage, but may not yet know finance. The motive is to create a financial data product with a very low barrier of use and understanding: ask for "Apple", get AAPL; ask for "10 year treasury", get a usable yield series; ask for a recent minute range, get normalized market events that can flow into Kafka, TimescaleDB, notebooks, or future analytics.
This is a personal research project and an early alpha package. It is not a production-grade market data client, trading system, investment tool, or source of financial advice. Free public data sources can be delayed, incomplete, rate limited, schema-changing, or unavailable.
The Python import name is fincore. The PyPI distribution name is fincore-py.
Current Scope
fincore-py currently focuses on data access, not trading or portfolio analytics.
Implemented today:
- Stock and ETF discovery across US, Australian, and Indian market contexts.
- Bond/yield series discovery for public US Treasury FRED series.
- Fuzzy instrument search and symbol resolution.
- Yahoo Finance OHLCV bars for daily and intraday intervals.
- FRED Treasury yield observations.
- Historical replay streams.
- Delayed polling streams for latest bars.
- Kafka-ready event envelopes.
- Optional Kafka sink via
fincore-py[kafka]. - Batch and streaming metric events via
fincore.analytics. - Sphinx documentation under
docs/.
Reserved for later:
- TimescaleDB sink.
- Additional paid/free source adapters.
- Trading or order execution, which is intentionally out of scope.
Package Shape
fincore
data
DataClient
market contexts: US, AU, IN
source descriptors
interval/date utilities
event envelopes
optional Kafka sink
analytics
MetricEngine
MetricSpec
normalized metric events
external row normalization
Rust extension
Yahoo Finance bar fetching
Nasdaq Trader, ASX, and NSE directory parsing
FRED yield fetching
normalized Python dict conversion
Installation
Create and activate a Python environment, then install build dependencies:
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m pip install -e .
Kafka support:
python -m pip install -r requirements-kafka.txt
Docs support:
python -m pip install -r requirements-docs.txt
Test support:
python -m pip install -e ".[test]"
tox
This project includes a Rust extension. A working Rust toolchain is required:
rustc --version
cargo --version
If Python 3.14 triggers a PyO3 maximum-version warning in a custom build environment:
export PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1
python -m pip install -e .
Restart notebook kernels after reinstalling because the compiled _fincore module may stay loaded.
Quick Start
from fincore.data import DataClient
client = DataClient()
client.search_instruments("apple", limit=5)
client.resolve_symbol("Apple")
Choose a market context:
us = DataClient(market="US")
au = DataClient(market="AU")
india = DataClient(market="IN")
au.search_instruments("bhp", limit=5)
india.search_instruments("reliance", limit=5)
Fetch daily bars:
bars = client.fetch_bars("Apple", "2024-01-01", "2024-01-10")
bars[:2]
Fetch Australian and Indian equities using names or exchange symbols:
au_bars = DataClient(market="AU").fetch_bars("BHP", "2024-01-01", "2024-01-10")
in_bars = DataClient(market="IN").fetch_bars("Reliance", "2024-01-01", "2024-01-10")
Fetch intraday bars:
bars = client.fetch_bars(
"AAPL",
"2024-01-02 09:30",
"2024-01-02 16:00",
interval="5m",
)
Fetch Treasury yields:
yields = client.fetch_bond_yields(
"10 year treasury",
start="2024-01-01",
end="2024-01-10",
)
Intervals
Yahoo Finance bars support:
1m, 2m, 5m, 15m, 30m, 60m, 90m,
1h, 1d, 5d, 1wk, 1mo, 3mo
Aliases such as 1hour, 1hr, day, and daily are normalized by the Python client.
Approximate Yahoo retention limits:
1m about 7 days
2m-30m about 60 days
60m/1h about 730 days
daily+ much longer
Market Contexts
DataClient defaults to the US market:
client = DataClient()
Supported market contexts:
US United States
AU Australia
IN India
The client uses the market context for instrument discovery and Yahoo symbol resolution:
US AAPL -> AAPL
AU BHP -> BHP.AX
IN RELIANCE -> RELIANCE.NS
You can also request a global discovery context:
client = DataClient(market="all")
client.search_instruments("bhp", markets=["US", "AU"])
Current free source choices:
US instruments Nasdaq Trader symbol directories
AU instruments ASX listed companies CSV
IN instruments NSE equity list CSV
Bars Yahoo Finance chart endpoint
US bond yields FRED public CSV
Data Sources And Limitations
fincore-py currently prefers free, public, and low-friction sources:
Nasdaq Trader US stock and ETF discovery
ASX Australian stock and ETF discovery
NSE Indian equity discovery
Yahoo Finance OHLCV bars for supported Yahoo symbols and intervals
FRED Public US Treasury yield observations
These sources are suitable for learning, prototyping, personal research, notebook exploration, stream-shape design, and downstream pipeline experiments. They are not a substitute for licensed exchange feeds, paid institutional datasets, audited historical data, or production trading infrastructure.
Important limitations:
- streams are delayed polling streams, not real exchange feeds
- intraday availability depends on Yahoo's retention windows
- source files and response schemas may change without notice
- AU and IN bars depend on Yahoo suffix coverage such as
.AXand.NS - current bond/yield support is US Treasury/FRED focused
- no data completeness, survivorship-bias, corporate-action, or split-adjustment guarantees are provided
Output Shapes
All public data methods return plain Python dictionaries. The schema is intentionally simple so downstream systems can serialize it to Kafka, JSONL, TimescaleDB, or future metric engines.
Instrument:
{
"source": "nasdaq_trader",
"symbol": "AAPL",
"yahoo_symbol": "AAPL",
"name": "Apple Inc. - Common Stock",
"market": "US",
"currency": "USD",
"asset_class": "stock",
"exchange": "NASDAQ",
"is_etf": False,
"raw": "...",
}
Bar:
{
"source": "yahoo",
"symbol": "AAPL",
"interval": "5m",
"timeframe": "5m",
"event_time": "2024-01-02T14:30:00+00:00",
"date": "2024-01-02",
"open": 100.0,
"high": 101.0,
"low": 99.5,
"close": 100.5,
"volume": 123456.0,
"received_time": "2024-01-02T14:31:00+00:00",
"raw": "...",
}
Bond yield observation:
{
"source": "fred",
"series_id": "DGS10",
"date": "2024-01-02",
"value": 4.0,
"received_time": "2024-01-02T00:00:00+00:00",
"raw": "2024-01-02,4.0",
}
Stream events use the envelope shape below, with source-specific values nested in payload:
{
"event_type": "bar",
"stream_type": "historical_replay",
"source": "yahoo",
"symbol": "AAPL",
"event_time": "2024-01-02T14:30:00+00:00",
"received_time": "2024-01-02T14:31:00+00:00",
"payload": {
"interval": "5m",
"timeframe": "5m",
"date": "2024-01-02",
"open": 100.0,
"high": 101.0,
"low": 99.5,
"close": 100.5,
"volume": 123456.0,
},
"raw": "...",
}
Metric event:
{
"event_type": "metric",
"metric": "return.simple",
"metric_name": "return.simple",
"source": "fincore.analytics",
"symbol": "AAPL",
"event_time": "2024-01-02T00:00:00+00:00",
"value": 0.0123,
"unit": "ratio",
"window": {
"kind": "bars",
"size": 1,
},
"inputs": {
"input_field": "close",
"close": 101.23,
},
"metadata": {
"interval": "1d",
},
}
Streams
Historical replay:
async for event in client.replay_bars(
"Apple",
"2024-01-02 09:30",
"2024-01-02 16:00",
interval="5m",
interval_seconds=0.1,
):
print(event)
Delayed polling stream:
async for event in client.stream_bars(
["Apple", "Microsoft"],
interval="1m",
lookback="1d",
poll_seconds=30,
):
print(event)
lookback means the recent range fetched on each poll. For example, lookback="1d" with interval="1m" asks Yahoo for the latest day of one-minute bars and emits only bars that have not already been seen.
Event Envelope
Streams emit normalized envelopes:
{
"event_type": "bar",
"stream_type": "historical_replay",
"source": "yahoo",
"symbol": "AAPL",
"event_time": "2024-01-02T14:30:00+00:00",
"received_time": "...",
"payload": {
"interval": "5m",
"open": 100.0,
"high": 101.0,
"low": 99.5,
"close": 100.5,
"volume": 123456,
},
"raw": "...",
}
This shape is intended for downstream systems such as Kafka, TimescaleDB, stream processors, and future analytics engines.
Kafka
from fincore.data import DataClient
from fincore.data.kafka import KafkaSink
client = DataClient()
sink = KafkaSink("localhost:9092", "market.bars")
await sink.publish_stream(
client.replay_bars("Apple", "2024-01-01", "2024-01-05")
)
Kafka remains optional. The core library does not require a broker.
Documentation
Build the Sphinx docs:
python -m pip install -r requirements-docs.txt
sphinx-build -b html docs docs/_build/html
The docs explain:
- what the library does
- how the data model works
- market data concepts for non-finance developers
- streaming and Kafka concepts
- the current API surface
- future analytics direction
Docs are deployed to GitHub Pages from .github/workflows/docs.yml on pushes to main, version tags, and manual dispatch.
Testing
The unit tests run through tox and avoid live network calls by stubbing the Rust-backed source functions:
python -m pip install -e ".[test]"
tox
CI runs tox, cargo fmt --check, and cargo check from .github/workflows/ci.yml.
Analytics
fincore.analytics consumes normalized bars, stream envelopes, or external row mappings. Python owns the API and state management; the numeric batch calculations run in the Rust extension.
Batch metrics:
from fincore.analytics import MetricEngine, MetricSpec
engine = MetricEngine()
events = engine.compute(
bars,
metrics=[
"return.simple",
"return.log",
MetricSpec("momentum.roc", window=3),
MetricSpec("volatility.rolling", window=5),
MetricSpec("auc.window", window=5),
],
)
Streaming metrics:
async for bar_event in client.replay_bars("Apple", "2024-01-01", "2024-01-10"):
for metric_event in engine.update(bar_event):
print(metric_event)
External rows, for example from a database:
events = engine.compute(
db_rows,
field_map={
"symbol": "ticker",
"event_time": "ts",
"close": "close_price",
"volume": "volume",
},
)
Implemented metric families:
- returns and log returns
- momentum
- first derivative / velocity
- second derivative / acceleration
- rolling volatility
- AUC over rolling price windows
- current drawdown
Planned next:
- yield spreads
- VWAP and volume metrics
- realized volatility variants
- direction and trend-regime signals
- linked temporal graph snapshots
The goal is custom analytics on the fly for streaming data:
async for metric_event in engine.run(client.stream_bars(["Apple"], interval="1m")):
...
Versioning And Publishing
Python package versions are derived from git tags through setuptools-scm.
For a beta pre-release:
git tag v0.1.0b0
git push origin v0.1.0b0
The publish workflow at .github/workflows/publish.yml builds distributions for both main pushes and version tags.
- Pushes to
mainpublish source-distribution development builds to PyPI, using versions like0.1.0.dev123. - Tags like
v0.1.0b0build beta wheels plus a source distribution and publish them to PyPI. - Later stable tags like
v0.1.0can use the same tagged release path.
Configure PyPI trusted publishing with:
Repository: <owner>/fincore
Workflow: publish.yml
Environment: pypi
Status
Early alpha implementation stage. The data client is usable for discovery, historical bars, yield series, replay streams, polling streams, and Kafka publishing for personal research and prototyping. The analytics layer now emits normalized metric events for batch and streaming workflows.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file fincore_py-0.1.0.dev4.tar.gz.
File metadata
- Download URL: fincore_py-0.1.0.dev4.tar.gz
- Upload date:
- Size: 48.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f036db87073addabb3afeb8672fbe2d4346295b8c8e45742f2108462a656abb2
|
|
| MD5 |
9cf2638eee9987f0da3b8d185ebf74a3
|
|
| BLAKE2b-256 |
46720cdce5301cfceb171d13ddf63c209568078b6833c54e5c22916ca7fa79d3
|
Provenance
The following attestation bundles were made for fincore_py-0.1.0.dev4.tar.gz:
Publisher:
publish.yml on avi2413/fincore
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fincore_py-0.1.0.dev4.tar.gz -
Subject digest:
f036db87073addabb3afeb8672fbe2d4346295b8c8e45742f2108462a656abb2 - Sigstore transparency entry: 2080872119
- Sigstore integration time:
-
Permalink:
avi2413/fincore@5e4859ecfef5f92bea40969e0d803833313b7952 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/avi2413
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5e4859ecfef5f92bea40969e0d803833313b7952 -
Trigger Event:
push
-
Statement type: