Skip to content

Commit 96a603e

Browse files
authored
Merge pull request #115 from jugaad-py/fix/nse-bhavcopy-format-migration
[Fix] Resolve NSE bhavcopy format migration issues #81 & #83
2 parents 684b64f + 8fba94b commit 96a603e

7 files changed

Lines changed: 548 additions & 19 deletions

File tree

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.32.0] - 2026-03-16
9+
10+
### Added
11+
- New `NSEDailyReports` class to handle NSE daily-reports API (39+ report types)
12+
- `NSEArchives.download_report()` method to download any NSE report by file key
13+
- `NSEArchives.list_available_reports()` method to discover available report types
14+
- Hybrid bhavcopy format support: UDiff (recent) + BHAVDATA-FULL (historical)
15+
- Tests for new report discovery and download functionality
16+
17+
### Fixed
18+
- Issue #81: NSE bhavcopy downloads failing for dates >= July 8, 2024 (BadZipFile error)
19+
- Issue #83: Bhavcopy format change - implemented automatic fallback to BHAVDATA-FULL
20+
- Bhavcopy now works for all dates using hybrid approach:
21+
- Recent dates (Jul 8, 2024+): Uses new UDiff format from daily-reports API
22+
- Historical dates: Uses BHAVDATA-FULL format (available for all dates)
23+
24+
### Changed
25+
- `bhavcopy_raw()` now automatically handles both UDiff and BHAVDATA-FULL formats
26+
- Data returned as-is per NSE updates (no backward compatibility guarantee)
27+
828
## [0.31.2] - 2026-03-16
929

1030
### Fixed

docs/API_REFERENCE.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,51 @@ Download derivatives data and save to CSV.
356356
- Same as `derivatives_df()`
357357
- `output` (str): Path for output CSV file
358358

359+
### NSE Daily Reports
360+
361+
#### `list_available_reports()`
362+
Discover all available daily reports from NSE.
363+
364+
**Parameters:** None
365+
366+
**Returns:**
367+
```python
368+
list # List of dictionaries with 'key' and 'name' for each report
369+
```
370+
371+
**Example:**
372+
```python
373+
from jugaad_data.nse import list_available_reports
374+
375+
reports = list_available_reports()
376+
# Returns: [{'key': 'CM-VOLATILITY', 'name': 'CM Volatility'}, ...]
377+
```
378+
379+
#### `download_report(report_key, to_date=None, output=None)`
380+
Download any NSE daily report (39+ report types available).
381+
382+
**Parameters:**
383+
- `report_key` (str): Report key (e.g., "CM-VOLATILITY", "NIFTY-50-ADVANCE-DECLINE")
384+
- `to_date` (datetime.date, optional): Date for report (defaults to NSE current date)
385+
- `output` (str, optional): Path for output file
386+
387+
**Returns:** File saved at `output` path or temp directory
388+
389+
**Example:**
390+
```python
391+
from jugaad_data.nse import download_report
392+
393+
# List available reports first
394+
download_report("CM-VOLATILITY", output="/path/to/file.csv")
395+
```
396+
397+
#### `stock_df(symbol, from_date, to_date)` - Format Note
398+
As of July 8, 2024, NSE transitioned from direct CSV format to compressed UDiff format. The library handles this automatically:
399+
- Dates >= July 8, 2024: Returns UDiff format (newer column structure)
400+
- Historical dates: Falls back to BHAVDATA-FULL format
401+
402+
Both formats are returned as raw CSV data with no column mapping. See [HISTORICAL_DATA_GUIDE](HISTORICAL_DATA_GUIDE.md) for detailed column specifications.
403+
359404
---
360405

361406
## BSE Module

docs/HISTORICAL_DATA_GUIDE.md

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@ A comprehensive guide to downloading historical market data using `jugaad-data`.
1818

1919
Bhavcopies are complete daily market snapshots published by stock exchanges after market close. They contain all traded contracts with their OHLC prices.
2020

21+
### Format Changes (July 8, 2024)
22+
23+
On July 8, 2024, NSE transitioned from the old ZIP-based bhavcopy format to the **Unified Distilled File Format (UDiff)**. The library now automatically handles both formats:
24+
25+
- **Recent Dates (≥ July 8, 2024):** Uses UDiff format from NSE's daily-reports API
26+
- Format: More comprehensive data structure
27+
- Availability: Current day + previous trading day (via API)
28+
29+
- **Historical Dates (< July 8, 2024):** Uses BHAVDATA-FULL format
30+
- Format: CSV with delivery information
31+
- Availability: All historical dates
32+
- No ZIP decompression required
33+
34+
**No action needed on your part** - the library automatically chooses the best available format!
35+
2136
### Types of Bhavcopies
2237

2338
1. **Equity Bhavcopy** - All equity securities traded on NSE
@@ -31,23 +46,38 @@ Bhavcopies are complete daily market snapshots published by stock exchanges afte
3146
from datetime import date
3247
from jugaad_data.nse import bhavcopy_save
3348

34-
# Download for specific date
49+
# Download for specific date (works for all dates, automatic format selection)
3550
bhavcopy_save(date(2020, 1, 1), "/path/to/directory")
51+
bhavcopy_save(date(2024, 9, 15), "/path/to/directory") # Uses UDiff if API available, else BHAVDATA-FULL
3652

