Python library for downloading and parsing B3 (Brazilian Stock Exchange) market data
Project description
b3quant
Python library for downloading and parsing historical market data from B3 (Brazilian Stock Exchange).
Features
- Download COTAHIST files - Yearly or daily historical data
- Parse to pandas DataFrames - Clean, typed data ready for analysis
- Filter by instrument type - Options, stocks, or all instruments
- Simple, Pythonic API - Intuitive interface
- Type hints - Full type annotations for better IDE support
- Caching - Avoid redundant downloads
- No R dependencies - Pure Python implementation
Installation
From PyPI (Recommended)
pip install b3quant
From Source (Development)
If you cloned the repository:
git clone https://github.com/renves/b3quant.git
cd b3quant
pip install -e .
Or using uv:
git clone https://github.com/renves/b3quant.git
cd b3quant
uv sync
uv run python your_script.py
Quick Start
import b3quant as pyb
# Get all options traded in 2024
options = pyb.get_options(year=2024)
# Filter by underlying asset
petr_options = options[options['underlying'] == 'PETR']
# Get specific columns
print(options[['ticker', 'strike_price', 'close_price', 'volume']].head())
Usage
Basic Usage
from b3quant import B3Quant
# Initialize
b3 = B3Quant()
# Get options for a single year
options_2024 = b3.get_options(year=2024)
# Get options for a specific month (year, month)
options_nov = b3.get_options(month=(2024, 11))
# Get options for a specific date
options_day = b3.get_options(date="2024-12-20")
# Get stocks data
stocks_2024 = b3.get_stocks(year=2024)
# Get all instruments
all_data = b3.get_all(year=2024)
Working with Options Data
import b3quant as pyb
# Get options
options = pyb.get_options(year=2024)
# Filter by type
calls = options[options['instrument_type'] == 'CALL']
puts = options[options['instrument_type'] == 'PUT']
# Filter by underlying
petr_options = options[options['underlying'] == 'PETR']
# Get options near expiration
short_term = options[options['days_to_maturity'] <= 30]
# Calculate moneyness (requires underlying price)
# You'll need to merge with stocks data or calculate separately
Advanced: Enrich with Underlying Prices
import b3quant as pyb
# Get options and stocks from a specific month
options = pyb.get_options(month=(2024, 11))
stocks = pyb.get_stocks(month=(2024, 11))
# Merge to get underlying prices
options_enriched = options.merge(
stocks[['ticker', 'trade_date', 'close_price']],
left_on=['underlying', 'trade_date'],
right_on=['ticker', 'trade_date'],
how='left',
suffixes=('', '_underlying')
)
# Calculate moneyness
options_enriched['moneyness'] = (
options_enriched['close_price_underlying'] /
options_enriched['strike_price']
)
# Filter ATM options (at-the-money)
atm_options = options_enriched[
(options_enriched['moneyness'] >= 0.95) &
(options_enriched['moneyness'] <= 1.05)
]
Custom Cache Directory
from b3quant import B3Quant
# Use custom cache directory
b3 = B3Quant(cache_dir="./my_data_cache")
options = b3.get_options(year=2024)
Force Re-download
# Force re-download even if file exists in cache
options = b3.get_options(year=2024, force_download=True)
DataFrame Schema
Options Data
| Column | Type | Description |
|---|---|---|
record_type |
str | Record type code |
trade_date |
date | Trading date |
ticker |
str | Option ticker (e.g., PETRL255) |
instrument_type |
str | CALL or PUT |
underlying |
str | Underlying asset code (e.g., PETR) |
company_name |
str | Company name |
strike_price |
float | Strike price in BRL |
maturity_date |
date | Expiration date |
open_price |
float | Opening premium |
high_price |
float | Highest premium |
low_price |
float | Lowest premium |
close_price |
float | Closing premium |
avg_price |
float | Average premium |
volume |
float | Trading volume in BRL |
trades_count |
int | Number of trades |
quantity |
int | Contracts traded |
days_to_maturity |
int | Days until expiration |
time_to_maturity |
float | Years until expiration |
Stocks Data
Similar schema but without strike_price, maturity_date, and option-specific fields.
Examples
Example 1: Calculate Implied Volatility Surface
import b3quant as pyb
import pandas as pd
# Get PETR4 options
options = pyb.get_options(year=2024)
petr_opts = options[options['underlying'] == 'PETR'].copy()
# Filter valid data
petr_opts = petr_opts[
(petr_opts['close_price'] > 0) &
(petr_opts['volume'] > 0) &
(petr_opts['days_to_maturity'] > 0)
]
# You would then calculate IV using Black-Scholes
# (requires additional libraries like scipy)
# ... your IV calculation here ...
Example 2: Analyze Option Volume by Strike
import b3quant as pyb
import matplotlib.pyplot as plt
options = pyb.get_options(year=2024)
# Filter PETR4 calls expiring in January 2025
petr_calls = options[
(options['underlying'] == 'PETR') &
(options['instrument_type'] == 'CALL') &
(options['maturity_date'] >= '2025-01-01') &
(options['maturity_date'] < '2025-02-01')
]
# Group by strike
volume_by_strike = petr_calls.groupby('strike_price')['volume'].sum()
# Plot
volume_by_strike.plot(kind='bar', figsize=(12, 6))
plt.title('PETR4 Call Options Volume by Strike (Jan 2025)')
plt.xlabel('Strike Price')
plt.ylabel('Volume (BRL)')
plt.show()
Development
See docs/DEVELOPMENT.md for detailed development setup and guidelines.
Quick start:
# Clone and setup
git clone https://github.com/renves/b3quant.git
cd b3quant
uv sync
# Run tests
uv run pytest -v
# Lint code
uv run ruff check b3quant/
CAPTCHA Handling
B3 sometimes requires CAPTCHA for downloads. If automatic download fails:
- Download manually from B3 website
- Save to cache directory (default:
./data/raw/) - Parse the file directly:
from b3quant.parsers.cotahist import COTAHISTParser
parser = COTAHISTParser()
options = parser.parse_file('path/to/COTAHIST_A2024.TXT', instrument_filter='options')
Data Source
All data comes from B3 (Brasil, Bolsa, Balcão) official historical data files.
Official B3 Data Page: https://www.b3.com.br/en_us/market-data-and-indices/data-services/market-data/historical-data/equities/historical-quotes/
Available Data:
- Yearly series: 1986 to current year (COTAHIST_A{YEAR}.ZIP)
- Monthly series: Last 12 months (COTAHIST_M{MM}{YEAR}.ZIP)
- Daily series: Current year (COTAHIST_D{DDMMYYYY}.ZIP)
Format Details:
- Format: COTAHIST (fixed-width text format, 245 bytes per line)
- Update frequency: Daily
- Historical depth: Since 1986
- License: Data is publicly available from B3
- Encoding: Latin-1
Contributing
Contributions are welcome! See docs/CONTRIBUTING.md for detailed guidelines.
Quick summary:
- Fork the repository
- Create a feature branch (
git checkout -b feat/amazing-feature) - Make your changes and add tests
- Run tests and linter
- Commit with conventional commits format
- Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Disclaimer
This library is not affiliated with or endorsed by B3. It is an independent project for educational and research purposes.
Market data provided by B3 is subject to their terms of use. Please review B3's data policies before using this library for commercial purposes.
Credits
This library was inspired by and builds upon the work of:
- rb3 by Wilson Freitas - R package for downloading B3 data
- b3fileparser by Carlos Oliveira - Python parser for COTAHIST files
b3quant combines the functionality of both libraries into a unified, Pythonic interface with additional features and optimizations.
Citation
If you use this library in your research, please cite:
@software{b3quant2024,
author = {Renan Alves},
title = {b3quant: Python library for B3 market data},
year = {2024},
url = {https://github.com/renves/b3quant}
}
Documentation
- Development Guide - Setup and development workflow
- Contributing Guide - How to contribute
- Publishing Guide - Release and publishing process
- Changelog - Version history
Support
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
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 b3quant-0.1.8.tar.gz.
File metadata
- Download URL: b3quant-0.1.8.tar.gz
- Upload date:
- Size: 16.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b8230194b408671ddc71a778d24f8838bd6d5b5f60d10fa81b210482cf08c09
|
|
| MD5 |
5dceb72d90ceaf82884f60c614658a69
|
|
| BLAKE2b-256 |
12c81bde74b8d8b43104ccef39bc4352c190382b8411e8a6e7f7e0f483c63601
|
File details
Details for the file b3quant-0.1.8-py3-none-any.whl.
File metadata
- Download URL: b3quant-0.1.8-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b22e48e9f330eb114d992650250d62b1642e18344b2ba0c2425cd87b4c4d188
|
|
| MD5 |
243a943dbad88734bd2ebf455ef06cc1
|
|
| BLAKE2b-256 |
6afe165423f85dd92040c851500497c3d76b8015192a48d60c711b60de5390fc
|