ALPHIODeveloper console

Docs

Full API reference for the Alphio open platform.

Chat integration guide →

Getting started

Quick start
  1. 1.Create an API key in API Key. Copy it once — we hash it before storage.
  2. 2.Onboard your end users: UpsertVirtualUser CreateChatSession /openchat-steam/completions
  3. 3.Wire your SSE reader to handle submitted delta* → done events.
curl https://api.alphio.ai/v1/openapi/users \
  -H "Authorization: Bearer pk_live_••••••••••••••••••••••••••••" \
  -H "Content-Type: application/json" \
  -d '{"partner_user_ref": "u_998877"}'
Base URL & envelope
Base URL
https://api.alphio.ai
Response envelope
{ ret, msg, data }
HTTP status
Always 200 (for non-SSE). Inspect ret for the business result.
SSE
Chat completions stream as text/event-stream.

Authentication

Every request carries a Bearer API key. End-user-scoped endpoints additionally need an X-Partner-User header.

HeaderValueWhen
AuthorizationBearer pk_live_…Every request
Content-Typeapplication/jsonEvery request
X-Partner-Useryour_user_idOnly for end-user-scoped endpoints: /openchat-steam/completions + whales/following/ranking
Accepttext/event-streamSSE chat only

The value of X-Partner-User is your own user ID. The platform maps it to a stable internal_user_id like op_{partner_code}_{nanoid}. The user must first be registered via UpsertVirtualUser or chat returns ret=10404.

Errors & limits

Error codes
HTTP is always 200; check ret
retMeaningTypical cause
0OKSuccess
10400Bad requestMissing required field / type mismatch / empty message
10401UnauthenticatedMissing / wrong / expired / revoked Bearer
10403ForbiddenUser disabled / cross-user access
10404Not foundUser not registered (call UpsertVirtualUser) / bad session_id
10429Rate limitedRPM quota exceeded
10500Server errorContact support with occurred_at / chat_id
10501Insufficient balanceTop up to resume chat
Rate limits & billing

Default ceilings: 600 partner RPM · 60 per-user RPM · 8 concurrent chat streams. Negotiated on a per-plan basis.

Billing: one chat round (submit → done) deducts one billable unit. Interrupted / disconnected sessions still bill (anti-spam). failed events do not bill. Analysis, Whales, and Data endpoints are free of charge.

Virtual users

Manage end-user identities under your partner account. Virtual users are created lazily; the same partner_user_ref always maps to the same internal_user_id.

POST/v1/openapi/users
UpsertVirtualUser

Register or fetch a virtual user. Idempotent — calling repeatedly with the same partner_user_ref is safe.

Request parameters
FieldTypeRequiredDescription
partner_user_refstringyesYour own user ID for this end user.
display_namestringnoOptional, for audit/debugging.
metadatastringnoOpaque JSON string, not parsed by the platform.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataVirtualUserResponse payload.
internal_user_idstringPlatform-assigned ID. Format: "op_{partner_code}_{nanoid12}".
partner_user_refstringEchoed back.
display_namestringEchoed back.
metadatastringEchoed back (JSON string).
statusstring"active" / "disabled".
is_newbooltrue only on first creation.
created_atstringISO8601 UTC.
last_active_atstringISO8601 UTC. Empty if never used.
Example request
curl -X POST https://api.alphio.ai/v1/openapi/users \
  -H "Authorization: Bearer pk_live_••••••••••••••••••••••••••••" \
  -H "Content-Type: application/json" \
  -d '{
    "partner_user_ref": "u_998877",
    "display_name": "Alice"
  }'
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "internal_user_id": "op_intellectia_qUk8CyDetjsK",
    "partner_user_ref": "u_998877",
    "display_name": "Alice",
    "metadata": "",
    "status": "active",
    "is_new": true,
    "created_at": "2026-06-09T08:02:14Z",
    "last_active_at": ""
  }
}
POST/v1/openapi/users/get
GetVirtualUser

Look up a virtual user by partner_user_ref. Response shape matches UpsertVirtualUser except is_new is always false.

Request parameters
FieldTypeRequiredDescription
partner_user_refstringyes
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataVirtualUserResponse payload.
internal_user_idstringPlatform-assigned ID. Format: "op_{partner_code}_{nanoid12}".
partner_user_refstringEchoed back.
display_namestringEchoed back.
metadatastringEchoed back (JSON string).
statusstring"active" / "disabled".
is_newbooltrue only on first creation.
created_atstringISO8601 UTC.
last_active_atstringISO8601 UTC. Empty if never used.
POST/v1/openapi/users/disable
DisableVirtualUser

Disable a virtual user. Their chat requests will return ret=10403 until re-enabled via UpsertVirtualUser.

Request parameters
FieldTypeRequiredDescription
partner_user_refstringyes
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataDisableVirtualUserDataResponse payload.
statusstringAlways "disabled".
POST/v1/openapi/users/list
ListVirtualUsers

Paginated list of your virtual users.

Request parameters
FieldTypeRequiredDescription
filterVirtualUserListFilternoOptional filters.
statusstringno"active" / "disabled" / "" (all).
created_afterstringnoISO8601 UTC.
created_beforestringnoISO8601 UTC.
pageint32no1-indexed. Default 1.
sizeint32noDefault 20, max 200.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataListVirtualUsersDataResponse payload.
itemsVirtualUser[]
internal_user_idstringPlatform-assigned ID. Format: "op_{partner_code}_{nanoid12}".
partner_user_refstringEchoed back.
display_namestringEchoed back.
metadatastringEchoed back (JSON string).
statusstring"active" / "disabled".
is_newbooltrue only on first creation.
created_atstringISO8601 UTC.
last_active_atstringISO8601 UTC. Empty if never used.
paginationPagination
pageint321-indexed.
sizeint32Items per page.
totalint64Total rows matching the filter.
has_moreboolWhether more pages exist.

Chat (SSE streaming)

Multi-turn AI chat with built-in skills (technical analysis, market data, news). Response is text/event-stream — every event is emitted as `event: NAME\ndata: JSON\n\n`. Unlike all other endpoints, the SSE stream is NOT wrapped in `{ret, msg, data}`.

POST/openchat-steam/completionsX-Partner-User required
ChatCompletions

Start a chat turn. Returns an SSE stream until done or failed.

Each delta.content is incremental — append to a client buffer. The final done event carries the full content as a sanity check.
Failed events do not bill. Submitted → done is one billable round.
Request parameters
FieldTypeRequiredDescription
chat_idstringyesYour generated unique ID for this turn, e.g. chat-{uuid}. Used for idempotency and tracing.
messagestringyesThe user's question.
metadataChatMetadatayes
session_idstringyesFrom CreateChatSession. Wrong/missing → ret=10404.
timezonestringnoIANA timezone, e.g. "Asia/Shanghai". Affects "today/yesterday" interpretation.
languagestringno"zh" / "en" / etc. Default: adaptive to user language.
Response fields
FieldTypeDescription
event: submittedSSEAcknowledgement that the request was accepted.
chat_idstringEchoed back.
statusstring"RUNNING".
user_idstringinternal_user_id resolved from X-Partner-User.
session_idstringEchoed back.
occurred_atstringISO8601 UTC.
event: statusSSEIntermediate progress.
stagestringagent_round_start / tool_call_start / model_call_start / etc.
messagestringHuman-readable status.
progressfloat0.0 – 1.0.
event: deltaSSEStreaming answer chunk.
contentstringIncremental fragment — append to a client buffer.
statusstring"RUNNING".
event: doneSSEStream complete.
contentstringFull final answer (sanity check against the joined deltas).
statusstring"SUCCESS".
progressfloat1.0.
token_usageobjectToken counters for billing visibility.
event: failedSSETerminal failure (insufficient balance, backend error, etc).
messagestringError description.
statusstring"FAILED".
Example request
curl -N -X POST https://api.alphio.ai/openchat-steam/completions \
  -H "Authorization: Bearer pk_live_••••••••••••••••••••••••••••" \
  -H "X-Partner-User: u_998877" \
  -H "Accept: text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{
    "chat_id": "chat-998877-1719283400",
    "message": "What is AAPL'\''s current RSI?",
    "metadata": {
      "session_id": "sess_ifm92XaV7gqx",
      "timezone": "America/New_York",
      "language": "en"
    }
  }'
Example response
event: submitted
data: {"chat_id":"chat-998877-1719283400","status":"RUNNING",
       "user_id":"op_intellectia_qUk8CyDetjsK","session_id":"sess_ifm92XaV7gqx",
       "occurred_at":"2026-06-09T08:18:24.77Z"}

event: status
data: {"chat_id":"...","stage":"agent_round_start",
       "status":"PROCESSING","progress":0.15,"message":"Understanding question"}

event: status
data: {"chat_id":"...","stage":"tool_call_start",
       "status":"PROCESSING","progress":0.50,"message":"Fetching technical indicators"}

event: delta
data: {"chat_id":"...","status":"RUNNING","content":"AAPL's current RSI(14) is 68,"}

event: delta
data: {"chat_id":"...","status":"RUNNING","content":" approaching the overbought zone (70)..."}

event: done
data: {"chat_id":"...","status":"SUCCESS","progress":1.0,
       "stage":"task_completed","content":"AAPL's current RSI(14) is 68, approaching..."}

Chat sessions & messages

A session groups related chat turns. History within a session is automatically injected as context.

POST/v1/openapi/chat/sessions/create
CreateChatSession
Request parameters
FieldTypeRequiredDescription
internal_user_idstringyesFrom UpsertVirtualUser.
titlestringnoDisplay title for your UI.
metadatastringnoOpaque JSON string.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataChatSessionResponse payload.
session_idstringFormat: "sess_{nanoid}".
internal_user_idstringOwner.
titlestring
metadatastringJSON string.
statusstring"active" / "deleted".
last_message_atstringISO8601 UTC. Empty for a freshly created session.
created_atstringISO8601 UTC.
updated_atstringISO8601 UTC.
POST/v1/openapi/chat/sessions/list
ListChatSessions
Request parameters
FieldTypeRequiredDescription
internal_user_idstringnoEmpty = list across all your virtual users.
statusstringno"active" / "deleted" / "" (all). Default "active".
pageint32noDefault 1.
sizeint32noDefault 20, max 200.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataListChatSessionsDataResponse payload.
itemsChatSession[]
session_idstringFormat: "sess_{nanoid}".
internal_user_idstringOwner.
titlestring
metadatastringJSON string.
statusstring"active" / "deleted".
last_message_atstringISO8601 UTC. Empty for a freshly created session.
created_atstringISO8601 UTC.
updated_atstringISO8601 UTC.
pageint321-indexed.
sizeint32Items per page.
totalint64Total rows matching the filter.
has_moreboolWhether more pages exist.
POST/v1/openapi/chat/sessions/get
GetChatSession
Request parameters
FieldTypeRequiredDescription
session_idstringyes
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataChatSessionResponse payload.
session_idstringFormat: "sess_{nanoid}".
internal_user_idstringOwner.
titlestring
metadatastringJSON string.
statusstring"active" / "deleted".
last_message_atstringISO8601 UTC. Empty for a freshly created session.
created_atstringISO8601 UTC.
updated_atstringISO8601 UTC.
POST/v1/openapi/chat/sessions/update
UpdateChatSession

Edit the title or metadata of an existing session.

Request parameters
FieldTypeRequiredDescription
session_idstringyes
titlestringnoEmpty = unchanged.
metadatastringnoEmpty = unchanged.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataChatSessionResponse payload.
session_idstringFormat: "sess_{nanoid}".
internal_user_idstringOwner.
titlestring
metadatastringJSON string.
statusstring"active" / "deleted".
last_message_atstringISO8601 UTC. Empty for a freshly created session.
created_atstringISO8601 UTC.
updated_atstringISO8601 UTC.
POST/v1/openapi/chat/sessions/delete
DeleteChatSession

Soft-delete by default. Message history remains queryable.

Request parameters
FieldTypeRequiredDescription
session_idstringyes
soft_deleteboolnoDefault true. Set false for permanent deletion.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataDeleteChatSessionDataResponse payload.
statusstring"deleted" / "hard_deleted".
POST/v1/openapi/chat/sessions/messages
ListSessionMessages

Cursor-paginated history. Order is by created_at DESC.

Request parameters
FieldTypeRequiredDescription
session_idstringyes
before_message_idstringnoCursor — pass the message_id of your current oldest message to fetch older ones.
sizeint32noDefault 50, max 200.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataListSessionMessagesDataResponse payload.
itemsChatMessage[]
message_idstringFormat: "msg_{nanoid}".
chat_idstringMatches the SSE chat_id. One chat_id usually produces 2 messages (user + assistant).
session_idstringMay be empty for session-less chat.
internal_user_idstring
rolestring"user" / "assistant".
contentstringRaw Markdown stream. May contain ```json card fences.
attachmentsChatAttachment[]
urlstringPre-signed URL. May expire.
mimestring
namestring
tool_callsChatToolCall[]
step_idstring
kindstring"round" / "tool_call".
roundint32
tool_namestring
args_jsonstringStringified tool arguments.
result_summarystring
statusstring"ok" / "error" / "running".
started_at_msint64Unix milliseconds.
ended_at_msint64Unix milliseconds.
sourcesChatSource[]
titlestring
urlstring
snippetstring
error_codestringNon-empty on terminal failure.
error_messagestring
doc_idstringChatbot's assistant doc_id.
created_atstringISO8601 UTC.
has_morebool
POST/v1/openapi/chat/messages/get
GetChatMessage
Request parameters
FieldTypeRequiredDescription
message_idstringyes
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataChatMessageResponse payload.
message_idstringFormat: "msg_{nanoid}".
chat_idstringMatches the SSE chat_id. One chat_id usually produces 2 messages (user + assistant).
session_idstringMay be empty for session-less chat.
internal_user_idstring
rolestring"user" / "assistant".
contentstringRaw Markdown stream. May contain ```json card fences.
attachmentsChatAttachment[]
urlstringPre-signed URL. May expire.
mimestring
namestring
tool_callsChatToolCall[]
step_idstring
kindstring"round" / "tool_call".
roundint32
tool_namestring
args_jsonstringStringified tool arguments.
result_summarystring
statusstring"ok" / "error" / "running".
started_at_msint64Unix milliseconds.
ended_at_msint64Unix milliseconds.
sourcesChatSource[]
titlestring
urlstring
snippetstring
error_codestringNon-empty on terminal failure.
error_messagestring
doc_idstringChatbot's assistant doc_id.
created_atstringISO8601 UTC.
POST/v1/openapi/chat/messages/rate
RateChatMessage

