mcSimulate
首发版本:3.00.6.4
语法
mcSimulate(evolve, initialState, timeGrid, numPaths, [numFactors=1], [params=NULL], [options=NULL])
详情
根据用户定义的状态演化函数生成完整模拟路径。函数负责生成标准正态伪随机驱动、处理随机因子相关性,并按时间网格推进状态。支持多状态、多因子、对偶变量和批次执行。
-
本函数不调用目标函数,也不计算估计值、样本方差、标准误或置信区间。
-
当前仅支持单节点 CPU 执行,不支持 GPU 或跨节点分布式调度。
-
参数、回调或任一批次执行失败时,整次调用失败,不返回部分路径或随机数。
参数
evolve 函数定义,指定自定义随机过程状态演化,函数签名固定为:evolve(t, state, dt, noise, params)。
| 参数 | 类型与形式 | 说明 |
|---|---|---|
| t | DOUBLE 标量 | 指定当前时间节点 timeGrid[i]。 |
| state | DOUBLE 矩阵 | 指定当前批次所有路径的当前状态,形状为 batchPathCount ×
stateDim。 |
| dt | DOUBLE 标量 | 指定当前时间步长度,等于相邻两个时间点之差 timeGrid[i+1] -
timeGrid[i]。 |
| noise | DOUBLE 矩阵 | 指定当前批次的随机驱动,形状为
|
| params | ANY | 调用 mcSimulate 传入的自定义参数 params。 |
其中:
- batchPathCount 为当前批次实际包含的路径数;
- stateDim 为状态维度,等于 initialState 的元素个数,标量对应 1;
- numFactors 为调用
mcSimulate传入的 numFactors 参数。
evolve 每批、每个时间步调用一次,返回 batchPathCount × stateDim 的 DOUBLE 矩阵。
initialState 数值标量或向量,指定随机过程的初始状态,即 timeGrid 第一个时间点的初始状态。指定为标量时表示单状态过程,指定为向量则表示多状态过程。
timeGrid 数值向量,指定模拟时间网格。至少包含两个非 NULL 的有限数值,且严格递增。支持非等间隔时间网格。
numPaths 正 INT 或 LONG 标量,指定模拟路径总数。启用对偶变量时,必须为大于 2 的偶数。
numFactors 可选参数, INT 标量,指定每个时间步输入状态演化函数的随机因子数,默认值为 1,必须大于 0。随机因子数与状态维度相互独立。
params 可选参数, ANY 类型对象,默认值为 NULL。指定用户自定义参数对象,传递给 evolve 函数。同一次模拟中的回调应将其作为只读对象使用。
options 可选参数,字典(STRING, ANY),默认值为 NULL。支持以下键:
| 键 | 类型与形式 | 默认值 | 说明 |
|---|---|---|---|
| "randomMethod" | STRING | "pseudo" | 指定随机采样方法。当前仅支持 "pseudo",即 Pseudo Random Monte Carlo,生成标准正态伪随机驱动。 |
| "seed" | INT / LONG | 自动生成 | 指定随机种子。未指定时由系统自动生成,并在返回结果字段 seed 中给出实际值。 |
| "corr" | 数值矩阵 | NULL | 指定随机因子之间的相关矩阵,维度为 numFactors ×
numFactors。必须对称、正定、对角线元素为 1,且不包含 NULL、NaN 或
Inf。系统在模拟开始前完成相关性分解,并将相关化后的标准正态随机驱动传入
evolve。相关性作用于随机因子,而非直接作用于状态变量。 |
| "antithetic" | BOOL | false | 指定是否启用对偶变量法(Antithetic Variates)。指定为 true
时启用对偶变量法,numPaths 必须为偶数且仍表示最终有效路径数,系统将基础随机驱动
Z 与 -Z 成对用于模拟。 |
| "batchSize" | INT / LONG | 自动确定 | 指定每批有效路径数,必须大于 0,用于控制批量计算粒度和内存占用。最后一个 batch 的路径数可以小于
"batchSize"。若 batchSize >
numPaths,按单批次执行。启用对偶模式时,必须为偶数。 |
| "returnRandomNumbers" | BOOL | false | 指定是否返回实际传入 evolve 的随机驱动。指定为 true 时结果额外包含
"randomNumbers" 键,其中已包含 Antithetic 配对和 "corr" 相关性变换后的结果。 |
| "parallel" | BOOL | true | 指定是否允许不同批次在本机 CPU 上并行执行。指定为 false 时串行执行。当前仅支持单节点 CPU 并行;不支持 GPU backend 和跨节点分布式调度。 |
返回值
返回一个字典,包含完整模拟路径以及模拟信息:
| 键 | 类型与形式 | 说明 |
|---|---|---|
| "paths" | ANY 向量 | 完整模拟路径。长度为 size(timeGrid),每个元素是 numPaths
× stateDim 的 DOUBLE
矩阵。按时间顺序排列,第一个元素为初始状态矩阵,最后一个元素为终值状态矩阵。 |
| "timeGrid" | DOUBLE 向量 | 实际使用的时间网格 |
| "numPaths" | LONG 标量 | 实际生成的路径数 |
| "numFactors" | INT 标量 | 随机因子数 |
| "seed" | LONG 标量 | 实际使用的随机种子 |
| "randomMethod" | STRING 标量 | 当前固定为 "pseudo" |
| "randomNumbers" | ANY 向量 | 实际传入状态演化函数的随机驱动。指定 returnRandomNumbers=true
时输出,长度等于 size(timeGrid) - 1,每个元素是 numPaths
× numFactors 的 DOUBLE 矩阵。 |
例子
例 1. 生成几何布朗运动路径及随机驱动
本例用 12 个等长时间步模拟 8 条价格路径,并指定 returnRandomNumbers = true 取回每一步的随机驱动。
def gbmEvolve(t, state, dt, noise, p) {
mu = (p["r"] - p["q"] - 0.5 * p["sigma"] * p["sigma"]) * dt
return state * exp(mu + p["sigma"] * sqrt(dt) * noise)
}
p = dict(STRING, DOUBLE)
p["r"] = 0.03
p["q"] = 0.0
p["sigma"] = 0.20
opt = dict(STRING, ANY)
opt["seed"] = 7
opt["batchSize"] = 8
opt["returnRandomNumbers"] = true
sim = mcSimulate(gbmEvolve, 100.0, 0..12 / 12.0, 8, 1, p, opt)
[size(sim["paths"]), shape(sim["paths"][0]), size(sim["randomNumbers"]), flatten(sim["paths"][12][, 0])]
// output: [13, [8, 1], 12, [86.07027033006177, 95.76439369271459, 70.83725029862133, 124.81301557000361, 99.78994602443282, 131.41412372603514, 90.4951917379586, 86.17040506214356]]
例 2. 生成两个相关因子的对偶随机驱动
相关矩阵指定因子间相关系数为 0.5,使用两个状态和两个因子。返回随机驱动的前两行为一组对偶配对,逐因子相加为 0。
def factorEvolve(t, state, dt, noise, params) {
return state + sqrt(dt) * noise
}
options = dict(keyType=STRING, valueType=ANY)
options["seed"] = 11
options["batchSize"] = 6
options["antithetic"] = true
options["corr"] = matrix(1.0 0.5, 0.5 1.0)
options["returnRandomNumbers"] = true
result = mcSimulate(evolve=factorEvolve, initialState=0.0 0.0,
timeGrid=0.0 1.0, numPaths=6, numFactors=2, options=options)
noise = result["randomNumbers"][0]
[noise[0, 0] + noise[1, 0], noise[0, 1] + noise[1, 1]]
// output: [0, 0]
例 3. 一次模拟中同时给多个行权价报价
报价单上要同时报三档行权价。重复调用 monteCarlo 会重复模拟,而 mcSimulate 只模拟一次,把终值状态加工成三列样本后交给 mcEstimate 汇总——三档报价天然基于同一批路径,估计值之间的协方差也可直接使用。
def gbmEvolve(t, state, dt, noise, p) {
return state * exp((p["rate"] - 0.5 * p["volatility"] * p["volatility"]) * dt + p["volatility"] * sqrt(dt) * noise)
}
p = dict(STRING, ANY)
p["rate"] = 0.03
p["volatility"] = 0.2
options = dict(STRING, ANY)
options["seed"] = 42
options["batchSize"] = 5000
simulation = mcSimulate(gbmEvolve, 100.0, 0..12 / 12.0, 50000, 1, p, options)
terminal = simulation["paths"][size(simulation["paths"]) - 1][, 0]
discount = exp(-p["rate"])
samples = discount * matrix(max(terminal - 90.0, 0.0), max(terminal - 100.0, 0.0), max(terminal - 110.0, 0.0))
estimate = mcEstimate(samples)
[estimate["estimate"], estimate["stdError"]]
// output: [[15.411808417905474, 9.397343043691492, 5.253868707329098], [0.075506895272312, 0.06270845678671, 0.048590695510175]]
例 4. 多状态过程的输出结构
模型自检时想确认方差路径始终非负、状态维度是否按列排列。多状态过程的每个路径切片是 numPaths × stateDim 矩阵,第 0 列是价格,第 1 列是方差。
def hestonEvolve(t, state, dt, noise, p) {
variance = max(state[, 1], 0.0)
nextSpot = state[, 0] * exp((p["rate"] - 0.5 * variance) * dt + sqrt(variance * dt) * noise[, 0])
nextVariance = max(variance + p["kappa"] * (p["theta"] - variance) * dt + p["xi"] * sqrt(variance * dt) * noise[, 1], 0.0)
return matrix(nextSpot, nextVariance)
}
p = dict(STRING, ANY)
p["rate"] = 0.03
p["kappa"] = 2.0
p["theta"] = 0.04
p["xi"] = 0.5
corrMatrix = matrix(1.0 0.0, 0.0 1.0)
corrMatrix[0, 1] = -0.7
corrMatrix[1, 0] = -0.7
options = dict(STRING, ANY)
options["seed"] = 42
options["batchSize"] = 5000
options["corr"] = corrMatrix
simulation = mcSimulate(hestonEvolve, 100.0 0.04, 0..12 / 12.0, 20000, 2, p, options)
spotPath = simulation["paths"][size(simulation["paths"]) - 1]
[size(simulation["paths"]), rows(spotPath), cols(spotPath), avg(spotPath[, 1])]
// output: [13, 20000, 2, 0.044645538557127]
相关函数: monteCarlo, mcEstimate
