【微科普】蒙特卡洛(全网最好懂,附MATLAB算法):用 “撒芝麻” 的智慧破解复杂挑战 —— 从披萨面积到金融风险的诗意算法
2025-10-04 14:42 tlnshuju 阅读(0) 评论(0) 收藏 举报“周末在家切了块不规则的披萨,想算它的面积却找不到合适的公式 —— 用尺子量边缘太麻烦,套几何公式又对不上形状。” 这种 “遇到复杂问题,精确计算难实现” 的场景,在生活和工作中随处可见:从算不规则地块面积,到预测股票未来收益的概率,再到模拟核反应堆的粒子运动。
而蒙特卡洛算法,就像一位懂 “随机” 的智慧老人 —— 它不用复杂公式,只需通过大量随机抽样,让 “概率” 成为丈量未知的尺子。“技术的魅力,在于用简单的逻辑对抗复杂的世界 —— 蒙特卡洛让‘随机’不再无序,而是成为破解难题的有序工具。”
序章:一块披萨引出的算法灵感
先回到披萨的问题:如何算一块边缘不规则的披萨面积?
如果用传统方法,可能需要:
- 用尺子把披萨边缘分成几十段小直线;
- 用多边形面积公式计算近似值;
- 分段越多,结果越准,但耗时也越长。
而蒙特卡洛的思路简单到 “反直觉”:
- 找一个能完全罩住披萨的正方形盘子,测量正方形的边长(比如 20cm,面积 400cm²);
- 抓一把芝麻,均匀撒在盘子上(假设撒了 1000 颗);
- 数一下落在披萨上的芝麻数量(比如 628 颗);
- 披萨面积 ≈ 正方形面积 × (披萨上的芝麻数 / 总芝麻数) = 400 × 628/1000 = 251.2cm²。
这个过程的核心逻辑是:当抽样足够多时,随机点的 “命中概率” 会无限接近 “面积占比”。而这,正是蒙特卡洛算法的本质 —— 用 “随机抽样” 逼近 “精确结果”,尤其适合解决 “公式难写、边界复杂” 的问题。
核心原理:从 “撒芝麻” 到数学逻辑
蒙特卡洛算法的核心,是 “大数定律” 和 “随机抽样” 的结合。我们用 “三个层层递进的场景”,拆解它的数学逻辑:
1. 基础场景:算 π 值 —— 理解 “抽样与概率的关系”
最经典的蒙特卡洛案例,是通过 “正方形内接圆” 算 π 值。
- 画一个边长为 2r 的正方形,内部画一个半径为 r 的内接圆;
- 正方形面积 = (2r)² = 4r²;
- 圆面积 = πr²;
- 圆面积 / 正方形面积 = π/4 → π = 4 × (圆内点数 / 总点数)。
生活类比:就像在正方形操场上画一个圆,随机喊 1000 个人站在操场上,数出站在圆内的人数(比如 785 人),就能算出 π≈4×785/1000=3.14,和真实值 3.1415926 非常接近。
2. 进阶场景:算不规则图形面积 —— 解决 “无公式可用” 的痛点
对于披萨这种无固定公式的图形,蒙特卡洛的步骤是:
- 确定边界:找一个能完全包含图形的 “外接矩形”(已知长和宽,面积可算);
- 随机抽样:生成大量在矩形内的随机点(x,y);
- 判断归属:对每个点,判断是否落在不规则图形内部(比如用 “射线法”:从点向右画射线,穿过图形边界的次数为奇数则在内部);
- 计算面积:图形面积 = 外接矩形面积 × (图形内点数 / 总点数)。
数学简化:设外接矩形面积为 S,总抽样数为 N,图形内抽样数为 K,则:\(Area = S \times \frac{K}{N}\)
- 意义:用 “随机点的命中比例” 反推未知面积,抽样次数越多,结果越精确。
3. 应用场景:金融风险评估 —— 预测 “概率分布”
在金融领域,蒙特卡洛常用来模拟股票未来的收益:
- 定义随机变量:假设股票收益率服从 “正态分布”(均值 μ,标准差 σ);
- 大量抽样:生成 10000 组未来 1 年的日收益率随机数据;
- 模拟路径:根据每组收益率,计算股票未来的价格走势;
- 风险评估:统计 “股价跌破止损线” 的次数占比,即为 “风险概率”。
生活类比:就像预测 “明天是否下雨”—— 通过分析过去 1000 天的天气数据,生成 1000 组明天的气象随机变量,统计 “下雨” 的次数占比(比如 30%),就是明天的降雨概率。
数学之美:蒙特卡洛的 “严谨性” 从何而来?
很多人觉得 “随机抽样” 很 “粗糙”,但蒙特卡洛的精确性,源于两个数学定理的支撑:
1. 大数定律:抽样越多,结果越准
大数定律的核心是:当随机试验次数足够多时,事件发生的频率会无限接近其概率。
- 比如抛硬币:抛 10 次可能有 7 次正面(70%),抛 1000 次则接近 50%,抛 100000 次则几乎等于 50%;
- 对应蒙特卡洛:抽样次数 N 越大,\(\frac{K}{N}\)越接近真实的 “面积占比 / 概率”,误差越小。
2. 中心极限定理:误差可控,结果可置信
中心极限定理告诉我们:大量独立随机变量的均值,会服从正态分布。
- 对蒙特卡洛而言,每次抽样的 “误差” 是独立随机变量,多次抽样后的 “平均误差” 会围绕 0 正态分布;
- 由此可计算 “置信区间”:比如 “有 95% 的把握,π 值在 3.13~3.15 之间”,让结果不仅有 “精度”,还有 “可信度”。
3. 收敛速度:为什么 “抽样次数要多”?
蒙特卡洛的收敛速度是\(O(\frac{1}{\sqrt{N}})\)—— 即 “误差与抽样次数的平方根成反比”:
- 若想把误差从 0.1 降到 0.01,抽样次数需从 100 次增加到 10000 次(翻 100 倍);
- 意义:虽然抽样次数越多越准,但 “精度提升” 的成本会越来越高,实际应用中需平衡 “精度” 和 “计算效率”。
实践落地:3 个蒙特卡洛场景的 MATLAB 脚本实现
下面用 3 个层层递进的 MATLAB 脚本,完整实现蒙特卡洛的核心应用。脚本无需额外工具箱,可直接复制运行,包含详细注释和可视化。
场景 1:基础版 —— 用蒙特卡洛算 π 值
功能:通过 “正方形内接圆” 抽样,计算 π 值,可视化抽样过程和误差变化。
% 蒙特卡洛算π值(基础版)
% 功能说明:
% 1. 生成正方形内的随机点,判断是否落在内接圆内
% 2. 计算π的近似值,统计不同抽样次数下的误差
% 3. 生成2个可视化窗口:抽样点分布、误差随次数变化曲线
% 运行说明:直接复制运行,无需额外文件;抽样次数N可修改(默认100000次)
clear; clc; close all;
%% 1. 参数设置
N = 100000; % 总抽样次数(可修改,越大越准)
r = 1; % 内接圆半径
square_side = 2*r; % 正方形边长(2r,与圆直径相等)
square_area = square_side^2; % 正方形面积
%% 2. 蒙特卡洛抽样
% 生成N个随机点(x,y),范围:[-r, r](正方形边界)
x = rand(1, N) * 2*r - r; % x∈[-r, r]
y = rand(1, N) * 2*r - r; % y∈[-r, r]
% 判断每个点是否落在圆内(x² + y² ≤ r²)
in_circle = zeros(1, N); % 1=在圆内,0=在圆外
for i = 1:Nif x(i)^2 + y(i)^2 <= r^2in_circle(i) = 1;end
end
% 统计圆内点数,计算π的近似值
K = sum(in_circle); % 圆内点数
pi_approx = 4 * K / N; % π≈4×(圆内点数/总点数)
pi_true = pi; % 真实π值
error = abs(pi_approx - pi_true); % 计算误差
%% 3. 可视化1:抽样点分布
figure('Name', '图1:蒙特卡洛算π——抽样点分布', 'Position', [100, 100, 600, 600]);
% 绘制正方形边界
hold on; axis equal; grid on;
rectangle('Position', [-r, -r, square_side, square_side], 'EdgeColor', 'black', 'LineWidth', 1.5);
% 绘制内接圆
theta = 0:0.01:2*pi;
circle_x = r * cos(theta);
circle_y = r * sin(theta);
plot(circle_x, circle_y, 'r-', 'LineWidth', 1.5, 'DisplayName', '内接圆');
% 绘制抽样点(圆内红色,圆外蓝色)
plot(x(in_circle==1), y(in_circle==1), 'r.', 'MarkerSize', 3, 'DisplayName', '圆内点');
plot(x(in_circle==0), y(in_circle==0), 'b.', 'MarkerSize', 3, 'DisplayName', '圆外点');
% 添加标题和图例
title(sprintf('蒙特卡洛算π:抽样次数=%d,π≈%.6f,真实值=%.6f,误差=%.6f', ...N, pi_approx, pi_true, error));
xlabel('x坐标'); ylabel('y坐标');
legend('Location', 'best');
%% 4. 可视化2:误差随抽样次数变化
figure('Name', '图2:蒙特卡洛算π——误差变化曲线', 'Position', [200, 200, 800, 400]);
% 计算不同抽样次数下的π值和误差(100次、200次...10000次)
sample_steps = 100:100:N; % 抽样次数步长
pi_history = zeros(1, length(sample_steps));
error_history = zeros(1, length(sample_steps));
for i = 1:length(sample_steps)current_N = sample_steps(i);current_K = sum(in_circle(1:current_N));pi_history(i) = 4 * current_K / current_N;error_history(i) = abs(pi_history(i) - pi_true);
end
% 绘制误差曲线
plot(sample_steps, error_history, 'g-', 'LineWidth', 1.5,'DisplayName', '误差曲线');
hold on;
% 添加误差阈值线(0.01)
plot([sample_steps(1), sample_steps(end)], [0.01, 0.01], 'r--', 'LineWidth', 1.2, 'DisplayName', '误差阈值0.01');
grid on;
xlabel('抽样次数'); ylabel('π值计算误差');
title('蒙特卡洛算π:误差随抽样次数变化(次数越多,误差越小)');
legend('Location', 'best');
%% 5. 输出结果
fprintf('=== 蒙特卡洛算π结果 ===\n');
fprintf('总抽样次数:%d\n', N);
fprintf('圆内点数:%d\n', K);
fprintf('π近似值:%.6f\n', pi_approx);
fprintf('真实π值:%.6f\n', pi_true);
fprintf('计算误差:%.6f\n', error);
fprintf('结论:抽样次数越多,误差越接近0,符合大数定律\n');
结果解读:
=== 蒙特卡洛算π结果 ===
总抽样次数:100000
圆内点数:78451
π近似值:3.138040
真实π值:3.141593
计算误差:0.003553
结论:抽样次数越多,误差越接近0,符合大数定律
- 图 1 中,红色点为圆内点,蓝色点为圆外点,抽样次数 100000 次时,π 值约为 3.14,误差低于0.004;
- 图 2 中,误差随抽样次数增加逐渐下降,当次数超过 35000 次后,误差稳定在 0.01 以内,验证了 “抽样越多越准” 的规律;
场景 2:进阶版 —— 算不规则图形面积(披萨 / 叶子)
功能:计算 “叶子形状” 的不规则图形面积,对比不同抽样次数的精度,可视化边界和抽样点。
% 随机封闭多边形的蒙特卡洛面积模拟
% 功能说明:
% 1. 随机生成简单多边形(无自相交),用鞋带公式计算准确面积
% 2. 用蒙特卡洛方法模拟面积,对比不同抽样次数的精度
% 3. 可视化多边形边界、抽样点分布及面积收敛曲线
% 运行说明:直接复制运行,每次运行生成不同图形;可修改N_list调整抽样次数
clear; clc; close all;
%% 1. 随机生成封闭多边形
% 生成6-10个随机顶点(按角度排序,确保多边形简单)
n_vertices = randi([6, 10]); % 顶点数:6-10个
theta = sort(rand(1, n_vertices) * 2*pi); % 角度:0~2π随机排序
r = 0.5 + rand(1, n_vertices) * 0.5; % 半径:0.5~1.0(避免顶点过于密集)
% 极坐标转直角坐标(中心在原点)
x = r .* cos(theta);
y = r .* sin(theta);
% 闭合多边形(首尾顶点相连)
x = [x, x(1)]; % 最后一点与第一点相同
y = [y, y(1)];
%% 2. 计算多边形的准确面积(鞋带公式)
% 鞋带公式:Area = 0.5 * |sum(x_i*y_{i+1} - x_{i+1}*y_i)|
polygon_area = 0;
for i = 1:length(x)-1 % 最后一点是闭合点,不重复计算polygon_area = polygon_area + (x(i)*y(i+1) - x(i+1)*y(i));
end
polygon_area = abs(polygon_area) * 0.5; % 取绝对值并乘以0.5
fprintf('=== 多边形准确面积(鞋带公式):%.4f ===\n', polygon_area);
%% 3. 确定外接矩形(完全包含多边形)
x_min = min(x); x_max = max(x);
y_min = min(y); y_max = max(y);
rect_width = x_max - x_min;
rect_height = y_max - y_min;
rect_area = rect_width * rect_height; % 外接矩形面积
%% 4. 蒙特卡洛模拟(多组抽样次数对比)
N_list = [1000, 5000, 10000, 50000, 100000]; % 抽样次数梯度
mc_area = zeros(1, length(N_list)); % 存储蒙特卡洛计算的面积
mc_error = zeros(1, length(N_list)); % 存储误差
for idx = 1:length(N_list)N = N_list(idx);% 生成矩形内的随机点x_rand = x_min + rand(1, N) * rect_width;y_rand = y_min + rand(1, N) * rect_height;% 判断每个点是否在多边形内(射线法)in_polygon = arrayfun(@(i) point_in_polygon(x_rand(i), y_rand(i), x, y), 1:N);% 计算面积与误差K = sum(in_polygon);mc_area(idx) = rect_area * K / N;mc_error(idx) = abs(mc_area(idx) - polygon_area);fprintf('抽样次数=%d:蒙特卡洛面积=%.4f,误差=%.4f\n', N, mc_area(idx), mc_error(idx));
end
%% 5. 可视化1:多边形边界与抽样点(最大抽样次数)
figure('Name', '图1:随机多边形与抽样点', 'Position', [100, 100, 700, 700]);
hold on; axis equal; grid on;
% 绘制外接矩形
rectangle('Position', [x_min, y_min, rect_width, rect_height], ...'EdgeColor', 'k', 'LineWidth', 1.2);
% 绘制多边形边界
plot(x, y, 'r-', 'LineWidth', 2, 'DisplayName', '多边形边界');
% 用最大抽样次数的点进行可视化
N_max = N_list(end);
x_rand = x_min + rand(1, N_max) * rect_width;
y_rand = y_min + rand(1, N_max) * rect_height;
in_polygon = arrayfun(@(i) point_in_polygon(x_rand(i), y_rand(i), x, y), 1:N_max);
% 绘制内外点(内绿外蓝)
plot(x_rand(in_polygon==1), y_rand(in_polygon==1), 'g.', 'MarkerSize', 1.5, 'DisplayName', '多边形内点');
plot(x_rand(in_polygon==0), y_rand(in_polygon==0), 'b.', 'MarkerSize', 1.5, 'DisplayName', '多边形外点');
title(sprintf('随机多边形(顶点数=%d):准确面积=%.4f,蒙特卡洛面积=%.4f', ...n_vertices, polygon_area, mc_area(end)));
xlabel('x坐标'); ylabel('y坐标');
legend('Location', 'best');
%% 6. 可视化2:面积误差随抽样次数变化
figure('Name', '图2:蒙特卡洛面积误差收敛曲线', 'Position', [200, 200, 800, 500]);
semilogx(N_list, mc_error, 'o-', 'Color', [0.8, 0.2, 0.2], 'LineWidth', 2, 'MarkerSize', 8);
hold on; grid on;
% 绘制误差参考线(0.01)
plot([N_list(1), N_list(end)], [0.01, 0.01], 'k--', 'LineWidth', 1.2, 'DisplayName', '误差阈值0.01');
% 添加误差标签
for i = 1:length(N_list)text(N_list(i)*1.1, mc_error(i)*1.1, sprintf('%.4f', mc_error(i)), ...'HorizontalAlignment', 'left', 'FontSize', 9);
end
xlabel('抽样次数(对数轴)');
ylabel('面积误差(蒙特卡洛值 - 准确值)');
title('蒙特卡洛面积误差随抽样次数变化(次数越多,误差越小)');
legend('Location', 'best');
ylim([0, max(mc_error)*1.2]);
%% 7. 结论输出
fprintf('\n=== 结论 ===\n');
fprintf('1. 随机多边形准确面积:%.4f(鞋带公式计算)\n', polygon_area);
fprintf('2. 蒙特卡洛模拟收敛性:抽样次数从1000→100000,误差从%.4f→%.4f\n', ...mc_error(1), mc_error(end));
fprintf('3. 规律:误差随抽样次数增加而减小,符合O(1/√N)收敛速度\n');
%% 工具函数:判断点是否在多边形内(射线法)
function flag = point_in_polygon(px, py, x, y)% 输入:点(px,py),多边形顶点(x,y)(已闭合)% 输出:1=在内部,0=在外部flag = 0;n = length(x) - 1; % 排除闭合点for i = 1:nj = i + 1;xi = x(i); yi = y(i);xj = x(j); yj = y(j);% 判断点是否在边的y范围内if ((yi > py) ~= (yj > py))% 计算射线与边的交点x坐标x_intersect = ( (py - yi) * (xj - xi) ) / (yj - yi) + xi;% 若交点在点右侧,则计数+1if px < x_intersectflag = 1 - flag; % 奇数次交叉=内部,偶数次=外部endendend
end
=== 多边形准确面积(鞋带公式):1.1518 ===
抽样次数=1000:蒙特卡洛面积=1.1186,误差=0.0332
抽样次数=5000:蒙特卡洛面积=1.1745,误差=0.0227
抽样次数=10000:蒙特卡洛面积=1.1523,误差=0.0004
抽样次数=50000:蒙特卡洛面积=1.1466,误差=0.0052
抽样次数=100000:蒙特卡洛面积=1.1500,误差=0.0019=== 结论 ===
1. 随机多边形准确面积:1.1518(鞋带公式计算)
2. 蒙特卡洛模拟收敛性:抽样次数从1000→100000,误差从0.0332→0.0019
3. 规律:误差随抽样次数增加而减小,符合O(1/√N)收敛速度
场景 3:应用版 —— 金融风险评估(股票收益模拟)
功能:模拟股票未来 1 年的价格走势,计算 “股价跌破止损线” 的风险概率,可视化收益分布和风险区间。
% 蒙特卡洛金融风险评估(应用版)
% 功能说明:
% 1. 假设股票日收益率服从正态分布,模拟未来250个交易日(1年)的价格走势
% 2. 生成10000组模拟路径,计算“股价跌破止损线”的风险概率
% 3. 生成3个可视化窗口:部分模拟路径、收益分布直方图、风险概率统计
% 运行说明:直接复制运行,无需额外文件;可修改initial_price/stop_loss调整参数
clear; clc; close all;
%% 1. 金融参数设置(基于真实股票数据假设)
initial_price = 100; % 股票初始价格(元)
stop_loss = 80; % 止损线(股价低于此值则止损,元)
mu = 0.0005; % 日收益率均值(年化约12.5%)
sigma = 0.01; % 日收益率标准差(年化约32%)
trading_days = 250; % 每年交易日数
simulation_times = 10000; % 模拟路径次数(越多越准)
%% 2. 蒙特卡洛模拟
% 生成10000组日收益率(正态分布:N(μ, σ²))
% 公式:日收益率 = μ + σ * 随机正态变量(randn生成N(0,1))
daily_return = mu + sigma * randn(simulation_times, trading_days);
% 计算每组模拟的股价走势(初始价格×累乘(1+日收益率))
stock_price = zeros(simulation_times, trading_days + 1); % 第1列是初始价格
stock_price(:, 1) = initial_price; % 第一天价格=初始价格
for i = 1:simulation_timesfor j = 1:trading_daysstock_price(i, j+1) = stock_price(i, j) * (1 + daily_return(i, j));end
end
%% 3. 风险统计
% 统计“每组模拟路径中,股价是否跌破止损线”
risk_count = 0;
for i = 1:simulation_timesif min(stock_price(i, :)) <= stop_lossrisk_count = risk_count + 1;end
end
risk_probability = risk_count / simulation_times; % 风险概率(跌破止损线的比例)
% 统计最终收益分布(250天后的收益率)
final_return = (stock_price(:, end) - initial_price) / initial_price;
return_mean = mean(final_return); % 平均收益率
return_std = std(final_return); % 收益率标准差
win_rate = sum(final_return > 0) / simulation_times; % 盈利概率(收益率>0)
%% 4. 可视化1:部分模拟路径(取前50组,避免图线杂乱)
figure('Name', '图1:蒙特卡洛金融模拟——股票价格路径', 'Position', [100, 100, 1000, 600]);
hold on; grid on;
days = 0:trading_days; % 天数(0=初始日,250=最后一天)
for i = 1:min(50, simulation_times)plot(days, stock_price(i, :), 'Color', [0.5, 0.5, 0.5, 0.6], 'LineWidth', 1);
end
% 绘制初始价格和止损线
plot(days, initial_price * ones(1, length(days)), 'k-', 'LineWidth', 1.5, 'DisplayName', '初始价格');
plot(days, stop_loss * ones(1, length(days)), 'r--', 'LineWidth', 1.5, 'DisplayName', '止损线');
% 突出显示“跌破止损线”的路径(取第1条风险路径)
risk_path_idx = find(min(stock_price) <= stop_loss, 1);
if ~isempty(risk_path_idx)plot(days, stock_price(risk_path_idx, :), 'r-', 'LineWidth', 2, 'DisplayName', '跌破止损线的路径');
end
title(sprintf('股票价格模拟(%d组路径,风险概率=%.2f%%)', simulation_times, risk_probability*100));
xlabel('交易日'); ylabel('股票价格(元)');
legend('Location', 'best');
%% 5. 可视化2:最终收益率分布直方图
figure('Name', '图2:蒙特卡洛金融模拟——收益率分布', 'Position', [200, 200, 800, 500]);
% 绘制直方图( bins=50,统计收益率分布)
histogram(final_return, 50, 'FaceColor', [0.6, 0.8, 1.0], 'EdgeColor', 'black');
hold on;
% 绘制平均收益率线和0收益线
plot([return_mean, return_mean], [0, max(histcounts(final_return, 50))], ...'g-', 'LineWidth', 1.5, 'DisplayName', sprintf('平均收益率=%.2f%%', return_mean*100));
plot([0, 0], [0, max(histcounts(final_return, 50))], ...'r--', 'LineWidth', 1.5, 'DisplayName', '0收益线(盈亏平衡)');
grid on;
xlabel('250天后的收益率(正=盈利,负=亏损)');
ylabel('模拟路径次数');
title(sprintf('股票最终收益率分布(盈利概率=%.2f%%,收益率标准差=%.2f%%)', win_rate*100, return_std*100));
legend('Location', 'best');
%% 6. 可视化3:风险概率统计(不同止损线下的风险)
figure('Name', '图3:蒙特卡洛金融模拟——不同止损线风险对比', 'Position', [300, 300, 800, 500]);
% 计算不同止损线下的风险概率(70元、75元、80元、85元、90元)
stop_loss_list = 70:5:90;
risk_prob_list = zeros(1, length(stop_loss_list));
for i = 1:length(stop_loss_list)current_stop_loss = stop_loss_list(i);current_risk_count = 0;for j = 1:simulation_timesif min(stock_price(j, :)) <= current_stop_losscurrent_risk_count = current_risk_count + 1;endendrisk_prob_list(i) = current_risk_count / simulation_times;
end
% 绘制风险概率曲线
plot(stop_loss_list, risk_prob_list*100, 'o-', 'LineWidth', 2, 'MarkerSize', 8, 'Color', 'red');
hold on; grid on;
% 添加数据标签
for i = 1:length(stop_loss_list)text(stop_loss_list(i)+0.5, risk_prob_list(i)*100+0.5, sprintf('%.2f%%', risk_prob_list(i)*100), ...'HorizontalAlignment', 'left', 'FontSize', 10);
end
xlabel('止损线价格(元)');
ylabel('风险概率(%)');
title('不同止损线下的风险概率(止损线越高,风险概率越大)');
ylim([0, max(risk_prob_list)*100 + 2]);
%% 7. 输出风险评估报告
fprintf('\n=== 蒙特卡洛股票风险评估报告 ===\n');
fprintf('基础参数:\n');
fprintf(' - 初始股价:%.2f元,止损线:%.2f元\n', initial_price, stop_loss);
fprintf(' - 日收益率均值:%.4f(年化%.2f%%),标准差:%.4f(年化%.2f%%)\n', ...mu, mu*250*100, sigma, sigma*sqrt(250)*100);
fprintf(' - 模拟路径:%d组,交易日:%d天(1年)\n', simulation_times, trading_days);
fprintf('\n风险统计结果:\n');
fprintf('1. 跌破止损线的风险概率:%.2f%%(%d/%d组路径)\n', risk_probability*100, risk_count, simulation_times);
fprintf('2. 250天后盈利概率:%.2f%%(收益率>0的路径比例)\n', win_rate*100);
fprintf('3. 平均收益率:%.2f%%,收益率标准差:%.2f%%\n', return_mean*100, return_std*100);
fprintf('\n投资建议:\n');
if risk_probability > 0.2fprintf(' - 风险概率较高(>20%%),建议降低止损线或减少仓位\n');
elseif risk_probability > 0.1fprintf(' - 风险概率中等(10%%-20%%),建议设置对冲策略\n');
elsefprintf(' - 风险概率较低(<10%%),可维持当前仓位\n');
end
%% 函数定义
% 函数:计算单组股票价格路径
function price_path = stock_price_simulation(initial_price, mu, sigma, trading_days)% 输入:初始价格、日收益率均值、标准差、交易日数% 输出:股票价格路径(1×(trading_days+1))daily_return = mu + sigma * randn(1, trading_days);price_path = zeros(1, trading_days + 1);price_path(1) = initial_price;for j = 1:trading_daysprice_path(j+1) = price_path(j) * (1 + daily_return(j));end
end
结果解读:
- 图 1 中,灰色线为 10000 组模拟路径中的前 50 组,红色线为 “跌破止损线” 的路径,可直观看到股价的随机波动;
- 图 2 中,收益率分布呈正态分布,平均收益率约 13.89%(年化),盈利概率约 60.19%,符合股票市场的 “风险与收益并存” 规律;
- 图 3 中,止损线从 70 元提高到 90 元,风险概率从 17.89% 增至 63.46%,说明 “止损线越严格,触发止损的风险越高”,为投资决策提供量化依据;
- 若修改
mu
和sigma
(比如将sigma
从 0.02 改为 0.01,降低波动率),风险概率会显著下降,验证了 “低波动率资产风险更低” 的常识。
=== 蒙特卡洛股票风险评估报告 ===
基础参数:
- 初始股价:100.00元,止损线:80.00元
- 日收益率均值:0.0005(年化12.50%),标准差:0.0200(年化31.62%)
- 模拟路径:10000组,交易日:250天(1年)风险统计结果:
1. 跌破止损线的风险概率:37.01%(3701/10000组路径)
2. 250天后盈利概率:60.19%(收益率>0的路径比例)
3. 平均收益率:13.89%,收益率标准差:36.79%
投资建议:
- 风险概率较高(>20%),建议降低止损线或减少仓位
=== 蒙特卡洛股票风险评估报告 ===
基础参数:
- 初始股价:100.00元,止损线:80.00元
- 日收益率均值:0.0005(年化12.50%),标准差:0.0100(年化15.81%)
- 模拟路径:10000组,交易日:250天(1年)风险统计结果:
1. 跌破止损线的风险概率:4.16%(416/10000组路径)
2. 250天后盈利概率:77.45%(收益率>0的路径比例)
3. 平均收益率:13.58%,收益率标准差:17.82%投资建议:
- 风险概率较低(<10%),可维持当前仓位
结语:蒙特卡洛的诗意 —— 在随机中寻找确定
从 “撒芝麻算披萨面积”,到 “模拟股票收益”,蒙特卡洛算法的本质,是 “用大量随机的‘点’,编织出确定的‘规律’”。它不追求 “一次算准”,而是通过 “多次尝试” 逼近真相 —— 这像极了生活中的道理:
- 想知道 “努力是否有回报”,不用纠结 “一次失败”,而是看 “长期努力后的成功概率”;
- 想找到 “最优解”,不用害怕 “试错”,而是通过 “多次尝试” 缩小范围,最终逼近目标。
技术的温度,正在于它能将复杂的数学逻辑,转化为解决生活问题的工具。蒙特卡洛告诉我们:“随机” 不是 “无序”,而是破解复杂问题的另一种 “有序”—— 当我们无法用公式精准计算时,不妨用 “随机抽样” 的智慧,在不确定中寻找确定。
下一篇,我们将探讨蒙特卡洛的进阶应用 ——“马尔可夫链蒙特卡洛(MCMC)”,看它如何解决 “高维复杂问题” 的抽样难题,比如模拟 AI 模型的参数分布。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/927238.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!