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!