The High-Performance Python SDK for Indian Equities (NSE & BSE)
A 1:1 drop-in replacement for yfinance (1.7.0+ compatible) supercharged with 10-year audited Ind AS financials, concalls with streamable audio MP3s, institutional stock screeners, multi-tab Excel models, and native AI/LLM data feeds.
Standard financial libraries like yfinance often fail Indian equity investors: Yahoo Finance truncates Indian financial statements to just 4–5 years, frequently experiences missing fundamental data, lacks conference calls and shareholding patterns, and breaks with upstream API changes.
bfinance solves this completely. It gives you the exact same API as yfinance 1.7.0+ so your existing code, charting tools, and backtesters work with zero code changes, while giving you access to deep Indian corporate data:
| Dimension |
yfinance (Standard) |
bfinance (Supercharged) |
|---|---|---|
| API Syntax Parity | 1.7.0+ Standard |
100% Drop-in Equivalent (yf.Ticker bf.Ticker) |
| Financial Statements Depth | 4 to 5 Years (Standard Yahoo) | 10 to 13+ Years (Audited Ind AS Statements) |
| Quarterly Statement History | 4 to 5 Quarters | 12 to 16+ Historical Quarters |
| Institutional Shareholding | Basic / Often Empty | 12Q Quarterly & 11Y Annual Trends (Promoter, FII, DII, Govt, Public) |
| Conference Calls & Transcripts | ❌ None | 40+ Concalls with Direct Audio MP3s, BSE PDFs & Presentations |
| Annual Reports & Credit Ratings | ❌ None | 15+ Years Annual Report PDFs & CRISIL/ICRA Credit Rationales |
| Sector & Industry Hierarchy | Generic Global Taxonomy |
4-Level Indian Taxonomy + Index Memberships (Nifty 50, Sensex) |
| Institutional Stock Screens | ❌ None | Built-in Screens: Coffee Can, Magic Formula, Debt-Free, High Yield |
| Custom Ratios & Scoring | ❌ None | Piotroski 9-Point Score, Graham Number, EV/EBITDA, Screener search |
| Excel Financial Modeling | ❌ None |
1-Line Multi-Tab .xlsx Export matching Screener "Export to Excel" |
| AI / LLM Context Engine | ❌ None | Native Token-Dense Markdown/JSON Dossiers & Prompt Factories |
| Anti-Blocking Architecture | ❌ None | Persistent SQLite Cache (24h TTL), User-Agent pool, Jitter pacing |
# Using pip
pip install bfinance
# Using uv (recommended)
uv add bfinanceSimply replace import yfinance as yf with import bfinance as yf:
import bfinance as yf
# 1. Initialize any NSE or BSE ticker (supports RELIANCE, RELIANCE.NS, 500325.BO)
ticker = yf.Ticker("RELIANCE")
# 2. Exact yfinance 1.7.0 APIs work out of the box!
print("Live CMP:", ticker.fast_info.last_price)
print("Market Cap:", ticker.fast_info.market_cap)
# Historical OHLCV (Exact DataFrame schema with Dividends & Splits)
hist = ticker.history(period="1mo", actions=True)
print(hist.tail())
# 3. Access 10-Year Audited Financial Statements
print(ticker.financials) # 10+ Years Ind AS Annual Income Statement
print(ticker.balance_sheet) # 10+ Years Annual Balance Sheet
print(ticker.cashflow) # 10+ Years Cash Flow Statement
print(ticker.quarterly_income_stmt) # 12+ Quarters Results
# 4. Multi-ticker downloading (yf.download equivalent)
data = yf.download(["TCS", "INFY", "HDFCBANK"], period="5d")Access over 40+ historical quarterly earnings calls, download PDFs, and stream raw audio:
import bfinance as bf
stock = bf.Ticker("TCS")
for call in stock.concalls[:3]:
print(f"[{call.date}] {call.title}")
print(" • PDF Transcript:", call.transcript_url)
print(" • Audio MP3 Link:", call.audio_url)
# Download the latest concall audio MP3 straight to disk
stock.download_concall_audio(index=0, dest_path="./tcs_concall.mp3")
# Download the latest transcript PDF
stock.download_concall_transcript(index=0, dest_path="./tcs_transcript.pdf")Track institutional accumulation across FIIs, Mutual Funds, and Promoters:
stock = bf.Ticker("RELIANCE")
# 12+ Quarters Distribution
print("Quarterly Shareholding (12Q):\n", stock.shareholding)
# 11+ Years Historical Long-Term Trend
print("Annual Shareholding (11Y):\n", stock.shareholding_yearly)stock = bf.Ticker("RELIANCE")
print("Sector:", stock.sector) # Energy
print("Industry Group:", stock.industry_group) # Oil, Gas & Consumable Fuels
print("Industry:", stock.industry) # Petroleum Products
print("Sub-Industry:", stock.sub_industry) # Refineries & Marketing
print("Indices:", stock.indices) # ['BSE Sensex', 'Nifty 50', 'BSE 500', ...]Search Screener's 500+ ratio directory and compute advanced investment metrics:
stock = bf.Ticker("RELIANCE")
# 1. Joseph Piotroski 9-Point F-Score
print("Piotroski Score:", stock.piotroski_score, "/ 9")
# 2. Benjamin Graham Maximum Fair Value
print("Graham Number: ₹", stock.graham_number)
# 3. Enterprise Value & Multiples
print("Enterprise Value: ₹", stock.enterprise_value, "Cr")
print("EV / EBITDA:", stock.ev_to_ebitda, "x")
print("Interest Coverage Ratio:", stock.interest_coverage, "x")
# 4. Search Screener's 500+ ratio catalog
results = bf.ratios.search("graham")
for r in results:
print(r["name"], "->", r["description"])Run pre-built institutional strategies or custom filters:
import bfinance as bf
# 1. Saurabh Mukherjea Coffee Can (10Y ROCE > 15% & ROE > 15%)
coffee_df = bf.screens.coffee_can.run(max_stocks=10)
print(coffee_df[['Symbol', 'Name', 'Price', 'ROCE_%', 'ROE_%']])
# 2. Joel Greenblatt Magic Formula (High ROCE + Attractive P/E)
magic_df = bf.screens.magic_formula.run(max_stocks=10)
# 3. Other built-in screens
bf.screens.debt_free_compounders.run()
bf.screens.high_dividend_yield.run()
bf.screens.undervalued_growth.run()
# 4. Custom Screener Predicate
growth_screen = bf.screens.custom(
name="High ROE Midcaps",
filter_fn=lambda t: (t.info.get("marketCapInCr") or 0) > 10000 and ((t.info.get("returnOnEquity") or 0) * 100) > 20
)
print(growth_screen.run(max_stocks=5))Export complete 10+ year statements and valuation ratios into an 8-sheet .xlsx workbook matching Screener's "Export to Excel":
stock = bf.Ticker("RELIANCE")
stock.to_excel("Reliance_10Y_Financial_Model.xlsx")Generates sheets: Overview, Profit & Loss, Quarters, Balance Sheet, Cash Flow, Shareholding, Ratios History, and Peers.
Feed 100% of corporate data directly to AI agents (Gemini, Claude, GPT, DeepSeek, LangChain, LlamaIndex, CrewAI):
stock = bf.Ticker("RELIANCE")
# 1. Generate token-dense Markdown financial dossier
markdown_dossier = stock.to_ai_context(format="markdown")
# 2. Or generate structured JSON dictionary
json_dossier = stock.to_ai_context(format="json")
# 3. Ready-to-run prompt templates
memo_prompt = stock.to_investment_memo_prompt() # Initiation Coverage Note
audit_prompt = stock.to_forensic_audit_prompt() # Forensic Accounting Check
concall_prompt = stock.to_concall_analyst_prompt() # Earnings Call Analysisfrom bfinance.ai import BFinanceAITools
# Get native OpenAI / Gemini tool calling schemas
tools = BFinanceAITools.get_openai_tools()
# Execute tool call returned by LLM
result = BFinanceAITools.execute_tool(
name="get_stock_dossier",
arguments={"symbol": "TCS", "format": "markdown"}
)bfinance is engineered for production environments where reliability and uptime are paramount:
- Persistent SQLite Caching (
~/.cache/bfinance/cache.db):- Fundamentals cached for 24 hours, search queries for 7 days, chart timeseries for 6 hours.
- 99% of requests resolve in < 1ms from disk cache without touching remote servers.
- Adaptive Request Pacing & Jitter:
- Automatic
150mspacing +10–50msGaussian micro-jitter to prevent WAF burst detection.
- Automatic
- Desktop Browser Pool Rotation:
- Automatically rotates realistic Chrome, Safari, Firefox, and Edge user-agents with complete browser headers.
- Exponential Backoff:
- Recovers gracefully from HTTP 429 rate limits without aggressive retry spam.
- Zero-Crash Graceful Degradation (
raise_errors=Falsedefault):- Missing data, invalid symbols, or delisted companies log structured warnings via standard Python
loggingand return safe empty DataFrames/dictionaries instead of throwing uncaught exceptions.
- Missing data, invalid symbols, or delisted companies log structured warnings via standard Python
- 📖 API Reference Manual: Exhaustive function-by-function guide.
- 🔄 yfinance Migration Guide: Step-by-step migration notes.
- 🤖 AI Agent Integration Guide: Using
bfinancewith LangChain, LlamaIndex, CrewAI, and OpenAI/Gemini. - 🧪 Contributing & Development: Testing and development setup.
bfinance maintains an exhaustive test suite with 54/54 tests passing:
# Run full test suite with uv
uv run pytestThis project is licensed under the MIT License. See LICENSE for complete terms.
- Educational & Academic Purpose Only:
bfinanceis an open-source software library developed strictly for academic, educational, and research purposes. It is NOT financial, investment, accounting, tax, or legal advice. - No Investment Liability: The developers, maintainers, and contributors are not SEBI-registered Research Analysts (RA) or Investment Advisors (RIA). No output from this library constitutes a recommendation or solicitation to buy, sell, or hold any security or financial derivative. Users assume 100% full responsibility for their own financial decisions and trading operations. In no event shall the authors be liable for any direct, indirect, or consequential financial losses.
- Independent Project & Non-Affiliation:
bfinanceis an independent open-source project and is not affiliated, endorsed, authorized, or certified by Yahoo! Inc.,yfinance, Screener.in (Mittal Analytics), NSE India, BSE India, or any of their parent entities or subsidiaries. All product names, trademarks, ticker symbols, and brand logos belong to their respective owners. - Data Verification & Fair Usage: Data is fetched from publicly accessible endpoints. Users are responsible for complying with the Terms of Service and rate limits of any upstream platforms. For mission-critical commercial applications, users should subscribe to official authorized market data providers.