رقمان لتوزيع
يصعب مقارنة عمود من العوائد بآخر. ويلخّص رقمان معظمه: المتوسط يبيّن أين تتمركز العوائد، والتباين يبيّن مدى تبعثرها حول ذلك المركز. لـ n من العوائد المتوسط هو sum(x) / n؛ ومجموع الانحرافات x - mean يساوي صفرًا دائمًا، فلقياس التبعثر تُربَّع أولًا. والتباين العيّني هو مجموع مربعات الانحرافات مقسومًا على n - 1 لا n: فقد قُدِّر المتوسط من البيانات نفسها مما يجعل الانحرافات أصغر قليلًا، والقسمة على n - 1 تصحح ذلك.
import numpy as np
returns = np.array([0.004, -0.002, 0.001, 0.003, -0.004, 0.002, 0.006, -0.001])
mean = returns.mean()
deviations = returns - mean
print(round(mean, 5)) # 0.00113
print(abs(deviations.sum()) < 1e-12) # True the deviations always add up to zero
variance = (deviations ** 2).sum() / (len(returns) - 1)
print(round(variance, 8), round(returns.var(ddof=1), 8)) # 1.098e-05 1.098e-05 the same as numpy's var(ddof=1)الانحراف المعياري والتقلب
غيّر التربيع الوحدات: تباين العوائد بوحدة «نسبة مئوية مربعة». وجذره التربيعي، الانحراف المعياري، يعود إلى وحدة العوائد، ويُسمى في التمويل التقلب. وهو أشيع مقياس للمخاطر. اليوم المعتاد لسهم كبير يتحرك نحو 1 إلى 2%، أي تقلب 0.01 إلى 0.02 يوميًا. ويُقرأ نسبةً إلى المتوسط: مع تقلب 1.2% يوميًا يبعد يوم -3.6% ثلاثة انحرافات معيارية.
std = np.sqrt(variance)
print(round(std, 6), round(returns.std(ddof=1), 6)) # 0.003314 0.003314 daily volatility of these returns
# How many standard deviations is the worst day from the mean?
print(round((returns.min() - mean) / std, 2)) # -1.55التحويل إلى سنوي ونسبة شارب
الأرقام اليومية صغيرة وقليلة الدلالة، لذا تُذكر سنويًا. ينمو المتوسط خطيًا مع الزمن (252 يوم تداول في السنة: اضرب في 252)، لكن التقلب ينمو مع الجذر التربيعي للزمن: اضرب في sqrt(252) أي نحو 15.9. والسبب أن الحركات اليومية العشوائية يلغي بعضها بعضًا جزئيًا، فتتراكم الريبة أبطأ من المتوسط. وتقسم نسبة شارب متوسط العائد فوق معدل الخالي من المخاطر (العائد الزائد) على التقلب: المكافأة لكل وحدة مخاطرة، مُحوَّلة إلى سنوي بالطريقة نفسها. وتتيح مقارنة استراتيجية هادئة بأخرى جامحة.
periods = 252
print(round(mean * periods, 4)) # 0.2835 annual mean: 28.35% (a made-up, very lucky sample)
print(round(std * np.sqrt(periods), 4)) # 0.0526 annual volatility: 5.26%
risk_free = 0.0001 # risk-free return of one day
excess = returns - risk_free
sharpe = excess.mean() / np.sqrt(((excess - excess.mean()) ** 2).sum() / (len(excess) - 1)) * np.sqrt(periods)
print(round(sharpe, 3)) # 4.91 absurdly good, because 8 lucky days prove nothing# How precisely do 8 days pin down the mean? The standard error is std / sqrt(n)
standard_error = std / np.sqrt(len(returns))
print(round(float(standard_error), 6)) # 0.001172 larger than the mean itself (0.00113)std / sqrt(n) أي 0.0012 هنا، وهو أكبر من المتوسط نفسه (0.0011). ونسبة شارب ممتازة على بضعة أسابيع لا تقول الكثير؛ وكلما زادت الملاحظات زادت الثقة بالمتوسط، وأرقام المخاطر أكثر ثباتًا بكثير من متوسطات العوائد.- المتوسط:
x.mean()؛ التباين العيّني:((x - mean) ** 2).sum() / (n - 1)؛ والتقلب جذره التربيعي. - حوّل المتوسط إلى سنوي بـ
* periodsوالتقلب بـ* sqrt(periods): المخاطر تنمو مع الجذر التربيعي للزمن. - شارب = متوسط العائد الزائد / انحرافه المعياري *
sqrt(periods): مكافأة لكل وحدة مخاطرة؛ والعينة القصيرة تجعلها غير موثوقة.
التالي: الالتواء والتفرطح، الإحصاءان اللذان يصفان شكل التوزيع إلى جانب مركزه وتشتته.
المختبر: ما الذي يُقيَّم
- قِس تشتت العوائد باستخدام
sample_variance25 نقطة - عبّر عن التشتت بوحدة العوائد باستخدام
sample_std25 نقطة - حوّل المتوسط والتقلب إلى سنوي باستخدام
annualized_stats25 نقطة - قيّم العائد لكل وحدة مخاطرة باستخدام
sharpe_ratio25 نقطة