使用 gs_quant 的 generate_series 生成随机价格时间序列:函数签名、实现原理与实战示例
2026/9/15 14:03:24 网站建设 项目流程

使用 gs_quant 的 generate_series 生成随机价格时间序列:函数签名、实现原理与实战示例

【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant

本篇技术指南围绕 gs-quant 时间序列统计模块中的generate_series工具函数展开,说明如何通过一行调用快速生成服从标准正态随机游走的模拟价格序列,用于单元测试、文档示例与快速原型验证。读完本文,你将掌握generate_series的参数语义、底层递推公式与随机数生成机制、Direction方向控制、测试约束,以及它与algebra系列函数组合使用的典型场景。

函数定位:时间序列模块的"示例数据工厂"

generate_series定义在 gs_quant/timeseries/statistics.py 中,属于 gs-quant 时间序列统计库(stats library)。该模块在文件头部注释中明确了自身定位:"基本算术与统计操作的时间序列库,涵盖概率与分布分析,一般不做金融专用逻辑"。generate_series是其中专门负责"生成样例时间序列"的辅助函数。

在模块导出层面,gs_quant/timeseries/init.py 通过from .statistics import *将整个 statistics 模块的公开符号导出,因此实际使用时可直接从gs_quant.timeseries命名空间导入,而无需深入内部子模块。

该函数在源码中被@plot_function装饰器标记(helper.py 中的定义),源码注释明确说明:所有不带下划线前缀的公开函数都可能被 Marquee Plot Service 导出为绘图函数,plot_function装饰器正是在标注"此函数应以纯函数形式导出至 plottool"。这意味着generate_series不仅能在本地 Python 环境调用,也被设计为可在 Marquee 绘图服务环境中直接使用的可导出函数。

函数签名与参数详解

def generate_series(length: int, direction: Direction = Direction.START_TODAY) -> pd.Series
参数类型默认值含义
lengthint必填生成的观测值数量(即返回序列的数据点个数)
directionDirectionDirection.START_TODAY生成的序列是"从今天开始"还是"截止到今天"
返回值pd.Series以日期为索引、随机生成的价格序列

Direction枚举与generate_series同文件定义(statistics.py 第 854-856 行):

class Direction(Enum): START_TODAY = 'start_today' END_TODAY = 'end_today'
  • Direction.START_TODAY(默认):序列的第一个日期是今天,索引向后延续;
  • Direction.END_TODAY:序列的最后一个日期是今天,索引向前回溯。

在文档系统(docs/functions/gs_quant.timeseries.statistics.generate_series.rst)中,该函数通过 Sphinxautofunction指令自动提取源码 docstring 渲染生成 API 文档,因此 docstring 中的参数说明、数学公式与示例就是该函数的权威技术文档。

实现原理:标准正态增量驱动的随机游走

从源码看,generate_series的生成逻辑分为三条主线:

1. 随机数生成:标准正态随机变量(IID)

rng = np.random.default_rng()

实现使用 NumPy 新一代GeneratorAPI(np.random.default_rng()),这是 NumPy 1.17 之后推荐的随机数生成方式,基于 PCG64 位生成器。每次调用都会生成独立的随机数流,因此连续调用generate_series两次会得到不同的序列——这一点在文档示例中经常被利用,例如生成两条独立序列后做addsubtract等运算。

后续每个时间步的增量来自rng.standard_normal(),即服从标准正态分布、均值为 0、标准差为 1 的独立同分布(IID)随机变量:

$$R \sim N(0, 1)$$

2. 价格递推:从基准 100 出发的绝对增量

levels = [100] for i in range(length - 1): levels.append(levels[i] * 1 + rng.standard_normal())

序列的初始值固定为100,随后每个观测按如下递推公式生成:

$$X_t = (1 + R)X_{t-1}$$

即每一步在原价格基础上加上一个标准正态随机数,本质是一个以100为起点的无漂移随机游走(random walk)。docstring 强调随机变量 $R$ 服从 $N(0, 1)$,因此增量序列是标准正态的,序列本身会在 100 附近随机波动,既不体现趋势也不回归均值。

3. 日期索引:自然日逐日递增

first = dt.date.today() if direction == Direction.END_TODAY: first -= dt.timedelta(days=length - 1) dates = [first] for i in range(length - 1): dates.append(dt.date.fromordinal(dates[i].toordinal() + 1))
  • 默认START_TODAY时,首日索引为今天,后续每个观测的日期在前一天基础上加 1 个自然日;
  • END_TODAY时,首日索引向前回拨length - 1天,使最后一个索引恰好落在今天;
  • 最终返回pd.Series(data=levels, index=dates, dtype=np.dtype(float)),索引为 Python 原生datetime.date对象组成的列表,数据为float类型。

从实现细节可以推断两点适用前提:一是索引基于自然日而非交易日历,因此跨周末、节假日不会跳过;二是序列值采用绝对增量叠加而非对数收益率复利,因此不适合直接当作金融资产的严格价格路径模型,它更适合作为"形状像时间序列的随机样本数据"。

实战用法:三种典型调用方式

1. 默认方向:从今天开始的 100 个观测

from gs_quant.timeseries import generate_series prices = generate_series(100)

