如何在 tikz/pgf 中绘制几何布朗运动

如何在 tikz/pgf 中绘制几何布朗运动

我正在尝试复制这个优秀的答案解释了如何在 TiKZ 中绘制布朗运动:

\newcommand{\Lathrop}[6]{% points, advance, rand factor, options, end label, truncate from point
    \draw[#4] (0,0)
    \foreach \x in {1,...,#6} { 
        -- ++ (#2,rand*#3)
    }
    coordinate (tempcoord) {};
    \pgfmathsetmacro{\remainingwidth}{(#1-#6)*#2}; % changed to a custom number
    \def\remainingwidthcustom{1};
    \draw[#4] (tempcoord) -- ++ (\remainingwidthcustom,0) node[right] {#5};
}

\begin{tikzpicture}
    \def\ylength{3}
    \pgfmathsetseed{3} % control pseudo-random number

    % Axis
    \coordinate (y) at (0,3); \coordinate (x) at (6,0);
    \draw[<->] (y) node[above] {$S$} -- (0,0) --  (x) node[right] {$\mathbb{N}$};

    % Brownian motion
    \Lathrop{750}{0.02}{0.21}{blue!70!black}{strike price $S_N$}{250};

\end{tikzpicture}

我的问题是,由于两个原因,我无法将其更改为几何布朗运动:

  1. 我无法通过pgfmathparse
  2. 我不完全理解-loop 里面的语法\foreach \x

任何帮助都将受到赞赏。

答案1

在此处输入图片描述

我使用了 Mark Wibrow 定义的函数(参见高斯随机数) 得到高斯随机数,然后根据该高斯随机数绘制具有不同方差值的几何高斯运动。

代码

\documentclass[11pt, margin=.5cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{math}

%% Mark Wibrow's code
\newcount\gaussF
\edef\gaussR{0}
\edef\gaussA{0}

\makeatletter
\pgfmathdeclarefunction{gaussR}{0}{%
 \global\advance\gaussF by 1\relax
 \ifodd\gaussF
  \pgfmathrnd@%
  \ifdim\pgfmathresult pt=0.0pt\relax%
    \def\pgfmathresult{0.00001}%
  \fi
  \pgfmathln@{\pgfmathresult}%
  \pgfmathmultiply@{-2}{\pgfmathresult}%
  \pgfmathsqrt@{\pgfmathresult}%
  \global\let\gaussR=\pgfmathresult%radius
  \pgfmathrnd@%
  \pgfmathmultiply@{360}{\pgfmathresult}%
  \global\let\gaussA=\pgfmathresult%angle
  \pgfmathcos@{\pgfmathresult}%
  \pgfmathmultiply@{\pgfmathresult}{\gaussR}%
 \else
  \pgfmathsin@{\gaussA}%
  \pgfmathmultiply@{\gaussR}{\pgfmathresult}%
 \fi
}

\pgfmathdeclarefunction{invgauss}{2}{%
  \pgfmathln{#1}% <- might need parsing
  \pgfmathmultiply@{\pgfmathresult}{-2}%
  \pgfmathsqrt@{\pgfmathresult}%
  \let\@radius=\pgfmathresult%
  \pgfmathmultiply{6.28318531}{#2}% <- might need parsing
  \pgfmathdeg@{\pgfmathresult}%
  \pgfmathcos@{\pgfmathresult}%
  \pgfmathmultiply@{\pgfmathresult}{\@radius}%
}

\pgfmathdeclarefunction{randnormal}{0}{%
  \pgfmathrnd@
  \ifdim\pgfmathresult pt=0.0pt\relax%
    \def\pgfmathresult{0.00001}%
  \fi%
  \let\@tmp=\pgfmathresult%
  \pgfmathrnd@%
  \ifdim\pgfmathresult pt=0.0pt\relax%
    \def\pgfmathresult{0.00001}%
  \fi
  \pgfmathinvgauss@{\pgfmathresult}{\@tmp}%
}

\begin{document}
\tikzmath{%
  real \m, \s, \xBound, \yBound, \v0;
  \xBound = 3.5;
  \yBound = 7;
  \m = 1;
  \v0 = .2;
  function GBM(\t, \ini, \s) { % argument, initial value, standard deviation
    return {\ini*exp((\m -\s*\s/2)*\t +\s*randnormal/10))};
  };
}
\begin{tikzpicture}[xscale=2]
  \draw[gray, ->] (-.5, 0) -- (\xBound +.5, 0);
  \draw[gray, ->] (0, -1.2) -- (0, \yBound);

  \foreach \s/\rgb in {.2/black, .5/violet, .7/blue,
    .9/green!70!black, 1.2/orange, 1.7/red}{%
    \draw[\rgb, thick] (0, \v0)
    \foreach \t in {.05, .1, ..., \xBound}{%
      -- (\t, {GBM(\t, \v0, \s)})
    };
  }
\end{tikzpicture}

\end{document}

相关内容