Up/down vote an assistant reply. Only valid for role=assistant messages.

Request parameters
FieldTypeRequiredDescription
message_idstringyes
ratingstringyes"up" or "down".
notestringnoOptional user note.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataRateChatMessageDataResponse payload.
message_idstringEchoed back.
ratingstringEchoed back.
created_atstringISO8601 UTC.
POST/v1/openapi/chat/recommend-questions
ChatRecommendQuestions

Suggested starter questions for your chat entry screen, regenerated daily from a digest of recent market news. Served from cache — this endpoint never invokes an LLM and is not billed. Each call returns a fresh random subset, so repeated calls give your UI variety.

Not billed and no X-Partner-User required.
An empty questions array with ret=0 means the daily batch is not available yet (or expired) — hide the suggestions UI rather than treating it as an error.
Request parameters
FieldTypeRequiredDescription
langstringnoLanguage tag: "en" / "en-us", "zh" / "zh-cn" / "zh-hans", "zh-tw" / "zh-hant" / "zh-hk". Case-insensitive. Empty or unrecognized falls back to "en".
countint32noMax questions to return. Default 10, max 50.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataChatRecommendQuestionsDataResponse payload.
questionsstring[]Randomly ordered subset of the day's batch.
langstringLanguage actually served after normalization/fallback: "en" / "zh-cn" / "zh-tw".
generated_atint64Unix seconds when the batch was generated.
Example request
curl -X POST https://api.alphio.ai/v1/openapi/chat/recommend-questions \
  -H "Authorization: Bearer pk_live_••••••••••••••••••••••••••••" \
  -H "Content-Type: application/json" \
  -d '{
    "lang": "en",
    "count": 3
  }'
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "questions": [
      "How could the latest Fed commentary affect rate-cut expectations this summer?",
      "Is NVDA's pullback after earnings a buying opportunity?",
      "What is driving the rally in gold prices this week?"
    ],
    "lang": "en",
    "generated_at": 1781136000
  }
}

Pivot point

Pivot point / support-resistance signals.

POST/v1/openapi/analysis/pivot-point/info
PivotPointInfo

Returns every 神奇九转 + RSI(6) pivot signal (DIP / ALERT) the algorithm fired within the look-back window. The K-line period is selectable with multiplier / timespan (1–720 minute, hour, day, week, month, quarter, year); both omitted = daily bars over the trailing 1 year, the behaviour that predates the fields. Computed server-side from datafabric kline (US / HK / crypto all supported); cached 5 minutes, 1 minute for intraday periods. Empty `data.list` with `ret=0` means no signal in the window — distinct from a real error.

Request parameters
FieldTypeRequiredDescription
codestringyesTicker, e.g. "AAPL", "00700", "BTC". Case-insensitive; uppercased server-side.
asset_typeint32yes0=stock, 1=etf, 2=crypto.
localestringnoMarket the ticker belongs to: "US", "HK", "FOREX", "METAL". Case-insensitive; uppercased server-side. Empty defaults to "US". Crypto (asset_type=2) keeps the field for shape consistency but it's inert.
multiplierint32noPeriod count, paired with timespan. Allowed values depend on timespan: minute 1–720, hour 1–12, month 1 / 3 (= quarter) / 12 (= year); day, week, quarter and year accept 1 only. Any other combination is a parameter error rather than a silently mis-aggregated series. Default 1.
timespanint32noK-line period unit: 2=minute, 3=hour, 4=day, 5=week, 6=month, 7=quarter, 8=year (1=second is not supported). Omitted together with multiplier = daily. Bar stamping — day and above carry the period's FIRST TRADING DAY (NVDA's August 2026 monthly bar is 2026-08-03, its Q1 and 2026 yearly bars are both 2026-01-02); minute and hour bars are right-edge stamped and anchored to each trading session's open, truncated at the close (HK 60m → 10:30 / 11:30 / 12:00 / 14:00 / 15:00 / 16:00, HK 90m → 11:00 / 12:00 / 14:30 / 16:00, and a 3m series stamps the 09:30 bar 09:33). This anchoring is done by THIS endpoint, which folds hourly widths from 5-minute bars for the purpose; /v1/openapi/data/kline passes timespan straight through to the vendor and returns its CLOCK-aligned hourly stamps (10:00, 11:00) instead — so a 60m bar read from the two endpoints carries different timestamps by design. Crypto and perp serve only the exchange's native widths: 1 / 3 / 5 / 15 / 30 / 60 / 120 / 240 / 360 / 480 / 720 minutes, plus day / week / month. Note the upstream vendor stamps week and above on the CALENDAR period start (August 2026 arrives as 08-01); this endpoint moves them onto the first day the market actually traded, so those stamps can differ from the same bar read through /v1/openapi/data/kline.
fromstringnoWindow start, YYYY-MM-DD (UTC, inclusive). Must be set together with to. The algorithm runs on exactly the [from, to] bars with no warmup preload — the signal math is window-sensitive (RSI warmup, TD-9 counts, FILTER suppression), so to reproduce the App chart's markers pass exactly the bar range the chart has loaded. Both empty = a default look-back sized for the period: 1 year for daily bars, days for a 1-minute series, decades for yearly.
tostringnoWindow end, YYYY-MM-DD (UTC, inclusive). Must be set together with from. Max span 5 years for minute / hour / day / week, 50 years for month / quarter / year. A LONGER window is not rejected — it is clamped to the ceiling, keeping `to` and moving `from` forward, and `msg` says which window actually ran (e.g. "ok (requested from 2020-12-07 exceeds the max span for this period; window clamped to 2021-08-27..2026-08-31)"). Windows shorter than 30 bars return "insufficient kline history" — which also means yearly signals only exist for tickers with 30+ years of history.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisPivotPointInfoDataResponse payload.
listAnalysisPivotAlertInfo[]Filtered signals in CHRONOLOGICAL ASCENDING order. Empty when no signal fired in the look-back window. For the latest signal, take list[list.length-1].
datestringBar label in the market's own timezone (UTC for crypto / perp): "YYYY-MM-DD HH:MM" for minute and hour periods, "YYYY-MM-DD" for day and above.
codestringEchoed ticker, uppercased.
signstring"DIP" (bullish reversal) or "ALERT" (bearish reversal).
markstring"Buy Signal" / "Sell Signal" — human-readable label.
pricestringDisplay price with 4-decimal precision. DIP = low × 0.98 (paint below the bar); ALERT = high × 1.03 (paint above).
tsint64Bar timestamp, unix seconds — the same instant date renders.
Example request
# Daily (period omitted — the pre-existing behaviour)
POST https://api.alphio.ai/v1/openapi/analysis/pivot-point/info
{ "code": "AAPL", "asset_type": 0, "locale": "US", "from": "2026-01-01", "to": "2026-07-28" }

# 60-minute bars
POST https://api.alphio.ai/v1/openapi/analysis/pivot-point/info
{ "code": "AAPL", "asset_type": 0, "locale": "US", "multiplier": 60, "timespan": 2 }
Example response
// Daily
{
  "ret": 0, "msg": "ok",
  "data": {
    "list": [
      {
        "date": "2026-02-09", "code": "AAPL",
        "sign": "ALERT", "mark": "Sell Signal",
        "price": "286.5460", "ts": 1770613200
      },
      {
        "date": "2026-06-09", "code": "AAPL",
        "sign": "DIP", "mark": "Buy Signal",
        "price": "291.7340", "ts": 1781007137
      }
    ]
  }
}

// 60-minute — note date carries the time of day
{
  "ret": 0, "msg": "ok",
  "data": {
    "list": [
      {
        "date": "2026-08-24 11:30", "code": "AAPL",
        "sign": "ALERT", "mark": "Sell Signal",
        "price": "286.5460", "ts": 1787585400
      },
      {
        "date": "2026-08-27 14:30", "code": "AAPL",
        "sign": "DIP", "mark": "Buy Signal",
        "price": "291.7340", "ts": 1787855400
      }
    ]
  }
}
POST/v1/openapi/analysis/pivot-point/signals
PivotPointSignals

Bulk scan / signal screener.

Request parameters
FieldTypeRequiredDescription
signal_typeint32yes0=all, 1=bottom (dip / bottom-reversal), 2=alert (top warning).
pageint32no1-indexed.
page_sizeint32noItems per page.
asset_typestringnoNumeric string: "0"=stock, "1"=etf, "2"=crypto. Empty = all.
periodint32no0=all, 1=15min, 2=30min, 3=1h, 4=2h, 5=4h. This is the screener's own enum — NOT the timespan / multiplier pair PivotPointInfo takes, and it has no daily or above option.
sort_fieldint32no0=timestamp, 2=volume (1=market_cap is deprecated).
orderstringno"asc" (default) / "desc".
first_idstringnoForward cursor.
last_idstringnoBackward cursor.
refreshboolnoForce-bust cache.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisPivotPointSignalsDataResponse payload.
signalsAnalysisDayTradingSignal[]
symbolstring
codestring
namestringCompany name.
logostring
pricestring
change_ratiostring
timestampint64Unix seconds.
signal_typesint32[]Active signal labels.
periodint32
klinesAnalysisKlinePoint[]OHLCV + technicals.
opendouble
highdouble
lowdouble
closedouble
volumedouble
timestampint64Unix seconds.
ma5double
ma20double
rsi6double
macddouble
macd_signaldouble
macd_histdouble
asset_typeint32
volumestring
idstringStable row ID for cursor pagination.
prev_closestring
totalint64Total rows matching the filter.
new_addint64Rows newly added since last query.

Swingmax (US)

Swing-trade signals for US equities.

POST/v1/openapi/analysis/swingmax/signals
SwingmaxSignals

Query open swingmax signals for the given tickers. Returns the SAME rich item shape as /swingmax/stocks (AnalysisSwingmaxStock — with kline, company name/logo, the r1/r2/r3 target ladder, stop loss). Ladder field names match the App swing-max/list payload one-to-one.

The status field is localized. A "lang" BODY PARAM takes priority when set; otherwise the "lang" REQUEST HEADER is used: omit both for English, "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Every other field (prices, timestamps) is language-independent.
Request parameters
FieldTypeRequiredDescription
tickersAnalysisAsset[]yesTickers to query.
asset_typeint32no0=stock, 1=etf, 2=crypto.
symbolstringnoLegacy field.
tickerstringnoPreferred field.
localestringno"US" / "HK".
langstringnoLocalizes the status text. When set it takes PRIORITY over the "lang" request header: "zh" / "zh-cn" = Simplified Chinese, "zh-tw" = Traditional Chinese. Omit/empty to fall back to the header (English by default).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisSwingmaxSignalsDataResponse payload.
signalsAnalysisSwingmaxStock[]Same item shape as /swingmax/stocks — one entry per matched open ticker.
symbolstring
codestring
company_namestring
logostring
returndoubleRealized return since entry, percent. Weighted over the ladder: 40% sold at Target 2 + 30% sold at Target 3 + the remaining 30% at final exit (unsold parts marked to the latest close).
entry_pricedouble
exit_pricedoubleFinal-exit fill price for the remaining position. 0 while the position is open.
entry_timestringEntry date string from upstream, e.g. "2026-06-02".
exit_timestringExit date string; empty while the position is open.
change_ratiodouble
klineAnalysisKlinePointV2[]Snapshot bars with full OHLC + volume — enough to draw candlesticks.
closedouble
timestampint64Unix seconds.
opendouble
highdouble
lowdouble
volumedouble
entry_time_tsint64Unix seconds.
exit_time_tsint64Unix seconds; 0 while open.
target_pricestringLegacy alias of r2_price (Target 2), kept for backward compatibility — prefer the r1/r2/r3_price ladder.
stop_lossstringStop-loss price. The whole remaining position exits if it is hit.
intervalint32Signal timeframe: 0=1d, 1=15min, 2=30min, 3=1h, 4=2h, 5=4h.
sideint320=long, 1=short.
market_capstring
current_pricestring
r1_pricestringTarget 1 price — the first (lowest) pivot level above entry. A price milestone only: no partial sell is executed at R1.
r1_signal_tsint64Reserved for shape parity with the App swing-max/list; always 0 on this stock feed (only the crypto pipeline fills R1 triggers).
r2_pricestringTarget 2 price. When first reached, the strategy sells 40% of the position. Same value as the legacy target_price.
r2_signal_tsint64Unix seconds when the price first reached Target 2 (40% partial exit executed); 0 if not reached yet.
r2_sell_pricestringFill price of the 40% partial exit at Target 2; empty if not reached yet.
r3_pricestringTarget 3 price — the highest ladder level. When first reached, the strategy sells another 30% of the position.
r3_signal_tsint64Unix seconds when the price first reached Target 3 (30% partial exit executed); 0 if not reached yet.
r3_sell_pricestringFill price of the 30% partial exit at Target 3; empty if not reached yet.
statusstringServer-rendered progress narrative (entry → 40% partial exit at Target 2 → 30% at Target 3 → final close) — same text the App shows on swing-max/list. Localized by the "lang" body param (priority) or "lang" request header: omit both for English, "zh" / "zh-cn" = Simplified Chinese, "zh-tw" = Traditional Chinese. Empty on the closed list (stype≠1).
Example request
POST https://api.alphio.ai/v1/openapi/analysis/swingmax/signals
Authorization: Bearer pk_live_••••••••••••••••••••••••••••
{
  "tickers":[
    {"asset_type":0,"ticker":"AAPL","locale":"US"},
    {"asset_type":0,"ticker":"NVDA","locale":"US"}
  ],
  "lang":"zh-tw"
}
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "signals":[
      {"symbol":"AAPL","code":"AAPL.O","company_name":"Apple Inc","logo":"https://...",
       "return":3.21,"entry_price":187.2,"exit_price":0,"entry_time":"2026-06-02","exit_time":"",
       "change_ratio":3.21,
       "kline":[{"close":190.5,"timestamp":1717286400,"open":188.9,"high":191.2,"low":188.1,"volume":51234567}],
       "entry_time_ts":1717286400,"exit_time_ts":0,"target_price":"210.5","stop_loss":"177.84",
       "interval":0,"side":0,"market_cap":"2.9T","current_price":"193.1",
       "r1_price":"198.6","r1_signal_ts":0,
       "r2_price":"210.5","r2_signal_ts":1719878400,"r2_sell_price":"211.02",
       "r3_price":"224.9","r3_signal_ts":0,"r3_sell_price":"",
       "status":"Booked partial profits @211.02 on 2026-07-01 09:35 ET and riding runners"}
    ]
  }
}
POST/v1/openapi/analysis/swingmax/stocks
SwingmaxStocks

