OpenAPI Quote
Use this skill to construct, review, explain, or execute AInvest quote API requests. Determine the access scene first, then choose endpoint, auth header, symbol format, indicator attrs, and response interpretation rules. Keep answers request-focused: do not introduce unrelated coverage tooling, undocumented endpoints, or guessed indicator parameters.
Sandbox Aime Claw scene:
https://open.ainvest.com/market/extquote/index/indicator/v2/snapshothttps://open.ainvest.com/market/extquote/index/indicator/v2/serieshttps://open.ainvest.com/market/extquote/index/relation/v1/listhttps://open.ainvest.com/market/extquote/ag/quote/v2/multi_klinehttps://open.ainvest.com/market/extquote/ag/quote/v2/single_tick- auth header:
Authorization: Bearer <AIME_API_KEY> - default header:
X-Auth-ProgId: 7080
B-side scene:
http://quote-apisix-gateway.hxapisix/index_api/indicator/v2/snapshothttp://quote-apisix-gateway.hxapisix/index_api/indicator/v2/serieshttp://quote-apisix-gateway.hxapisix/index_api/relation/v1/listhttp://quote-apisix-gateway.hxapisix/quote/v2/multi_klinehttp://quote-apisix-gateway.hxapisix/quote/v2/single_tick- auth header:
apikey: <caller-provided apikey> - default header:
X-Auth-ProgId: 7080 - B-side apikey is application-scoped:
index_api/indicator/v2andindex_api/relation/v1endpoints normally use theindex-apiapp key, whilequote/v2endpoints normally use thequoteagapp key. Do not assume they are interchangeable. - Only require the apikey for the endpoint family being called. If the user only needs
snapshot,series, orrelation_list, do not ask forquoteag; if the user only needsmulti_klineorsingle_tick, do not ask forindex-api.
C-side scene:
https://extquote.ainvest.com/index_api/indicator/v2/snapshothttps://extquote.ainvest.com/index_api/indicator/v2/serieshttps://extquote.ainvest.com/index_api/relation/v1/listhttps://quote.ainvest.com/quote/v2/multi_klinehttps://quote.ainvest.com/quote/v2/single_tick- auth header:
Cookie: <caller-provided cookie> - default header:
X-Auth-ProgId: 7080
Supported markets:
- US stocks
- ETFs
- bonds
- crypto
- options
Supported data types:
- snapshot quote data
- historical series data
- relation lists such as ETF holdings, index components, prompt components, and group components
- minute or candlestick K-line data
- single-symbol tick-by-tick trade data
This skill focuses on request body design and response interpretation. When the user wants actual quote or relation data for a symbol, construct the request and fetch data directly when the selected scene has auth. Only sandbox Aime Claw reads auth from the environment variable AIME_API_KEY and composes Authorization: Bearer <AIME_API_KEY>. For B-side fetches, use the caller-provided apikey as the apikey header, choosing the index-api apikey for snapshot/series/relation_list and the quoteag apikey for multi_kline/single_tick. For C-side fetches, use the caller-provided Cookie string as the Cookie header. sw8 is handled by the client layer and does not need to be expanded unless the user explicitly asks.
When this skill is installed in the sandbox and the user asks for actual quote retrieval, prefer this skill over older indicator-only quote skills. This priority is especially important for minute K-line, 分时行情, 逐笔成交, and 成交明细 requests.
For actual local execution, use scripts/fetch_quote.py. It reads one request body from --template, --body-file, or --body-json, infers the endpoint when possible, and sends the request for --scene sandbox|b|c. Use --dry-run to print the endpoint, redacted headers, and body without sending a request.
For exported metric metadata, use scripts/export_indicators.py to pull the current AInvest-supported indicator workbook from Tangram into references/generated/export_metric_meta_new.xlsx inside this skill, then use scripts/build_quote_csvs.py to build generated CSV indexes and scripts/find_quote_params.py to search references/generated/quote_request_lookup.csv. If Tangram access is unavailable, use the newest trusted workbook already present at references/generated/export_metric_meta_new.xlsx or pass an explicit workbook with build_quote_csvs.py --input <path>. Generated rows use Tangram column C *IndexAPI代码 as the request indicator_id. The generated attrs_json comes from column S 扩展属性; legacy attr requirements from references/legacy/id_dict.md are still the first priority when present. Always send attr.time_period in lowercase, for example day_1 or min_5. Treat generated CSVs as lookup aids, not as a reason to mix incompatible categories or skip required symbol/auth checks.
Current Tangram export columns are authoritative for generated lookup metadata: use column C *IndexAPI代码 as indicator_id; use column S 扩展属性 as the primary attr source; use column U 支持排序; use column Z 接入指南标签 to choose snapshot/series and time_range; use column AA 证券实体类型 for category/symbol handling; use column AB 交易所 for exchange context. For periods, prefer time_period values from column S attrs, and fall back to id_router.yaml only when column S does not define time_period.
At the first use of this skill in each conversation, run scripts/export_indicators.py --status before metric lookup or request construction. Tell the user how long ago the local Tangram workbook was updated, or that it is missing, and ask whether to update it now. Do this only once per conversation unless the user explicitly asks for freshness again. If the user asks to update, refresh, or rebuild local indicator metadata, run scripts/export_indicators.py --rebuild-csvs and report whether the workbook export and generated CSV rebuild succeeded. Do not silently use stale generated lookup data without the first-use freshness notice.
Quick workflow
- Classify the request as one of: watchlist, ranking list, stock detail snapshot, related symbols, relation list, industry linkage, ETF holdings, historical series, minute K-line, or single-symbol tick details.
- Decide whether the user wants a request body only or an actual data fetch.
- If the user wants actual quote or relation data, pick the scene first: sandbox Aime Claw, B-side, or C-side.
- Use sandbox by default only when the user context is the sandbox/Aime Claw environment or no B/C context is provided.
- Use B-side when the user mentions B-side, internal gateway, apisix, service-to-service, or
quote-apisix-gateway.hxapisix. - Use C-side when the user mentions C-side, browser/client, web, cookie auth, or public quote domains.
- For sandbox, check whether
AIME_API_KEYis available. - For B-side or C-side, extract the caller-provided apikey or Cookie from the current user request or prior conversation context.
- If the selected scene has the required auth, build the request and fetch data directly.
- Compose the scene-specific auth header.
- If auth is unavailable, fall back to request construction and explain which env/header is missing.
- Choose the endpoint:
- Use
snapshotfor realtime values, rankings, related symbols, constituents, subsectors, and holdings. - Use
relation_listfor a plain list of related codes or ids without indicator values, such as ETF holding codes, index components, prompt components, or group components. - Use
seriesfor continuous historical points such as past 30-day NAV or premium series. - Use
multi_klinefor K-line, candlestick, minute-bar, and分时行情requests. When the user asks for分时行情, build a minute K-line request such asmin_1ormin_5. For full same-day minute data, prefertime_range = {"trade_date": 0, "date_offset": 0}. - Use
single_tickfor逐笔成交,成交明细, or time-and-sales requests.
- Use
- Confirm the market context when relevant: US stock, ETF, bond, crypto, or option. Use this to choose suitable symbol examples, indicators, and attrs.
- Resolve user-provided security or industry text before choosing the symbol source:
- When the user input contains a direct code, Ticker, security Chinese/English name, ETF name, bond name, crypto symbol, option symbol, industry Chinese/English name, or industry alias, first use the
ainvest-marketcodeskill to resolve it into an AInvestmarket_codeif that skill is installed. - If
ainvest-marketcodeis unavailable, ask for an explicit AInvestmarket_codeor use a caller-provided resolved market code. Do not guess a market code from ticker/name text. - Treat this resolution as a required upstream step for
security, related-symbol, holdings, K-line, and tick requests that need a concrete tradable symbol or industry code. - If the user already provides an explicit AInvest
market_codesuch as185:AAPL, use it directly and do not re-resolve unless ambiguity remains. - Do not call
ainvest-marketcodeformarket_envindicators, because macro or market-environment metrics do not require a market code.
- When the user input contains a direct code, Ticker, security Chinese/English name, ETF name, bond name, crypto symbol, option symbol, industry Chinese/English name, or industry alias, first use the
- Choose the symbol source:
market_codefor watchlists and stock detail pages.market,block_id, orprompt_idfor ranking pools.prompt_idwithattr.market_codefor related stocks or ETFs.link_codewithattr.link_typefor industry constituents, subsectors, and ETF holdings.relation_listuses top-levelsymbolplussymbol_type, not the snapshotsymbolarray; supportedsymbol_typevalues aremarket_code,prompt_id, andgroup_id.code_listformulti_klineandsingle_tick. Split a directmarket_codesuch as185:AAPLintomarket = "185"andcodes = ["AAPL"].
- For metric lookup requests, search generated CSV first:
- On the first use of this skill in the current conversation, run
scripts/export_indicators.py --status, summarize local workbook freshness, and ask whether to update before continuing. - If the user asks to update local Tangram data or rebuild generated lookup CSVs, run
scripts/export_indicators.py --rebuild-csvsbefore searching. - Run
scripts/find_quote_params.py --query <metric text or id>whenreferences/generated/quote_request_lookup.csvexists. - Use the returned
indicator_id,endpoint,access_guide,category,symbol_type,exchange,attrs_json, andtime_range_jsonas the primary request-construction fields. - Treat the returned
templateas a non-authoritative scenario hint only. It can suggest a nearby JSON starting point, but do not let it overrideendpoint,access_guide, symbol rules, attrs, time_range, or the user's actual scenario. - Treat legacy
references/legacy/id_dict.mdas the first priority for seriestime_rangeshape. If the legacy table saysbegin_end, use{"type":"begin_end","begin_time":<recent_trading_day_ms>,"end_time":0,...}by default;begin_time = 0andend_time = 0means full-history retrieval and should be avoided unless the user explicitly asks.begin_timeand non-zeroend_timemust be millisecond timestamps, not seconds. If it saystrade_date = 0, use{"type":"trade_date","trade_date":0,...}; otherwise use the generated/defaultend_countform. - Preserve nested
tech_param.childrenand other structured attrs fromattrs_jsonwhen composing the indicatorattr. - For
event_id, look up candidate IDs inreferences/event_id_index.csvfirst, then inspectreferences/event_id.mdfor the surrounding event meaning. - For
tech_param, first reuse the working examples inreferences/tech_param_retry_request.jsonwhen the indicator id is present there; otherwise consultreferences/tech.mdand keep the parameter structure required by the selected technical indicator. - For interval phrases such as
5分钟区间涨幅, choose the intervalinr-*metric and map the time phrase intoattr.time_period; do not treat the time phrase as part of the metric alias. - For
market_envrows, do not look up or require market codes and do not includesymbol; query market-environment indicators separately fromsecurityindicators. If a query needs both categories, build separate request bodies. - If no generated CSV row matches, use the split indicator references in
references/, then fall back toreferences/legacy/id_dict.md.
- On the first use of this skill in the current conversation, run
- Build
indicatorentries and always includereq_unique_id;req_unique_idmust be unique within the same request, because duplicates are rejected as request errors. - Add control fields:
snapshot:pageis required; includesortandfilteronly when needed.relation_list:pageis optional; include it only when the result list should be paged.sortandfilterare not supported.series: choose a supportedtime_rangetype for the requested indicator.multi_kline: choose a validtime_period,time_range, and optionaladjust_type.single_tick: use the supportedtime_rangecombinationtrade_date = 0,count, andend_time.
- Warn only on parameter errors or unsupported combinations. Do not treat empty values as request errors.
Fixed business rules
- Endpoint paths are fixed by request type, but the host/base path depends on the scene: sandbox, B-side, or C-side.
- Direct sandbox fetches require
Authorization: Bearer <AIME_API_KEY>. - Direct B-side fetches require an
apikeyheader supplied by the caller; do not read it from a default environment variable. Use theindex-apiapikey forsnapshot,series, andrelation_list, and thequoteagapikey formulti_klineandsingle_tick. Do not require both apikeys unless the user request actually calls both endpoint families. - Direct C-side fetches require a
Cookieheader supplied by the caller; do not read it from a default environment variable. - All request scenes should include the default header
X-Auth-ProgId: 7080. - Do not write caller-provided Cookie or apikey values into repository docs, templates, or durable files.
- Do not rely on scripts that are not present in this skill directory. The supported local scripts are listed in the Scripts section.
- Watchlists keep user-added order by default, so omit
sortunless the user explicitly asks to sort. related stockandrelated ETFqueries useprompt_idplusattr.market_code.- Industry constituents and subsectors use
link_code. - ETF holdings use
link_codewithattr.link_type = "holding"andvaluemust contain exactly one ETF code. 分时行情should be built as a minutemulti_klinerequest, notsingle_trend.single_tickis for one symbol only.multi_klinesupports at most 16 symbols per request and at most 2000 returned K-line rows per request.- crypto and options only support
trade_class = "intraday"for these basic quote requests. - US stocks and indices support
pre_market,intraday, andpost_market. - Empty values are acceptable. Example: an option-only indicator queried on an ETF may return null or empty data.
relation_listonly supportsrelation = "holding"or"component"andsymbol_type = "market_code","prompt_id", or"group_id". It returns list items asdata.data[].v;data.symbol_typedescribes the returned item type and may differ from the requestsymbol_type.relation_listholdingonly expands ETF holdings forsymbol_type = "market_code"; holding requests for prompt/group symbols can validly return an empty list.- Invalid indicators are silently absent from the response; do not assume one returned item per requested indicator.
- Frontend display rule: when response
attr.value_typeisratioorratio2, display the value with%. - For exported metric metadata, prefer
references/generated/quote_request_lookup.csvwhen it exists. Then use the split indicator references inreferences/, then fall back toreferences/legacy/id_dict.mdfor uncovered metrics. The dictionary is not complete, so do not block on missing ids and do not try to validate all indicators exhaustively. - Keep interval metric aliases time-neutral. For example,
inr-price_change_ratio_pct-summay have aliases like区间收盘价涨幅and区间涨幅, but not5分钟区间涨幅; parse5分钟intotime_period=MIN_5at query time. - When a request needs a concrete symbol and the user provides a code, Ticker, security name, ETF name, bond name, crypto/option symbol, industry name, or industry alias, resolve it with
ainvest-marketcodebefore composing the quote request when that skill is available. If it is not available, require an explicit AInvestmarket_codeor caller-provided resolved code. Use the resulting AInvestmarket_codeas the source of truth formarket_codesymbols and for splitting intomarket+codesinmulti_kline/single_tick. - Keep
market_envandsecurityrequests separate.market_envindicators such as crypto dominance, fear/greed, and altcoin season index do not need market codes; their snapshot bodies can omitsymbol. - For
series.time_range.type = "begin_end",begin_timeand non-zeroend_timeare millisecond timestamps.end_time = 0means latest/current endpoint-supported end time. Do not send second-level Unix timestamps forbegin_end. Avoidbegin_time = 0withend_time = 0unless the user explicitly wants all history. - Send
attr.time_periodvalues in lowercase. Uppercase values from old dictionaries or Excel exports must be normalized before request execution. - For option call/put volume and turnover indicators
volume_call,turnover_call,volume_put, andturnover_put, include the indicator attrsend_count = {"end_time": 0, "count": 1}or{"end_time": 0, "count": 2}andtrade_date = 0. These attrs are required even when the rest of the request is a normalsnapshotindicator body.
Output expectations
When generating an answer, prefer this order:
- State whether this will be a live fetch or a request-construction-only answer.
- If live fetch is possible, state the scene and auth header shape used, without exposing the secret value.
- State which endpoint to use and why.
- Provide the request body.
- If a live fetch is not possible, call out the missing header or execution requirement.
- Mention response mapping details if relevant:
req_unique_idis the stable mapping key.snapshotmissing values may appear as{"v": null}.seriesmissing historical data may appear as an empty array.relation_listreturns relation items underdata.data[].v, with total count underdata.page.total.multi_klinereturns rows underdata.quote_data[].value[].single_tickreturns trade-print rows underdata.quote_data[].value[].
Live fetch response format
When a live fetch is performed, keep the answer concise and structured around the fetched result instead of dumping the full raw JSON.
Preferred order:
- State that live data was fetched and identify the endpoint.
- State which auth/header path was used:
- used sandbox
Authorization: Bearer <AIME_API_KEY>, B-sideapikey, or C-sideCookie - mention any additional request headers only if they matter for the request
- used sandbox
- Summarize the requested symbol, main indicators, and returned values.
- Include the request body when it helps reproducibility.
- Only mention raw response details that affect interpretation, such as null values, missing indicators, or empty series.
For snapshot live fetches, prefer a compact value summary such as:
- symbol
- indicator name
- returned value
- whether the value was null
For series live fetches, prefer a compact trend summary such as:
- symbol
- indicator name
- point count
- time range mode
- first and last point when useful
For relation_list live fetches, prefer a compact list summary such as:
- requested relation and source symbol
- returned
symbol_type - total count
- first few returned
vvalues when useful
For multi_kline live fetches, prefer a compact bar summary such as:
- symbol
time_period- returned bar count
- first and last bar time when useful
- latest close or OHLC summary when useful
For single_tick live fetches, prefer a compact trade summary such as:
- symbol
- returned trade count
- most recent trade time
- most recent trade price
- recent trade side and size when useful
Do not paste the entire raw response unless the user explicitly asks for it.
If the API returns an error during a live fetch:
- State that the live fetch failed.
- Include
status_codeandstatus_msgif available. - Identify whether the problem is auth-related, parameter-related, or data-related.
- If helpful, provide the corrected request body or the missing header requirement.
If scene auth is unavailable:
- State that a live fetch was not attempted because the required auth source is missing.
- Provide the request body the user can run.
- Call out the required header for the selected scene.
References
- Reference entry point:
references/index.md - Routing and endpoint choice:
references/routing.md - Snapshot rules and limits:
references/snapshot.md - Series rules and limits:
references/series.md - Basic minute K-line and tick rules:
references/basic-quote.md - Relation list rules and examples:
references/relation.md - Symbol source selection:
references/symbols.md - Frontend display and null handling:
references/display.md - Quote scenario patterns:
references/scenarios.md - Manual test headers and production curl example:
references/testing.md - Live fetch success examples:
references/live-fetch-examples.md - Template authoring rules:
references/template-writing.md - Indicator attrs:
references/indicator-attrs.md - Snapshot indicator quick reference:
references/snapshot-indicators.md - Series indicator quick reference:
references/series-indicators.md - Business pool quick reference:
references/business-pools.md - Generated metric lookup CSVs:
references/generated/ - Full legacy indicator dictionary:
references/legacy/id_dict.md - Event id lookup index:
references/event_id_index.csv - Event id full reference:
references/event_id.md - Technical indicator parameter reference:
references/tech.md - Technical indicator retry examples:
references/tech_param_retry_request.json - Template lookup by scenario:
references/template-index.md - Raw basic quote protocol reference:
references/gms-http-v2.md - Legacy raw protocol references:
references/legacy/snapshot_cf.md,references/legacy/series_cf.md
Assets
Use the JSON files in assets/request-templates/ as starting points for the main quote scenarios. Adjust indicators and sort fields based on the user request instead of rewriting from scratch.
Scripts
scripts/fetch_quote.py: execute one quote request from a template or JSON body. Supports--scene sandbox|b|c; sandbox usesAIME_API_KEY, B-side accepts--index-api-apikeyor--quoteag-apikey, and C-side requires caller-provided--auth-valueunless--dry-runis used.scripts/export_indicators.py: check freshness with--status, export the current AInvest-supported Tangram indicator workbook toreferences/generated/export_metric_meta_new.xlsx, and rebuild generated lookup CSVs with--rebuild-csvs.scripts/build_quote_csvs.py: buildid_dict_quote.csvandquote_request_lookup.csvfrom the exported metric metadata workbook.scripts/find_quote_params.py: search generated request parameters by metric id, source code, Chinese name, or English name.scripts/validate_templates.py: validate request templates and basicfetch_quote.py --dry-runendpoint inference.
