news 2026/8/31 22:16:44

用拓扑数据分析挖掘量化因子:从持久同调到Python实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用拓扑数据分析挖掘量化因子:从持久同调到Python实战

在量化研究里经常遇到这样一类问题:日常使用的动量、波动率、均线偏离等因子,本质上是价格序列的一阶或二阶统计量,一旦行情进入复杂的震荡、趋势切换和量价背离阶段,这些统计特征容易钝化。近几年,不少量化团队开始尝试用拓扑数据分析(TDA)从“形状”和“连通性”的角度去刻画行情结构,并把提取到的持续性特征作为新的候选因子。本文会围绕这个方向做一次完整的实战拆解,从拓扑数据分析的基本概念讲起,逐步完成 Python 环境配置、时间序列点云构建、持久图计算、拓扑特征提取以及因子 IC 和分组收益检验,适合已经有 Python 基础、想了解 TDA 因子挖掘方法的量化研究者和数据科学从业者。

这里先说明一点:本文不是论文复现,也不是宣称 TDA 因子一定能提升收益,而是给出一套可以照着运行、照着扩展的最小闭环方案。读完这篇文章,你能够自己把任意一段行情数据转换成拓扑因子,并接入已有的多因子分析流程。

1. 为什么用拓扑数据分析做行情结构因子挖掘

1.1 传统行情因子的局限

传统因子大多建立在价格、成交量、持仓量等数据的统计特征上,例如:

  • 动量因子:过去 20 日收益率。
  • 波动率因子:过去 20 日收益率的滚动标准差。
  • 均值回归因子:当前价格偏离移动平均线的程度。
  • 量价相关性因子:成交量与价格的相关系数。

这类因子有一个共同特点:它们描述的是数据的“数值分布”或“时间相关性”,很难描述数据作为一种几何对象时的“结构”。比如两个标的过去 20 天的收益率均值、标准差完全一致,但一个呈现缓慢爬升趋势,另一个呈现反复震荡格局,传统统计因子可能把它们看成同一类状态。拓扑数据分析的作用,就是把这种“形状差异”变成可计算的数值特征。

另一个常见问题是:金融时间序列噪声大、非平稳,传统特征对异常值敏感。拓扑不变量对连续形变具有不变性,这是 TDA 在噪声环境下仍有价值的重要原因。

1.2 拓扑数据分析能做什么

拓扑数据分析(Topological Data Analysis)是一种基于代数拓扑和计算几何的数据分析方法。它不直接关心数据的坐标,也不关心数据降维到几个主成分,而是关注数据点云在多个尺度下的连通分支、环状结构、空洞等拓扑特征。

在行情结构因子挖掘中,TDA 通常被用来做两件事:

  • 第一,把一维行情序列通过“滑窗嵌入”构造为高维点云,再用 TDA 描述这个点云内部的结构。
  • 第二,计算持久图,从图的点分布中提取数值特征,例如持久环的数量、寿命、总持久性等,这些数值可以作为候选因子进入多因子模型。

与 PCA、t-SNE 等降维方法相比,TDA 更适合回答“数据里是否存在某种持续存在的结构”这一类问题,而不是“数据如何排列在一个平面上”。这一点恰好契合行情结构研究中对“趋势持续性”“震荡循环”“状态切换”等概念的描述需求。

1.3 拓扑因子与传统因子的边界

拓扑因子并不是要完全替代传统因子。它在实际研究中的角色更像是一种“增量视角”:

  • 传统因子擅长捕捉线性趋势和波动强度。
  • 拓扑因子擅长捕捉循环结构、分离结构和多尺度下的持续性特征。

因此,一个比较合理的做法是:先独立计算拓扑因子,再与动量、波动率、流动性等传统因子放在同一个正交化框架里比较,观察它是否提供了额外的预测信息。如果拓扑因子与已有因子高度相关,那么它的贡献有限;如果相关性低且 IC 稳定,就需要进一步研究其背后的行情解释。

2. 拓扑数据分析的核心概念

2.1 点云:从行情序列到高维空间

拓扑数据分析处理的对象通常是“点云”,也就是一组点的集合。行情数据是时间序列,不能直接输入 TDA 管线,需要先转换成点云。最常见的转换方式是“滑窗嵌入”。

假设我们有过去 60 个交易日的收益率序列:

