Skip to main content

股票关联的概念是老标签还是新叙事:get_stock_concept_heat 首末提及时间的 10 个问答

Updated 3 min readMarkdown

摘要

熔岩(Lava)概念板块热度有两个方向:「概念 → 个股」由 get_concept_stock_heat(/concepts/stocks)负责,「个股 → 概念」由 get_stock_concept_heat(GET /concepts/by-stock)负责。后者对一只股票返回它在回看期内关联的各个概念,以及每个概念被提到几次、第一次和最近一次被提到的时间、有多少机构/大V 提到。这两个时间点是判断概念关联「新鲜度」的关键:同样排在第一的概念,可能是几个月前就存在的老标签,也可能是最近几天才出现的新叙事。本文用 10 个问答讲清参数、时间字段的读法、新鲜度分档方法以及与其他熔岩数据板块的配合。文中数字均为示例,分档结果是描述性标签。

一、接口速查

项目 内容
HTTP 路径 /concepts/by-stock
MCP 工具 get_stock_concept_heat
股票标识 ts_code(如 300750.SZ)或 stock_name,二选一
days 回看天数,默认 90,范围 1~365
limit 返回条数,默认 30,最大 200
每行内容 概念名、被提到次数、第一次被提到时间、最近一次被提到时间、机构/大V 数
计费 每次 0.005 元,非 2xx 不计费

每行字段的具体列名以 OpenAPI 为准;下文为了表述方便,把两个时间记作「首提时间」与「最近时间」,把计数记作 mentions 与 agencies。

二、参数类问答

Q:days 默认 90,和概念成分排行的默认 30 为什么不同?
A:两个接口回答的问题不同。/concepts/stocks 关注某概念「最近谁被提得多」,默认 30 天;/concepts/by-stock 关注一只股票「挂了哪些概念」,需要更长的回看才能看到完整的概念画像,默认 90 天。两者 days 都可以显式指定,引用结果时写上取值即可。

Q:limit 默认 30 够用吗?
A:对大多数股票够用;被广泛讨论的股票可能关联上百个概念。如果目的是做新鲜度分档,建议 limit=200,否则排在 30 名以后的新概念可能被截掉——新概念初期提及数少,恰恰最容易排在后面。

Q:用 stock_name 还是 ts_code?
A:优先 ts_code。简称可能变更或重名,代码可以直接与自有行情、行业数据关联。

三、时间字段类问答

Q:「首提时间」是这个概念第一次和该股关联的时间吗?
A:应理解为回看期内第一次被提到的时间。若 days=90,一个一年前就存在的老概念,首提时间也会落在 90 天窗口的起点附近。要区分「真正的新概念」和「回看期起点的老概念」,用较大的 days(例如 365)再取一次:两次首提时间都很近的,才是近期新出现的关联。

Q:「最近时间」能说明什么?
A:说明这个关联最近是否仍在被讨论。首提时间早、最近时间也近,是持续活跃的老标签;首提时间早、最近时间很久以前,是已经沉寂的标签。最近时间与调用时刻的差,可以用响应里的 meta.server_time(带 +08:00)计算。

Q:两个时间的时区是什么?
A:熔岩消息面记录的时间为北京时间。入库时统一标注为 Asia/Shanghai,计算时间差前先确认两个时间戳都已带时区,避免与 UTC 时间混算。

Q:首提时间与 /hot/first-mentions 的「首次被提到」是同一回事吗?
A:不是。首提流 /hot/first-mentions(get_first_mention_stocks)的口径是股票在此前 7 天一次都没被提过、在最近 hours 小时内(默认 24,最多 72)首次被提到,返回 first_time、首提主体的 agency_id 与分数;而 /concepts/by-stock 的首提时间是股票与某个概念的关联在回看期内第一次出现。前者描述股票本身是否「新冒头」,后者描述概念标签是否「新贴上」。日频面板 /panel/daily 的 is_first_mention_day 又是按自然日标记的股票级口径,三者不要混用。

四、新鲜度分档示例

把首提时间与最近时间换算成「距调用时刻的天数」,可以给每个概念打一个描述性标签。以下为示例阈值与示例读数:

概念(示例) mentions agencies 首提距今(天) 最近距今(天) 标签
概念甲 412 96 88 0 持续活跃
概念乙 37 14 4 0 新近出现
概念丙 65 22 85 41 已沉寂
概念丁 9 3 2 1 新近出现,样本小

分档规则(示例阈值,可按研究需要调整):

新近出现:首提距今 <= 7 天(且用 days=365 复核后仍 <= 7 天)
持续活跃:首提距今 > 30 天,最近距今 <= 3 天
已沉寂:  最近距今 > 30 天
其他:    记为「中间状态」,不强行归类
样本小:  agencies < 5 时附加此标记
# freshness.py —— 示例,地址与令牌为占位
import os, requests, pandas as pd

BASE = os.environ.get("LAVA_BASE", "<YOUR_LAVA_BASE>/subscribe/v1")
H = {"Authorization": "Bearer " + os.environ.get("LAVA_API_KEY", "<YOUR_TOKEN>")}

def by_stock(code, days):
    r = requests.get(BASE + "/concepts/by-stock",
                     params={"ts_code": code, "days": days, "limit": 200},
                     headers=H, timeout=60).json()
    assert r["ok"], r["code"]
    rows = r["data"] if isinstance(r["data"], list) else r["data"].get("list", [])
    return pd.DataFrame(rows), pd.Timestamp(r["meta"]["server_time"])

