المشي العشوائي بخطوات متقلصة
تخيّل سعرًا يتحرك صعودًا أو هبوطًا كل ثانية بمقدار عشوائي. اجعل الفترة أقصر فأقصر وقلّص كل خطوة ليبقى التشتت الكلي معقولًا: النهاية هي الحركة البراونية W(t) التي وُضعت لوصف حبوب اللقاح في الماء وتبناها باشلييه عام 1900 لنمذجة الأسعار. وتُعرَّف بثلاث خواص: W(0) = 0؛ والزيادات على فترات غير متداخلة مستقلة؛ وW(t) - W(s) طبيعي بمتوسط 0 وتباين t - s.
import numpy as np
rng = np.random.default_rng(1)
dt = 0.01
z = rng.standard_normal(5) # standard normal draws
increments = z * np.sqrt(dt) # each step over dt has standard deviation sqrt(dt)
print(np.round(increments, 4))المسار مجموع تراكمي
لمحاكاة مسار على شبكة أزمنة 0, dt, 2 dt, ... نسحب z طبيعيًا معياريًا لكل خطوة ونحجّمه بـsqrt(dt) ونجمع: W(k * dt) هو مجموع أول k زيادة، np.cumsum. ونضع 0 في المقدمة لأن المسار يبدأ من 0. وتباين W(t) يساوي t، فيتسع تشتت الموضع بجذر الزمن، وهو قانون الجذر التربيعي نفسه في تحجيم التقلب والقيمة المعرضة.
import numpy as np
def brownian_path(z, dt):
return np.concatenate([[0.0], np.cumsum(z * np.sqrt(dt))])
rng = np.random.default_rng(1)
n, dt = 252, 1 / 252
ends = np.array([brownian_path(rng.standard_normal(n), dt)[-1] for _ in range(4000)])
print(round(float(ends.mean()), 3), round(float(ends.var()), 3)) # about 0 and 1: W(1) is a standard normalمسار خشن إلى ما لا نهاية
المسار البراوني متصل لكنه غير أملس في أي موضع، وطوله لانهائي. وللخشونة مقياس دقيق هو التباين التربيعي، مجموع مربعات الخطوات. وفي المنحنى الأملس يؤول هذا المجموع إلى 0 كلما دقّت الشبكة؛ أما في الحركة البراونية فيبقى الزمن المنقضي t أيًّا كانت الشبكة لأن مربع كل خطوة نحو dt وعددها t / dt. وهذه الحقيقة (dW)^2 = dt هي ما يميز التفاضل والتكامل العشوائي عن العادي، وهي مفتاح المواضيع التالية.
import numpy as np
def quadratic_variation(path):
return float(np.sum(np.diff(path) ** 2))
rng = np.random.default_rng(2)
t = 2.0
for steps in (10, 100, 10000):
dt = t / steps
path = np.concatenate([[0.0], np.cumsum(rng.standard_normal(steps) * np.sqrt(dt))])
print(steps, round(quadratic_variation(path), 3)) # settles near 2.0 as the grid gets finer
smooth = np.linspace(0, 1, 10001) * 2
print(round(quadratic_variation(smooth), 5)) # a straight line: close to 0الانجراف والتقلب
للسعر اتجاه ومقياس. والحركة البراونية الحسابية ذات الانجراف هي X(t) = mu * t + sigma * W(t): mu الانجراف (الاتجاه لكل وحدة زمن) وsigma التقلب (مقياس الجزء العشوائي). وهي أبسط نموذج لتغير السعر، ويمكن أن تصبح سالبة، ولذلك تُنمذج الأسعار نفسها بحركة براونية هندسية في الموضوع التالي. وتظل لبنة أساسية للفائدة والهوامش.
import numpy as np
def drifted_path(z, dt, mu, sigma):
t = np.arange(len(z) + 1) * dt
w = np.concatenate([[0.0], np.cumsum(z * np.sqrt(dt))])
return mu * t + sigma * w
rng = np.random.default_rng(3)
n, dt = 252, 1 / 252
path = drifted_path(rng.standard_normal(n), dt, 0.08, 0.2) # 8% a year drift, 20% volatility
print(round(float(path[-1]), 4), "after one year; the drift alone would give 0.08")
print(np.round(drifted_path(np.zeros(4), 0.25, 0.08, 0.2), 4)) # no noise: just the trend linenp.random.default_rng(seed)) فيصبح التشغيل قابلًا للتكرار. ومسار واحد لا يثبت شيئًا: فإحصاءات مثل متوسط W(1) أو تباينه لا تظهر إلا عبر آلاف المسارات، ويتناقص خطأ تقدير مونت كارلو مثل 1 / sqrt(paths).- تبدأ الحركة البراونية من 0 وزياداتها طبيعية مستقلة بتباين
dt: تُحاكى بـz * sqrt(dt)ومجموع تراكمي. - تباين
W(t)هوt، والتباين التربيعي للمسار يبقى الزمن المنقضي:(dW)^2 = dt. - أضف الاتجاه والمقياس بـ
X(t) = mu * t + sigma * W(t)؛ مسار واحد لا يثبت شيئًا والإحصاءات تحتاج مسارات كثيرة.
التالي: الحركة البراونية الهندسية، النموذج الذي لا تصبح فيه الأسعار سالبة.
المختبر: ما الذي يُقيَّم
- حجِّم الصدمات باستخدام
brownian_increments25 نقطة - ابنِ المسار باستخدام
brownian_path25 نقطة - قِس الخشونة باستخدام
quadratic_variation25 نقطة - أضف اتجاهًا باستخدام
drifted_path25 نقطة