r_1, r_2, ..., r_60

用长度为 10 的窗口、步长为 2 去切分这段序列,就能得到一系列子向量:

[r_1, r_2, ..., r_10] [r_3, r_4, ..., r_12] [r_5, r_6, ..., r_14] ...

每个子向量可以看作是 10 维空间中的一个点,所有子向量的集合就是一个点云。这样,一个时间窗口内的行情状态,就被映射成为高维空间中的一块点云。后面的持久同调计算,都是在这块点云上进行的。

这里需要注意两种滑窗概念的区别:

  • 第一种是“行情样本的滑窗嵌入”,用于把一个序列转成点云,本文使用这种方式。
  • 第二种是“因子计算的滚动窗口”,每隔若干根 K 线滑动一次,用于生成时间序列上的因子值。

在实战代码中,两者会同时出现,需要区分清楚。

2.2 单纯复形与过滤

得到了点云之后,TDA 需要在点云上构造一种叫做“单纯复形”的组合结构。简单理解,单纯复形是由点、边、三角形、四面体等基本几何单元按规则拼成的结构。

最常用的是 Vietoris-Rips 复形,简称 Rips 复形。它的构造规则如下:

  • 当两个点之间的距离小于阈值 ε 时,这两个点之间连一条边。
  • 当三个点两两之间的距离都小于 ε 时,这三个点构成一个三角形。
  • 当四个点两两之间的距离都小于 ε 时,这四个点构成一个四面体。

随着 ε 从 0 逐渐增大,点云中会有越来越多的边、三角形和更高维的单纯形出现,整个过程称为“过滤”。这个动态扩张的过程,是后续计算拓扑特征的核心基础。

Rips 复形之所以被广泛使用,是因为它只需要点云的距离矩阵,计算方式直接,适合处理各类点云数据。虽然它的单纯形数量增长很快,但配合持久同调的加速算法,在中小规模点云上仍然很高效。

2.3 持久同调与持久图

在过滤过程中,点云里的拓扑结构会不断出生和消失:

  • 0 维拓扑特征代表“连通分量”,即相互连接在一起的点的集合。
  • 1 维拓扑特征代表“环”或“孔洞”,即点云中形成的闭合圈。
  • 2 维拓扑特征代表“空腔”,类似三维空间中的气泡。

每个拓扑结构都有一个“出生尺度”和一个“死亡尺度”。如果某个环在很大尺度范围内始终存在,说明它不是一个偶然的噪声结构,而可能对应数据中比较显著的循环或周期模式。

持久图是记录这些出生和死亡信息的二维图。图中每个点对应一个拓扑特征:

  • 横坐标是出生尺度。
  • 纵坐标是死亡尺度。
  • 点离对角线越远,说明该结构存在的时间尺度越长,越重要。

例如,H0 持久图上的点,通常有一个点是无穷大,对应最大的连通分量;H1 持久图上的点,反映的是点云中显著环的数量和寿命。

持久图的价值在于:它完整记录了数据在多尺度下的拓扑指纹。接下来提取因子,本质上就是把持久图压缩成一个个可用于截面排序的数值指标。

2.4 从持久图到拓扑因子

持久图本身是二维分布,不能直接作为单因子使用,还需要进一步特征化。常用特征包括:

  • 持久环数量:有限寿命拓扑特征的数量。
  • 平均寿命:所有非无穷点的寿命均值。
  • 最大寿命:寿命最长的特征对应的尺度差。
  • 总持久性:所有有限寿命之和。
  • 各维特征的组合:把 H0 和 H1 的特征拼接起来,或做组合运算。

这些特征可以在每个滚动窗口上计算,形成一条因子时间序列。之后再和未来收益做相关分析,就完成了“拓扑结构”到“候选因子”的映射。

如果希望比较两段行情之间的拓扑差异,还可以使用持久图之间的 Bottleneck 距离或 Wasserstein 距离。这会进入更细粒度的行情分类和状态识别场景,本文先不做展开。

3. 环境准备与依赖安装

3.1 运行环境

本文示例使用 Python 3.8 及以上版本即可,推荐使用 Python 3.9 或 3.10。操作系统可以是 Windows、macOS 或 Linux。建议先在项目目录下创建独立的虚拟环境,避免依赖冲突。

