هل تتنبأ الإشارة بشيء؟
قبل بناء استراتيجية على إشارة اسأل هل تشير في الاتجاه الصحيح. في كل يوم تعطي الإشارة درجة لكل سهم، وبعد يوم يكون لكل سهم عائد. ومعامل المعلومات (IC) هو الارتباط عبر الأسهم بين الدرجة والعائد اللاحق. وهو بين -1 و1؛ والصفر يعني انعدام القدرة التنبؤية. والإشارات الحقيقية ضعيفة: معامل معلومات من 0.02 إلى 0.05 مفيد أصلًا لأنه يتكرر عبر أسهم كثيرة وأيام كثيرة.
import numpy as np
signal = np.array([0.3, -1.2, 0.8, 0.1, 1.5]) # today's score for five stocks
returns = np.array([0.01, -0.02, 0.005, -0.004, 0.03]) # their returns over the next day
s = signal - signal.mean()
r = returns - returns.mean()
ic = np.sum(s * r) / np.sqrt(np.sum(s ** 2) * np.sum(r ** 2)) # the Pearson correlation
print(round(float(ic), 4))
print(round(float(np.corrcoef(signal, returns)[0, 1]), 4)) # the same numberمعامل المعلومات الرتبي: متين أمام القيم الشاذة
يهيمن على ارتباط بيرسون القيم المتطرفة: فسهم ذو درجة هائلة أو قفزة 40% في يوم قد يقلبه. أما معامل المعلومات الرتبي فيستبدل بكل مصفوفة رتب قيمها (1 للأصغر) ويربط الرتب. وهو لا يسأل إلا هل ينتهي ما تضعه الإشارة أعلى في مرتبة أعلى، مهما كان حجم الأرقام، فلا يتغير بأي تحويل تصاعدي للإشارة. وهو النسخة التي تذكرها معظم الفرق الكمية، وهو ارتباط سبيرمان.
# The rank of each value: argsort gives the order, assigning 1..n through it gives the ranks
import numpy as np
values = np.array([30.0, 10.0, 20.0, 5.0])
order = np.argsort(values) # positions from smallest to largest: [3 1 2 0]
ranks = np.empty(len(values))
ranks[order] = np.arange(1, len(values) + 1)
print(order, ranks) # [3 1 2 0] [4. 2. 3. 1.]# Ranks via argsort, and a rank IC that shrugs off an extreme value
import numpy as np
def ranks(values):
order = np.argsort(values)
out = np.empty(len(values))
out[order] = np.arange(1, len(values) + 1)
return out
def ic(a, b):
a, b = a - a.mean(), b - b.mean()
return float(np.sum(a * b) / np.sqrt(np.sum(a ** 2) * np.sum(b ** 2)))
signal = np.array([0.3, -1.2, 0.8, 0.1, 1.5])
returns = np.array([0.01, -0.02, 0.005, -0.004, 0.03])
print(ranks(signal)) # [3. 1. 4. 2. 5.]
print(round(ic(signal, returns), 4), round(ic(ranks(signal), ranks(returns)), 4))
signal_with_outlier = signal.copy()
signal_with_outlier[4] = 1000.0 # one absurd score
print(round(ic(signal_with_outlier, returns), 4), round(ic(ranks(signal_with_outlier), ranks(returns)), 4))الاتساق عبر الزمن: نسبة معلومات معامل المعلومات
معامل المعلومات ليوم واحد مضطرب. احسبه كل يوم لتحصل على سلسلة، وانظر إلى متوسطها وثباتها. وICIR، أي متوسط المعامل مقسومًا على انحرافه المعياري، يكافئ الإشارات التي تصيب قليلًا كل يوم على التي تصيب كثيرًا في أيام قليلة. وهو نسبة شبيهة بشارب للإشارة نفسها. وسلسلة يومية من القيم بمتوسط 0.03 وانحراف 0.06 لها ICIR قدره 0.5.
# A daily rank-IC series for a weak signal, and its ICIR
import numpy as np
def ranks(values):
out = np.empty(len(values))
out[np.argsort(values)] = np.arange(1, len(values) + 1)
return out
def ic(a, b):
a, b = a - a.mean(), b - b.mean()
return float(np.sum(a * b) / np.sqrt(np.sum(a ** 2) * np.sum(b ** 2)))
rng = np.random.default_rng(8)
daily_ics = []
for day in range(250):
signal = rng.normal(size=300) # 300 stocks
returns = 0.01 * (0.05 * signal + rng.normal(size=300)) # the signal explains a sliver of the return
daily_ics.append(ic(ranks(signal), ranks(returns)))
daily_ics = np.array(daily_ics)
print(round(float(daily_ics.mean()), 4), round(float(daily_ics.std(ddof=1)), 4))
print(round(float(daily_ics.mean() / daily_ics.std(ddof=1)), 3))- معامل المعلومات هو الارتباط بين إشارة اليوم عبر الأسهم وعوائدها اللاحقة؛ من 0.02 إلى 0.05 مفيد وفوق 0.1 مريب.
- يربط معامل المعلومات الرتبي الرتب (
argsortمرتين): متين أمام القيم الشاذة ولا يتغير بأي تحويل تصاعدي للإشارة. - ICIR = متوسط IC / انحرافه المعياري عبر أيام كثيرة: يكافئ المهارة الثابتة؛ وقيّم دائمًا خارج العينة.
التالي: القيمة المعرضة للخطر التاريخية، الخسارة التي لا ينبغي أن تتجاوزها المحفظة إلا في أسوأ الأيام.
المختبر: ما الذي يُقيَّم
- رتّب القيم باستخدام
ranks25 نقطة - اربط الإشارة بالنتيجة باستخدام
ic25 نقطة - تجاهل القيم الشاذة باستخدام
rank_ic25 نقطة - احكم على الاتساق باستخدام
icir25 نقطة