Content
# Tool List
[](https://pypi.org/project/easyquotes/)
[](https://pypi.org/project/easyquotes/)
[](LICENSE)
[](https://github.com/easyquotes/easyquotes/actions/workflows/publish.yml)
[](https://122.51.7.196/api-reference)
📚 **[Explore the API Documentation](https://122.51.7.196/api-reference)** — Browse all REST APIs, request parameters, response structures, and available capabilities.
**Stock market data API, Python SDK and MCP server for A-shares, Hong Kong stocks, US stocks, ETF holdings intelligence and institutional fund portfolios.**
EasyQuotes is more than just a stock market data SDK: In addition to real-time quotes, intraday and historical K-lines for A-shares, Hong Kong stocks, and US stocks, it also provides ETF holdings transparency, fund and institutional holdings analysis, ETF incremental tracking, and potential leader discovery capabilities that integrate ETF consensus, theme intensity, price trends, capital flows, and potential leader lists. All features can be accessed directly through REST APIs or MCP. Suitable for quantitative research, investment research tools, and AI agents.
<p align="center">
<a href="https://122.51.7.196">
<img src="docs/images/homepage.webp" alt="EasyQuotes Financial Data API Homepage: Global Market Quotes, Real-time Financial News, and Multi-Market Data Services" width="1200">
</a>
</p>
<p align="center"><a href="https://122.51.7.196">Visit EasyQuotes Official Website</a></p>
## Core Features
| Capability | What can you do |
|------|------------|
| Unified Multi-Market Quotes | Use a unified symbol format to query quotes, intraday data, K-lines, transactions, and order books for A-shares, Hong Kong stocks, and US stocks |
| ETF Real-time and Holdings Transparency | ETF/T+0 ETF rankings, ETF constituent stocks, stocks held by ETFs, and interval-added ETF holdings |
| Fund and Institutional Holdings Analysis | Fund new entry/exit/increment/decrement rankings, stock holdings institutions, and querying a single fund's stock portfolio |
| ETF-Driven Potential Leader Discovery | Integrate ETF increments, consensus, theme heat, trends, capital flows, and potential leader lists to generate explanations, snapshots, and backtests |
| AI Agent Native Access | Clients like Cursor and Claude Desktop can directly access all tools without installing SDKs, using remote MCP calls |
| Multiple Integration Methods | Python SDK, REST API, Streamable HTTP MCP, SSE MCP, and WebSocket |
## Installation
```bash
pip install easyquotes
```
Optional extensions:
```bash
pip install "easyquotes[stream]" # WebSocket synchronous push
pip install "easyquotes[stream-async]" # WebSocket asynchronous push
```
Python version requirements: >= 3.10
## Quick Start
Configure API Key via environment variables:
```bash
export EASYQUOTE_API_KEY="eq_your_key_here"
```
SDK defaults to connecting to `https://122.51.7.196`. If you need to override the server endpoint, set:
```bash
export EASYQUOTE_BASE_URL="https://quotes.example.com"
```
```python
from easyquote import EasyQuoteClient
client = EasyQuoteClient() # Automatically reads EASYQUOTE_API_KEY
quote = client.get_quote("600519.SH")
print(f"{quote.name}: {quote.price} ({quote.change_pct:+.2f}%)")
```
You can also pass the `api_key` directly:
```python
client = EasyQuoteClient(api_key="eq_your_key_here")
```
## Direct MCP Access
No need to install the Python SDK; clients that support MCP can directly connect to the EasyQuote service:
| Protocol | Endpoint | Applicable Clients |
|------|------|------------|
| Streamable HTTP | `https://122.51.7.196/mcp` | Cursor, modern MCP clients |
| SSE | `https://122.51.7.196/sse` | Claude Desktop, older MCP clients |
Authentication uses the HTTP Header: `x-api-key: <your-api-key>`.
### Cursor / Streamable HTTP
```json
{
"mcpServers": {
"easyquote": {
"url": "https://122.51.7.196/mcp",
"headers": {
"x-api-key": "eq_your_key_here"
}
}
}
}
```
### Claude Desktop / SSE
```json
{
"mcpServers": {
"easyquote": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://122.51.7.196/sse",
"--header",
"x-api-key: eq_your_key_here"
]
}
}
}
```
MCP exposes capabilities like quotes, K-lines, ETF holdings, fund and institutional holdings, potential leader discovery, capital flows, financial data, technical analysis, and natural language stock selection as directly callable tools. For detailed configurations, visit the [MCP Integration Page](https://122.51.7.196/dashboard/mcp).
After accessing, you can directly ask AI agents:
- “Query which ETFs hold Guizhou Maotai and sort by weight.”
- “Which stocks did funds newly enter in the last quarter?”
- “Query the main holdings of 510300.”
- “Find potential leaders using ETF increments and theme intensity, and explain the risks.”
## ETF and Fund Featured APIs
These capabilities are already included in REST APIs and remote MCP:
| Endpoint | Capability |
|------|------|
| `GET /api/v1/etf/ranking` | ETF real-time rankings, supports T+0 ETF |
| `GET /api/v1/etf/list` | Full market ETF and T+0 ETF lists |
| `GET /api/v1/etf/holdings` | Query ETF real-time subscription or quarterly report holdings |
| `GET /api/v1/etf/stock-holders-db` | Query which ETFs hold a stock |
| `GET /api/v1/etf/stock-holders-new` | Query ETFs that newly hold a stock within an interval |
| `GET /api/v1/fund/new-positions` | Fund/QFII/social security institution new entry, exit, increment, and decrement rankings |
| `GET /api/v1/fund/holders` | Query funds and institutions holding a stock |
| `GET /api/v1/fund/portfolio` | Query a single fund's stock portfolio |
| `GET /api/v1/dragon/market-map` | ETF, industry, concept, and hotspot market direction map |
| `GET /api/v1/dragon/hunt` | ETF-driven potential leader hunter |
| `GET /api/v1/dragon/explain` | Explain a stock's potential leader status and risks |
REST Example:
```bash
curl -H "x-api-key: eq_your_key_here" \
"https://122.51.7.196/api/v1/etf/stock-holders-db?code=600519"
curl -G -H "x-api-key: eq_your_key_here" \
--data-urlencode "change=new" \
--data-urlencode "hold_type=fund" \
"https://122.51.7.196/api/v1/fund/new-positions"
```
## Symbol Code Format
| Market | Format Example | Description |
|----------|------------------|--------------------------|
| A-share Shanghai | `600519.SH` | Shanghai Stock Exchange, suffix `.SH` |
| A-share Shenzhen | `000001.SZ` | Shenzhen Stock Exchange, suffix `.SZ` |
| A-share BJI | `836239.BJ` | Beijing Stock Exchange, suffix `.BJ` |
| Hong Kong Stock | `00700.HK` | Five-digit code, suffix `.HK` |
| US Stock | `TSLA.US` | Stock code, suffix `.US` |
| Index | `000001.SH` | SSE index, etc. |
## API Reference
### Quotes
| Method | Description |
|------|------|
| `get_quote(symbol)` | Single symbol real-time quote, returns `Quote` |
| `get_quotes(symbols)` | Batch real-time quotes, returns `list[Quote]` |
| `get_snapshots(symbols)` | Batch quote snapshots (mac protocol), `symbols` is `[{'market':'SH','code':'600519'}]` |
| `get_depths(symbols)` | Batch five-level order books (mac protocol) |
### K-Lines
| Method | Description |
|------|------|
| `get_klines(symbol, period, count, start)` | A-share/Hong Kong/US stock historical K-lines, returns `list[KLine]` |
| `get_index_klines(symbol, period, count, start)` | Index K-lines |
| `get_global_klines(market, code, period, count, adjust)` | Overseas market K-lines, `adjust='qfq'` (forward adjusted) / `'hfq'` (backward adjusted) |
`period` optional values: `"1m"` / `"5m"` / `"15m"` / `"30m"` / `"60m"` / `"daily"` / `"weekly"` / `"monthly"`
### Intraday
| Method | Description |
|------|------|
| `get_minute(symbol)` | A-share/Hong Kong/US stock intraday data, returns `list[MinuteBar]` |
| `get_minute_history(symbol, date)` | Historical intraday data for a specific date, `date='20260617'` |
### Transactions
| Method | Description |
|------|------|
| `get_transactions(symbol, start, count)` | Today's transaction details |
| `get_transaction_history(symbol, date, start, count)` | Historical transaction data, `date='20260617'` |
### Fund Flow
| Method | Description |
|------|------|
| `get_fund_flow(symbol)` | Today's main capital flow, returns `FundFlow` |
| `get_fund_flow_history(symbol, start, count)` | Historical fund flow list |
### A-share Fundamentals
| Method | Description |
|------|------|
| `get_finance(symbol)` | A-share financial indicators (PE/PB/EPS, etc.) |
| `get_xdxr(symbol)` | Ex-rights and ex-dividend records |
| `get_announcements(code, count, page)` | Company announcement list, `code='600519'` (without market suffix) |
### Global Fundamentals
| Method | Description |
|------|------|
| `get_company(symbol)` | Company overview, returns `Company`, supports A-share/Hong Kong/US stock |
| `get_executives(symbol)` | Executive information, returns `list[Executive]` |
| `get_financial_reports(symbol, kind)` | Financial reports, `kind='ALL'/'ANNUAL'/'QUARTERLY'` |
### Sectors
| Method | Description |
|------|------|
| `get_sectors(block_file)` | Sector data, `block_file` optional `'block_zs.dat'` (industry index) / `'block_gn.dat'` (concept) / `'block_fg.dat'` (style) |
| `get_board_ranking(board_type, top_n, sort_by, ascending)` | Sector rise and fall rankings, `board_type='industry'/'concept'/'style'` |
| `get_board_members(board_symbol, count)` | Sector member list |
### Market
| Method | Description |
|------|------|
| `get_market_stat()` | Market statistics (number of rising and falling stocks, trading volume, etc.) |
| `get_security_list(market, start)` | Security list, `market='SH'/'SZ'/'BJ'` |
| `get_security_count(market)` | Security count, returns `int` |
### Global Quotes
| Method | Description |
|------|------|
| `get_global_quote(market, code)` | Overseas single quote, `market='US'/'HK'/'HK_GEM'` etc. |
| `get_global_klines(market, code, period, count, adjust)` | Overseas K-lines |
### Streaming
| Method | Description |
|------|------|
| `stream()` | Synchronous WebSocket push, requires installing `easyquotes[stream]` |
| `stream_async()` | Asynchronous WebSocket push, requires installing `easyquotes[stream-async]` |
## Usage Examples
### Batch Get Quotes
```python
quotes = client.get_quotes(["600519.SH", "000001.SZ", "TSLA.US", "00700.HK"])
for q in quotes:
print(f"{q.symbol} {q.price:>10.2f} {q.change_pct:+.2f}%")
```
### K-Line Data
```python
klines = client.get_klines("600519.SH", period="daily", count=120)
for k in klines[-5:]:
print(f"{k.datetime} O:{k.open} H:{k.high} L:{k.low} C:{k.close} V:{k.volume}")
```
### Historical Intraday
```python
bars = client.get_minute_history("600519.SH", date="20260617")
for b in bars[:10]:
print(b.time, b.price, b.volume)
```
### Fund Flow
```python
ff = client.get_fund_flow("600519.SH")
print(f"Main net inflow: {ff.net_main / 1e8:.2f} billion")
```
### Sector Rankings
```python
ranking = client.get_board_ranking(board_type="industry", top_n=10, sort_by="change_pct")
for b in ranking:
print(b["name"], b["change_pct"])
```
### Synchronous WebSocket Push
```python
with client.stream() as ws:
ws.subscribe(["600519.SH", "000001.SZ", "TSLA.US"])
for event in ws:
if event["op"] == "quotes":
for q in event["data"]:
print(q["symbol"], q["last_price"])
```
### Asynchronous WebSocket Push
```python
import asyncio
async def main():
async with client.stream_async() as ws:
await ws.subscribe(["600519.SH", "TSLA.US"])
async for event in ws:
print(event)
asyncio.run(main())
```
### Transaction by Transaction
```python
ticks = client.get_transactions("600519.SH", start=0, count=50)
for t in ticks:
print(t["time"], t["price"], t["volume"], t["direction"])
```
### Overseas Market Data
```python
# Get NASDAQ stock K-line
klines = client.get_global_klines("US", "TSLA", period="daily", count=60)
# Get Hong Kong stock quote
quote = client.get_global_quote("HK", "00700")
```
## Error Handling
```python
from easyquote import EasyQuoteClient
from easyquote import AuthError, RateLimitError, APIError, NotFoundError
client = EasyQuoteClient(api_key="eq_your_key")
try:
quote = client.get_quote("600519.SH")
except AuthError:
print("Invalid API Key or not set")
except RateLimitError:
print("Request frequency exceeds the limit, please try again later")
except NotFoundError:
print("Instrument does not exist")
except APIError as e:
print(f"API Error {e.code}: {e.message}")
```
## Self-Hosted Deployment
If using a self-hosted EasyQuote backend (based on easy-tdx FastAPI service), it is recommended to specify the service address via an environment variable:
```bash
export EASYQUOTE_BASE_URL="https://quotes.example.com"
```
The client will automatically read this configuration:
```python
client = EasyQuoteClient(api_key="eq_your_key")
```
You can also explicitly specify it for a single client using the `base_url` parameter, which takes priority over environment variables:
```python
client = EasyQuoteClient(
api_key="eq_your_key",
base_url="https://quotes.example.com",
)
```
Both HTTP and WebSocket will automatically switch to the specified address (`wss://` corresponds to HTTPS, `ws://` corresponds to HTTP).
> In a production environment, HTTPS should be used. When accessing via HTTP, the API Key will be transmitted in plain text over the network.
## License
MIT
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available