खोज…


क्विंटाइल विश्लेषण: यादृच्छिक डेटा के साथ

सुरक्षा कारकों की प्रभावकारिता के मूल्यांकन के लिए क्विंटाइल विश्लेषण एक सामान्य ढांचा है।

एक कारक क्या है

एक कारक प्रतिभूतियों के सेट स्कोरिंग / रैंकिंग के लिए एक विधि है। समय में एक विशेष बिंदु के लिए और प्रतिभूतियों के एक विशेष सेट के लिए, एक कारक को पांडा श्रृंखला के रूप में दर्शाया जा सकता है जहां सूचकांक सुरक्षा पहचानकर्ताओं की एक सरणी है और मान स्कोर या रैंक हैं।

यदि हम समय के साथ कारक स्कोर लेते हैं, तो हम समय के प्रत्येक बिंदु पर, कारकों के स्कोर के क्रम के आधार पर प्रतिभूतियों के सेट को 5 बराबर बाल्टियों या क्विंटलों में विभाजित कर सकते हैं। संख्या 5 के बारे में कुछ भी विशेष रूप से पवित्र नहीं है। हम 3 या 10. का उपयोग कर सकते थे लेकिन हम अक्सर 5 का उपयोग करते हैं। अंत में, हम यह निर्धारित करने के लिए पांच बाल्टियों में से प्रत्येक के प्रदर्शन को ट्रैक करते हैं कि रिटर्न में सार्थक अंतर है या नहीं। हम सबसे उच्च रैंक के साथ सबसे कम रैंक के साथ बाल्टी के रिटर्न में अंतर पर अधिक ध्यान केंद्रित करते हैं।


चलो कुछ पैरामीटर सेट करके और यादृच्छिक डेटा उत्पन्न करके शुरू करते हैं।

यांत्रिकी के साथ प्रयोग को सुविधाजनक बनाने के लिए, हम हमें यह पता लगाने के लिए यादृच्छिक कोड बनाते हैं कि यह कैसे काम करता है।

रैंडम डेटा शामिल हैं

  • रिटर्न : निर्दिष्ट संख्या में प्रतिभूतियों और अवधि के लिए यादृच्छिक रिटर्न उत्पन्न करते हैं।
  • सिग्नल : प्रतिभूतियों और अवधि की निर्दिष्ट संख्या और रिटर्न के साथ सहसंबंध के निर्धारित स्तर के लिए यादृच्छिक संकेत उत्पन्न करते हैं। एक कारक के उपयोगी होने के लिए, स्कोर / रैंक और बाद के रिटर्न के बीच कुछ जानकारी या सहसंबंध होना चाहिए। यदि सहसंबंध नहीं थे, तो हम इसे देखेंगे। यह पाठक के लिए एक अच्छा अभ्यास होगा, इस विश्लेषण को 0 सहसंबंध के साथ उत्पन्न यादृच्छिक डेटा के साथ डुप्लिकेट करें।

प्रारंभ

import pandas as pd
import numpy as np

num_securities = 1000
num_periods = 1000
period_frequency = 'W'
start_date = '2000-12-31'

np.random.seed([3,1415])

means = [0, 0]
covariance = [[  1., 5e-3],
              [5e-3,   1.]]

# generates to sets of data m[0] and m[1] with ~0.005 correlation
m = np.random.multivariate_normal(means, covariance,
                                  (num_periods, num_securities)).T

अब एक समय श्रृंखला सूचकांक और सुरक्षा आईडी का प्रतिनिधित्व करने वाला एक सूचकांक उत्पन्न करते हैं। फिर रिटर्न और सिग्नल के लिए डेटाफ्रेम बनाने के लिए उनका उपयोग करें

ids = pd.Index(['s{:05d}'.format(s) for s in range(num_securities)], 'ID')
tidx = pd.date_range(start=start_date, periods=num_periods, freq=period_frequency)

मैं m[0] को 25 से विभाजित करता हूं जो कि स्टॉक रिटर्न की तरह दिखता है। मैं मामूली सकारात्मक रिटर्न देने के लिए 1e-7 भी जोड़ता हूं।

security_returns = pd.DataFrame(m[0] / 25 + 1e-7, tidx, ids)
security_signals = pd.DataFrame(m[1], tidx, ids)

pd.qcut - pd.qcut बकेट बनाएँ

आइए प्रत्येक अवधि के लिए pd.qcut बकेट में मेरे संकेतों को विभाजित करने के लिए pd.qcut का उपयोग करें।

def qcut(s, q=5):
    labels = ['q{}'.format(i) for i in range(1, 6)]
    return pd.qcut(s, q, labels=labels)
    
cut = security_signals.stack().groupby(level=0).apply(qcut)

हमारे रिटर्न पर सूचकांक के रूप में इन कटौती का उपयोग करें