示例中主要使用以下库:

  • numpy:数值计算。
  • pandas:行情数据和因子处理。
  • scipy:Spearman 相关系数计算。
  • ripser:持久同调计算,核心计算库。
  • matplotlib(可选):持久图可视化。

其中 ripser 是 Topological Data Analysis 中最常用的 Python 包之一,底层使用 C++ 实现,计算速度较快。另一个常用库是 giotto-tda(gtda),它提供了更完整的管线封装,但依赖相对较重。为了减少环境复杂度和保持代码可读性,本文使用 ripser。

3.2 安装依赖

在项目根目录打开终端,使用以下命令安装:

pip install ripser persim numpy pandas scipy matplotlib

如果你的机器上已经配置了 Jupyter Notebook,也可以直接在 notebook 中运行以上命令。安装完成后,可以用一行代码验证:

from ripser import Rips import numpy as np print("RipsER version OK")

如果安装过程中遇到编译失败问题,通常是因为 pip 版本过低、缺少编译器或者系统 Python 版本过旧。建议先把 pip 升级到最新版本,再安装:

pip install --upgrade pip

不建议在系统全局环境里直接安装这些科学计算库,尤其当系统 Python 被其他项目依赖时,很容易出现版本冲突。

3.3 一个最小可运行示例

安装完依赖后,可以先运行下面这个最小示例,确认持久同调计算链路正常:

from ripser import Rips import numpy as np np.random.seed(0) # 生成 80 个三维点 points = np.random.normal(size=(80, 3)) rips = Rips(maxdim=1) dgms = rips.fit_transform(points) print("H0 点数:", len(dgms[0])) print("H1 点数:", len(dgms[1]))

如果能够正常输出 H0 和 H1 的点数,说明 ripser 安装成功,后续的因子挖掘实验可以在此基础上进行。

4. 完整实战:从行情序列到拓扑因子

为了把前面的概念串起来,这一节实现一个完整的因子挖掘流程:使用一段模拟行情数据,滑窗构建点云,计算持久图特征,构造拓扑因子,并做初步的 IC 和分组收益检验。

4.1 实验设计

整体流程可以拆成以下五个步骤:

  1. 构造演示行情数据:用几何布朗运动生成一段日线价格和收益率序列。
  2. 对每个分析窗口中的收益率序列做滑窗嵌入,构建高维点云。
  3. 使用 RipsER 计算点云的 H0 和 H1 持久图。
  4. 从持久图中提取各维度的总持久性、平均寿命、最大寿命等特征。
  5. 将拓扑特征作为候选因子,与未来 20 日收益计算 Spearman IC,并查看分组收益。

这里使用模拟数据的主要原因是保证代码可复现。换成真实行情数据时,只需要把df替换成包含closeret列的数据框即可。

4.2 构建行情数据与滑窗点云

先看数据部分。我们生成 1500 个交易日的模拟收盘价和收益率:

import numpy as np import pandas as pd np.random.seed(42) n_days = 1500 rets = np.random.normal(0.0003, 0.01, n_days) close = 100 * np.cumprod(1 + rets) idx = pd.date_range("2021-01-04", periods=n_days, freq="B") df = pd.DataFrame({"close": close}, index=idx) df["ret"] = df["close"].pct_change().fillna(0) df.head()

这里使用的pct_change()会计算日收益率,后面的滑窗嵌入基于收益率而不是收盘价。原因是收益率序列通常更平稳,而价格序列带有明显的趋势和量纲,直接用价格做距离计算容易被绝对水平主导。

接下来定义滑窗嵌入函数,把一个等长序列切分成多个高维子向量:

def build_point_cloud(series, embed_dim=10, embed_step=2): """ 将一维序列转换为高维点云。 参数说明: series: 一维收益率序列 embed_dim: 子窗口长度,决定点云维度 embed_step: 子窗口采样步长 """ n = len(series) points = [ series[i:i + embed_dim] for i in range(0, n - embed_dim + 1, embed_step) ] # 如果序列长度不够,至少保留一个点 if not points: points.append(series[-embed_dim:]) return np.array(points)

这里的核心思路是:在同一个分析窗口内部,把连续的embed_dim个收益率视为一个点,然后让窗口在序列上滑动,得到一系列点。这些点在embed_dim维空间中形成一块点云,后续的拓扑结构就从这块点云中计算。

