# mean reversion test
# 그러므로 비독립적이고 시계열인지 판별하기 위해 많이 사용하는 방법으로 ADF와 허스트 지수가 있다.
#Two test exist; ADF and Hust indicator
#ADF 테스트: 어떤 시계열 데이터가 랜덤워크를 따른다는 가설을 세우고, 이 가설을 검증해 랜덤워크인지 아닌지를 판단
#ADF test is to hypothesize that some time series data follow a random walk, and to test this hypothesis to determine whether it is a random walk or not
# Calculate and output the CADF test on the residuals
# 1st value : test statistic / 2nd : p-value /4th : number of data / 5th : critical value
def load_stock_data(file_name):
df = pd.read_pickle(file_name)
return df
df_samsung = load_stock_data('samsung_2010to2017.csv')
df_hyundai = load_stock_data('hyundai_2010to2017.csv')
adf_result = ts.adfuller(df_samsung["Close"])
pprint.pprint(adf_result)
# t statistic -0.01 is bigger than all of critical value (1,5,10%),
# therefore price of samsung cannot be used for regression analysis
(-0.013073453583186293,
0.95743747408121949,
4,
1881,
{'1%': -3.4338312580685653,
'10%': -2.5675886567541726,
'5%': -2.8630777789723392},
42203.249409277974)
#허스트 지수 (hust indicator)
#정상과정은 랜덤워크 GBM보다 천천히 값이 퍼져나가게 된다.
#분산을 확산속도로 치환할수 있고 그 값을 GBM(기하적 브라운운동) 속도와 비교하면 랜덤워크인지 판별 가능
#H=0.5 -> GBM 동일 랜덤워크( same as GBM)
#H=0 -> 평균회귀 (mean reversion)
#H=1 -> 추세 성향 (momentum)
def get_hurst_exponent(df,lags_count=100):
lags = range(2, lags_count)
ts = np.log(df)
tau = [np.sqrt(np.std(np.subtract(ts[lag:], ts[:-lag]))) for lag in lags]
poly = np.polyfit(np.log(lags), np.log(tau), 1)
result = poly[0]*2.0
return result
df_samsung = load_stock_data('samsung_2010to2017.csv')
df_hyundai = load_stock_data('hyundai_2010to2017.csv')
hurst_samsung = get_hurst_exponent(df_samsung['Close'])
hurst_hyundai = get_hurst_exponent(df_hyundai['Close'])
print("Hurst Exponent : Samsung=%s, Hyundai=%s" % (hurst_samsung,hurst_hyundai))
Hurst Exponent : Samsung=0.477958163648, Hyundai=0.422901700868
#평균회귀의 half life
#삼성과 현대는 평균회귀 모델을 적용하기에 부적합
#하지만 두가지 테스트 통과에 실패했더라도 알파 창출하는 종목있다. 알파 창출 여부를 위한 테스트 Half-life
#half life는 값이 평균으로 회귀하는데 걸리는 시간을 의미하는것
#평균회귀 성향이 있는 랜덤과정을 Ornstein-Uhlenbeck Process 이라고 한다.
#half-life는 펑균회귀 속도인 lambda와 반비례 관계에 있다.
#half-life값이 크다는 것은 장기간 지속하는 경향이 있다. 반대로 작다는 것은 변동성이 크다
#half-life의 수치는 사용한 시간 단위이기 때문에 데이터 시간 단위에 주의를 기울여야한다.
def get_half_life(df):
price = pd.Series(df)
lagged_price = price.shift(1).fillna(method="bfill")
delta = price - lagged_price
beta = np.polyfit(lagged_price, delta, 1)[0]
half_life = (-1*np.log(2)/beta)
return half_life
half_life_samsung = get_half_life(df_samsung['Close'])
half_life_hyundai = get_half_life(df_hyundai['Close'])
print("Half_life : Samsung=%s, Hyundai=%s" % (half_life_samsung,half_life_hyundai))
Half_life : Samsung=971.701411991, Hyundai=160.672993043
0 Comment to "Mean Reversion Indicators : Hust, Half-life about Samsung & Hyundai "
Post a Comment