Python SDK for London Strategic Edge real-time market data
Project description
lse-data
Python SDK for London Strategic Edge real-time market data.
Stream live prices for 4,000+ instruments including stocks, crypto, forex, indices, commodities, ETFs, and 81,000+ options contracts.
Install
pip install lse-data
Quick start
from lse import LSE
client = LSE(api_key="your_api_key")
for tick in client.stream(["BTC/USD", "AAPL", "EUR/USD"]):
print(f"{tick.symbol}: ${tick.price}")
Get your API key at londonstrategicedge.com/data.
Features
- Historical OHLCV candles for 4,000+ instruments (REST, no WebSocket needed)
- Real-time WebSocket streaming with auto-reconnect
- 4,000+ symbols: US/UK/EU/Asia stocks, crypto, forex, indices, commodities, ETFs
- 81,000+ option contracts via
subscribe_options() - Symbol catalog API for discovery before subscribing
- Server-side symbol validation (invalid symbols rejected immediately)
- Dynamic subscribe/unsubscribe at runtime
- Graceful disconnect (from callbacks or other threads)
- Sync and async interfaces
- Callback and iterator patterns
- Zero config, just an API key
Usage
Historical candles
Fetch OHLCV candles for any instrument. No WebSocket connection needed.
from lse import LSE
client = LSE(api_key="your_key")
# As a list of dicts
result = client.candles("XAU/USD", start="2021-01-01", end="2026-01-01", timeframe="1d")
print(f"{result['rows']} candles, plan: {result['plan']}")
for c in result["data"][-3:]:
print(f"{c['timestamp']} close={c['close']}")
# As a pandas DataFrame (pip install lse-data[pandas])
df = client.candles("AAPL", "2025-01-01", "2026-01-01", timeframe="1h", as_dataframe=True)
print(df.tail())
Supported timeframes: 1m, 5m, 15m, 30m, 1h, 2h, 4h, 1d
Works for all 4,000+ instruments: stocks, crypto, forex, ETFs, commodities, indices.
Stream ticks (simplest)
from lse import LSE
client = LSE(api_key="your_key")
for tick in client.stream(["BTC/USD", "ETH/USD", "AAPL"]):
print(f"{tick.symbol:12s} ${tick.price:>12,.2f}")
Callback style
from lse import LSE
def on_tick(tick):
print(f"{tick.symbol}: {tick.price}")
client = LSE(api_key="your_key")
client.on("tick", on_tick)
client.connect(symbols=["BTC/USD", "ETH/USD"])
Async streaming
import asyncio
from lse import LSE
async def main():
client = LSE(api_key="your_key")
async for tick in client.stream_async(["BTC/USD"]):
print(tick)
asyncio.run(main())
Save to CSV
import csv, datetime
from lse import LSE
client = LSE(api_key="your_key")
with open("ticks.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["time", "symbol", "price", "bid", "ask"])
for tick in client.stream(["BTC/USD", "ETH/USD"]):
writer.writerow([
datetime.datetime.now().isoformat(),
tick.symbol, tick.price, tick.bid, tick.ask,
])
Tick object
Each tick has these fields:
| Field | Type | Description |
|---|---|---|
symbol |
str |
Instrument symbol (e.g. BTC/USD, AAPL) |
price |
float |
Latest price |
bid |
float |
Bid price (if available) |
ask |
float |
Ask price (if available) |
volume |
float |
Volume (if available) |
timestamp |
float |
Unix timestamp |
name |
str |
Human-readable name (e.g. Apple Inc.) |
Events
When using the callback style with .on():
| Event | Callback args | Description |
|---|---|---|
tick |
Tick |
New price tick |
connected |
(none) | WebSocket connected |
authenticated |
(none) | API key accepted |
disconnected |
(none) | Connection lost (will auto-reconnect) |
error |
str |
Error message |
Symbol catalog
Query available instruments before subscribing. No WebSocket connection needed.
from lse import LSE
client = LSE(api_key="your_key")
# Get all available symbols
all_symbols = client.catalog()
print(f"{len(all_symbols)} instruments available")
# Filter by category: stock, crypto, forex, etf, commodity, index
stocks = client.catalog(category="stock")
crypto = client.catalog(category="crypto")
# Each entry has symbol, display_name, and category
for s in crypto[:5]:
print(f"{s['symbol']:12s} {s['display_name']:20s} {s['category']}")
The catalog returns every subscribable instrument. Use it to build symbol pickers, validate user input, or discover what is available.
Available categories
| Category | Count | Examples |
|---|---|---|
| stock | ~3,987 | AAPL, NVDA, TSLA, 0005.HK, 7203.T |
| forex | ~62 | EUR/USD, GBP/JPY, USD/CHF |
| crypto | ~58 | BTC/USD, ETH/USD, SOL/USD |
| etf | ~25 | SPY, QQQ, IWM, GLD |
| commodity | ~23 | XAU/USD, WTICO/USD, NATGAS/USD |
| index | ~13 | US30, NAS100, UK100 |
Options streaming
Subscribe to entire options chains by underlying. One call gives you every contract (calls + puts, all strikes, all expiries).
from lse import LSE
client = LSE(api_key="your_key")
def on_tick(tick):
print(f"{tick.symbol}: ${tick.price:.2f}")
client.on("tick", on_tick)
client.subscribe_options(["AAPL", "TSLA"])
client.connect()
To stop receiving a chain:
client.unsubscribe_options(["TSLA"])
Unsubscribe
Remove symbols at runtime without disconnecting:
client.unsubscribe(["BTC/USD"]) # stop one symbol
client.subscribe(["SOL/USD"]) # add another
Disconnect
Stop the stream and exit cleanly. Works from callbacks or another thread:
tick_count = 0
def on_tick(tick):
global tick_count
tick_count += 1
if tick_count >= 100:
client.disconnect() # connect()/stream() returns
client.on("tick", on_tick)
client.connect(symbols=["BTC/USD"])
print("Done, collected 100 ticks")
Async version:
await client.disconnect_async()
Requirements
- Python 3.8+
websockets(installed automatically)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lse_data-0.5.1.tar.gz.
File metadata
- Download URL: lse_data-0.5.1.tar.gz
- Upload date:
- Size: 12.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7de80e6823c64b19523222fa57acba6c46c226f14d0256623019efc48c935ec4
|
|
| MD5 |
df0337195203a8794b2e5c9918e5749d
|
|
| BLAKE2b-256 |
7c7a5e6286839434d1783f58c1fc9e88fb3195ede7e67539c1a12c714ccf1db8
|
File details
Details for the file lse_data-0.5.1-py3-none-any.whl.
File metadata
- Download URL: lse_data-0.5.1-py3-none-any.whl
- Upload date:
- Size: 11.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
57fc1457861b838960600a4d3bf17936bdebaf4c253749dcfb582154627b98f1
|
|
| MD5 |
c35c9ab6f37f630b5276d67992dab1f7
|
|
| BLAKE2b-256 |
b57e728e473772c4ef0233544e83a214fcb956f3114f749d8b9e8be50725ff9e
|