Runtime and credentials
- Python 3.10+ and a virtual environment
-
A DeepSeek API key stored as
DEEPSEEK_API_KEY - An entitled, documented market-data source or a QVeris account
- A server-side secret manager for production
Finance & Market Data
Build reliable real-time stock data workflows for DeepSeek with verified timestamps, market coverage, freshness, and failure handling.
Published: April 18, 2026 · By the QVeris Team


Keep the model credential and market-data credential on the server. The browser or mobile client should call your backend, never either vendor directly with embedded secrets.
DEEPSEEK_API_KEY
python -m venv .venv
# activate .venv for your shell
python -m pip install openai httpx
The DeepSeek API is compatible with the OpenAI client pattern
used below. httpx is only for the example
provider adapter; use the official SDK if your chosen feed
requires one.
A request completed now can still return a delayed quote, a previous close, or an old cache entry. Before writing code, decide which instruments, sessions, feeds, delay classes, and maximum ages are acceptable for each user experience.
Compare the provider’s event timestamp with retrieval time. Do not infer freshness from request completion. A watchlist may tolerate a short cache; a user asking “now” may require a stricter rule.
A symbol may be ambiguous across venues. Resolve exchange, asset class, country, and share class. If confidence is insufficient, return candidates and let DeepSeek ask a focused clarification.
Provider plans and exchange rights determine what “live” means. Carry the provider, feed, session, and delay status through the tool result instead of letting the model invent a label.
DeepSeek detects a current-data request and proposes structured arguments.
Your backend validates symbols, fields, limits, and user policy.
A server-side adapter selects and calls the entitled market feed.
The adapter returns stable fields plus timestamps and error state.
DeepSeek summarizes only the supplied evidence and names its limits.
If the application consumes a WebSocket feed, ingest and aggregate it in a normal streaming service. Send DeepSeek a bounded snapshot or selected event. Token-by-token generation is not a market-data transport.
A bare price is difficult to verify. Use one normalized envelope for success, stale data, ambiguous instruments, missing entitlement, timeout, and provider failure.
{
"status": "ok",
"instrument": {"symbol": "EXAMPLE", "exchange": "VENUE"},
"quote": {"value": "provider_value", "field": "last_trade",
"currency": "USD"},
"freshness": {
"provider_time": "ISO-8601",
"retrieved_at": "ISO-8601",
"session": "regular",
"delay": "provider_label"
},
"source": {"provider": "provider_name",
"feed": "entitled_feed"}
}
Illustrative schema only: field names and meanings must be mapped to the selected provider’s official documentation.
DeepSeek’s official API exposes function tools. The model returns function arguments; your code executes the function and sends its result back. DeepSeek’s documentation explicitly notes that the model does not execute the function itself.
import json
from openai import OpenAI
client = OpenAI(api_key=DEEPSEEK_API_KEY,
base_url="https://api.deepseek.com")
tools = [{
"type": "function",
"function": {
"name": "get_current_stock_quote",
"description": "Get a current, read-only stock quote.",
"parameters": {
"type": "object",
"properties": {
"symbol": {"type": "string"},
"exchange": {"type": "string"}
},
"required": ["symbol"],
"additionalProperties": False
}
}
}]
messages = [
{"role": "system", "content":
"For current market facts, use the quote tool. Never substitute memory. "
"State source, provider timestamp, session, and delay status."},
{"role": "user", "content": user_question}
]
first = client.chat.completions.create(
model="deepseek-v4-pro",
messages=messages, tools=tools,
tool_choice="required"
).choices[0].message
args = json.loads(first.tool_calls[0].function.arguments)
quote = execute_validated_quote(args) # your server-side code
messages += [first, {
"role": "tool",
"tool_call_id": first.tool_calls[0].id,
"content": json.dumps(quote)
}]
answer = client.chat.completions.create(
model="deepseek-v4-pro", messages=messages, tools=tools
).choices[0].message.content
Treat arguments as untrusted input. Parse JSON, reject unexpected keys, normalize case, cap list lengths, resolve venue ambiguity, and apply authorization before contacting a provider. The API reference warns that generated arguments may be invalid or contain hallucinated parameters.
Use auto when the same assistant handles stable
educational questions and current-data questions. At the
application layer, classify hard freshness intent and require
the tool for those requests.
The endpoint and response fields below are intentionally generic. Map them to the official documentation and entitlement of the provider you actually select; do not copy field names blindly.
import os, re
from datetime import datetime, timezone
import httpx
SYMBOL = re.compile(r"^[A-Z][A-Z0-9.-]{0,14}$")
def execute_validated_quote(arguments):
symbol = str(arguments.get("symbol", "")).strip().upper()
exchange = str(arguments.get("exchange", "")).strip().upper() or None
if not SYMBOL.fullmatch(symbol):
return {"status": "error", "code": "invalid_symbol"}
response = httpx.get(
os.environ["MARKET_DATA_URL"],
params={"symbol": symbol, "exchange": exchange},
headers={"Authorization": "Bearer " + os.environ["MARKET_DATA_API_KEY"]},
timeout=4.0
)
response.raise_for_status()
raw = response.json()
provider_time = datetime.fromisoformat(
raw["timestamp"].replace("Z", "+00:00")
)
retrieved_at = datetime.now(timezone.utc)
age_seconds = (retrieved_at - provider_time).total_seconds()
if age_seconds < 0 or age_seconds > MAX_QUOTE_AGE_SECONDS:
return {"status": "error", "code": "stale_quote",
"provider_time": provider_time.isoformat()}
return {
"status": "ok",
"instrument": {"symbol": raw["symbol"],
"exchange": raw["exchange"]},
"quote": {"value": raw["price"],
"field": raw["price_type"],
"currency": raw["currency"]},
"freshness": {"provider_time": provider_time.isoformat(),
"retrieved_at": retrieved_at.isoformat(),
"session": raw["session"],
"delay": raw["delay_label"]},
"source": {"provider": raw["provider"],
"feed": raw["feed"]}
}
User asks for the current quote. DeepSeek requests the
function. The backend returns an ok envelope. The
final answer states the resolved symbol and exchange, price
meaning, currency, provider time, session, source, and delay
label.
If the adapter returns stale_quote,
not_entitled, or timeout, DeepSeek
says that a current price could not be verified and retains
any available timestamp. It does not output a remembered
price.
Read DeepSeek’s official Tool Calls guide · Check the current Chat Completion schema
When your DeepSeek application needs more than one fixed endpoint, QVeris can serve as the capability layer: discover a market-data function, inspect its input and provider metadata, then call it from your backend. DeepSeek sees one narrow application function; credentials and provider selection remain server-side.
Describe the need—such as a current quote with source and timestamp—rather than assuming a provider.
Confirm the schema, provider notes, expected output, cost signals, and freshness semantics.
Validate arguments, call the inspected capability, normalize the result, and preserve trace IDs.
There is no universal cache duration for real-time stock market data. Define a maximum age per route, then confirm the provider entitlement can meet it. The values below are policy examples, not exchange or provider guarantees.
| Experience | Retrieval pattern | Trade-off to document |
|---|---|---|
| One current quote | Request a fresh snapshot; cache only within the declared maximum age. | Provider latency and one billable retrieval per cache miss. |
| Multi-symbol watchlist | Prefer a documented batch or snapshot endpoint; cap symbols. | Lower call overhead, but the oldest item may determine freshness. |
| Continuous monitoring | Ingest WebSocket events outside DeepSeek; summarize selected events. | Stream infrastructure cost versus fewer model calls and bounded context. |
| Educational question | Skip the live tool unless the answer depends on a current fact. | Lowest cost and latency without pretending stable knowledge is live data. |
| Risk | Deterministic control | What DeepSeek should say |
|---|---|---|
| Market closed | Return session status and identify last trade versus previous close. | Name the session and as-of time. |
| Stale cache | Compare provider time with a route-specific maximum age. | Say a current quote could not be verified. |
| Ambiguous symbol | Resolve venue and identity; return candidates. | Ask one precise clarification. |
| Not entitled | Surface the provider error; do not silently downgrade. | State that the feed cannot meet the requested freshness. |
| Timeout or rate limit | Use bounded retries, circuit breaking, and explicit errors. | Fail honestly; never substitute memory. |
Pass only when the answer preserves instrument identity, price meaning, currency, event time, session, source, and delay status—and refuses to repair missing live data with model knowledge.
DeepSeek should not be treated as the market-data source. Its tool-calling API can request an external quote function that your application executes, validates, and returns to the model.
Force the quote tool for current-price intent, require provider and retrieval timestamps, reject results outside your freshness policy, and report tool failures instead of using memory.
No. Stable concepts may not need live data. Current price, latest, today, market status, pre-market, and after-hours requests should use a live-data path.
Keep quote retrieval read-only. Order placement needs a separate, tightly authorized action with deterministic risk controls, idempotency, audit logs, and explicit confirmation.
Start with one read-only symbol lookup. Inspect the capability, record the source and timestamps, then deliberately test stale data and provider failure.
A verified profile link does not guarantee entitlement, field availability, price or current execution success; inspect the current contract before calling.