Browse the supported universe. NOTE: only stype=1 returns the OPEN positions pool; any other value returns the removed/closed list. The r1/r2/r3 ladder fields are only filled for stype=1 — the closed list comes from an older store without ladder data, so they are empty/0 there.

data.total is the count AFTER keyword filtering and BEFORE paging — divide it by size to get the page count. Paging past the last page returns an empty list with total unchanged, which is the normal way to detect the end, not an error.
The status field is localized. A "lang" BODY PARAM takes priority when set; otherwise the "lang" REQUEST HEADER is used: omit both for English, "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Every other field (prices, timestamps) is language-independent.
Request parameters
FieldTypeRequiredDescription
stypeint32yesGetSwingMaxStocksType. 1=open pool, 2=removed(closed), 3=today, 4=today-open, 5=today-update. Only stype=1 = open pool.
sort_typeint32no1-4 match the platform-wide meaning shared with every other list endpoint: 1=latest, 2=oldest, 3=highest return, 4=lowest return. 5-11 are extra orderings only this endpoint supports: 5=latest exit, 6=oldest exit, 7=latest entry, 8=oldest entry, 9=highest market cap, 10=lowest market cap, 11=highest potential.
pageint64no1-based. 0 or negative is treated as unset and means page 1.
sizeint32noRows per page. Default 100. No ceiling on this endpoint — Swingmax is browse-style data, unlike DayTrading which caps at 10.
keywordstringnoCase-insensitive substring match on ticker, code and company name. Omit to disable filtering. Max 64 characters.
sideint32no0=long, 1=short.
trade_statusint32no0=not traded, 1=traded, 2=all.
langstringnoLocalizes the status text. When set it takes PRIORITY over the "lang" request header: "zh" / "zh-cn" = Simplified Chinese, "zh-tw" = Traditional Chinese. Omit/empty to fall back to the header (English by default).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisSwingmaxStocksDataResponse payload.
stocksAnalysisSwingmaxStock[]
symbolstring
codestring
company_namestring
logostring
returndoubleRealized return since entry, percent. Weighted over the ladder: 40% sold at Target 2 + 30% sold at Target 3 + the remaining 30% at final exit (unsold parts marked to the latest close).
entry_pricedouble
exit_pricedoubleFinal-exit fill price for the remaining position. 0 while the position is open.
entry_timestringEntry date string from upstream, e.g. "2026-06-02".
exit_timestringExit date string; empty while the position is open.
change_ratiodouble
klineAnalysisKlinePointV2[]Snapshot bars with full OHLC + volume — enough to draw candlesticks.
closedouble
timestampint64Unix seconds.
opendouble
highdouble
lowdouble
volumedouble
entry_time_tsint64Unix seconds.
exit_time_tsint64Unix seconds; 0 while open.
target_pricestringLegacy alias of r2_price (Target 2), kept for backward compatibility — prefer the r1/r2/r3_price ladder.
stop_lossstringStop-loss price. The whole remaining position exits if it is hit.
intervalint32Signal timeframe: 0=1d, 1=15min, 2=30min, 3=1h, 4=2h, 5=4h.
sideint320=long, 1=short.
market_capstring
current_pricestring
r1_pricestringTarget 1 price — the first (lowest) pivot level above entry. A price milestone only: no partial sell is executed at R1.
r1_signal_tsint64Reserved for shape parity with the App swing-max/list; always 0 on this stock feed (only the crypto pipeline fills R1 triggers).
r2_pricestringTarget 2 price. When first reached, the strategy sells 40% of the position. Same value as the legacy target_price.
r2_signal_tsint64Unix seconds when the price first reached Target 2 (40% partial exit executed); 0 if not reached yet.
r2_sell_pricestringFill price of the 40% partial exit at Target 2; empty if not reached yet.
r3_pricestringTarget 3 price — the highest ladder level. When first reached, the strategy sells another 30% of the position.
r3_signal_tsint64Unix seconds when the price first reached Target 3 (30% partial exit executed); 0 if not reached yet.
r3_sell_pricestringFill price of the 30% partial exit at Target 3; empty if not reached yet.
statusstringServer-rendered progress narrative (entry → 40% partial exit at Target 2 → 30% at Target 3 → final close) — same text the App shows on swing-max/list. Localized by the "lang" body param (priority) or "lang" request header: omit both for English, "zh" / "zh-cn" = Simplified Chinese, "zh-tw" = Traditional Chinese. Empty on the closed list (stype≠1).
totalint32
POST/v1/openapi/analysis/swingmax/open
SwingmaxOpen

Returns every currently-open position in a single call by default. Static signals only — no kline, no realtime return, no company name/logo. Cheap, cached ~1 minute.

data.total is the count AFTER keyword filtering and BEFORE paging — divide it by size to get the page count. Paging past the last page returns an empty list with total unchanged, which is the normal way to detect the end, not an error.
Request parameters
FieldTypeRequiredDescription
pageint32no1-based. 0 or negative is treated as unset and means page 1.
sizeint32noRows per page. Omit to return every open position in one call — that is the historical behaviour of this endpoint and it is unchanged. Set it only if you want pages.
sort_typeint32no0 = endpoint default, 1 = latest first, 2 = oldest first, 3/4 = by potential_gain (target-based upside, NOT realised return), high/low first. The same number means the same thing on the US and HK endpoints.
keywordstringnoCase-insensitive substring match on ticker and code — this endpoint carries no company name. Omit to disable filtering. Max 64 characters.
langstringnoLocalizes server-rendered status text. Takes priority over the lang header.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisSwingmaxOpenDataResponse payload.
positionsAnalysisSwingmaxOpenPosition[]Every currently-open position.
symbolstring
codestring
buy_pricestringEntry / Buy Target.
stop_lossstring
target1stringSell Target 1 (r2).
target2stringSell Target 2 (r3).
potential_gaindoubleStatic: (r3/buy - 1) * 100, percent.
signal_timeint64Entry time, unix seconds.
last_exit_tsint64Exit time, unix seconds; 0 when open.
totalint32
Example request
POST https://api.alphio.ai/v1/openapi/analysis/swingmax/open
{}
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "positions":[
      {"symbol":"GME","code":"GME.N","buy_price":"21.715","stop_loss":"20.629",
       "target1":"24.252","target2":"28.152","potential_gain":29.6,
       "signal_time":1647388800,"last_exit_ts":0}
    ],
    "total": 1
  }
}

Swingmax (HK)

Swing-trade signals for Hong Kong equities. Same engine and same r2/r3 target ladder as the US endpoints, but a separate item shape: HK carries board_lot and trade_currency, which are meaningless for US equities. Amounts are in trade_currency, not always HKD.

POST/v1/openapi/analysis/swingmax/hk/signals
SwingmaxHKSignals

Current open swingmax positions for the given HK tickers. Mirrors /swingmax/signals on the US side, including the fact that it returns OPEN positions only. Until 2026-09-08 this endpoint also returned closed positions — the status filter was missing, so querying two tickers could return a decade of history alongside the live ones. If you were relying on that to read past trades, switch to /swingmax/hk/stocks with stype=2 (closed); that is the endpoint built for it.

Field names match US swingmax as of 2026-09-09: name is now company_name, buy_date/buy_price are entry_time/entry_price, sell_date/sell_price are exit_time/exit_price, and the r2_triggered/r3_triggered booleans are gone — use r2_signal_ts/r3_signal_ts > 0 instead. The booleans said that a target was hit but never when, so no marker could be placed on a chart. entry_time_ts and exit_time_ts are new. Also on 2026-09-09: profit_rate was renamed to return, and entry_price / exit_price / return became numbers instead of strings — all three now match US swingmax exactly. HK-specific fields (trade_currency, board_lot, realized, exit_reason, hold_days) are unchanged.
Open positions only — a ticker with no live position returns nothing here even if it traded many times before. Use /swingmax/hk/stocks (date range + stype) to browse history.
Bars arrive on this endpoint. They were empty from launch until 2026-09-07 — the field was in the response shape but nothing ever filled it, so callers got an empty array with no error and reasonably concluded HK had no bars. If you cached that conclusion, re-check.
Universe: ordinary shares and REITs only. Warrants, CBBCs, ETFs and LIPs are excluded — HK lists roughly 30k derivative warrants against 3k ordinary shares, so an unfiltered pool would be about 90% derivatives.
Additional filters: average daily turnover at least HKD 20M, close at least HKD 2, market cap at least HKD 3B. The price floor exists because the HK main board has no delisting rule equivalent to the US $1 threshold.
Amounts are in trade_currency, NOT always HKD. Check the field before aggregating across symbols.
Request parameters
FieldTypeRequiredDescription
tickersstring[]yesHK codes to query — 5 digits each, e.g. 00700.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisSwingmaxHKSignalsDataResponse payload.
signalsAnalysisSwingmaxHKItem[]One entry per matched ticker.
symbolstringHK code — always 5 digits, e.g. 00700.
codestringSymbol with the .HK suffix.
company_namestringCompany name, in the language of the listing.
trade_currencystringHKD / CNY / USD. HK has three trading counters; the same company can list under more than one symbol, so amounts are NOT comparable across symbols without checking this. HK-only field.
board_lotint32Shares per lot. HK trades in lots, not shares — 00700 is 100 shares/lot (~HKD 40k). 0 means the lot size could not be resolved. HK-only field.
entry_timestringSignal date, a Hong Kong trading day (YYYY-MM-DD).
entry_time_tsint64Entry time, unix seconds — midnight HKT on entry_time. Always > 0. Use this to place the entry marker; it saves parsing the date string.
entry_pricedoubleBuy target (breakout level), in trade_currency. The entry marker goes here. A number, not a string — matching US swingmax.
stop_lossstringSupport level. Entry minus 15%; moves up to the entry price once r2 triggers.
r2_pricestringSell Target 1 (first resistance).
r2_sell_pricestringActual r2 fill; empty when not triggered. This is the price to mark, not r2_price.
r2_signal_tsint64r2 trigger time, unix seconds. 0 means not triggered — draw the first target marker only when this is > 0. Same rule as US swingmax.
r3_pricestringSell Target 2 (second resistance).
r3_sell_pricestringActual r3 fill; empty when not triggered.
r3_signal_tsint64r3 trigger time, unix seconds. 0 means not triggered — draw the second target marker only when this is > 0.
exit_timestringExit date; empty while the position is still open.
exit_time_tsint64Exit time, unix seconds. 0 while the position is open — this one field carries both when it exited and whether it has exited, exactly as in US swingmax. There is no exit_signal_ts field in either market.
exit_pricedoubleFinal exit price. The exit marker goes here. 0 while the position is open — check exit_time_ts, not this, to tell open from closed.
returndoubleNet return of the WHOLE position, decimal fraction. Same field, same meaning and same type as US swingmax return. It was called profit_rate until 2026-09-09.
realizedstringReturn already banked by the scale-out, decimal fraction. This — not return — is the win indicator: realized > 0 means the trade counted as a win, matching how US swingmax reports its win rate. The two numbers differ materially, so do not mix them. HK-only field.
exit_reasonstringALERT = stopped at the original -15% stop (the only losing bucket). BREAKEVEN = r2 was hit, the stop moved up to the entry price, and it later stopped out at cost. R3 = took profit and gave back via the trailing stop. MAX_HOLD = held the full 60 trading days. HK-only field.
hold_daysint32Trading days held. HK-only field.
statusstringopen / closed.
klineAnalysisKlinePointV2[]Daily bars with full OHLC + volume — enough to draw candlesticks. Roughly the last 90 calendar days, ending today. Same source and format as the US endpoints. NOT returned by /swingmax/hk/open, which is built for pulling the whole list at once and would inflate several times over with bars.
closedouble
timestampint64Unix seconds.
opendouble
highdouble
lowdouble
volumedouble
Example request
POST https://api.alphio.ai/v1/openapi/analysis/swingmax/hk/signals
Authorization: Bearer pk_live_••••••••••••••••••••••••••••
{"tickers":["00700","09988"]}
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "signals":[
      {"symbol":"00700","code":"00700.HK","company_name":"腾讯控股","trade_currency":"HKD","board_lot":100,
       "entry_time":"2026-03-12","entry_time_ts":1773244800,"entry_price":402.4,"stop_loss":"402.4000000",
       "r2_price":"441.8000000","r2_sell_price":"441.8000000","r2_signal_ts":1775750400,
       "r3_price":"482.8800000","r3_sell_price":"","r3_signal_ts":0,
       "exit_time":"","exit_time_ts":0,"exit_price":0,"return":0,"realized":"0.0391000",
       "exit_reason":"","hold_days":31,"status":"open"}
    ]
  }
}
POST/v1/openapi/analysis/swingmax/hk/stocks
SwingmaxHKStocks

Browse HK swingmax signals over a date range. Mirrors /swingmax/stocks on the US side.