4.3 计算持久图并提取拓扑特征

下面定义拓扑特征提取函数。它对每个点云调用 RipsER 计算 H0、H1 两维的持久图,并输出四个常见特征:拓扑特征数量、平均寿命、最大寿命和总持久性。

from ripser import Rips # 复用同一个 Rips 对象,避免反复初始化 rips = Rips(maxdim=1, verbose=False) def compute_topological_features(series, embed_dim=10, embed_step=2): """ 输入:一段收益率序列 输出:H0 和 H1 的拓扑特征字典 """ pc = build_point_cloud(series, embed_dim, embed_step) # 对每个维度做标准化,减弱量纲差异的影响 pc = (pc - pc.mean(axis=0)) / (pc.std(axis=0) + 1e-9) dgms = rips.fit_transform(pc) feats = {} for dim in range(2): dgm = dgms[dim] # 去掉死亡时间为无穷大的点 finite = dgm[np.isfinite(dgm[:, 1])] if len(finite) == 0: lifetimes = np.array([0.0]) else: lifetimes = finite[:, 1] - finite[:, 0] feats[f"h{dim}_num"] = len(finite) feats[f"h{dim}_mean_life"] = lifetimes.mean() feats[f"h{dim}_max_life"] = lifetimes.max() feats[f"h{dim}_total_pers"] = lifetimes.sum() return feats

这里有几个实现细节需要说明:

  • Rips(maxdim=1)会同时计算 H0 和 H1,H2 及以上维数计算成本更高,在行情结构研究中通常先从 H1 开始验证。
  • 持久图中包含死亡时间为正无穷的点,它们代表始终存在的连通分量或环,统计寿命时通常剔除,否则会出现无穷大值。
  • 对点云按列标准化后,持久图的绝对尺度会发生变化,但特征之间的相对大小仍可用于因子排序。如果你希望保留行情的原始振幅信息,可以去掉标准化步骤。

4.4 滚动计算因子

有了拓扑特征提取函数之后,就可以滚动生成因子时间序列。参数选择如下:

  • analysis_window = 60:每个因子样本回溯 60 个交易日。
  • embed_dim = 10:子窗口长度。
  • embed_step = 2:点云内部滑窗步长。
  • sample_step = 5:每隔 5 个交易日计算一次因子,降低计算量。

代码如下:

analysis_window = 60 embed_dim = 10 embed_step = 2 sample_step = 5 records = [] for end in range(analysis_window, len(df), sample_step): window_ret = df["ret"].iloc[end - analysis_window:end].values feats = compute_topological_features(window_ret, embed_dim, embed_step) feats["date"] = df.index[end - 1] records.append(feats) factor_df = pd.DataFrame(records).set_index("date") print(factor_df.head())

这个循环的本质是:在每一个因子生成日,只使用当天之前analysis_window个交易日的数据计算拓扑特征,不包含未来数据,这符合因子计算中“避免前视偏差”的基本要求。

输出会得到一个包含多列拓扑特征的因子表,例如:

  • h0_num:H0 连通分量数量,通常与分析窗口内点云的点数接近。
  • h1_num:H1 环的数量。
  • h1_total_pers:H1 总持久性,是后续最常用的拓扑因子。
  • h1_max_life:H1 最大寿命,代表最显著环的持续尺度。

4.5 因子有效性初评:IC 与分组收益

因子构造完成后,需要评估它是否与未来收益存在相关性。这里使用未来 20 日收益作为预测目标:

from scipy.stats import spearmanr # 计算未来 20 日收益 factor_df["ret_future20"] = ( df["close"].shift(-20) / df["close"] - 1 ).reindex(factor_df.index) # 全局 Spearman IC for col in ["h0_total_pers", "h1_total_pers", "h1_max_life"]: ic, pval = spearmanr(factor_df[col], factor_df["ret_future20"]) print(f"{col}: Spearman IC = {ic:.4f}, p-value = {pval:.4f}")

Spearman IC 衡量因子值和未来收益之间的秩相关性,取值范围在 -1 到 1 之间。绝对值越大,说明因子的单调预测能力越强。通常在实际因子研究中,我们会观察 IC 的均值、标准差和 IC > 0 的占比,而不能只看某一段时间的 IC。