returns_cut = security_returns.stack().rename('returns') \
    .to_frame().set_index(cut, append=True) \
    .swaplevel(2, 1).sort_index().squeeze() \
    .groupby(level=[0, 1]).mean().unstack()

विश्लेषण

प्लॉट रिटर्न

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(15, 5))
ax1 = plt.subplot2grid((1,3), (0,0))
ax2 = plt.subplot2grid((1,3), (0,1))
ax3 = plt.subplot2grid((1,3), (0,2))

# Cumulative Returns
returns_cut.add(1).cumprod() \
    .plot(colormap='jet', ax=ax1, title="Cumulative Returns")
leg1 = ax1.legend(loc='upper left', ncol=2, prop={'size': 10}, fancybox=True)
leg1.get_frame().set_alpha(.8)

# Rolling 50 Week Return
returns_cut.add(1).rolling(50).apply(lambda x: x.prod()) \
    .plot(colormap='jet', ax=ax2, title="Rolling 50 Week Return")
leg2 = ax2.legend(loc='upper left', ncol=2, prop={'size': 10}, fancybox=True)
leg2.get_frame().set_alpha(.8)

# Return Distribution
returns_cut.plot.box(vert=False, ax=ax3, title="Return Distribution")

fig.autofmt_xdate()

plt.show()

यहाँ छवि विवरण दर्ज करें

scatter_matrix साथ scatter_matrix सहसंबंध की कल्पना करें

from pandas.tools.plotting import scatter_matrix

scatter_matrix(returns_cut, alpha=0.5, figsize=(8, 8), diagonal='hist')
plt.show()

यहाँ छवि विवरण दर्ज करें

अधिकतम ड्रा डाउन की गणना और कल्पना करें

def max_dd(returns):
    """returns is a series"""
    r = returns.add(1).cumprod()
    dd = r.div(r.cummax()).sub(1)
    mdd = dd.min()
    end = dd.argmin()
    start = r.loc[:end].argmax()
    return mdd, start, end

def max_dd_df(returns):
    """returns is a dataframe"""
    series = lambda x: pd.Series(x, ['Draw Down', 'Start', 'End'])
    return returns.apply(max_dd).apply(series)

यह किसकी तरह दिखता है

max_dd_df(returns_cut)

यहाँ छवि विवरण दर्ज करें

इसे साजिश करते हैं

draw_downs = max_dd_df(returns_cut)

fig, axes = plt.subplots(5, 1, figsize=(10, 8))
for i, ax in enumerate(axes[::-1]):
    returns_cut.iloc[:, i].add(1).cumprod().plot(ax=ax)
    sd, ed = draw_downs[['Start', 'End']].iloc[i]
    ax.axvspan(sd, ed, alpha=0.1, color='r')
    ax.set_ylabel(returns_cut.columns[i])

fig.suptitle('Maximum Draw Down', fontsize=18)
fig.tight_layout()
plt.subplots_adjust(top=.95)

यहाँ छवि विवरण दर्ज करें

सांख्यिकी की गणना करें

कई संभावित आँकड़े हैं जिन्हें हम शामिल कर सकते हैं। नीचे कुछ ही हैं, लेकिन प्रदर्शित करते हैं कि कैसे हम नए आंकड़ों को अपने सारांश में शामिल कर सकते हैं।

def frequency_of_time_series(df):
    start, end = df.index.min(), df.index.max()
    delta = end - start
    return round((len(df) - 1.) * 365.25 / delta.days, 2)

def annualized_return(df):
    freq = frequency_of_time_series(df)
    return df.add(1).prod() ** (1 / freq) - 1
    
def annualized_volatility(df):
    freq = frequency_of_time_series(df)
    return df.std().mul(freq ** .5)

def sharpe_ratio(df):
    return annualized_return(df) / annualized_volatility(df)

def describe(df):
    r = annualized_return(df).rename('Return')
    v = annualized_volatility(df).rename('Volatility')
    s = sharpe_ratio(df).rename('Sharpe')
    skew = df.skew().rename('Skew')
    kurt = df.kurt().rename('Kurtosis')
    desc = df.describe().T
    
    return pd.concat([r, v, s, skew, kurt, desc], axis=1).T.drop('count')

हम केवल describe फ़ंक्शन का उपयोग करके समाप्त करेंगे क्योंकि यह अन्य सभी को एक साथ खींचता है।

describe(returns_cut)

यहाँ छवि विवरण दर्ज करें


यह व्यापक होने का मतलब नहीं है। यह कई पांडा की विशेषताओं को एक साथ लाने के लिए है और यह दर्शाता है कि आप इसका उपयोग कैसे कर सकते हैं ताकि आपके लिए महत्वपूर्ण प्रश्नों का उत्तर दे सकें। यह मात्रात्मक कारकों की प्रभावकारिता का मूल्यांकन करने के लिए उपयोग किए जाने वाले मैट्रिक्स के प्रकारों का एक सबसेट है।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow