As a developer who has worked extensively with overseas financial data APIs, I recently took on a project requiring access to Nigerian Stock Exchange (NGX / NSENG) data. I encountered quite a few challenges and learned some valuable lessons along the way.
Unlike the mature API ecosystems of A-share or U.S. markets, documentation and Chinese-language resources for the Nigerian market are almost non-existent — even English materials are very limited. In this article, I’ll share my real-world experience using the iTick API to fetch real-time quotes and historical K-line data for NG stocks. I hope this can save time for others facing similar needs.
1. Preparation: API Setup Basics
1.1 Registration & API Token
iTick is currently one of the more reliable local financial data providers for the Nigerian market, offering both real-time and historical data.
First, go to the official website Register a developer account, complete email verification, and you’ll receive your API_TOKEN (sometimes still called API_KEY in older docs). This token is the core credential for all subsequent API calls — keep it secure.
1.2 Environment Setup
I’m using Python 3.8+. You only need two main libraries for basic usage:
pip install requests pandas mplfinance
-
requests— for HTTP calls -
pandas— for data structuring -
mplfinance— optional, for candlestick charting
2.实战1 – Fetching Real-time Quotes
Current endpoint (2026):
GET /stock/quote?region=NG&code=xxxx
Important: The market code for Nigeria is now NG (not NSENG anymore).
Clean & Reusable Implementation
import requests
import time
from typing import Dict, Optional
import pandas as pd
class ITickNGAPI:
"""
iTick API wrapper for Nigerian (NG) stock market data – 2026 version
"""
def __init__(self, token: str):
self.base_url = "https://api.itick.org"
self.token = token
self.headers = {
"accept": "application/json",
"token": self.token
}
def get_realtime_quote(self, stock_code: str) -> Optional[Dict]:
"""
Get real-time quote for a single stock
:param stock_code: e.g. "DANGCEM"
:return: quote dictionary or None if failed
"""
for retry in range(3):
try:
url = f"{self.base_url}/stock/quote"
params = {
"region": "NG",
"code": stock_code.upper() # must be uppercase
}
response = requests.get(
url,
headers=self.headers,
params=params,
timeout=10
)
if response.status_code == 200:
result = response.json()
if result.get("code") == 0 and "data" in result:
quote = result["data"]
return {
"Symbol": quote["s"],
"Last Price": quote["ld"],
"Open": quote["o"],
"High": quote["h"],
"Low": quote["l"],
"Volume": quote["v"],
"Change": quote["ch"],
"Change %": quote["chp"],
"Timestamp": quote["t"],
"Trading Status": quote["ts"] # 0=normal, 1=suspended, etc.
}
else:
print(f"No real-time data found for {stock_code} or API error")
return None
else:
print(f"Request failed – status {response.status_code} – retry {retry+1}")
time.sleep(1.5)
except requests.exceptions.Timeout:
print(f"Timeout – retry {retry+1}")
time.sleep(1.5)
except Exception as e:
print(f"Exception: {str(e)}")
return None
return None
# ────────────────────────────────────────────────
if __name__ == "__main__":
MY_TOKEN = "your_itick_token_here"
api = ITickNGAPI(MY_TOKEN)
quote = api.get_realtime_quote("DANGCEM")
if quote:
print("=== Nigerian (NG) Real-time Quote ===")
for k, v in quote.items():
print(f"{k: <14}: {v}")
Sample Output
=== Nigerian (NG) Real-time Quote ===
Symbol : DANGCEM
Last Price : 312.5
Open : 310.0
High : 315.0
Low : 308.0
Volume : 156800
Change : 2.5
Change % : 0.81
Timestamp : 1765526889000
Trading Status: 0
3.实战2 – Fetching Historical K-Line Data
Current endpoint (2026):
GET /stock/kline?region=NG&code=xxxx&kType=8&limit=100
Common kType values:
-
8→ Daily -
9→ Weekly -
10→ Monthly -
1~7→ Minute bars (1min, 5min, 15min, etc.)
Implementation – Historical K-lines
# Add this method to the ITickNGAPI class above
def get_historical_klines(
self,
stock_code: str,
k_type: int = 8, # 8 = daily
limit: int = 100,
end_timestamp: int = None # optional end time (ms)
) -> Optional[pd.DataFrame]:
"""
Fetch historical k-line data
"""
try:
url = f"{self.base_url}/stock/kline"
params = {
"region": "NG",
"code": stock_code.upper(),
"kType": k_type,
"limit": limit
}
if end_timestamp:
params["et"] = end_timestamp
response = requests.get(
url, headers=self.headers, params=params, timeout=12
)
if response.status_code == 200:
result = response.json()
if result.get("code") == 0 and isinstance(result.get("data"), list):
data = result["data"]
if not data:
print(f"No historical data for {stock_code}")
return None
df = pd.DataFrame(data)
df = df[["t", "o", "h", "l", "c", "v"]]
df.rename(columns={
"t": "timestamp_ms",
"o": "Open",
"h": "High",
"l": "Low",
"c": "Close",
"v": "Volume"
}, inplace=True)
# Convert UTC ms → Beijing time
df["datetime"] = pd.to_datetime(df["timestamp_ms"], unit="ms", utc=True)
df["datetime"] = df["datetime"].dt.tz_convert("Asia/Shanghai")
df["date"] = df["datetime"].dt.strftime("%Y-%m-%d %H:%M:%S")
# Reorder columns
df = df[["date", "Open", "High", "Low", "Close", "Volume", "timestamp_ms"]]
return df
else:
print("Unexpected API response format")
return None
else:
print(f"K-line request failed – status {response.status_code}")
return None
except Exception as e:
print(f"Error fetching k-line: {str(e)}")
return None
# ────────────────────────────────────────────────
if __name__ == "__main__":
# ... (api instance already created)
df = api.get_historical_klines("DANGCEM", k_type=8, limit=60)
if df is not None:
print("\n=== Historical Daily K-line (first 5 rows) ===")
print(df.head())
# Optional: candlestick chart
import mplfinance as mpf
plot_df = df.copy()
plot_df["date"] = pd.to_datetime(plot_df["date"])
plot_df.set_index("date", inplace=True)
mpf.plot(
plot_df,
type='candle',
volume=True,
title='DANGCEM (NG) Daily',
ylabel='Price (NGN)',
figratio=(16,9),
style='yahoo'
)
4. Important Notes (2026 Edition)
- Market code is
NG— not NSENG anymore - Authentication now uses plain
tokenheader (no moreBearer api_key:secret) - All timestamps are millisecond Unix timestamps in UTC
- Free tier has rate limits — add sleep or upgrade plan for production use
- Prices are in Nigerian Naira (NGN)
5. Summary & Recommendations
Integrating Nigerian stock data is definitely less plug-and-play than U.S. or Chinese markets, but once you understand the quirks (market code change, timestamp handling, rate limits), it becomes manageable.
Key takeaways:
- Always implement timeout + retry logic
- Convert timestamps properly (UTC → your target timezone)
- Use pandas early — it makes data cleaning and visualization much easier
Disclaimer: This article is for technical reference only. It does not constitute investment advice. Investing involves risks.
Official Documentation
https://docs.itick.org/rest-api/stocks/stock-kline
GitHub Organization
https://github.com/itick-org/
Hope this helps someone trying to access NGX data in 2026!
Feel free to leave questions or share your own experience in the comments.
Good luck with your project!
Top comments (0)