分组收益检验可以让因子的单调性看得更直观:

# 按 H1 总持久性分成 5 组 factor_df["quantile"] = pd.qcut( factor_df["h1_total_pers"], 5, labels=False, duplicates="drop" ) group_ret = factor_df.groupby("quantile")["ret_future20"].mean() print(group_ret)

如果因子的分组收益呈现明显的单调上升或下降,说明该因子对收益截面有较强的解释力;如果分组收益没有规律,则说明该拓扑特征在模拟数据上没有预测价值。

4.6 结果解读

需要强调,使用随机模拟数据运行上述脚本时,IC 通常会接近 0,分组收益也不会有明显单调性。这是正常现象,因为几何布朗运动产生的价格序列本身没有可预测的结构。更重要的是,这套流程可以完整地运行,并且已经展示了从行情序列到拓扑因子再到因子检验的全部环节。

当你把数据源换成真实行情数据后,需要注意两个判断维度:

  • 第一,拓扑特征是否稳定。如果某个标的的 H1 特征时有时无,说明它的行情结构在不同时期差异较大,因子适用性有限。
  • 第二,拓扑因子是否提供增量信息。即使拓扑因子本身 IC 较高,也需要和传统动量、波动率因子做正交化检验,确认它不是已有因子的重复表达。

5. 常见问题与排查思路

5.1 计算量太大、内存暴涨

Rips 持久同调需要计算点云两两之间的距离,因此复杂度随点数增加明显上升。如果点云数量超过几千个点,可能会遇到内存不足或计算时间过长的问题。

可以采取以下优化手段:

  • 增大embed_step,减少点云内的点数。
  • 增大sample_step,减少滚动因子的频次。
  • 对点云进行随机降采样,但要注意不要破坏核心结构。
  • 分时段计算,避免一次性处理整段超长历史数据。

在实际项目中,更推荐把持久图计算缓存下来。因为同样的行情数据,在参数不变时,拓扑特征不会变化,重复计算只会浪费计算资源。

5.2 持久图里大量噪声点

持久图中的点数量很多,并不代表行情结构丰富。真正的“有效结构”通常只占少数,大多数点离对角线非常近,可以被视为噪声。

处理思路是设置寿命阈值:

# 例如只保留寿命大于 0.1 的特征点 valid = dgm[np.isfinite(dgm[:, 1])] valid = valid[valid[:, 1] - valid[:, 0] > 0.1]

但寿命阈值的设定需要谨慎,过大的阈值会丢失真实结构,过小的阈值又无法过滤噪声。建议先画出持久图观察分布,再决定阈值范围。

另外,数据标准化会显著影响寿命大小。如果对点云做了标准化,特征的寿命阈值需要重新校准,不能直接使用未标准化时的经验值。

5.3 H1 特征不稳定

H1 特征常常出现时有时无的情况,尤其在行情趋势非常强的时候,收益率点云可能呈一条倾斜的流形,内部没有明显的环状结构,因此 H1 总持久性可能为 0。

面对这种情况,可以考虑:

  • 使用 H0 和 H1 的组合特征,而不是只依赖 H1。
  • 在更长周期上观察,例如用周线数据代替日线。
  • 引入成交量、振幅等多维特征,让点云包含更多结构信息,而不是只使用收益率。

5.4 参数选择与过拟合

拓扑因子涉及的参数较多,例如analysis_windowembed_dimembed_stepsample_step。参数不同,因子分布可能差异很大。如果在某组参数下 IC 很高,但参数稍微调整就失效,很可能是在过拟合历史数据。

推荐的做法是做一个参数敏感性矩阵:固定其他参数,对目标参数从小到大变化,观察 IC 的均值和稳定性。如果因子在较宽的参数范围内都表现稳定,那么它进入组合模型的可信度会更高。

常见问题汇总如下:

问题现象常见原因解决思路
安装 ripser 失败pip 版本过旧、缺少编译器升级 pip、安装构建工具、使用虚拟环境
计算时间过长点云点数过多增大采样步长、降采样、缓存结果
持久图全是噪声数据未标准化或窗口过短调整嵌入维度、设置寿命阈值
H1 特征经常为 0行情本身缺乏稳定环状结构使用 H0/H1 组合特征、改成周线数据
IC 波动剧烈参数过拟合参数敏感性分析、样本外测试
因子与传统因子高度相关拓扑特征和已知统计量重复做因子正交化,计算增量 IC

