Contents
LSEG Data Library
Access financial data from LSEG (London Stock Exchange Group), formerly Refinitiv, via the lseg.data Python library.
Query Enforcement
IRON LAW: NO DATA CLAIM WITHOUT SAMPLE INSPECTION
Before claiming ANY LSEG query succeeded, follow these steps:
- VALIDATE field names exist (check prefixes: TR., CF_)
- VALIDATE RIC symbology is correct (.O, .N, .L, .T)
- EXECUTE the query
- INSPECT sample rows with
.head() or .sample()
- VERIFY critical columns are not NULL
- VERIFY date range matches expectations
- CLAIM success only after all checks pass
This is not negotiable. Claiming data retrieval without inspecting results is LYING to the user about data quality.
Rationalization Table - STOP If You Think:
| Excuse |
Reality |
Do Instead |
| “The query returned data, so it worked” |
Returned data ≠ correct data |
INSPECT for NULLs, wrong dates, invalid values |
| “User gave me the RIC” |
Users often use wrong suffixes |
VERIFY symbology against RIC Symbology section |
| “I’ll let pandas handle missing data” |
You’ll propagate bad data downstream |
CHECK for NULLs BEFORE returning |
| “Field names look right” |
Typos are common (TR.EPS vs TR.Eps) |
VALIDATE field names in documentation first |
| “Just a quick test” |
Test queries teach bad habits |
Full validation even for tests |
| “I can check the data later” |
You won’t |
Inspection is MANDATORY before claiming success |
| “Rate limits don’t matter for small queries” |
Small queries add up |
CHECK rate limits section, use batching |
Red Flags - STOP Immediately If You Think:
- “Let me run this and see what happens” → NO. Validate field names and RICs FIRST.
- “The API will error if something is wrong” → NO. API returns empty results, not errors.
- “I’ll just return the dataframe to the user” → NO. Inspect sample BEFORE returning.
- “Market data is always up-to-date” → NO. Check Date Awareness section (T-1 lag).
Data Validation Checklist
Before EVERY data retrieval claim, verify the following:
For ld.get_data() (fundamentals/ESG):
For ld.get_history() (time series):
For symbol_conversion.Definition() (mapping):
For ALL queries:
Quick Start
To get started with LSEG Data Library, initialize a session and execute queries:
import lseg.data as ld
# Initialize session
ld.open_session()
# Get fundamentals
df = ld.get_data(
universe=[‘AAPL.O’, ‘MSFT.O’],
fields=[‘TR.CompanyName’, ‘TR.Revenue’, ‘TR.EPS’]
)
print(df.head()) # Inspect sample data
# Get historical prices
prices = ld.get_history(
universe=’AAPL.O’,
fields=[‘OPEN’, ‘HIGH’, ‘LOW’, ‘CLOSE’, ‘VOLUME’],
start=‘2023-01-01’,
end=‘2023-12-31’
)
print(prices.head()) # Inspect sample data
# Close session
ld.close_session()
Authentication
Configure LSEG authentication using either a config file or environment variables.
Config File Method
Create lseg-data.config.json:
{
“sessions”: {
“default”: “platform.ldp”,
“platform”: {
“ldp”: {
“app-key”: “YOUR_APP_KEY”,
“username”: “YOUR_MACHINE_ID”,
“password”: “YOUR_PASSWORD”
}
}
}
}
Environment Variables Method
Set the following environment variables for LSEG authentication:
# Configure LSEG credentials via environment variables
export RDP_USERNAME=”YOUR_MACHINE_ID”
export RDP_PASSWORD=”YOUR_PASSWORD”
export RDP_APP_KEY=”YOUR_APP_KEY”
Core APIs
| API |
Use Case |
Example |
ld.get_data() |
Point-in-time data |
Fundamentals, ESG scores |
ld.get_history() |
Time series |
Historical prices, OHLCV |
ld.news.get_headlines() |
News headlines |
Company news, topic filtering |
symbol_conversion.Definition() |
ID mapping |
RIC ↔ ISIN ↔ CUSIP |
Key Field Prefixes
| Prefix |
Type |
Example |
TR. |
Refinitiv fields |
TR.Revenue, TR.EPS |
TR.MnA |
Mergers & Acquisitions |
TR.MnAAcquirorName, TR.MnADealValue |
TR.NI |
Equity/New Issues (IPOs) |
TR.NIIssuer, TR.NIOfferPrice |
TR.JV |
Joint Ventures/Alliances |
TR.JVDealName, TR.JVStatus |
TR.SACT |
Shareholder Activism |
TR.SACTLeadDissident |
TR.PP |
Poison Pills |
TR.PPPillAdoptionDate |
TR.LN |
Syndicated Loans |
TR.LNTotalFacilityAmount |
TR.PJF |
Infrastructure/Project Finance |
TR.PJFProjectName |
TR.PEInvest |
Private Equity/Venture Capital |
TR.PEInvestRoundDate |
TR.Muni |
Municipal Bonds |
TR.MuniIssuerName |
CF_ |
Composite (real-time) |
CF_LAST, CF_BID |
RIC Symbology
| Suffix |
Exchange |
Example |
.O |
NASDAQ |
AAPL.O |
.N |
NYSE |
IBM.N |
.L |
London |
VOD.L |
.T |
Tokyo |
7203.T |
Rate Limits
| Endpoint |
Limit |
get_data() |
10,000 data points/request |
get_history() |
3,000 rows/request |
| Session |
500 requests/minute |
Additional Resources
Reference Files
references/fundamentals.md - Financial statement fields, ratios, estimates
references/esg.md - ESG scores, pillars, controversies
references/symbology.md - RIC/ISIN/CUSIP conversion
references/pricing.md - Historical prices, real-time data
references/screening.md - Stock screening with Screener object
references/news.md - News headlines, pagination, query syntax
references/mna.md - Mergers & acquisitions deals (SDC Platinum, 2,683 fields)
references/equity-new-issues.md - IPOs, follow-ons, equity offerings (SDC Platinum, 1,708 fields)
references/joint-ventures.md - Joint ventures, strategic alliances (SDC Platinum, 301 fields)
references/corporate-governance.md - Shareholder activism, poison pills (SDC Platinum)
references/syndicated-loans.md - Syndicated loan deals (SDC Platinum)
references/infrastructure.md - Infrastructure/project finance deals (SDC Platinum)
references/private-equity.md - Private equity/venture capital investments (SDC Platinum)
references/municipal-bonds.md - Municipal bond issuances (SDC Platinum)
references/api-discovery.md - Reverse-engineering APIs via CDP network monitoring
references/troubleshooting.md - Common issues and solutions
references/wrds-comparison.md - LSEG vs WRDS data mapping
Example Files
examples/historical_pricing.ipynb - Historical price retrieval
examples/fundamentals_query.py - Fundamental data patterns
examples/stock_screener.ipynb - Dynamic stock screening
Scripts
scripts/test_connection.py - Validate LSEG connectivity
Local Sample Repositories
LSEG API samples at ~/resources/lseg-samples/:
Example.RDPLibrary.Python/ - Core API examples
Examples.DataLibrary.Python.AdvancedUsecases/ - Advanced patterns
Article.DataLibrary.Python.Screener/ - Stock screening
Refinitiv Codebook
Interactive JupyterLab environment with pre-configured LSEG access:
- URL:
https://workspace.refinitiv.com/codebook/
- Environment: JupyterHub with Python 3.8, pre-installed
refinitiv.data library
- Session: Auto-authenticated via Workspace credentials (
{name=’codebook’})
# In Codebook, session opens automatically with Workspace auth
import refinitiv.data as rd
rd.open_session() # Returns session with name=’codebook’
# Query data immediately
df = rd.news.get_headlines(‘R:AAPL.O AND SUGGAC’, count=10)
Note: Codebook uses refinitiv.data (older name) rather than lseg.data. Both APIs are equivalent.
Date Awareness
When querying market data, account for current date context and market data lag.
Market Data Lag
Market data typically has T-1 availability, meaning today’s data becomes available tomorrow. Adjust date ranges accordingly.
Date Range Example
Use current date context when querying historical prices:
from datetime import datetime, timedelta
# Get recent market data
end_date = datetime.now()
start_date = end_date - timedelta(days=365)
# Adjust to exclude recent data (T-1 for market data availability)
end_date = end_date - timedelta(days=1)
df = ld.get_history(
universe=”AAPL.O”,
fields=[‘CLOSE’],
start=start_date.strftime(‘%Y-%m-%d’),
end=end_date.strftime(‘%Y-%m-%d’)
)
Remember: Always account for the T-1 lag in market data availability.
1---2name: lseg-data3description: This skill should be used when the user asks to “access LSEG data”, “query Refinitiv”, “get market data from Refinitiv”, “download fundamentals from LSEG”, “access ESG scores”, “convert RIC to ISIN”, “get shareholder activism data”, “query poison pills”, “access corporate governance data”, “find activist campaigns”, “get syndicated loans data”, “query loan deals”, “get infrastructure projects”, “query project finance data”, “get private equity data”, “query VC investments”, “find PE-backed companies”, “get M&A data”, “query mergers and acquisitions”, “find acquisition deals”, “get IPO data”, “query equity offerings”, “find new issues”, “get joint venture data”, “query strategic alliances”, “get news headlines”, “query news data”, “fetch news articles”, or needs the LSEG Data Library Python API.4---5
6## Contents
7
8- [Query Enforcement](#query-enforcement)
9- [Quick Start](#quick-start)
10- [Authentication](#authentication)
11- [Core APIs](#core-apis)
12- [Key Field Prefixes](#key-field-prefixes)
13- [RIC Symbology](#ric-symbology)
14- [Rate Limits](#rate-limits)
15- [Additional Resources](#additional-resources)
16
17# LSEG Data Library
18
19Access financial data from LSEG (London Stock Exchange Group), formerly Refinitiv, via the `lseg.data` Python library.
20
21## Query Enforcement
22
23### IRON LAW: NO DATA CLAIM WITHOUT SAMPLE INSPECTION
24
25Before claiming ANY LSEG query succeeded, follow these steps:
261. **VALIDATE** field names exist (check prefixes: TR., CF_)
272. **VALIDATE** RIC symbology is correct (.O, .N, .L, .T)
283. **EXECUTE** the query
294. **INSPECT** sample rows with `.head()` or `.sample()`
305. **VERIFY** critical columns are not NULL
316. **VERIFY** date range matches expectations
327. **CLAIM** success only after all checks pass
33
34This is not negotiable. Claiming data retrieval without inspecting results is LYING to the user about data quality.
35
36### Rationalization Table - STOP If You Think:
37
38| Excuse | Reality | Do Instead |
39|--------|---------|------------|
40| “The query returned data, so it worked” | Returned data ≠ correct data | INSPECT for NULLs, wrong dates, invalid values |
41| “User gave me the RIC” | Users often use wrong suffixes | VERIFY symbology against RIC Symbology section |
42| “I’ll let pandas handle missing data” | You’ll propagate bad data downstream | CHECK for NULLs BEFORE returning |
43| “Field names look right” | Typos are common (TR.EPS vs TR.Eps) | VALIDATE field names in documentation first |
44| “Just a quick test” | Test queries teach bad habits | Full validation even for tests |
45| “I can check the data later” | You won’t | Inspection is MANDATORY before claiming success |
46| “Rate limits don’t matter for small queries” | Small queries add up | CHECK rate limits section, use batching |
47
48### Red Flags - STOP Immediately If You Think:
49
50- “Let me run this and see what happens” → NO. Validate field names and RICs FIRST.
51- “The API will error if something is wrong” → NO. API returns empty results, not errors.
52- “I’ll just return the dataframe to the user” → NO. Inspect sample BEFORE returning.
53- “Market data is always up-to-date” → NO. Check Date Awareness section (T-1 lag).
54
55### Data Validation Checklist
56
57Before EVERY data retrieval claim, verify the following:
58
59**For `ld.get_data()` (fundamentals/ESG):**
60- [ ] Field names use correct prefix (TR. for Refinitiv)
61- [ ] RIC symbology verified (correct exchange suffix)
62- [ ] Result inspection: `.head()` or `.sample()` executed
63- [ ] NULL check on critical fields (e.g., revenue, EPS)
64- [ ] Row count verification (is result size reasonable?)
65- [ ] Date context verified (fiscal periods, as-of dates)
66
67**For `ld.get_history()` (time series):**
68- [ ] Field names are valid (OPEN, HIGH, LOW, CLOSE, VOLUME, or CF_ prefixes)
69- [ ] Start/end dates specified explicitly
70- [ ] Date range adjusted for T-1 availability (market data lag)
71- [ ] Result inspection: check first and last rows
72- [ ] NULL check on OHLCV fields
73- [ ] Date continuity check (gaps in trading days expected, but not in date sequence)
74
75**For `symbol_conversion.Definition()` (mapping):**
76- [ ] Input identifier type specified correctly
77- [ ] Result inspection: verify mapped values exist
78- [ ] NULL check (some securities may not have all identifiers)
79
80**For ALL queries:**
81- [ ] Rate limits considered (batch if >10k data points)
82- [ ] Session management: `open_session()` at start, `close_session()` at end
83- [ ] Error handling: try/except for network failures
84- [ ] Sample inspection BEFORE claiming data is ready
85
86## Quick Start
87
88To get started with LSEG Data Library, initialize a session and execute queries:
89
90```python
91import lseg.data as ld
92
93# Initialize session
94ld.open_session()
95
96# Get fundamentals
97df = ld.get_data(
98 universe=[‘AAPL.O’, ‘MSFT.O’],
99 fields=[‘TR.CompanyName’, ‘TR.Revenue’, ‘TR.EPS’]
100)
101print(df.head()) # Inspect sample data
102
103# Get historical prices
104prices = ld.get_history(
105 universe=’AAPL.O’,
106 fields=[‘OPEN’, ‘HIGH’, ‘LOW’, ‘CLOSE’, ‘VOLUME’],
107 start=‘2023-01-01’,
108 end=‘2023-12-31’
109)
110print(prices.head()) # Inspect sample data
111
112# Close session
113ld.close_session()
114```
115
116## Authentication
117
118Configure LSEG authentication using either a config file or environment variables.
119
120### Config File Method
121
122Create `lseg-data.config.json`:
123```json
124{
125 “sessions”: {
126 “default”: “platform.ldp”,
127 “platform”: {
128 “ldp”: {
129 “app-key”: “YOUR_APP_KEY”,
130 “username”: “YOUR_MACHINE_ID”,
131 “password”: “YOUR_PASSWORD”
132 }
133 }
134 }
135}
136```
137
138### Environment Variables Method
139
140Set the following environment variables for LSEG authentication:
141
142```bash
143# Configure LSEG credentials via environment variables
144export RDP_USERNAME=”YOUR_MACHINE_ID”
145export RDP_PASSWORD=”YOUR_PASSWORD”
146export RDP_APP_KEY=”YOUR_APP_KEY”
147```
148
149## Core APIs
150
151| API | Use Case | Example |
152|-----|----------|---------|
153| `ld.get_data()` | Point-in-time data | Fundamentals, ESG scores |
154| `ld.get_history()` | Time series | Historical prices, OHLCV |
155| `ld.news.get_headlines()` | News headlines | Company news, topic filtering |
156| `symbol_conversion.Definition()` | ID mapping | RIC ↔ ISIN ↔ CUSIP |
157
158## Key Field Prefixes
159
160| Prefix | Type | Example |
161|--------|------|---------|
162| `TR.` | Refinitiv fields | `TR.Revenue`, `TR.EPS` |
163| `TR.MnA` | Mergers & Acquisitions | `TR.MnAAcquirorName`, `TR.MnADealValue` |
164| `TR.NI` | Equity/New Issues (IPOs) | `TR.NIIssuer`, `TR.NIOfferPrice` |
165| `TR.JV` | Joint Ventures/Alliances | `TR.JVDealName`, `TR.JVStatus` |
166| `TR.SACT` | Shareholder Activism | `TR.SACTLeadDissident` |
167| `TR.PP` | Poison Pills | `TR.PPPillAdoptionDate` |
168| `TR.LN` | Syndicated Loans | `TR.LNTotalFacilityAmount` |
169| `TR.PJF` | Infrastructure/Project Finance | `TR.PJFProjectName` |
170| `TR.PEInvest` | Private Equity/Venture Capital | `TR.PEInvestRoundDate` |
171| `TR.Muni` | Municipal Bonds | `TR.MuniIssuerName` |
172| `CF_` | Composite (real-time) | `CF_LAST`, `CF_BID` |
173
174## RIC Symbology
175
176| Suffix | Exchange | Example |
177|--------|----------|---------|
178| `.O` | NASDAQ | `AAPL.O` |
179| `.N` | NYSE | `IBM.N` |
180| `.L` | London | `VOD.L` |
181| `.T` | Tokyo | `7203.T` |
182
183## Rate Limits
184
185| Endpoint | Limit |
186|----------|-------|
187| `get_data()` | 10,000 data points/request |
188| `get_history()` | 3,000 rows/request |
189| Session | 500 requests/minute |
190
191## Additional Resources
192
193### Reference Files
194
195- **`references/fundamentals.md`** - Financial statement fields, ratios, estimates
196- **`references/esg.md`** - ESG scores, pillars, controversies
197- **`references/symbology.md`** - RIC/ISIN/CUSIP conversion
198- **`references/pricing.md`** - Historical prices, real-time data
199- **`references/screening.md`** - Stock screening with Screener object
200- **`references/news.md`** - News headlines, pagination, query syntax
201- **`references/mna.md`** - Mergers & acquisitions deals (SDC Platinum, 2,683 fields)
202- **`references/equity-new-issues.md`** - IPOs, follow-ons, equity offerings (SDC Platinum, 1,708 fields)
203- **`references/joint-ventures.md`** - Joint ventures, strategic alliances (SDC Platinum, 301 fields)
204- **`references/corporate-governance.md`** - Shareholder activism, poison pills (SDC Platinum)
205- **`references/syndicated-loans.md`** - Syndicated loan deals (SDC Platinum)
206- **`references/infrastructure.md`** - Infrastructure/project finance deals (SDC Platinum)
207- **`references/private-equity.md`** - Private equity/venture capital investments (SDC Platinum)
208- **`references/municipal-bonds.md`** - Municipal bond issuances (SDC Platinum)
209- **`references/api-discovery.md`** - Reverse-engineering APIs via CDP network monitoring
210- **`references/troubleshooting.md`** - Common issues and solutions
211- **`references/wrds-comparison.md`** - LSEG vs WRDS data mapping
212
213### Example Files
214
215- **`examples/historical_pricing.ipynb`** - Historical price retrieval
216- **`examples/fundamentals_query.py`** - Fundamental data patterns
217- **`examples/stock_screener.ipynb`** - Dynamic stock screening
218
219### Scripts
220
221- **`scripts/test_connection.py`** - Validate LSEG connectivity
222
223### Local Sample Repositories
224
225LSEG API samples at `~/resources/lseg-samples/`:
226- `Example.RDPLibrary.Python/` - Core API examples
227- `Examples.DataLibrary.Python.AdvancedUsecases/` - Advanced patterns
228- `Article.DataLibrary.Python.Screener/` - Stock screening
229
230### Refinitiv Codebook
231
232Interactive JupyterLab environment with pre-configured LSEG access:
233
234- **URL**: `https://workspace.refinitiv.com/codebook/`
235- **Environment**: JupyterHub with Python 3.8, pre-installed `refinitiv.data` library
236- **Session**: Auto-authenticated via Workspace credentials (`{name=’codebook’}`)
237
238```python
239# In Codebook, session opens automatically with Workspace auth
240import refinitiv.data as rd
241rd.open_session() # Returns session with name=’codebook’
242
243# Query data immediately
244df = rd.news.get_headlines(‘R:AAPL.O AND SUGGAC’, count=10)
245```
246
247**Note**: Codebook uses `refinitiv.data` (older name) rather than `lseg.data`. Both APIs are equivalent.
248
249## Date Awareness
250
251When querying market data, account for current date context and market data lag.
252
253### Market Data Lag
254
255Market data typically has T-1 availability, meaning today’s data becomes available tomorrow. Adjust date ranges accordingly.
256
257### Date Range Example
258
259Use current date context when querying historical prices:
260
261```python
262from datetime import datetime, timedelta
263
264# Get recent market data
265end_date = datetime.now()
266start_date = end_date - timedelta(days=365)
267
268# Adjust to exclude recent data (T-1 for market data availability)
269end_date = end_date - timedelta(days=1)
270
271df = ld.get_history(
272 universe=”AAPL.O”,
273 fields=[‘CLOSE’],
274 start=start_date.strftime(‘%Y-%m-%d’),
275 end=end_date.strftime(‘%Y-%m-%d’)
276)
277```
278
279Remember: Always account for the T-1 lag in market data availability.