Field names match US swingmax as of 2026-09-09: name is now company_name, buy_date/buy_price are entry_time/entry_price, sell_date/sell_price are exit_time/exit_price, and the r2_triggered/r3_triggered booleans are gone — use r2_signal_ts/r3_signal_ts > 0 instead. The booleans said that a target was hit but never when, so no marker could be placed on a chart. entry_time_ts and exit_time_ts are new. Also on 2026-09-09: profit_rate was renamed to return, and entry_price / exit_price / return became numbers instead of strings — all three now match US swingmax exactly. HK-specific fields (trade_currency, board_lot, realized, exit_reason, hold_days) are unchanged.
Bars arrive on this endpoint. They were empty from launch until 2026-09-07 — the field was in the response shape but nothing ever filled it, so callers got an empty array with no error and reasonably concluded HK had no bars. If you cached that conclusion, re-check.
data.total is the count AFTER keyword filtering and BEFORE paging — divide it by size to get the page count. Paging past the last page returns an empty list with total unchanged, which is the normal way to detect the end, not an error.
Universe: ordinary shares and REITs only. Warrants, CBBCs, ETFs and LIPs are excluded — HK lists roughly 30k derivative warrants against 3k ordinary shares, so an unfiltered pool would be about 90% derivatives.
Additional filters: average daily turnover at least HKD 20M, close at least HKD 2, market cap at least HKD 3B. The price floor exists because the HK main board has no delisting rule equivalent to the US $1 threshold.
Amounts are in trade_currency, NOT always HKD. Check the field before aggregating across symbols.
Request parameters
FieldTypeRequiredDescription
stypeint32noGetSwingMaxStocksType. 1=open pool, 2=closed, 3=today's new signals, 4=today's still-open. 5 (today-updated) returns InvalidArgument on HK: the HK signal table records only entry_time, with no last-updated column to distinguish it.
sideint32no0=long. HK swingmax is long-only, so side=1 (short) returns InvalidArgument rather than an empty list — an empty list reads as "no signals today" and would leave you waiting for data that never comes.
trade_statusint32no0 or 2 (all). HK has no paper-trade execution tracking, so trade_status=1 (traded) returns InvalidArgument.
pageint64no1-based. 0 or negative is treated as unset and means page 1.
sizeint32noRows per page. Default 100, capped at 500.
sort_typeint32no0 = endpoint default, 1 = latest first, 2 = oldest first, 3/4 = by return (whole-trade net P&L), high/low first. Note this is NOT realized, which is the banked scale-out portion used for win-rate — the two differ materially. The same number means the same thing on the US and HK endpoints.
keywordstringnoCase-insensitive substring match on ticker, code and company name. Omit to disable filtering. Max 64 characters.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisSwingmaxHKStocksDataResponse payload.
stocksAnalysisSwingmaxHKItem[]One entry per signal. This array was called items until 2026-09-09; it is stocks now, matching US /swingmax/stocks. Reading the old key gets you nothing and no error — it looks like HK returned no data.
symbolstringHK code — always 5 digits, e.g. 00700.
codestringSymbol with the .HK suffix.
company_namestringCompany name, in the language of the listing.
trade_currencystringHKD / CNY / USD. HK has three trading counters; the same company can list under more than one symbol, so amounts are NOT comparable across symbols without checking this. HK-only field.
board_lotint32Shares per lot. HK trades in lots, not shares — 00700 is 100 shares/lot (~HKD 40k). 0 means the lot size could not be resolved. HK-only field.
entry_timestringSignal date, a Hong Kong trading day (YYYY-MM-DD).
entry_time_tsint64Entry time, unix seconds — midnight HKT on entry_time. Always > 0. Use this to place the entry marker; it saves parsing the date string.
entry_pricedoubleBuy target (breakout level), in trade_currency. The entry marker goes here. A number, not a string — matching US swingmax.
stop_lossstringSupport level. Entry minus 15%; moves up to the entry price once r2 triggers.
r2_pricestringSell Target 1 (first resistance).
r2_sell_pricestringActual r2 fill; empty when not triggered. This is the price to mark, not r2_price.
r2_signal_tsint64r2 trigger time, unix seconds. 0 means not triggered — draw the first target marker only when this is > 0. Same rule as US swingmax.
r3_pricestringSell Target 2 (second resistance).
r3_sell_pricestringActual r3 fill; empty when not triggered.
r3_signal_tsint64r3 trigger time, unix seconds. 0 means not triggered — draw the second target marker only when this is > 0.
exit_timestringExit date; empty while the position is still open.
exit_time_tsint64Exit time, unix seconds. 0 while the position is open — this one field carries both when it exited and whether it has exited, exactly as in US swingmax. There is no exit_signal_ts field in either market.
exit_pricedoubleFinal exit price. The exit marker goes here. 0 while the position is open — check exit_time_ts, not this, to tell open from closed.
returndoubleNet return of the WHOLE position, decimal fraction. Same field, same meaning and same type as US swingmax return. It was called profit_rate until 2026-09-09.
realizedstringReturn already banked by the scale-out, decimal fraction. This — not return — is the win indicator: realized > 0 means the trade counted as a win, matching how US swingmax reports its win rate. The two numbers differ materially, so do not mix them. HK-only field.
exit_reasonstringALERT = stopped at the original -15% stop (the only losing bucket). BREAKEVEN = r2 was hit, the stop moved up to the entry price, and it later stopped out at cost. R3 = took profit and gave back via the trailing stop. MAX_HOLD = held the full 60 trading days. HK-only field.
hold_daysint32Trading days held. HK-only field.
statusstringopen / closed.
klineAnalysisKlinePointV2[]Daily bars with full OHLC + volume — enough to draw candlesticks. Roughly the last 90 calendar days, ending today. Same source and format as the US endpoints. NOT returned by /swingmax/hk/open, which is built for pulling the whole list at once and would inflate several times over with bars.
closedouble
timestampint64Unix seconds.
opendouble
highdouble
lowdouble
volumedouble
totalint32
Example request
POST https://api.alphio.ai/v1/openapi/analysis/swingmax/hk/stocks
Authorization: Bearer pk_live_••••••••••••••••••••••••••••
{"stype":2,"page":1,"size":50,"sort_type":1}
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "stocks":[
      {"symbol":"00700","code":"00700.HK","company_name":"腾讯控股","trade_currency":"HKD","board_lot":100,
       "entry_time":"2026-03-12","entry_time_ts":1773244800,"entry_price":402.4,"stop_loss":"402.4000000",
       "r2_price":"441.8000000","r2_sell_price":"441.8000000","r2_signal_ts":1775750400,
       "r3_price":"482.8800000","r3_sell_price":"","r3_signal_ts":0,
       "exit_time":"2026-04-28","exit_time_ts":1777305600,"exit_price":402.4,
       "return":0.0391,"realized":"0.0391000",
       "exit_reason":"BREAKEVEN","hold_days":31,"status":"closed"}
    ],
    "total": 1
  }
}
POST/v1/openapi/analysis/swingmax/hk/open
SwingmaxHKOpen

Returns every currently-open HK position in a single call by default. Mirrors /swingmax/open on the US side, including the shared paging parameters.

This endpoint changed shape on 2026-09-09 to match US /swingmax/open field for field. It no longer returns the same item as /swingmax/hk/signals and /swingmax/hk/stocks. The same numbers now carry different names depending on which endpoint you call: buy_price is entry_price, target1 is r2_price, target2 is r3_price, signal_time is entry_time_ts, last_exit_ts is exit_time_ts. That split exists in US swingmax and HK now mirrors it, so the two markets' /open responses are interchangeable. Fields with no counterpart here — company_name, return, realized, exit_reason, hold_days, kline — are on /swingmax/hk/signals and /swingmax/hk/stocks.
data.total is the count AFTER keyword filtering and BEFORE paging — divide it by size to get the page count. Paging past the last page returns an empty list with total unchanged, which is the normal way to detect the end, not an error.
Universe: ordinary shares and REITs only. Warrants, CBBCs, ETFs and LIPs are excluded — HK lists roughly 30k derivative warrants against 3k ordinary shares, so an unfiltered pool would be about 90% derivatives.
Additional filters: average daily turnover at least HKD 20M, close at least HKD 2, market cap at least HKD 3B. The price floor exists because the HK main board has no delisting rule equivalent to the US $1 threshold.
Amounts are in trade_currency, NOT always HKD. Check the field before aggregating across symbols.
Request parameters
FieldTypeRequiredDescription
pageint32no1-based. 0 or negative is treated as unset and means page 1.
sizeint32noRows per page. Omit to return every open position in one call — that is the historical behaviour of this endpoint and it is unchanged. Set it only if you want pages.
sort_typeint32no0 = endpoint default, 1 = latest first, 2 = oldest first, 3/4 = by return (whole-trade net P&L, not the banked realized portion), high/low first. The same number means the same thing on the US and HK endpoints.
keywordstringnoCase-insensitive substring match on ticker, code and company name. Omit to disable filtering. Max 64 characters.
langstringnoLocalizes server-rendered status text. Takes priority over the lang header.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisSwingmaxHKOpenDataResponse payload.
positionsAnalysisSwingmaxHKOpenPosition[]Every currently-open HK position. Field for field the same shape as US /swingmax/open, including HK-only trade_currency and board_lot at the end.
symbolstringHK code — always 5 digits, e.g. 00700.
codestringSymbol with the .HK suffix.
buy_pricestringEntry / Buy Target, in trade_currency. Same number that /swingmax/hk/signals calls entry_price — a string here, a double there, because this endpoint mirrors US /swingmax/open.
stop_lossstringSupport level. Entry minus 15%; moves up to the entry price once target1 triggers.
target1stringSell Target 1 (r2). Same number /swingmax/hk/signals calls r2_price.
target2stringSell Target 2 (r3). Same number /swingmax/hk/signals calls r3_price.
potential_gaindoubleStatic: (target2/buy_price - 1) * 100, percent, rounded to 2 decimals. Identical computation to US swingmax, so the two markets' values are directly comparable. Note it measures the distance to target2, the FURTHER target — a position that already ran past target1 still reports the full distance to target2. This is what sort_type 3/4 sorts by on this endpoint.
signal_timeint64Entry time, unix seconds. Same number /swingmax/hk/signals calls entry_time_ts.
last_exit_tsint64Exit time, unix seconds; always 0 here since this endpoint returns open positions only.
trade_currencystringHKD / CNY / USD. buy_price and both targets are in this currency, so they are NOT comparable across symbols without checking it. HK-only field.
board_lotint32Shares per lot. HK trades in lots, not shares — 00700 is 100 shares/lot. 0 means the lot size could not be resolved. HK-only field.
totalint32Rows after filtering, before paging.
Example request
POST https://api.alphio.ai/v1/openapi/analysis/swingmax/hk/open
{}
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "positions":[
      {"symbol":"00700","code":"00700.HK","buy_price":"402.4","stop_loss":"342.04",
       "target1":"441.8","target2":"482.88","potential_gain":20,
       "signal_time":1787155200,"last_exit_ts":0,
       "trade_currency":"HKD","board_lot":100}
    ],
    "total": 1
  }
}

DayTrading (US)

Intraday signals for US equities. A different animal from Swingmax: signals fire on 15m/30m bars, a dozen or so a day, and most resolve within hours — Swingmax is a daily-bar swing strategy whose positions live for weeks. Poll accordingly.

POST/v1/openapi/analysis/daytrading/open
DaytradingOpen

Positions from one US trading session, open and closed. Which session: on a trading day before the US open (09:30 ET), and on any non-trading day, it is the previous trading session; from the open onward it is the current one, including after the close. Closed positions carry sell_price, sell_ts and a realized return_rate; open ones carry current_price and a live return_rate. NOTE: between the open and the first signal of the day (intraday signals only start at 10:00 ET), and on days when no signal fires at all, the current session is empty — that is expected, not an outage.

The status field is localized. The "lang" body param takes priority when set; otherwise the "lang" request header is used: omit both for English, "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Every other field (prices, timestamps) is language-independent.
The response array is data.list, as on all three daytrading endpoints. It was called positions on /open and signals on /signals until 2026-09-10. Reading the old key yields nothing and no error — it looks like the endpoint returned no data.
There is deliberately no time-range parameter. The signal set is small (about 2k rows for US in total), so page + total is enough to reach any record — and a hidden default window is a trap: callers who pass nothing get an empty list and conclude the endpoint is broken, which is exactly what happened when the HK history endpoint launched. Sort with sort_type, then walk the pages using total.
data.total is the count AFTER keyword filtering and BEFORE paging — divide it by size to get the page count. Paging past the last page returns an empty list with total unchanged, which is the normal way to detect the end, not an error.
Intraday signals fire only in two windows — 10:00-11:00 and 13:00-14:00 ET — and everything still open is force-closed at 15:50 ET. Outside US market hours this endpoint will usually return an empty list, which is correct, not an outage.
Request parameters
FieldTypeRequiredDescription
pageint32no1-based. 0 or negative is treated as unset and means page 1.
sizeint32noRows per page. Default 10, capped at 10 — DayTrading is polled frequently, so the page ceiling is deliberately lower than Swingmax's.
sort_typeint32no0 = endpoint default (by return_rate, high to low — realized for closed positions, live unrealized for open ones), 1 = latest first, 2 = oldest first, 3 = highest return first, 4 = lowest return first. The same number means the same thing on the US and HK endpoints.
keywordstringnoCase-insensitive substring match on ticker, code and company name. Omit to disable filtering. Max 64 characters.
langstringnoLocalizes the status text. When set it takes priority over the "lang" request header: "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Omit or leave empty to fall back to the header (English by default).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisDaytradingOpenDataResponse payload.
listAnalysisDaytradingPosition[]Every position of the session this endpoint is showing — open and closed. Field for field the same shape as /daytrading/signals and /daytrading/history.
idint64Signal id.
symbolstringBare code. US: NVDA. HK: five digits, e.g. 00700.
codestringSuffixed form. US: NVDA.O. HK: 00700.HK.
namestringCompany name.
logostringLogo URL; empty when unavailable.
intervalstringBar interval behind the entry, 15m or 30m.
signal_datestringSignal day on that market's trading calendar, YYYY-MM-DD. Derived from buy_ts in the market's own timezone — an HK 09:30 signal is still the previous day in New York.
signal_timestringHuman-readable trigger time, YYYY-MM-DD HH:MM:SS in the market's own timezone. Same format as on /daytrading/signals and /daytrading/history.
buy_tsint64Entry time, unix seconds.
buy_pricestringEntry price.
sell_tsint64Exit time, unix seconds; 0 while the position is still open. This endpoint returns every position of the session it shows, closed ones included, so closed rows carry their exit time.
sell_pricestringExit price; empty while the position is still open.
stop_loss_pricestringStrategy stop, entry × 0.97 — both markets stop at -3%. Without it you cannot reproduce the strategy.
current_pricestringLatest price.
return_ratestringCurrent return, percent.
statusstringHuman-readable progress text. Same field as on /daytrading/signals and /daytrading/history.
klinesAnalysisKlinePointV2[]Minute bars, same point shape as everywhere else in this API. Sorted by timestamp ascending (oldest first) — the same order in both markets, on all three daytrading endpoints, and as swingmax.
totalint32Rows after filtering, before paging.
Example request
POST https://api.alphio.ai/v1/openapi/analysis/daytrading/open
Authorization: Bearer pk_live_••••••••••••••••••••••••••••
{"page":1,"size":10,"sort_type":1}
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "list":[
      {"id":90211,"symbol":"NVDA","code":"NVDA.O","name":"NVIDIA Corp","logo":"https://.../nvda.png",
       "interval":"15m","signal_date":"2025-08-19","signal_time":"2025-08-19 10:00:00",
       "buy_ts":1755612000,"buy_price":"118.42","sell_ts":0,"sell_price":"",
       "stop_loss_price":"114.87","current_price":"119.80",
       "return_rate":"1.17","status":"Entered @118.42 and staying patient",
       "klines":[]}
    ],
    "total": 1
  }
}
POST/v1/openapi/analysis/daytrading/signals
DaytradingSignals