6. 工程实践与量化应用建议

6.1 数据清洗与预处理

拓扑特征对输入数据的量纲和尺度比较敏感。如果点云中同时包含收益率、成交量和振幅,不同特征的数值范围差异很大,距离度量会被数值较大的维度主导。建议在构造点云前统一做标准化,或者先对各列做 winsorize 处理,降低极端值的影响。

同时要注意,行情数据中的除权除息、停牌、异常大单都可能产生孤立点或异常距离,这会直接污染持久图。最好先做复权处理和停牌过滤,再进入 TDA 计算流程。

6.2 因子去极值与中性化

计算出的拓扑因子往往带有明显的截面分布偏度,直接参与回归或排序可能受到极端值影响。在进入多因子模型前,建议做以下处理:

  • 去极值:例如用中位数加减 5 倍 MAD 截断。
  • 标准化:将因子转换为 z-score。
  • 中性化:如果因子与市值、行业、波动率大小存在显著相关,可以用线性回归把因子残差化,得到风险中性后的拓扑因子。

这一步对所有因子都适用,拓扑因子也不例外。否则后续的 IC 分析可能只是因为因子间接暴露在行业或市值因子上。

6.3 滚动窗口与计算缓存

在真实项目中,通常需要每天或每周更新因子,而不是只计算一次。拓扑特征的计算成本比普通统计特征高,建议把持久图结果按“标的 + 参数 + 截止日期”缓存

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/31 22:15:57

STM32U5G9固件与Option Bytes打包合并为单个Hex的产线烧录实践

1. 为什么我要把固件和Option Bytes塞进同一个hex1.1 先聊聊STM32U5G9这颗片的调性STM32U5系列是ST家主打超低功耗和安全性的一代产品,STM32U5G9更是这一系里的高配型号,Cortex-M33内核带着TrustZone,Flash容量做得很大,跑各种带安…

作者头像 李华
网站建设 2026/8/31 22:15:52

基于STM32F446的双通道SiPM符合测量与峰值检测系统

1. 双通道符合测量到底在测什么:SiPM信号读数的核心命题在实验室里同时接两路SiPM,比接一路要麻烦得多。我这次在STM32F446RE上做了一套双通道SiPM的信号峰值检测和符合计时,说白了就是把过去用示波器加NIM插件机箱干的活,搬进一颗…

作者头像 李华
网站建设 2026/8/31 22:12:55

STM32N6570-DK调试报错:Target is not responding排查与解决

这段时间不少朋友在跑STM32N6570-DK和STM32Cube AI Studio组合时,都被同一个报错卡得头皮发麻:固件下载显示成功、校验也通过,结果紧接着弹出一句 Target is not responding ,仿佛芯片原地消失。这个报错我也遇到过,…

作者头像 李华
网站建设 2026/8/31 22:11:25

STM32N6570 AI工程调试失败:PSRAM初始化顺序导致Target is not responding

下载验证通过,紧接着调试器弹 "Target is not responding"——这是我第一次把 STM32Cube AI Studio 生成的模型工程烧进 STM32N6570-DK 时的遭遇。程序下载和校验都成功了,点击 Debug 之后却连不上目标板,这个错误在 STM32N6 系列这…

作者头像 李华
网站建设 2026/8/31 22:09:36

VMware虚拟机创建、VMtools安装与系统镜像下载校验全攻略

这次我们把 VMware 虚拟机的三件事一次讲透:VM 虚拟机怎么创建、VMtools 有什么用、系统镜像去哪里下载并校验。很多人在虚拟机装好系统后才发现鼠标进不去、屏幕拉伸还难看、文件拖不过去、网络也上不去,这些问题其实都指向同一个原因:VMtoo…

作者头像 李华
网站建设 2026/8/31 22:08:31

DeepSeek API计费调整:从token成本结构到调用优化与报错排查

最近一周,技术群里最热闹的话题之一,就是 DeepSeek API 平台又要调整计费规则了。消息传出来的时候,很多人的第一反应是“周末打折”还是“偷偷涨价”?尤其是 8 月 23 日起执行新规这个时间点,让不少用 DeepSeek API 做…

作者头像 李华