d90, now = by_stock("<CODE>", 90)
d365, _ = by_stock("<CODE>", 365)
# 概念名与两个时间的列名以 OpenAPI 为准,这里假设为 concept / first_time / last_time
m = d90.merge(d365[["concept", "first_time"]], on="concept", suffixes=("", "_365"))
for c in ("first_time", "last_time", "first_time_365"):
    m[c + "_age"] = (now - pd.to_datetime(m[c]).dt.tz_localize("Asia/Shanghai")).dt.days

两次调用计费两次。若时间字符串已带时区,把 tz_localize 换成 tz_convert。

五、与其他板块配合的问答

Q:一个「新近出现」的概念,下一步查什么?
A:先用 get_market_hot_concepts(/hot/concepts)看该概念在全市场是否也在热榜上;再用 get_concept_stock_heat(/concepts/stocks,concept 精确匹配、≤30 字符)看该概念下还有哪些股票被提到。如果只有这一只股票在讨论该概念,标签更可能是个股层面的叙事。

Q:能用这个接口做历史回测吗?
A:它返回的是从调用时刻往回的统计,不带 as_of_date 参数,无法还原历史某一天的概念画像。需要日频历史时,用 /panel/daily 的 type=concept(names 传概念名)取概念层面的自然日序列,并注明口径不同。

Q:概念名可以直接传给其他接口吗?
A:可以,而且推荐这样做。/concepts/by-stock 返回的概念名就是标准名,直接作为 /concepts/stocks 的 concept 或 /panel/daily 的 names 传入,可以避免手写别名导致的精确匹配失败。

熔岩站点的个股概念查询工具页提供了同一方向(个股 → 概念)的只读展示,适合人工查看一只股票的概念画像;需要做新鲜度分档、批量或落库时,再用上面的接口复现。

六、常见误读对照表

误读 实际口径 规范写法(示例)
「概念乙首提距今 4 天,所以是这只股票的新概念」 首提时间只在回看期内成立 「days=90 与 days=365 两次取数,首提均在 4 天内」
「概念甲提及最多,所以它是这只股票的主题」 提及多可能来自长期累积 「90 天回看内概念甲 mentions=412,最近距今 0 天」
「概念丙最近距今 41 天,说明关联已经失效」 只说明回看期内最近一次被提到在 41 天前 「概念丙近 41 天无新提及」
「两只股票都挂了概念甲,所以它们会同步变化」 概念关联只描述讨论中的共现 「两只股票在回看期内都与概念甲共现」
「limit=30 没返回的概念就不存在」 只是排在前 30 名之外 「limit=200 下复核」

误读的共同来源是省略了 days、limit 和时间基准。只要写清这三项,读者就能判断标签的适用范围。

七、落库字段与复核节奏

为了让新鲜度标签可以追溯,建议每次保存:

  • 请求参数:ts_code、days、limit;
  • 响应元数据:meta.server_time、meta.request_id,以及计费字段 meta.billing.charged_yuan;
  • 每行:概念名、mentions、agencies、首提时间、最近时间;
  • 本地计算列:首提距今天数、最近距今天数、days=365 复核结果、标签与是否样本小。

复核节奏可以按研究用途决定:对固定观察列表做周度快照即可看到标签迁移,例如某概念从「新近出现」变为「持续活跃」或「已沉寂」;盘中不需要高频调用,因为概念画像是长回看统计,短时间内变化很小。把相邻两次快照按概念名对齐,统计新增、消失和标签变化的数量,就是一张简单的概念画像变更表。

需要注意,概念画像变更表记录的是讨论中的共现关系变化,不代表公司业务或分类的变化;涉及行业归属的问题,仍以自有的行业分类数据为准。

八、用消息面记录抽样核对

分档只基于计数与时间。想看「新近出现」的概念具体是在什么语境下与股票共现,可以用个股消息面 get_stock_news_heat(/opinions)取同一只股票最近几天的记录。每条记录带 topic_time、agency_id、agency_score、stocks、concepts、summary(≤120 字)和 detail(≤600 字),在本地筛出 concepts 中包含该概念名的记录,按 topic_time 排序抽样阅读 summary 即可。

r = requests.get(BASE + "/opinions",
                 params={"ts_code": "<CODE>", "days": 7, "limit": 200},
                 headers=H, timeout=60).json()
assert r["ok"], r["code"]
data = r["data"]
recs = data.get("list", []) if isinstance(data, dict) else data
hit = [x for x in recs if "<概念标准名>" in (x.get("concepts") or [])]
print(len(hit), [x["topic_time"] for x in hit[:5]])

抽样核对有两个用途:确认新概念的共现不是少数主体的重复表达(可按匿名 agency_id 计数),以及确认首提时间附近确实存在相关记录。/opinions 的 days 最大 90,记录受 limit 截断,条数等于 200 时应缩短区间。核对结果仍然只记录事实,不把摘要内容改写为结论。

结论

get_stock_concept_heat 的价值不只在于「哪个概念提及最多」,更在于每个概念的首提时间与最近时间。用较长的 days 复核首提时间、用 meta.server_time 计算距今天数、给小样本附加标记,就能把一只股票的概念关联区分为持续活跃、新近出现和已沉寂三类,并与概念热榜、概念成分排行和日频面板衔接成完整的只读研究流程。

数据来自熔岩消息面热度监测,仅供研究参考,不构成投资建议。

只读监测与字段说明见:https://lava.ai-dolphin.com/tools/stock-concepts

No comments yet. Be the first to comment.

More from this blog