Skip to content

Commit bdbbca2

Browse files
authored
Merge pull request #117 from jugaad-py/fix/issue-97-derivatives-api
[Fix] Issue #97 - derivatives_df() API endpoint fix
2 parents f50e9ff + be2bba7 commit bdbbca2

5 files changed

Lines changed: 80 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@ 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.33.1] - 2026-03-16
9+
10+
### Fixed
11+
- Issue #97: `derivatives_df()` and `derivatives_csv()` returning empty or failing with 404 error
12+
- NSE deprecated `/api/historical/fo/derivatives` endpoint
13+
- Now uses updated `/api/historicalOR/foCPV` endpoint
14+
- Added `year` parameter to API requests as required by new endpoint
15+
- Historical data availability limited to recent periods per NSE data retention
16+
17+
### Added
18+
- Test coverage for `derivatives_df()` with both futures (FUTIDX) and options (OPTIDX) data
19+
- Test coverage for `derivatives_raw()` with different instrument types
20+
- Documentation note about historical data availability for derivatives
21+
822
## [0.33.0] - 2026-03-16
923

1024
### Changed

docs/API_REFERENCE.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,12 @@ Download derivatives data and save to CSV.
385385
- Same as `derivatives_df()`
386386
- `output` (str): Path for output CSV file
387387

388+
**Note on Historical Data:**
389+
- As of v0.34.0+, the derivatives API endpoint has been updated to use NSE's new `/api/historicalOR/foCPV` endpoint
390+
- Historical data is available for recent periods (typically current and past few months)
391+
- Data availability depends on NSE's data retention policies
392+
- For very old historical data (prior to ~6 months), data may not be available
393+
388394
### NSE Daily Reports
389395

390396
#### `list_available_reports()`

jugaad_data/nse/history.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def __init__(self):
4646
}
4747
self.path_map = {
4848
"stock_history": "/api/historicalOR/generateSecurityWiseHistoricalData",
49-
"derivatives": "/api/historical/fo/derivatives",
49+
"derivatives": "/api/historicalOR/foCPV",
5050
"equity_quote_page": "/report-detail/eq_security",
5151
}
5252
self.base_url = "https://www.nseindia.com"
@@ -95,7 +95,8 @@ def _derivatives(self, symbol, from_date, to_date, expiry_date, instrument_type,
9595
'from': from_date.strftime('%d-%m-%Y'),
9696
'to': to_date.strftime('%d-%m-%Y'),
9797
'expiryDate': expiry_date.strftime('%d-%b-%Y').upper(),
98-
'instrumentType': instrument_type
98+
'instrumentType': instrument_type,
99+
'year': from_date.year
99100
}
100101
if "OPT" in instrument_type:
101102
if not(strike_price and option_type):

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "jugaad-data"
7-
version = "0.33.0"
7+
version = "0.33.1"
88
requires-python = ">= 3.9"
99
authors = [{name = "jugaad-coder", email = "abc@xyz.com"}]
1010
description = "Free Zerodha API python library"

tests/test_nse.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,62 @@ class TestDerivatives(TestCase):
167167
def setUp(self):
168168
setup_test(self)
169169

170+
def test_derivatives_raw_futures(self):
171+
"""Test fetching futures derivatives data"""
172+
symbol = "NIFTY"
173+
from_date = date(2026, 3, 9)
174+
to_date = date(2026, 3, 16)
175+
expiry_date = date(2026, 3, 30)
176+
instrument_type = "FUTIDX"
177+
178+
raw = nse.derivatives_raw(symbol, from_date, to_date, expiry_date, instrument_type,
179+
strike_price=None, option_type=None)
180+
assert len(raw) > 0
181+
# Verify required fields for futures
182+
assert 'FH_TIMESTAMP' in raw[0]
183+
assert 'FH_SYMBOL' in raw[0]
184+
assert 'FH_CLOSING_PRICE' in raw[0]
185+
assert raw[0]['FH_SYMBOL'] == symbol
186+
187+
def test_derivatives_raw_options(self):
188+
"""Test fetching options derivatives data"""
189+
symbol = "NIFTY"
190+
from_date = date(2026, 3, 9)
191+
to_date = date(2026, 3, 16)
192+
expiry_date = date(2026, 3, 30)
193+
instrument_type = "OPTIDX"
194+
strike_price = 23000
195+
option_type = "PE"
196+
197+
raw = nse.derivatives_raw(symbol, from_date, to_date, expiry_date, instrument_type,
198+
strike_price=strike_price, option_type=option_type)
199+
assert len(raw) > 0
200+
# Verify required fields for options
201+
assert 'FH_TIMESTAMP' in raw[0]
202+
assert 'FH_OPTION_TYPE' in raw[0]
203+
assert 'FH_STRIKE_PRICE' in raw[0]
204+
assert raw[0]['FH_OPTION_TYPE'] == option_type
205+
assert raw[0]['FH_STRIKE_PRICE'] == strike_price
206+
207+
def test_derivatives_df(self):
208+
"""Test fetching derivatives as dataframe"""
209+
symbol = "NIFTY"
210+
from_date = date(2026, 3, 9)
211+
to_date = date(2026, 3, 16)
212+
expiry_date = date(2026, 3, 30)
213+
instrument_type = "OPTIDX"
214+
strike_price = 23000
215+
option_type = "PE"
216+
217+
df = nse.derivatives_df(symbol, from_date, to_date, expiry_date, instrument_type,
218+
strike_price=strike_price, option_type=option_type)
219+
assert len(df) > 0
220+
# Verify required columns for options
221+
assert 'DATE' in df.columns
222+
assert 'EXPIRY' in df.columns
223+
assert 'STRIKE PRICE' in df.columns
224+
assert 'OPTION TYPE' in df.columns
225+
assert 'CLOSE' in df.columns
170226

171227
class TestIndexHistory(TestCase):
172228
def setUp(self):

0 commit comments

Comments
 (0)