Want to pull IPO listing prices, Day 1 gains, and historical charts directly from NSE/BSE without scraping websites?
Here are working Python scripts using official/public APIs that deliver clean data for research.
These fetch equity historical prices for any listed IPO, perfect for building your own IPO listing gains tracker that compares debut performance with long‑term returns.

Prerequisites (Quick Setup)
bashpip install yfinance nsepy requests pandas yfinance
Note: NSEpy works for NSE; yfinance handles both NSE/BSE with Yahoo Finance proxy. For production, consider paid APIs like Alpha Vantage or broker feeds.
Script1: NSE Historical Prices via NSEpy (Most Accurate)
pythonfrom nsepy import get_history
from datetime import date, timedelta
import pandas as pd
def fetch_nse_ipo_history(symbol, from_date, to_date):
"""
Fetch NSE historical prices for IPO research
symbol: 'RELIANCE' or 'TATAMOTORS'
"""
try:
# Get data from listing date to today
df = get_history(
symbol=symbol,
start=date(*from_date),
end=date(*to_date),
index=True
)
return df[['Close', 'High', 'Low', 'Volume']]
except Exception as e:
print(f"Error fetching {symbol}: {e}")
return None
# Example: Track recent IPO from listing day
ipo_data = fetch_nse_ipo_history('EXAMPLEIPO', (2026, 1, 21), (2025, 12, 18))
if ipo_data is not None:
print("IPO Listing Day High:", ipo_data['High'].iloc[0])
print(ipo_data.head())
Script2: NSE/BSE via yfinance (Easiest, Cross-Exchange)
pythonimport yfinance as yf
import pandas as pd
def fetch_yfinance_ipo(symbol, period="3mo"):
"""
Fetch NSE (.NS) or BSE (.BO) IPO data via Yahoo Finance
Example: 'ABCIPO.NS' or 'DEFIPO.BO'
"""
ticker = yf.Ticker(symbol)
hist = ticker.history(period=period)
if not hist.empty:
listing_gain = ((hist['High'].iloc[0] - hist['Close'].iloc[-1]) / hist['Close'].iloc[-1]) * 100
print(f"Day 1 High Gain: {listing_gain:.1f}%")
return hist[['High', 'Low', 'Close', 'Volume']]
return None
# Track multiple IPOs
ipos = ['EXAMPLE1.NS', 'EXAMPLE2.BO']
for ipo in ipos:
data = fetch_yfinance_ipo(ipo)
if data is not None:
print(f"\n{ipo} Listing Performance:")
print(data.head())
Script3: NSE Historical CSV Direct Download (Bulk Data)
pythonimport requests
import pandas as pd
from io import StringIO
def download_nse_cm_data(symbol, from_date, to_date):
"""
Direct NSE historical data dump (daily OHLCV)
"""
url = f"https://www.nseindia.com/api/historical/cm/equity?symbol={symbol}&series=[%22EQ%22]&from={from_date}&to={to_date}"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept-Language': 'en-US,en;q=0.9'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = response.json()['data']
df = pd.DataFrame(data, columns=['Symbol', 'Series', 'Open', 'High', 'Low', 'Close', 'Volume'])
return df
return None
# Usage
nse_data = download_nse_cm_data('RELIANCE', '26-01-2025', '18-12-2025')
Script 4: BSE Historical via Alpha Vantage (Paid/Free Tier)
pythonimport requests
import pandas as pd
def fetch_bse_via_av(symbol, api_key, from_date, to_date):
"""
BSE data via Alpha Vantage (free tier: 5 calls/min)
Sign up: alphavantage.co
"""
url = f"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol={symbol}.BSE&apikey={api_key}"
data = requests.get(url).json()
df = pd.DataFrame(data['Time Series (Daily)']).T
df.index = pd.to_datetime(df.index)
df = df[['4. close', '2. high', '3. low']].astype(float)
return df
# av_key = "YOUR_FREE_KEY"
# bse_data = fetch_bse_via_av("TATAMOTORS", av_key, "2026-01-01", "2025-12-18")
Once you have these datasets, you can benchmark each script’s output against our framework for tracking past IPO listing gains and interpreting Day 1 moves.
Complete IPO Performance Tracker Script
pythonimport yfinance as yf
import pandas as pd
def ipo_performance_tracker(ipo_symbols):
"""
Track listing gains for multiple IPOs
"""
results = []
for symbol in ipo_symbols:
ticker = yf.Ticker(symbol)
hist = ticker.history(period="6mo")
if len(hist) > 1:
issue_price = hist['Close'].iloc[-1] # Assume last as proxy
list_high = hist['High'].iloc[0]
gain_pct = ((list_high - issue_price) / issue_price) * 100
results.append({
'Symbol': symbol,
'List High': list_high,
'Issue Price': issue_price,
'Day 1 Gain %': gain_pct,
'Current Price': hist['Close'].iloc[0]
})
return pd.DataFrame(results)
# Track 2026 IPOs
recent_ipos = ['ABCIPO.NS', 'DEFIPO.BO', 'GHIIPO.NS']
tracker = ipo_performance_tracker(recent_ipos)
print(tracker.sort_values('Day 1 Gain %', ascending=False))
tracker.to_csv('ipo_gains_2026.csv', index=False)
This function lets you compare Day 1 performance across several issues and relate those moves to factors influencing high listing gains in IPOs such as demand, pricing, and market sentiment.
Pro Tips for Reliable Data
- NSE Suffix: Add
.NS(NSE) or.BO(BSE) to Yahoo symbols - Listing Date: Cross-check exact list date from Chittorgarh/NSE before analysis
- Volume Spike: Day 1 volume >> average confirms listing day
- Rate Limits: yfinance = unlimited; NSEpy = NSE blocks heavy use, Alpha Vantage = 5/min free
- GMP Proxy: Combine these post‑listing numbers with IPO GMP today data for pre‑list predictions and to see how grey‑market expectations compare with actual listing prices.
Export & Visualize Results
pythonimport matplotlib.pyplot as plt
# From tracker DataFrame above
tracker.plot(x='Symbol', y='Day 1 Gain %', kind='bar')
plt.title('2026 IPO Listing Gains')
plt.ylabel('Gain %')
plt.savefig('ipo_gains_chart.png')
plt.show()
These scripts give you IPO historical prices from NSE and BSE APIs in seconds CSV exports, charts, and gain calculations, so you can quickly compare them with best performing IPOs in recent years.
Scale for portfolio tracking or backtesting, and combine these results with a fundamental checklist on how to analyse an IPO to decide which listings deserve deeper research. For 100+ IPOs, loop through Screener.in CSV exports as input.









