High-performance async Bangladesh stock market data library with batch processing
Project description
bdfinance
High-performance async Python library for fetching Bangladesh stock market data from the Dhaka Stock Exchange (DSE).
Inspired by yfinance, bdfinance provides a familiar Ticker-based API backed by async HTTP, automatic caching, structured logging, and Pydantic-validated models.
Features
- Async-first — built on
httpxwith HTTP/2 and connection pooling - Ticker API — unified interface per symbol: quote, history, info, depth, news, fundamentals
- Batch processing — fetch data for multiple symbols concurrently
- Caching — pluggable memory or Redis cache with configurable TTL
- Pydantic models — strongly typed, auto-validated data models
- Retry & rate limiting — exponential backoff with configurable rate limits
- Structured logging — powered by
structlog - Treasury bonds — coupon rates, approximate YTM calculations
Installation
Requires Python 3.12+.
pip install bdfinance
Or install from source:
git clone https://github.com/your-username/bdfinance.git
cd bdfinance
pip install .
Dependencies
| Package | Purpose |
|---|---|
httpx[http2] |
Async HTTP client with HTTP/2 |
beautifulsoup4 + lxml |
HTML parsing |
pandas |
DataFrames for historical/tabular data |
pydantic + pydantic-settings |
Data models and configuration |
tenacity |
Retry logic |
structlog |
Structured logging |
aiocache + msgpack |
Caching layer |
Quick Start
import asyncio
from bdfinance import BDStockClient
async def main():
async with BDStockClient() as client:
ticker = client.ticker("GP")
# Current quote
quote = await ticker.quote()
print(f"{quote.symbol}: LTP {quote.ltp}, Change {quote.change}")
# Historical data (returns pandas DataFrame)
df = await ticker.history(period="1y")
print(df.head())
# Company information
info = await ticker.info()
print(info.basic_information.company_name)
# Market depth
depth = await ticker.depth()
print(f"Buy: {depth.buy_price} | Sell: {depth.sell_price}")
# Fundamentals (quote + info + PE combined)
fundamentals = await ticker.fundamentals()
asyncio.run(main())
Multiple Tickers
async with BDStockClient() as client:
tickers = client.tickers(["GP", "BEXIMCO", "ACI"])
for symbol, ticker in tickers.items():
quote = await ticker.quote()
print(f"{symbol}: {quote.ltp}")
Configuration
Both ClientConfig and CacheConfig use pydantic-settings and can be configured via constructor arguments or environment variables (prefixed with BDFINANCE_ / BDFINANCE_CACHE_).
from bdfinance import BDStockClient, ClientConfig, CacheConfig
config = ClientConfig(
timeout=60.0,
max_retries=5,
rate_limit=20,
enable_cache=True,
)
cache_config = CacheConfig(
backend="memory", # or "redis"
ttl=600, # seconds
)
async with BDStockClient(config=config, cache_config=cache_config) as client:
...
| Env Variable | Default | Description |
|---|---|---|
BDFINANCE_TIMEOUT |
30.0 |
Request timeout (seconds) |
BDFINANCE_MAX_RETRIES |
3 |
Max retry attempts |
BDFINANCE_RATE_LIMIT |
10 |
Max requests per second |
BDFINANCE_ENABLE_CACHE |
true |
Enable response caching |
BDFINANCE_CACHE_BACKEND |
memory |
memory or redis |
BDFINANCE_CACHE_TTL |
300 |
Cache TTL (seconds) |
BDFINANCE_CACHE_REDIS_URL |
redis://localhost:6379/0 |
Redis URL |
See docs/configuration.md for the full reference.
Documentation
| Document | Description |
|---|---|
| Client & Ticker | BDStockClient and Ticker API reference |
| Configuration | ClientConfig and CacheConfig details |
| Models | Pydantic data models (trading, market, news, company) |
| Repositories | Low-level TradingRepository, MarketRepository, NewsRepository |
| Caching | Cache backends, key generation, TTL management |
| Utilities | Data cleaners, date helpers, HTML parsers |
Usage Examples
Historical Data
# By date range
df = await ticker.history(start="2024-01-01", end="2024-12-31")
# By period shorthand
df = await ticker.history(period="6mo") # 6 months
df = await ticker.history(period="1y") # 1 year
df = await ticker.history(period="30d") # 30 days
Market Data (via repositories)
async with BDStockClient() as client:
# Market overview
overview = await client.market.get_market_overview(period="7d")
# Latest P/E ratios
pe = await client.market.get_latest_pe()
# Top stocks / gainers / losers
top = await client.market.get_top_stocks()
gainers = await client.market.get_top_10_gainers()
losers = await client.market.get_top_10_losers()
# Sector listing
sectors = await client.market.get_sector_listed()
# Treasury bond yields
bonds = await client.market.get_tbond_yields(tenor="10Y")
News
async with BDStockClient() as client:
ticker = client.ticker("GP")
# Company-specific news
news = await ticker.news()
# AGM news for this company
agm = await ticker.agm_news()
# All DSE news (via repository)
all_news = await client.news.get_all_news()
Cache Management
async with BDStockClient() as client:
# Clear all cached data
await client.clear_cache()
Project Structure
bdfinance/
├── __init__.py # Public API exports
├── client.py # BDStockClient entry point
├── ticker.py # Unified Ticker interface
├── config.py # ClientConfig / CacheConfig
├── constants.py # DSE URLs and endpoints
├── http_client.py # Async HTTP client
├── cache.py # Cache backends (memory / redis)
├── parsers.py # HTML parsing utilities
├── models/
│ ├── trading.py # CurrentTradeData, BasicHistoricalData, ...
│ ├── market.py # MarketInfo, MarketDepth, CompanyInfo, TBondInfo
│ ├── news.py # AGMNews, News
│ └── company.py # DSECompanyData and sub-models
├── repositories/
│ ├── base.py # BaseRepository with get_data / get_dataframe
│ ├── trading.py # TradingRepository
│ ├── market.py # MarketRepository
│ └── news.py # NewsRepository
└── utils/
├── common.py # Dict helpers
├── data_cleaners.py # clean_float, clean_int, clean_symbol, ...
├── date_helper.py # Period parsing, date conversion
└── parse_com_info.py # DSE company page parser
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bdfinance-0.5.0.tar.gz.
File metadata
- Download URL: bdfinance-0.5.0.tar.gz
- Upload date:
- Size: 44.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
289b81fba8c3515bfd34dc1ec52dce2f5a2bf7f5d345b5b46f77caf6b31745f7
|
|
| MD5 |
3d49c3b2bee0bd727bc6a5423af8270a
|
|
| BLAKE2b-256 |
afd5b55dcd9f055a878100f4777b4a34e836d7530ee57cf8635740421d4864aa
|
File details
Details for the file bdfinance-0.5.0-py3-none-any.whl.
File metadata
- Download URL: bdfinance-0.5.0-py3-none-any.whl
- Upload date:
- Size: 42.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
42181adce31174487c206f80c79ecaa3f526bb1b716278174c2d6fb6b64d0ff6
|
|
| MD5 |
3e11c4d0630d56c5f571f84f15909f80
|
|
| BLAKE2b-256 |
88877e7853505ed2058c4d3dc6d26a15420b85233cb91ac659dc481a9c633e26
|