生成 100 个观测,索引从今天开始、逐日递增,第一个值恒为 100,其余为随机游走结果。

2. 反向对齐:截止到今天

from gs_quant.timeseries import generate_series, Direction prices = generate_series(100, Direction.END_TODAY)

生成 100 个观测,索引最后一天恰好是今天,适用于需要"样本期结束于当前"的对齐场景。

3. 与代数函数组合:模拟加法、加权篮子等

generate_series在 gs-quant 内部被广泛用作示例数据源。gs_quant/timeseries/algebra.py 中大量公开函数的 docstring 示例都以generate_series(100)生成输入序列,例如:

from gs_quant.timeseries.algebra import add, subtract, multiply, divide a = generate_series(100) b = generate_series(100) add(a, b, Interpolate.STEP) # 序列逐点相加 subtract(a, b, Interpolate.STEP) # 序列逐点相减

weighted_sum的示例则展示了利用两条独立序列构造加权组合:

from gs_quant.timeseries.algebra import weighted_sum prices1 = generate_series(100) prices2 = generate_series(100) mybasket = weighted_sum([prices1, prices2], [0.7, 0.3])

由于generate_series的两条输出拥有相同的逐日日期索引,天然适合align对齐与逐元素运算,这正是它在addmultiplypowersqrtabs_floorfilter_filter_dates等函数示例中被反复引用的原因。

测试验证:行为约束有据可依

generate_series的行为约束在单元测试 gs_quant/test/timeseries/test_statistics.py 的test_generate_series中得到明确固化:

def test_generate_series(): x = generate_series(100) assert len(x) == 100 assert x.index[0] == dt.date.today() assert x.iloc[0] == 100 x = generate_series(100, Direction.END_TODAY) assert len(x) == 100 assert x.index[-1] == dt.date.today() assert x.iloc[0] == 100

测试确认了三项可验证契约:

  1. 长度契约:返回序列长度严格等于length
  2. 起点契约:默认模式下首日索引为今天;
  3. 终点契约END_TODAY模式下最后一日索引为今天;
  4. 初值契约:无论方向如何,iloc[0]恒等于 100。

此外,test_econometrics.py 中生成Direction.END_TODAY序列用于计量类函数测试,test_measures.py 则将generate_series(100).rename('spot')作为指标计算的输入。可以推断,generate_series在仓库中承担着"确定性约束 + 随机内容"的测试样本角色:结构可断言,数值则覆盖随机路径。

相关延伸:分钟级兄弟函数 generate_series_intraday

在同一文件紧随其后定义了generate_series_intraday(statistics.py 第 912-965 行),面向分钟级高频样例数据:

  • 默认方向START_INTRADAY_NOW从当前时间(按分钟取整)开始,END_INTRADAY_NOW则截止到当前时间;
  • 观测间隔固定 1 分钟,索引为pd.DatetimeIndex
  • 增量缩放至标准差 0.001(R ~ N(0, 0.001)),以匹配分钟级波动量级;
  • 同样从 100 起步、同样使用default_rng()
from gs_quant.timeseries import generate_series_intraday prices = generate_series_intraday(120) # 2 小时、从当前时间开始 prices = generate_series_intraday(1440, IntradayDirection.END_INTRADAY_NOW) # 24 小时、截止当前

两者的关系是:generate_series负责日频(date-based)样例,generate_series_intraday负责分钟频样例,构成覆盖两种常用时间粒度的样例数据生成能力。

注意事项与适用边界

基于源码实现,使用时有以下几点需要留意:

  • 随机性不可复现:内部直接构造新的default_rng(),没有seed参数,同一代码重复运行结果不同。若需要可复现的测试数据,应在调用外层自行设置 NumPy 全局种子或采用其他方案;
  • 自然日索引:索引逐自然日 +1,会包含周末与节假日,与交易日历(如 gs_quant/datetime/gscalendar.py 提供的日历逻辑)无关联;
  • 无漂移绝对增量:$X_t = X_{t-1} + R$(等价于 $(1+R)X_{t-1}$ 中取初值 100、增量直接叠加),不含漂移项,不适合模拟具有趋势或波动率聚集特征的资产路径;
  • 示例定位:docstring 将其定性为 "Generate sample timeseries"(生成样例时间序列),源码模块注释也将自身定位为非金融专用逻辑,因此它适合教学演示、单元测试与快速原型,不应直接替代基于真实市场数据的建模流程;
  • 首值恒定:序列第一个值永远为 100,若测试逻辑依赖序列水平,需要意识到这一点。

总结

generate_series是 gs-quant 时间序列模块中最轻量的数据入口之一:一行代码即可获得具有完整日期索引、float 类型的随机价格序列,配合Direction枚举可以灵活控制序列锚定在"今天"的哪一端。其源码实现清晰直白——default_rng()生成标准正态增量、100 起步逐日叠加、自然日索引逐日递增——并有对应单元测试固化其行为契约。无论你是想为代数运算函数构造演示数据、为回测或统计方法准备结构可控的随机样本,还是快速验证一个时间序列处理逻辑,generate_series都是值得优先尝试的起点;若需要分钟级粒度,则可选用同一文件中的generate_series_intraday作为补充。

【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询