Raw signal records over a time range — what fired and how it resolved, as opposed to /daytrading/open which describes the current book.

The status field is localized. The "lang" body param takes priority when set; otherwise the "lang" request header is used: omit both for English, "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Every other field (prices, timestamps) is language-independent.
The response array is data.list, as on all three daytrading endpoints. It was called positions on /open and signals on /signals until 2026-09-10. Reading the old key yields nothing and no error — it looks like the endpoint returned no data.
Field names now match /daytrading/open and /daytrading/history — this endpoint used to expose dip_price / alert_price, which were the signal table's own column names. Only the names changed; the values map one-to-one. All three daytrading endpoints now return the same 17 fields; what differs is the rows, not the shape — this one carries in-flight signals, /history holds settled round-trips only.
There is deliberately no time-range parameter. The signal set is small (about 2k rows for US in total), so page + total is enough to reach any record — and a hidden default window is a trap: callers who pass nothing get an empty list and conclude the endpoint is broken, which is exactly what happened when the HK history endpoint launched. Sort with sort_type, then walk the pages using total.
data.total is the count AFTER keyword filtering and BEFORE paging — divide it by size to get the page count. Paging past the last page returns an empty list with total unchanged, which is the normal way to detect the end, not an error.
Keep the range short. This is an intraday strategy — a multi-week range is both slow and not what the data is for.
Historical win-rate figures are NOT exposed here on purpose: the internal historical analyzer currently evaluates past signals against today's stock universe, which is look-ahead biased. Do not derive strategy performance from a long backfill of this endpoint.
Request parameters
FieldTypeRequiredDescription
tickersAnalysisAsset[]noOptional exact filter by code. An array of OBJECTS, not of strings: [{"ticker":"00700"}]. Omit it to get every signal, which is what this endpoint did before the field existed. Matches both the bare code and the suffixed one, case-insensitively. Filtering happens before paging, so total is the filtered count.
asset_typeint32no0=stock, 1=etf, 2=crypto.
symbolstringnoLegacy field.
tickerstringnoPreferred field.
localestringno"US" / "HK".
pageint32no1-based. 0 or negative is treated as unset and means page 1.
sizeint32noRows per page. Default 10, capped at 10 — DayTrading is polled frequently, so the page ceiling is deliberately lower than Swingmax's.
sort_typeint32no0 = endpoint default, 1 = latest first, 2 = oldest first, 3/4 = by peak unrealized gain while the position was held, high/low first. That number is computed upstream and is no longer returned as a field — the three daytrading endpoints expose the same 17 fields and nothing else. The same number means the same thing on the US and HK endpoints.
keywordstringnoCase-insensitive substring match on the ticker code only — the signal table has no company-name column. Use /open if you need to search by name. Omit to disable filtering. Max 64 characters.
langstringnoLocalizes the status text. When set it takes priority over the "lang" request header: "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Omit or leave empty to fall back to the header (English by default).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisDaytradingSignalsDataResponse payload.
listAnalysisDaytradingSignalItem[]One entry per signal.
idint64
symbolstringBare code. US: NVDA. HK: five digits, e.g. 00700.
codestringSuffixed form. Empty on US — that pipeline has no ticker lookup on this path.
namestringCompany name. Populated on HK (real name from the HK code table). Empty on US.
logostringLogo URL. Empty on both: HK has no logo source, and the US pipeline is left untouched here.
intervalstringBar interval that produced the entry, 15m or 30m.
signal_datestringSignal day on that market's trading calendar, YYYY-MM-DD.
signal_timestringHuman-readable trigger time. HK only.
buy_tsint64Entry time, unix seconds.
buy_pricestringEntry signal price.
sell_tsint64Exit time, unix seconds. 0 while still open.
sell_pricestringExit signal price; empty while still open.
stop_loss_pricestringStrategy stop (entry × 0.97 — both markets stop at -3%).
current_pricestringLatest price; empty for settled signals.
return_ratestringPercent, not a fraction. Same name and meaning as on /open and /history.
statusstringHuman-readable progress/exit text — the same field as status on /open and /history.
klinesAnalysisKlinePointV2[]Minute bars centred on the entry. Sorted by timestamp ascending (oldest first) — the same order in both markets, on all three daytrading endpoints, and as swingmax.
totalint32
Example request
POST https://api.alphio.ai/v1/openapi/analysis/daytrading/signals
Authorization: Bearer pk_live_••••••••••••••••••••••••••••
{"page":1,"size":10,"sort_type":1}
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "list":[
      {"id":90211,"symbol":"NVDA","date":"2026-08-19","created_at":1755612000,
       "dip_price":"118.42","dip_time_interval":"15m","dip_timestamp":1755612000,
       "status":"booked","status_message":"Booked partial profits @121.97",
       "alert_timestamp":1755620100}
    ],
    "total": 1
  }
}
POST/v1/openapi/analysis/daytrading/history
DaytradingHistory

Closed round-trips — one row per completed entry-and-exit, with both prices, both timestamps and the realised return. Deliberately carries no K-line data. Call /v1/openapi/data/kline if you need bars — inlining them here would grow the payload by an order of magnitude for callers who only want the numbers.

The status field is localized. The "lang" body param takes priority when set; otherwise the "lang" request header is used: omit both for English, "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Every other field (prices, timestamps) is language-independent.
There is deliberately no time-range parameter. The signal set is small (about 2k rows for US in total), so page + total is enough to reach any record — and a hidden default window is a trap: callers who pass nothing get an empty list and conclude the endpoint is broken, which is exactly what happened when the HK history endpoint launched. Sort with sort_type, then walk the pages using total.
data.total is the count AFTER keyword filtering and BEFORE paging — divide it by size to get the page count. Paging past the last page returns an empty list with total unchanged, which is the normal way to detect the end, not an error.
Easy to confuse with /daytrading/signals: signals is the event log (what fired, what state it is in now), history is the P&L ledger (did this trade make money). Signals answers "what happened", history answers "how did it end".
When you pass a symbol, the most recent still-open position for that symbol is prepended as a synthetic row with exit_time, exit_price and return_rate all 0 — and it is inserted after paging, so that page can return size + 1 rows and total will not count it. The HK endpoint does not do this.
Filter on exit_time > 0 before computing any statistic. It is the only rule that holds for both markets, and it keeps those return_rate 0 rows from being counted as break-even trades in a win rate.
Request parameters
FieldTypeRequiredDescription
symbolstringnoOptional ticker, e.g. NVDA. Omit for all symbols. Passing one enables the synthetic open-position row described in the notes.
pageint32no1-based. 0 or negative is treated as unset and means page 1.
sizeint32noRows per page. Default 10, capped at 10 — DayTrading is polled frequently, so the page ceiling is deliberately lower than Swingmax's.
sort_typeint32no0 = endpoint default, 1 = latest first, 2 = oldest first. 3 and 4 (by return) return InvalidArgument here: this endpoint pages upstream, so sorting would only reorder the current page — sort client-side after fetching all pages instead. The same number means the same thing on the US and HK endpoints.
keywordstringnoExact ticker match, applied upstream before paging (the trades table has no name column). If symbol is also set, symbol wins — an exact filter should not be overridden by a fuzzy one. Omit to disable filtering. Max 64 characters.
langstringnoLocalizes the status text. When set it takes priority over the "lang" request header: "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Omit or leave empty to fall back to the header (English by default).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisDaytradingHistoryDataResponse payload.
listAnalysisDaytradingHistoryItem[]One entry per round-trip, newest entry first.
idint64
symbolstringBare code. US: NVDA. HK: five digits, e.g. 00700.
codestringSuffixed form. US: NVDA.O. HK: 00700.HK.
namestringCompany name.
logostringLogo URL; empty when unavailable.
intervalstringBar interval behind the entry, 15m or 30m.
signal_datestringSignal day on that market's trading calendar, YYYY-MM-DD.
signal_timestringHuman-readable trigger time.
buy_tsint64Entry time, unix seconds.
buy_pricestringEntry price.
sell_tsint64Exit time, unix seconds. 0 = not settled yet.
sell_pricestringExit price; empty when not settled.
stop_loss_pricestringStrategy stop price (HK daytrading stops at -3%). This was missing before — without it you cannot reproduce or check the strategy.
current_pricestringLatest price.
return_ratestringPercent, not a fraction: "2.35" means +2.35%. Same name and meaning as on /daytrading/open.
statusstringHuman-readable exit text. Same field as on /daytrading/open.
klinesAnalysisKlinePointV2[]Minute bars around the trade — the same series the product cards draw candlesticks from. Previously suppressed by this layer even though upstream always returned them. Sorted by timestamp ascending (oldest first) — the same order in both markets, on all three daytrading endpoints, and as swingmax.
totalint32Total rows matching the range, for paging. Excludes the synthetic open-position row.
Example request
POST https://api.alphio.ai/v1/openapi/analysis/daytrading/history
Authorization: Bearer pk_live_••••••••••••••••••••••••••••
Content-Type: application/json

{ "symbol": "NVDA", "page": 1, "size": 20 }
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "list": [
      {
        "id": 3521,
        "symbol": "NVDA",
        "code": "NVDA",
        "trade_date": "2026-08-19",
        "entry_time": 1755612000,
        "exit_time": 1755620100,
        "entry_price": "118.4200",
        "exit_price": "121.9700",
        "return_rate": "3.00",
        "interval": "15m",
        "exit_reason": "Booked 3.00% profits @121.97 at 11:35 AM"
      }
    ],
    "total": 1
  }
}

DayTrading (HK)

Intraday signals for HK equities. Same shape as the US feed but a SEPARATE pipeline end to end — its own process, its own signal table, its own switch. One market going down does not affect the other, which is also why the paths differ instead of taking a locale parameter. The strategy parameters are NOT the US ones: take profit at 0.5%, book on a 0.2% pull-back from the high, stop at -3%, and entries only fire while the market (equal-weighted intraday move across the pool) is below -0.8%. Those numbers were calibrated on HK data — the US set (3% / 1%) scored a 46.5% win rate with negative expectancy when replayed on HK bars. Sessions are 09:30-12:00 and 13:00-16:00 HKT; signal windows are 10:00-11:00 and 13:00-14:00, and anything still open is force-closed at 15:50.

POST/v1/openapi/analysis/daytrading/hk/open
DaytradingHKOpen

Positions from one Hong Kong trading session, open and closed. Which session: on a trading day before the HK open (09:30 HKT), and on any non-trading day, it is the previous trading session; from the open onward it is the current one, including after the close. `code` carries the .HK suffix (00700.HK); `symbol` is the bare five-digit number. Closed positions carry sell_price, sell_ts and a realized return_rate; open ones carry current_price and a live return_rate. NOTE: between the open and the first signal of the day (intraday signals only start at 10:00 HKT), and on days when the market-breadth gate never opens, the current session is empty — that is expected, not an outage.

The status field is localized. The "lang" body param takes priority when set; otherwise the "lang" request header is used: omit both for English, "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Every other field (prices, timestamps) is language-independent.
The response array is data.list, as on all three daytrading endpoints. It was called positions on /open and signals on /signals until 2026-09-10. Reading the old key yields nothing and no error — it looks like the endpoint returned no data.
There is deliberately no time-range parameter. The signal set is small (about 2k rows for US in total), so page + total is enough to reach any record — and a hidden default window is a trap: callers who pass nothing get an empty list and conclude the endpoint is broken, which is exactly what happened when the HK history endpoint launched. Sort with sort_type, then walk the pages using total.
data.total is the count AFTER keyword filtering and BEFORE paging — divide it by size to get the page count. Paging past the last page returns an empty list with total unchanged, which is the normal way to detect the end, not an error.
Intraday signals fire only in two windows — 10:00-11:00 and 13:00-14:00 HKT — and everything still open is force-closed at 15:50 HKT. Note the lunch break: the HK session runs 09:30-12:00 and 13:00-16:00, so the second window opens right at the afternoon bell. Outside HK market hours this endpoint will usually return an empty list, which is correct, not an outage.
Request parameters
FieldTypeRequiredDescription
pageint32no1-based. 0 or negative is treated as unset and means page 1.
sizeint32noRows per page. Default 10, capped at 10 — DayTrading is polled frequently, so the page ceiling is deliberately lower than Swingmax's.
sort_typeint32no0 = endpoint default (by return_rate, high to low — realized for closed positions, live unrealized for open ones), 1 = latest first, 2 = oldest first, 3 = highest return first, 4 = lowest return first. The same number means the same thing on the US and HK endpoints.
keywordstringnoCase-insensitive substring match on ticker, code and company name. Omit to disable filtering. Max 64 characters.
langstringnoLocalizes the status text. When set it takes priority over the "lang" request header: "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Omit or leave empty to fall back to the header (English by default).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisDaytradingOpenDataResponse payload.
listAnalysisDaytradingPosition[]Every position of the session this endpoint is showing — open and closed. Field for field the same shape as /daytrading/signals and /daytrading/history.
idint64Signal id.
symbolstringBare code. US: NVDA. HK: five digits, e.g. 00700.
codestringSuffixed form. US: NVDA.O. HK: 00700.HK.
namestringCompany name.
logostringLogo URL; empty when unavailable.
intervalstringBar interval behind the entry, 15m or 30m.
signal_datestringSignal day on that market's trading calendar, YYYY-MM-DD. Derived from buy_ts in the market's own timezone — an HK 09:30 signal is still the previous day in New York.
signal_timestringHuman-readable trigger time, YYYY-MM-DD HH:MM:SS in the market's own timezone. Same format as on /daytrading/signals and /daytrading/history.
buy_tsint64Entry time, unix seconds.
buy_pricestringEntry price.
sell_tsint64Exit time, unix seconds; 0 while the position is still open. This endpoint returns every position of the session it shows, closed ones included, so closed rows carry their exit time.
sell_pricestringExit price; empty while the position is still open.
stop_loss_pricestringStrategy stop, entry × 0.97 — both markets stop at -3%. Without it you cannot reproduce the strategy.
current_pricestringLatest price.
return_ratestringCurrent return, percent.
statusstringHuman-readable progress text. Same field as on /daytrading/signals and /daytrading/history.
klinesAnalysisKlinePointV2[]Minute bars, same point shape as everywhere else in this API. Sorted by timestamp ascending (oldest first) — the same order in both markets, on all three daytrading endpoints, and as swingmax.
totalint32Rows after filtering, before paging.
Example request
POST https://api.alphio.ai/v1/openapi/analysis/daytrading/hk/open
Authorization: Bearer pk_live_••••••••••••••••••••••••••••
{"page":1,"size":10,"sort_type":1}
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "list":[
      {"id":13,"symbol":"00522","code":"00522.HK","name":"ASMPT Ltd","logo":"https://.../00522.png",
       "interval":"30m","signal_date":"2026-09-10","signal_time":"2026-09-10 13:41:49",
       "buy_ts":1789018909,"buy_price":"164.40","sell_ts":0,"sell_price":"",
       "stop_loss_price":"159.47","current_price":"165.60",
       "return_rate":"0.73","status":"Entered @164.40 and staying patient",
       "klines":[]}
    ],
    "total": 1
  }
}
POST/v1/openapi/analysis/daytrading/hk/signals
DaytradingHKSignals