3753
# Download for date range
38-
for d in range(1, 31):
54+
from datetime import timedelta
55+
start_date = date(2024, 1, 1)
56+
end_date = date(2024, 12, 31)
57+
current = start_date
58+
while current <= end_date:
3959
try:
40-
bhavcopy_save(date(2020, 1, d), "/path/to/directory")
60+
bhavcopy_save(current, "/path/to/directory")
61+
print(f"Downloaded bhavcopy for {current}")
4162
except:
4263
pass # Holiday or weekend
64+
current += timedelta(days=1)
4365
```
4466

45-
**Output file:** `cm01Jan2020bhav.csv`
67+
**Output file:** `cm01Jan2020bhav.csv` or `cm15Sep2024bhav.csv`
4668

4769
**CSV Columns:**
70+
For historical dates (BHAVDATA-FULL format):
71+
```
72+
SYMBOL, SERIES, DATE, PREV_CLOSE, OPEN_PRICE, HIGH_PRICE, LOW_PRICE,
73+
LAST_PRICE, CLOSE_PRICE, AVG_PRICE, TTL_TRD_QNTY, TURNOVER_LACS,
74+
NO_OF_TRADES, DELIV_QTY, DELIV_PER
75+
```
76+
77+
For recent dates (UDiff format):
4878
```
49-
SYMBOL, SERIES, OPEN, HIGH, LOW, CLOSE, LAST, PREVCLOSE, TOTTRDQTY,
50-
TOTTRDVAL, DATE, TOTTRNUM, ISIN
79+
TradDt, BizDt, Sgmt, Src, FinInstrmTp, FinInstrmId, ISIN, TckrSymb,
80+
SctySrs, XpryDt, ... (enhanced data structure)
5181
```
5282

5383
### Download Full Bhavcopy (with Delivery Data)
@@ -64,6 +94,58 @@ full_bhavcopy_save(date(2020, 1, 1), "/path/to/directory")
6494
Delivery Quantity %
6595
```
6696

97+
### Download Other NSE Reports (39+ types available)
98+
99+
The library now provides access to 39+ NSE reports through the daily-reports API:
100+
101+
#### List Available Reports
102+
103+
```python
104+
from jugaad_data.nse import NSEArchives
105+
106+
nse = NSEArchives()
107+
108+
# See all available reports
109+
reports = nse.list_available_reports()
110+
111+
for file_key, info in reports.items():
112+
print(f"{file_key}: {info['displayName']}")
113+
print(f" Available dates: {[d['date'] for d in info['dates']]}")
114+
```
115+
116+
#### Download Specific Reports
117+
118+
```python
119+
from jugaad_data.nse import NSEArchives
120+
121+
nse = NSEArchives()
122+
123+
# Download volatility data
124+
info = nse.download_report('CM-VOLATILITY', "/path/to/save")
125+
print(f"Downloaded: {info['file_name']}")
126+
print(f"Trading date: {info['trading_date']}")
127+
128+
# Other available reports:
129+
# 'CM-UDIFF-BHAVCOPY-CSV' - UDiff format bhavcopy (zip)
130+
# 'CM-BULK-DEAL' - Bulk deals data
131+
# 'CM-BLOCK-DEAL' - Block deals data
132+
# 'CM-SHORT-SELLING' - Short selling data
133+
# 'CM-VOLATILITY' - Daily volatility
134+
# 'CM-CIRCUIT' - Circuit breaker updates
135+
# ... and 33+ more report types
136+
```
137+
138+
**Return Value:**
139+
```python
140+
{
141+
'file_path': '/path/to/save/filename.csv', # Local file path
142+
'file_name': 'CMVOLT_13032026.CSV', # Actual file name from NSE
143+
'trading_date': '13-Mar-2026', # Trading date of report
144+
'size': '292.78 KB', # File size
145+
'cached': False # Whether file was cached
146+
}
147+
```
148+
67149
### Download F&O Bhavcopy
68150

69151
```python

docs/QUICKSTART.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,31 @@ Output includes:
178178
- Government Securities rates
179179
- Index values (Sensex, Nifty 50)
180180

181+
### Download NSE Daily Reports (39+ Report Types)
182+
183+
NSE publishes 39+ different reports daily including volatility data, advance/decline data, and more.
184+
185+
```python
186+
from jugaad_data.nse import list_available_reports, download_report
187+
188+
# Discover all available reports
189+
reports = list_available_reports()
190+
for report in reports[:5]: # Show first 5
191+
print(f"{report['key']}: {report['name']}")
192+
193+
# Download a specific report (e.g., CM Volatility)
194+
download_report("CM-VOLATILITY", output="cm_volatility.csv")
195+
196+
# Download another report type
197+
download_report("NIFTY-50-ADVANCE-DECLINE", output="nifty_advance_decline.csv")
198+
```
199+
200+
Available reports include:
201+
- CM-VOLATILITY: Equity segment volatility measures
202+
- NIFTY-50-ADVANCE-DECLINE: NIFTY 50 advance/decline statistics
203+
- NIFTY-NEXT-50-ADVANCE-DECLINE: NIFTY Next 50 statistics
204+
- And 36+ more report types
205+
181206
### Command Line Interface
182207

183208
```bash
@@ -226,6 +251,7 @@ $ jdata derivatives -s NIFTY -f 2020-01-01 -t 2020-01-23 -e 2020-01-23 -i OPTIDX
226251
✅ Fetch live index and turnover data
227252
✅ Fetch option chains
228253
✅ Fetch current rates from RBI website
254+
✅ Download 39+ NSE daily reports (volatility, advance/decline, etc.)
229255
✅ Pandas dataframe support
230256
✅ Command-line interface
231257

0 commit comments

Comments
 (0)