수색…


Quintile Analysis : 무작위 데이터로

Quintile 분석은 보안 요소의 효율성을 평가하기위한 공통 프레임 워크입니다.

요인은 무엇인가?

요인은 유가 증권 집합에 점수를 매기거나 순위를 매기는 방법입니다. 특정 시점 및 특정 유가 증권 집합에 대해 요소는 보안 식별자의 배열이고 점수는 점수 또는 순위 인 팬더 시리즈로 나타낼 수 있습니다.

시간이 지남에 따라 요인 점수를 취하면 각 시점에서 요소 점수의 순서에 따라 유가 증권 집합을 5 개의 동등한 버킷 또는 5 분위로 나눌 수 있습니다. 특히 5 번에 대해서는 신성한 것이 없습니다. 우리는 3 번이나 10 번을 사용할 수있었습니다. 그러나 5 번을 자주 사용합니다. 마지막으로 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

이제시 계열 인덱스와 보안 ID를 나타내는 인덱스를 생성 해 보겠습니다. 그런 다음이를 사용하여 반품 및 신호를위한 데이터 프레임을 만듭니다.

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 - Quintile Buckets 만들기

pd.qcut 을 사용하여 각 신호를 5 분 버킷으로 나눕니다.

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 Quintile 상관 관계 시각화

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