Raw signal records over a time range — what fired and how it resolved, as opposed to /daytrading/hk/open which describes the current book.

The status field is localized. The "lang" body param takes priority when set; otherwise the "lang" request header is used: omit both for English, "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Every other field (prices, timestamps) is language-independent.
The response array is data.list, as on all three daytrading endpoints. It was called positions on /open and signals on /signals until 2026-09-10. Reading the old key yields nothing and no error — it looks like the endpoint returned no data.
Field names now match /daytrading/open and /daytrading/history — this endpoint used to expose dip_price / alert_price, which were the signal table's own column names. Only the names changed; the values map one-to-one. All three daytrading endpoints now return the same 17 fields; what differs is the rows, not the shape — this one carries in-flight signals, /history holds settled round-trips only.
There is deliberately no time-range parameter. The signal set is small (about 2k rows for US in total), so page + total is enough to reach any record — and a hidden default window is a trap: callers who pass nothing get an empty list and conclude the endpoint is broken, which is exactly what happened when the HK history endpoint launched. Sort with sort_type, then walk the pages using total.
data.total is the count AFTER keyword filtering and BEFORE paging — divide it by size to get the page count. Paging past the last page returns an empty list with total unchanged, which is the normal way to detect the end, not an error.
Keep the range short. This is an intraday strategy — a multi-week range is both slow and not what the data is for.
Historical win-rate figures are NOT exposed here on purpose: the internal historical analyzer currently evaluates past signals against today's stock universe, which is look-ahead biased. Do not derive strategy performance from a long backfill of this endpoint.
Request parameters
FieldTypeRequiredDescription
tickersAnalysisAsset[]noOptional exact filter by code. An array of OBJECTS, not of strings: [{"ticker":"00700"}]. Omit it to get every signal, which is what this endpoint did before the field existed. Matches both the bare code and the suffixed one, case-insensitively. Filtering happens before paging, so total is the filtered count.
asset_typeint32no0=stock, 1=etf, 2=crypto.
symbolstringnoLegacy field.
tickerstringnoPreferred field.
localestringno"US" / "HK".
pageint32no1-based. 0 or negative is treated as unset and means page 1.
sizeint32noRows per page. Default 10, capped at 10 — DayTrading is polled frequently, so the page ceiling is deliberately lower than Swingmax's.
sort_typeint32no0 = endpoint default, 1 = latest first, 2 = oldest first, 3/4 = by peak unrealized gain while the position was held, high/low first. That number is computed upstream and is no longer returned as a field — the three daytrading endpoints expose the same 17 fields and nothing else. The same number means the same thing on the US and HK endpoints.
keywordstringnoCase-insensitive substring match on the ticker code only — the signal table has no company-name column. Use /open if you need to search by name. Omit to disable filtering. Max 64 characters.
langstringnoLocalizes the status text. When set it takes priority over the "lang" request header: "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Omit or leave empty to fall back to the header (English by default).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisDaytradingSignalsDataResponse payload.
listAnalysisDaytradingSignalItem[]One entry per signal.
idint64
symbolstringBare code. US: NVDA. HK: five digits, e.g. 00700.
codestringSuffixed form. Empty on US — that pipeline has no ticker lookup on this path.
namestringCompany name. Populated on HK (real name from the HK code table). Empty on US.
logostringLogo URL. Empty on both: HK has no logo source, and the US pipeline is left untouched here.
intervalstringBar interval that produced the entry, 15m or 30m.
signal_datestringSignal day on that market's trading calendar, YYYY-MM-DD.
signal_timestringHuman-readable trigger time. HK only.
buy_tsint64Entry time, unix seconds.
buy_pricestringEntry signal price.
sell_tsint64Exit time, unix seconds. 0 while still open.
sell_pricestringExit signal price; empty while still open.
stop_loss_pricestringStrategy stop (entry × 0.97 — both markets stop at -3%).
current_pricestringLatest price; empty for settled signals.
return_ratestringPercent, not a fraction. Same name and meaning as on /open and /history.
statusstringHuman-readable progress/exit text — the same field as status on /open and /history.
klinesAnalysisKlinePointV2[]Minute bars centred on the entry. Sorted by timestamp ascending (oldest first) — the same order in both markets, on all three daytrading endpoints, and as swingmax.
totalint32
Example request
POST https://api.alphio.ai/v1/openapi/analysis/daytrading/hk/signals
Authorization: Bearer pk_live_••••••••••••••••••••••••••••
{"page":1,"size":10,"sort_type":1}
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "list":[
      {"id":90211,"symbol":"09988","date":"2026-08-19","created_at":1755612000,
       "dip_price":"118.42","dip_time_interval":"15m","dip_timestamp":1755612000,
       "status":"booked","status_message":"Booked partial profits @121.97",
       "alert_timestamp":1755620100}
    ],
    "total": 1
  }
}
POST/v1/openapi/analysis/daytrading/hk/history
DaytradingHKHistory

Closed round-trips — one row per completed entry-and-exit, with both prices, both timestamps and the realised return. Deliberately carries no K-line data. Call /v1/openapi/data/kline if you need bars — inlining them here would grow the payload by an order of magnitude for callers who only want the numbers.

The status field is localized. The "lang" body param takes priority when set; otherwise the "lang" request header is used: omit both for English, "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Every other field (prices, timestamps) is language-independent.
There is deliberately no time-range parameter. The signal set is small (about 2k rows for US in total), so page + total is enough to reach any record — and a hidden default window is a trap: callers who pass nothing get an empty list and conclude the endpoint is broken, which is exactly what happened when the HK history endpoint launched. Sort with sort_type, then walk the pages using total.
data.total is the count AFTER keyword filtering and BEFORE paging — divide it by size to get the page count. Paging past the last page returns an empty list with total unchanged, which is the normal way to detect the end, not an error.
This endpoint is currently seeded with BACKTEST rows, not live fills. They are identifiable two ways: dip_id is negative (live signal ids are positive and auto-increment), and exit_reason starts with "Backtest:". Live rows begin appending from the 2026-09-08 session onward, into the same list.
What the backtest is: the production signal generator replayed over 5-minute bars for 414 HK names across 2026-06-10 to 2026-09-02 (63 sessions), with the live parameters — 0.5% take-profit, 0.2% trailing drawdown, -3% stop, entries only while the equal-weighted pool is down more than 0.8% on the day. 394 round-trips, 72.1% of them positive.
Backtest caveats that do not apply to live rows: fills are taken at bar prices rather than at the tick the live engine would have traded, and no transaction cost is deducted. HK round-trip cost is about 0.22%, which takes mean return per trade from +0.30% down to +0.081%. Do not present these figures as realised performance.
Easy to confuse with /daytrading/hk/signals: signals is the event log (what fired, what state it is in now), history is the P&L ledger (did this trade make money). Signals answers "what happened", history answers "how did it end".
exit_time = 0 means the round-trip is not settled yet — either still held, or the exit price was missing. Those rows carry return_rate 0 as well; treat 0/0 as "unknown", not as "broke even".
return_rate is gross in both kinds of row. The live writer derives it from alert_price / dip_price with no cost deducted, and the backtest rows follow the same convention on purpose — mixing gross and net in one column would make the two indistinguishable.
Request parameters
FieldTypeRequiredDescription
symbolstringnoOptional. Bare five-digit HK code (00700). Omit for all symbols.
pageint32no1-based. 0 or negative is treated as unset and means page 1.
sizeint32noRows per page. Default 10, capped at 10 — DayTrading is polled frequently, so the page ceiling is deliberately lower than Swingmax's.
sort_typeint32no0 = endpoint default, 1 = latest first, 2 = oldest first. 3 and 4 (by return) return InvalidArgument here: this endpoint pages upstream, so sorting would only reorder the current page — sort client-side after fetching all pages instead. The same number means the same thing on the US and HK endpoints.
keywordstringnoExact ticker match, applied upstream before paging (the trades table has no name column). If symbol is also set, symbol wins — an exact filter should not be overridden by a fuzzy one. Omit to disable filtering. Max 64 characters.
langstringnoLocalizes the status text. When set it takes priority over the "lang" request header: "zh" / "zh-cn" for Simplified Chinese, "zh-tw" for Traditional Chinese. Omit or leave empty to fall back to the header (English by default).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataAnalysisDaytradingHistoryDataResponse payload.
listAnalysisDaytradingHistoryItem[]One entry per completed round-trip, newest entry first.
idint64
symbolstringBare code. US: NVDA. HK: five digits, e.g. 00700.
codestringSuffixed form. US: NVDA.O. HK: 00700.HK.
namestringCompany name.
logostringLogo URL; empty when unavailable.
intervalstringBar interval behind the entry, 15m or 30m.
signal_datestringSignal day on that market's trading calendar, YYYY-MM-DD.
signal_timestringHuman-readable trigger time.
buy_tsint64Entry time, unix seconds.
buy_pricestringEntry price.
sell_tsint64Exit time, unix seconds. 0 = not settled yet.
sell_pricestringExit price; empty when not settled.
stop_loss_pricestringStrategy stop price (HK daytrading stops at -3%). This was missing before — without it you cannot reproduce or check the strategy.
current_pricestringLatest price.
return_ratestringPercent, not a fraction: "2.35" means +2.35%. Same name and meaning as on /daytrading/open.
statusstringHuman-readable exit text. Same field as on /daytrading/open.
klinesAnalysisKlinePointV2[]Minute bars around the trade — the same series the product cards draw candlesticks from. Previously suppressed by this layer even though upstream always returned them. Sorted by timestamp ascending (oldest first) — the same order in both markets, on all three daytrading endpoints, and as swingmax.
totalint32Total rows matching the range, for paging.
Example request
POST https://api.alphio.ai/v1/openapi/analysis/daytrading/hk/history
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{ "symbol": "00700", "page": 1, "size": 20 }
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "list": [
      {
        "id": 12,
        "symbol": "00700",
        "code": "00700.HK",
        "trade_date": "2026-09-08",
        "entry_time": 1788838200,
        "exit_time": 1788845400,
        "entry_price": "445.4000",
        "exit_price": "448.2000",
        "return_rate": "0.63",
        "interval": "15m",
        "exit_reason": "Booked 0.63% profits @448.20 at 12:30 PM"
      }
    ],
    "total": 1
  }
}

Whales tracker

Endpoints tracking institutional (13F) and Congressional holdings. entity_type: 1=institution, 2=congress member. seo_name is the stable partner-facing identifier. All return/chart values are decimal fractions (0.012 = +1.2%). Rankings are cached ~10s server-side.

POST/v1/openapi/whales/top-returns
TopReturns

Institutions ranked by the chosen period's return, descending. Institutions only — for congress members use Ranking with entity_type=2.

Request parameters
FieldTypeRequiredDescription
periodstringyes"1d" / "1w" / "1m" / "3m" / "1y".
limitint32yes1 – 50.
includestringnoComma-separated: "chart" (equity curve) / "holdings" (top_holdings ≤2 tickers + holding_count) / "performance" (sharpe_ratio + mdd) / "returns" (return_1d / return_1w / return_1m / return_1y). Empty = base fields only.
keywordstringnoFuzzy entity-name filter (matches names containing the keyword). Empty = no filtering.
sortstringno"<field>:<asc|desc>", one field at a time. Fields: total_return (the requested period's return), sharpe_ratio, return_1d, return_1w, return_1m, return_1y, mdd. Empty = period return, descending. Sorting works regardless of include — include only controls which fields are returned.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataWhalesTopReturnsDataResponse payload.
entitiesWhalesEntity[]Ranked by return_value descending by default; sort overrides the order.
namestringEntity display name.
actionstringCurrently always "Holding" on ranking endpoints; empty on FollowingRanking.
return_valuedoubleReturn for the requested period, decimal fraction (0.618 = +61.8%). TopReturnsByAsset always uses the 3m return.
top_holdingsWhalesHolding[]Largest positions, tickers only. Only populated when include contains holdings (capped at 2-3 tickers).
tickerstringTicker symbol.
holding_countint32Number of positions in the latest filing. 0 unless include contains holdings.
chartWhalesChartPoint[]Equity-curve points. Only populated when include contains chart.
datestringYYYY-MM-DD.
valuedoubleCumulative return since tracking began, decimal fraction (0.618 = +61.8%).
avatarstringCDN avatar URL.
entity_typeint321=institution, 2=congress.
seo_namestringStable slug — the partner-facing identifier, feed it to DetailsBySeoName.
sharpe_ratiodoubleSharpe ratio of the tracked portfolio. Only populated when include contains performance.
mdddoubleMaximum drawdown, computed from the equity curve. Positive decimal fraction (0.2 = 20% drawdown). Only populated when include contains performance.
return_1ddouble1-day return, decimal fraction (0.012 = +1.2%). Only populated when include contains returns.
return_1wdouble1-week return, decimal fraction. Only populated when include contains returns.
return_1mdouble1-month return, decimal fraction. Only populated when include contains returns.
return_1ydouble1-year return, decimal fraction. Only populated when include contains returns.
POST/v1/openapi/whales/ranking
Ranking

Ranking filtered by entity_type. Query one period (period → data.entities) or up to 4 at once (periods → data.period_groups).

top_holdings is always empty on this endpoint for partner API calls.
Sending both period and periods returns an InvalidArgument error.
Request parameters
FieldTypeRequiredDescription
periodstringnoSingle-period query: "1d" / "1w" / "1m" / "3m" / "1y". Exactly one of period / periods must be set.
periodsstring[]noMulti-period query: up to 4 unique values from the same set. Response returns one period_groups entry per requested period, in request order.
limitint32yes1 – 50 (applies to each period's list).
includestringnoComma-separated: "chart" (mini equity curve per entity) / "performance" (sharpe_ratio + mdd) / "returns" (return_1d / return_1w / return_1m / return_1y).
entity_typeWhalesEntityTypeyesINSTITUTION (1) / CONGRESS (2).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataWhalesRankingDataResponse payload.
entitiesWhalesEntity[]Populated for single-period requests.
namestringEntity display name.
actionstringCurrently always "Holding" on ranking endpoints; empty on FollowingRanking.
return_valuedoubleReturn for the requested period, decimal fraction (0.618 = +61.8%). TopReturnsByAsset always uses the 3m return.
top_holdingsWhalesHolding[]Largest positions, tickers only. Only populated when include contains holdings (capped at 2-3 tickers).
tickerstringTicker symbol.
holding_countint32Number of positions in the latest filing. 0 unless include contains holdings.
chartWhalesChartPoint[]Equity-curve points. Only populated when include contains chart.
datestringYYYY-MM-DD.
valuedoubleCumulative return since tracking began, decimal fraction (0.618 = +61.8%).
avatarstringCDN avatar URL.
entity_typeint321=institution, 2=congress.
seo_namestringStable slug — the partner-facing identifier, feed it to DetailsBySeoName.
sharpe_ratiodoubleSharpe ratio of the tracked portfolio. Only populated when include contains performance.
mdddoubleMaximum drawdown, computed from the equity curve. Positive decimal fraction (0.2 = 20% drawdown). Only populated when include contains performance.
return_1ddouble1-day return, decimal fraction (0.012 = +1.2%). Only populated when include contains returns.
return_1wdouble1-week return, decimal fraction. Only populated when include contains returns.
return_1mdouble1-month return, decimal fraction. Only populated when include contains returns.
return_1ydouble1-year return, decimal fraction. Only populated when include contains returns.
period_groupsWhalesRankingPeriodGroup[]Populated for multi-period requests, in the same order as req.periods.
periodstringThe requested period this group belongs to.
entitiesWhalesEntity[]Ranking list for this period.
namestringEntity display name.
actionstringCurrently always "Holding" on ranking endpoints; empty on FollowingRanking.
return_valuedoubleReturn for the requested period, decimal fraction (0.618 = +61.8%). TopReturnsByAsset always uses the 3m return.
top_holdingsWhalesHolding[]Largest positions, tickers only. Only populated when include contains holdings (capped at 2-3 tickers).
tickerstringTicker symbol.
holding_countint32Number of positions in the latest filing. 0 unless include contains holdings.
chartWhalesChartPoint[]Equity-curve points. Only populated when include contains chart.
datestringYYYY-MM-DD.
valuedoubleCumulative return since tracking began, decimal fraction (0.618 = +61.8%).
avatarstringCDN avatar URL.
entity_typeint321=institution, 2=congress.
seo_namestringStable slug — the partner-facing identifier, feed it to DetailsBySeoName.
sharpe_ratiodoubleSharpe ratio of the tracked portfolio. Only populated when include contains performance.
mdddoubleMaximum drawdown, computed from the equity curve. Positive decimal fraction (0.2 = 20% drawdown). Only populated when include contains performance.
return_1ddouble1-day return, decimal fraction (0.012 = +1.2%). Only populated when include contains returns.
return_1wdouble1-week return, decimal fraction. Only populated when include contains returns.
return_1mdouble1-month return, decimal fraction. Only populated when include contains returns.
return_1ydouble1-year return, decimal fraction. Only populated when include contains returns.
POST/v1/openapi/whales/top-returns-by-asset
TopReturnsByAsset

Reverse-lookup: institutions currently holding a specific ticker, ranked by their 3-month return (descending). return_value is always the 3m return.

Request parameters
FieldTypeRequiredDescription
assetWhalesAssetyesThe ticker to look up.
asset_typeint32no0=stock, 1=etf.
tickerstringyesTicker symbol, e.g. "AAPL".
localestringno"US" (default) / "HK".
includestringnoComma-separated: "chart" / "holdings" / "performance" / "returns". With holdings, the queried ticker is guaranteed to appear in top_holdings.
limitint32noDefaults to 6 when omitted.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataWhalesTopReturnsDataResponse payload.
entitiesWhalesEntity[]Ranked by 3m return, descending.
namestringEntity display name.
actionstringCurrently always "Holding" on ranking endpoints; empty on FollowingRanking.
return_valuedoubleReturn for the requested period, decimal fraction (0.618 = +61.8%). TopReturnsByAsset always uses the 3m return.
top_holdingsWhalesHolding[]Largest positions, tickers only. Only populated when include contains holdings (capped at 2-3 tickers).
tickerstringTicker symbol.
holding_countint32Number of positions in the latest filing. 0 unless include contains holdings.
chartWhalesChartPoint[]Equity-curve points. Only populated when include contains chart.
datestringYYYY-MM-DD.
valuedoubleCumulative return since tracking began, decimal fraction (0.618 = +61.8%).
avatarstringCDN avatar URL.
entity_typeint321=institution, 2=congress.
seo_namestringStable slug — the partner-facing identifier, feed it to DetailsBySeoName.
sharpe_ratiodoubleSharpe ratio of the tracked portfolio. Only populated when include contains performance.
mdddoubleMaximum drawdown, computed from the equity curve. Positive decimal fraction (0.2 = 20% drawdown). Only populated when include contains performance.
return_1ddouble1-day return, decimal fraction (0.012 = +1.2%). Only populated when include contains returns.
return_1wdouble1-week return, decimal fraction. Only populated when include contains returns.
return_1mdouble1-month return, decimal fraction. Only populated when include contains returns.
return_1ydouble1-year return, decimal fraction. Only populated when include contains returns.
POST/v1/openapi/whales/following/rankingX-Partner-User required
FollowingRanking

Ranks the entities the calling user follows (their watchlist) by the chosen period's return, descending. Requires X-Partner-User, like the watchlist endpoints.

A user's first-ever call auto-seeds their watchlist with the featured entities from Home.
Request parameters
FieldTypeRequiredDescription
periodstringyes"1d" / "1w" / "1m" / "3m" / "1y".
limitint32yes1 – 50. Truncates the sorted list.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataWhalesFollowingRankingDataResponse payload.
entitiesWhalesEntity[]Only name, return_value, avatar, entity_type and seo_name are populated here — no action / top_holdings / holding_count / chart / performance metrics.
namestringEntity display name.
actionstringCurrently always "Holding" on ranking endpoints; empty on FollowingRanking.
return_valuedoubleReturn for the requested period, decimal fraction (0.618 = +61.8%). TopReturnsByAsset always uses the 3m return.
top_holdingsWhalesHolding[]Largest positions, tickers only. Only populated when include contains holdings (capped at 2-3 tickers).
tickerstringTicker symbol.
holding_countint32Number of positions in the latest filing. 0 unless include contains holdings.
chartWhalesChartPoint[]Equity-curve points. Only populated when include contains chart.
datestringYYYY-MM-DD.
valuedoubleCumulative return since tracking began, decimal fraction (0.618 = +61.8%).
avatarstringCDN avatar URL.
entity_typeint321=institution, 2=congress.
seo_namestringStable slug — the partner-facing identifier, feed it to DetailsBySeoName.
sharpe_ratiodoubleSharpe ratio of the tracked portfolio. Only populated when include contains performance.
mdddoubleMaximum drawdown, computed from the equity curve. Positive decimal fraction (0.2 = 20% drawdown). Only populated when include contains performance.
return_1ddouble1-day return, decimal fraction (0.012 = +1.2%). Only populated when include contains returns.
return_1wdouble1-week return, decimal fraction. Only populated when include contains returns.
return_1mdouble1-month return, decimal fraction. Only populated when include contains returns.
return_1ydouble1-year return, decimal fraction. Only populated when include contains returns.
POST/v1/openapi/whales/details
Details

Full entity detail by id (from any ranking response).

Request parameters
FieldTypeRequiredDescription
idint32yes≥ 1.
includestringnoComma-separated: "chart" (equity curves), "trade_update" (recent trades + last_updated), "current_holdings" (sector distribution). Base fields and positions are always returned.
entity_typeWhalesEntityTypeyesINSTITUTION (1) / CONGRESS (2).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataWhalesEntityDetailsResponse payload.
namestringEntity display name.
is_watchedboolWhether the requesting user watches this entity. Always false on partner API calls — no user context is forwarded on this endpoint.
top20_holding_mvint64Aggregate market value (USD) of the entity's 20 largest positions, per the latest filing.
last_updatedstringDate (YYYY-MM-DD) of the most recent reported portfolio change. Only populated when include contains trade_update.
holding_countint32Number of positions currently held.
descriptionstringShort text description of the entity.
performanceWhalesPerformanceTracked-portfolio performance stats. Returns are decimal fractions (0.012 = +1.2%).
return_1ddoubleLatest 1-day return, decimal fraction.
sharpe_ratiodoubleSharpe ratio of the tracked portfolio.
total_returndoubleCumulative return since tracking began, decimal fraction.
annualized_returndoubleAnnualized return, decimal fraction.
chartsWhalesChartsEquity curves. Only populated when include contains chart.
strategyWhalesChartPoint[]Entity portfolio equity curve.
datestringYYYY-MM-DD.
valuedoubleCumulative return since tracking began, decimal fraction (0.618 = +61.8%).
sp500WhalesChartPoint[]S&P 500 benchmark over the same window.
datestringYYYY-MM-DD.
valuedoubleCumulative return since tracking began, decimal fraction (0.618 = +61.8%).
trade_updatesWhalesTradeUpdate[]Portfolio changes from the most recent rebalance/filing. Only populated when include contains trade_update.
datestringRebalance date, YYYY-MM-DD.
actionstring"buy" / "sell" / "hold" — derived from the weight change (rounded to 2 decimals).
tickerstringTicker symbol, e.g. "NVDA".
codestringExchange-qualified code, e.g. "NVDA.O".
namestringSecurity display name.
asset_typeint320=stock, 1=etf.
localestring"US" / "HK".
old_percentdoublePortfolio weight (%) before the change.
new_percentdoublePortfolio weight (%) after the change.
fill_pricedoublePrice at the rebalance date.
current_holdingsWhalesCurrentHoldingsCurrent portfolio. positions is always returned; sector_distribution requires include=current_holdings.
sector_distributionWhalesSectorWeight[]Sector weights of the current portfolio. Only populated when include contains current_holdings.
sectorstringSector name; "other" when unclassified.
weightdoubleWeight of the sector, in %.
positionsWhalesPosition[]All current positions.
tickerstringTicker symbol, e.g. "NVDA".
codestringExchange-qualified code, e.g. "NVDA.O".
namestringSecurity display name.
asset_typeint320=stock, 1=etf.
localestring"US" / "HK".
cost_pricedoubleAverage cost per share.
current_percentdoubleCurrent portfolio weight (%).
total_returndoubleCumulative return of the position since entry.
sector_distribution_descstringServer-generated text summary of the sector mix.
entity_typeint321=institution, 2=congress.
institution_profileWhalesInstitutionProfileOnly set for institutions (entity_type=1).
person_namestringFund manager / key person name.
avatarstringCDN avatar URL.
profilestringManager / institution bio.
investing_philosophystringInvesting-philosophy blurb.
congress_member_infoWhalesCongressMemberInfoOnly set for congress members (entity_type=2).
avatarstringAvatar URL.
partystringPolitical party, e.g. "Republican" / "Democrat".
organizationstringChamber, e.g. "Senate" / "House".
faqWhalesFAQInfo[]Server-generated FAQ entries derived from the stats above (holding count, returns, AUM).
questionstring
answerstring
POST/v1/openapi/whales/details-by-seo-name
DetailsBySeoName

Same as Details but keyed by stable seo_name (from any ranking / search / home response). Preferred when you cached an entity earlier.

Request parameters
FieldTypeRequiredDescription
seo_namestringyesStable entity slug, min_len 1.
includestringnoComma-separated: "chart" (equity curves), "trade_update" (recent trades + last_updated), "current_holdings" (sector distribution). Base fields and positions are always returned.
entity_typeWhalesEntityTypeyesINSTITUTION (1) / CONGRESS (2).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataWhalesEntityDetailsResponse payload.
namestringEntity display name.
is_watchedboolWhether the requesting user watches this entity. Always false on partner API calls — no user context is forwarded on this endpoint.
top20_holding_mvint64Aggregate market value (USD) of the entity's 20 largest positions, per the latest filing.
last_updatedstringDate (YYYY-MM-DD) of the most recent reported portfolio change. Only populated when include contains trade_update.
holding_countint32Number of positions currently held.
descriptionstringShort text description of the entity.
performanceWhalesPerformanceTracked-portfolio performance stats. Returns are decimal fractions (0.012 = +1.2%).
return_1ddoubleLatest 1-day return, decimal fraction.
sharpe_ratiodoubleSharpe ratio of the tracked portfolio.
total_returndoubleCumulative return since tracking began, decimal fraction.
annualized_returndoubleAnnualized return, decimal fraction.
chartsWhalesChartsEquity curves. Only populated when include contains chart.
strategyWhalesChartPoint[]Entity portfolio equity curve.
datestringYYYY-MM-DD.
valuedoubleCumulative return since tracking began, decimal fraction (0.618 = +61.8%).
sp500WhalesChartPoint[]S&P 500 benchmark over the same window.
datestringYYYY-MM-DD.
valuedoubleCumulative return since tracking began, decimal fraction (0.618 = +61.8%).
trade_updatesWhalesTradeUpdate[]Portfolio changes from the most recent rebalance/filing. Only populated when include contains trade_update.
datestringRebalance date, YYYY-MM-DD.
actionstring"buy" / "sell" / "hold" — derived from the weight change (rounded to 2 decimals).
tickerstringTicker symbol, e.g. "NVDA".
codestringExchange-qualified code, e.g. "NVDA.O".
namestringSecurity display name.
asset_typeint320=stock, 1=etf.
localestring"US" / "HK".
old_percentdoublePortfolio weight (%) before the change.
new_percentdoublePortfolio weight (%) after the change.
fill_pricedoublePrice at the rebalance date.
current_holdingsWhalesCurrentHoldingsCurrent portfolio. positions is always returned; sector_distribution requires include=current_holdings.
sector_distributionWhalesSectorWeight[]Sector weights of the current portfolio. Only populated when include contains current_holdings.
sectorstringSector name; "other" when unclassified.
weightdoubleWeight of the sector, in %.
positionsWhalesPosition[]All current positions.
tickerstringTicker symbol, e.g. "NVDA".
codestringExchange-qualified code, e.g. "NVDA.O".
namestringSecurity display name.
asset_typeint320=stock, 1=etf.
localestring"US" / "HK".
cost_pricedoubleAverage cost per share.
current_percentdoubleCurrent portfolio weight (%).
total_returndoubleCumulative return of the position since entry.
sector_distribution_descstringServer-generated text summary of the sector mix.
entity_typeint321=institution, 2=congress.
institution_profileWhalesInstitutionProfileOnly set for institutions (entity_type=1).
person_namestringFund manager / key person name.
avatarstringCDN avatar URL.
profilestringManager / institution bio.
investing_philosophystringInvesting-philosophy blurb.
congress_member_infoWhalesCongressMemberInfoOnly set for congress members (entity_type=2).
avatarstringAvatar URL.
partystringPolitical party, e.g. "Republican" / "Democrat".
organizationstringChamber, e.g. "Senate" / "House".
faqWhalesFAQInfo[]Server-generated FAQ entries derived from the stats above (holding count, returns, AUM).
questionstring
answerstring
POST/v1/openapi/whales/home
Home

Static editorial list of featured entities (ARK, Nancy Pelosi, Berkshire Hathaway, Soros, Renaissance, Pershing Square). Empty body.

Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataWhalesHomeDataResponse payload.
itemsWhalesHomeInfo[]Curated, fixed order — not a ranking.
namestringEntity display name.
coverstringCDN cover-image URL for the home card.
labelstringEditorial tag; currently always "Featured".
entity_typeint321=institution, 2=congress.
seo_namestringFeed to DetailsBySeoName.
POST/v1/openapi/whales/faq
FAQ

Static product-level FAQ about the Whales tracker, localized via Accept-Language (English default, Chinese supported). Not entity-specific — per-entity FAQ comes in Details.faq. Empty body.

Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataWhalesFAQDataResponse payload.
itemsWhalesFAQInfo[]Fixed question/answer list.
questionstring
answerstring
POST/v1/openapi/whales/watchlist/listX-Partner-User required
WatchlistList

List entities the user follows, with their returns across all periods. Requires X-Partner-User.

A user's first-ever call auto-seeds their watchlist with the featured entities from Home. If they later unfollow everything, the list stays empty.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataWhalesWatchlistListDataResponse payload.
itemsWhalesWatchlistItem[]One row per followed entity.
namestringEntity display name.
entity_typeint321=institution, 2=congress.
return_1ddouble1-day return, decimal fraction (0.012 = +1.2%).
return_7ddouble7-day return, decimal fraction.
return_1mdouble1-month return, decimal fraction.
return_3mdouble3-month return, decimal fraction.
return_1ydouble1-year return, decimal fraction.
avatarstringCDN avatar URL.
seo_namestringStable slug for DetailsBySeoName.
POST/v1/openapi/whales/watchlist/createX-Partner-User required
WatchlistCreate

Add an entity to the calling user's watchlist. Requires X-Partner-User.

Request parameters
FieldTypeRequiredDescription
idint32yesInternal numeric entity id, ≥ 1.
entity_typeWhalesEntityTypeyesINSTITUTION (1) / CONGRESS (2).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success.
msgstringStatus / error message.
POST/v1/openapi/whales/watchlist/deleteX-Partner-User required
WatchlistDelete

Remove an entity from the calling user's watchlist. Requires X-Partner-User.

Request parameters
FieldTypeRequiredDescription
idint32yesInternal numeric entity id, ≥ 1.
entity_typeWhalesEntityTypeyesINSTITUTION (1) / CONGRESS (2).
Response fields
FieldTypeDescription
retint32Business return code. 0 = success.
msgstringStatus / error message.

Market data

Raw market data endpoints powering Chat card details. Keyed by symbol; partner UIs typically fetch these on-demand when expanding a card.

POST/v1/openapi/data/valuation
DataValuation

Historical valuation time-series.

Request parameters
FieldTypeRequiredDescription
tickerstringyese.g. "AAPL".
valuation_typeint32yesEValuationType. 0=PE / 1=PB / 2=PS / 3=Price-to-FCF / 4=EV-EBITDA / 5=Price-to-OCF / 6=FCF-Yield / 7=EV-EBIT.
is_forwardboolnotrue=forward, false=trailing (default).
fromstringnoYYYY-MM-DD. Default last 1Y.
tostringnoYYYY-MM-DD. Default today.
localestringno"US" / "HK".
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataDataValuationDataResponse payload.
valuationDataValuationItem[]Time series.
tstringDate (YYYY-MM-DD).
vstringValuation value.
variance_infoDataVarianceInfoFive reference bands.
meanstring
variancestring
overvaluedstringmean + 1σ.
undervaluedstringmean − 1σ.
strongly_overvaluedstringmean + 2σ.
strongly_undervaluedstringmean − 2σ.
Example request
POST https://api.alphio.ai/v1/openapi/data/valuation
{ "ticker":"AAPL", "valuation_type":0, "from":"2025-06-01", "to":"2026-06-01", "locale":"US" }
Example response
{
  "ret": 0, "msg": "ok",
  "data": {
    "valuation":[{"t":"2025-06-01","v":"28.5"},{"t":"2025-06-02","v":"28.7"}, ...],
    "variance_info":{
      "mean":"30.2","variance":"3.1",
      "overvalued":"33.3","undervalued":"27.1",
      "strongly_overvalued":"36.4","strongly_undervalued":"24.0"
    }
  }
}
POST/v1/openapi/data/rating
DataRating

Analyst ratings.

Request parameters
FieldTypeRequiredDescription
tickerstringyese.g. "AAPL".
fromstringnoYYYY-MM-DD.
tostringnoYYYY-MM-DD.
pageint32no1-indexed.
sizeint32no1 – 100, default 20.
localestringno"US" / "HK".
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataDataRatingDataResponse payload.
resultsDataStockAnalysis
tickerstring
codestring
analysesDataAnalysisItem[]
rating_analyststring
rating_datestring
rating_actionstring"upgrade" / "downgrade" / "maintain" / "initiate".
rating_analyst_starsdouble
rating_analyst_firmstring
rating_price_targetstring
ratingstringe.g. "buy" / "hold".
rating_upsidedouble
analysis_summaryDataAnalysisSummaryAggregate snapshot.
codestring
symbolstring
average_price_targetstring
buyint32Count of buy ratings.
contentstring[]Highlight bullets.
highest_price_targetstring
holdint32Count of hold ratings.
lowest_price_targetstring
paginationDataPagination
current_pageint32
total_pagesint32
total_itemsint32
POST/v1/openapi/data/snapshot
DataSnapshot

Financial-metric snapshot (per-quarter or annual).

Request parameters
FieldTypeRequiredDescription
codestringyes
typeint32yesEFinancialIndicatorsType. 1=EPS / 2=Revenue / 3=ROE / 4=Gross Margin / 5=Net Margin / 6=Current Ratio / 7=Debt to Equity / 8=Operating Margin.
report_typeint32yesFinanceReportType. 1=annual / 2=quarterly.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataDataSnapshotDataResponse payload.
columnsDataSnapshotColumn[]Each column = one metric series.
namestring
valuesDataSnapshotValue[]One cell per period.
titlestringe.g. "Q1 2026".
valuedouble
cur_typestringCurrency / unit.
validboolfalse → missing data; render as "—".
POST/v1/openapi/data/kline
DataKline

OHLCV bars.

Request parameters
FieldTypeRequiredDescription
tickersWhalesAsset[]yesMax 20 per request.
asset_typeint32noSymbolType: 0=stock, 1=etf, 2=crypto, 3=commodity, 4=forex, 5=perp.
tickerstringnoe.g. "TSLA".
localestringno"US" / "HK".
fromstringnoYYYY-MM-DD (US-Eastern) or unix seconds.
tostringnoYYYY-MM-DD (US-Eastern) or unix seconds.
multiplierint32noe.g. 1, 5, 15.
timespanint32noTimespanOpt. 2=minute, 3=hour, 4=day, 5=week, 6=month, 7=quarter, 8=year. Values outside 2–8 are rejected.
limitint32noMax 1000. Default 500.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataDataKlineDataResponse payload.
seriesDataKlineSeries[]One series per requested ticker.
tickerstring
asset_typeint32
pointsDataKlinePoint[]OHLCV bars. Numbers are strings to avoid precision loss.
openstring
highstring
lowstring
closestring
volumestringTraded value (turnover) for the bar — per proto this is 成交额, not share count.
timestampint64Unix seconds.
Example request
POST https://api.alphio.ai/v1/openapi/data/kline
{
  "tickers":[ { "asset_type":0, "ticker":"TSLA", "locale":"US" } ],
  "from":"2026-06-09", "to":"2026-07-09",
  "multiplier":1, "timespan":4, "limit":30
}
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "series": [
      {
        "ticker": "TSLA",
        "asset_type": 0,
        "points": [
          {"open":"391.09","high":"396.14","low":"388.42","close":"394.26",
           "volume":"58231290","timestamp":"1783486800"}
        ]
      }
    ]
  }
}
POST/v1/openapi/data/price-prediction
DataPricePrediction

Historical OHLC bars backing the price-prediction card — no forecast fields in the payload itself. Request is a discriminated union by ticker_type; response has matching stock_data / crypto_data.

Request parameters
FieldTypeRequiredDescription
ticker_typestringyes"stock" / "etf" / "" → stock branch; "crypto" → crypto branch.
stockDataPricePredictionStockReqnoRequired when ticker_type is stock / etf / empty.
codestringnoTicker, e.g. "AAPL".
multiplierint32noTime multiplier.
timespanint32noTimespanOpt. 2=minute, 3=hour, 4=day, 5=week, 6=month, 7=quarter, 8=year.
timestampint64noAnchor end-time (unix seconds). Empty = now.
countint32noBars to return. Max 5000, recommended 800.
localestringno"US" / "HK".
cryptoDataPricePredictionCryptoReqnoRequired when ticker_type = "crypto".
typeint32noQueryType. 1=crypto spot, 2=etf, 3=crypto derivative (HL perps).
symbolstringno
multiplierint32no
timespanint32noTimespanOpt. 2=minute, 3=hour, 4=day, 5=week, 6=month, 7=quarter, 8=year.
limitint32no
start_timeint64noUnix seconds.
end_timeint64noUnix seconds.
symbol_liststring[]noBatch query — per-symbol series come back in crypto_data.infos.
localestringnoSource platform for multi-source assets, e.g. "HYPERLIQUID". Empty = default source.
Response fields
FieldTypeDescription
retint32Business return code. 0 = success, non-zero = error code (see Errors).
msgstringHuman-readable status / error message. "ok" on success.
dataDataPricePredictionDataResponse payload.
ticker_typestringEchoed back.
stock_dataDataPricePredictionStockDataPresent on the stock branch.
pointsDataPricePredictionStockPoint[]Historical bars, oldest first.
codestring
closedouble
highdouble
lowdouble
transactionsint64Share volume (per proto: 交易量).
opendouble
timestampint64Unix seconds.
volumedoubleTraded value / turnover (per proto: 成交额), not share count.
vwapdoubleVolume-weighted average price.
otcbool
pre_closedoublePrevious-period values (pre_* mirror the base fields).
pre_highdouble
pre_lowdouble
pre_transactionsint64
pre_opendouble
pre_timestampint64
pre_volumedouble
pre_vwapdouble
symbolstring
last_timeint64Unix seconds.
crypto_dataDataPricePredictionCryptoDataPresent on the crypto branch.
pointsDataPricePredictionCryptoPoint[]Bars for the primary symbol.
highdouble
opendouble
lowdouble
closedouble
timestampint64Unix seconds.
volumeint64Legacy integer volume — kept for old clients only.
volume_decimaldoublePreferred: float volume (needed for fractional assets like HL perps).
infosmap<string, DataPricePredictionCryptoSeries>Per-symbol series when symbol_list was provided.
Example request
POST https://api.alphio.ai/v1/openapi/data/price-prediction
{
  "ticker_type":"stock",
  "stock":{ "code":"AAPL", "multiplier":1, "timespan":4, "count":800, "locale":"US" }
}
Example response
{
  "ret": 0,
  "msg": "ok",
  "data": {
    "ticker_type": "stock",
    "stock_data": {
      "points": [
        {"code":"AAPL","close":195.5,"open":194.2,"high":196.1,"low":193.8,
         "timestamp":1717286400,"volume":48230000.0,"vwap":195.1,"otc":false}
      ],
      "last_time": 1717286400
    }
  }
}
POST/v1/openapi/data/screener/stock
DataScreenerStock

Stock screener. Request / response follow the upstream datafabric schema (chatfinbot.datafabric.v1.SelectStocksReq / SelectStocksRsp). Contact us for the full schema, or reuse a screenId returned by a Chat card.

POST/v1/openapi/data/screener/etf
DataScreenerETF

ETF screener. Uses chatfinbot.datafabric.v1.SelectEtfsReq / SelectEtfsRsp upstream.

POST/v1/openapi/data/screener/crypto
DataScreenerCrypto

Crypto screener. Uses chatfinbot.datafabric.v1.SelectCryptosReq / SelectCryptosRsp upstream.