< 5. 변동성 돌파 전략과 노이즈 분석 - (1) >


1. 개요

2. 노이즈 계산

3. 평균 노이즈 계산

4. 변동성 돌파 전략과 노이즈 상관 분석


해당 포스트를 읽기 전에 위 포스트를 읽길 추천한다.


지난 포스트까지 노이즈를 계산하고 변동성 돌파 매매 수익율와 상관 분석을 했다. 상관 분석 결과 상관성의 거의 없는 걸로 나타났다. 노이즈와 주가 간의 비례 관계는 상식적으로도 맞지 않는다. 주가의 예측은 불가능하기 때문이다. 


흔히들 주식은 확률 게임이라고 말한다. 게임에서 이길 확률이 1% 이상이 되도 수익이 날 수 있다. 이길 확률을 높이면 그만큼 수익은 더 커진다. 그래서 노이즈 값에 따라 그 날 수익이 나는 지 안 나는 지 확률로 나타낼 수 있지 않을까? 라는 생각을 하게 됬다. 노이즈와 수익이 날 확률에 어떠한 경향성이 있다면 이는 게임에서 이길 확률이 높다는 의미가 된다. 즉, 수익율이 높아질 것이다. 


이번 포스트는 이에 대해 알아볼 것이다. 평균 노이즈 값이 변동성 돌파 매매의 수익이 날 확률과 어떠한 경향성이 있을 지 코드로 파악해보고 분석해본다. 


이를 위해 노이즈값과 수익율 데이터가 필요하다. 이를 위해 지난 포스트에서 설명한 DB 관련 코드를 그대로 사용한다. 코드에 대한 설명은 지난 포스트를 참조하길 바란다.     

from sqlalchemy import create_engine
import pymysql
pymysql.install_as_MySQLdb()
import pandas as pd
import logging as log

class StockDB(object):
    # 싱글톤 패턴
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = object.__new__(cls)
            return cls._instance
        return cls._instance


    def __init__(self, password):
        log.info("Connecting database.....")

        try:
            self.engine = create_engine("mysql+mysqldb://root:"+password+"@localhost/stock", encoding='utf-8')
            self.conn = pymysql.connect(host='localhost', user='root', password=password, db='stock', charset='utf8')
            self.cursor = self.conn.cursor()
        except Exception as e:
            log.warning("Connecting database Error : {}".format(repr(e)))

    def select_noise_profit_data(self, market, profit_type, noise_type):
        log.info("Selecting market all data....")

        sql = "select pft.Profit, Nos.Noise from " \
              "(select Code, Date, Profit from "+market+"_profit_"+profit_type+") as pft " \
              "join (select * from "+market+"_noise_"+noise_type+") as Nos on pft.Code=Nos.Code and pft.Date=Nos.Date;"

        try:
            data = pd.read_sql(sql, self.conn)
        except Exception as e:
            log.info("Selecting market all data Error : {}".format(repr(e)))

        return data

위 StockDB 클래스에서 불러온 평균 노이즈 값과 수익율 데이터로 노이즈 값과 수익이 나는 지 여부의 경향성을 파악해 보자. 다음은 이에 대한 코드이다. 설명은 코드 아래에 있다.


import logging as log
import pandas as pd
import StockDB as db
import sys

log.basicConfig(stream=sys.stdout, level=log.DEBUG)

market = "kosdaq"
profit_type = "6"
noise_type = "40"



dB = db.StockDB("qhdks12#$")

data = dB.select_noise_profit_data(market, profit_type, noise_type)

positive = data[data['Profit']>0]
negative = data[data['Profit']<=0]
bins = [0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1]

positive_cut = pd.cut(positive['Noise'], bins=bins, include_lowest=True)
positive_counts = positive_cut.value_counts(sort=False)

negative_cut = pd.cut(negative['Noise'], bins=bins, include_lowest=True)
negative_counts = negative_cut.value_counts(sort=False)

print(positive_counts)
print(negative_counts)
print(positive_counts/(positive_counts+negative_counts))


불러온 노이즈값과 수익율 데이터를 수익율을 기준으로 분리한다. 수익율이 0보다 큰 데이터를 'positive' , 수익율이 0보다 같은 데이터를 'negative'로 했다. 'pd.cut'을 이용해서 'bins'를 기준으로 데이터를 분리한다. 분리는 0.1 단위로 한다. 그러면 "positive_cut"는 0보다 큰 수익율에 대한 노이즈 값을 0.1로 분리해놓은 데이터가 된다. "value_counts"를 호출하면 분리된 각 단위에 속해 있는 데이터의 수를 반환한다. "negative_counts"는 수익율이 0보다 같거나 작은 노이즈 값을 0.1 단위로 분리해 각 단위에 속해 있는 데이터 수를 나타낸다. 
그리고 positive_counts/(positive_counts+negative_counts) 를 한다. 이는 분리된 각 노이즈 집합의 총 매매에 대한 수익이 날 확률을 나타낸다. 이 값을 이용해 수익이 날 확률과 노이즈 값의 경향성을 파악할 수 있다. 참고로 "positive_counts"와 "negative_counts"를 출력하는 이유는 각 노이즈 집합에 포함된 경우의 수가 많은 지 확인하기 위해서다. 경우의 수가 별로 없면 확률은 무의미하기 때문이다. 물론 이 대신 "positive_counts+negative_counts" 값을 출력해도 된다.

다음은 위 코드의 출력 결과이다. 코스닥 시장에 대해서 평균 노이즈 값 40을 적용했다. 변동성 돌파 매매 Scope 값은 6개월 단위로 했다. 

결과를 보자. 0.1 단위로 분리 된걸 알 수 있다. 노이즈 값이 작을 수록 수익일 확률이 더 높은 걸 알 수 있다. "0.2~0.3" 범위는 경우의 수가 너무 없어 의미가 없다. 하지만 "0.3~0.4" 범위는 수익이 날 확률이 58%로 거의 60% 가깝다. 


위는 코스닥 종목을 대상, 평균 노이즈 값을 40으로 계산한 결과이다. 아래 표는 필자가 가지고 있는 데이터로 나타낸 모든 수치이다. ( 노이즈 범위는 공통적으로 0.1 단위로 했다. ) 가로 축은 평균 노이즈로 적용한 값, 세로 축은 노이즈 값 범위이다. '(XX)' 에서 XX는 해당 범위에 있는 경우의 수다.  




위 차트를 보자. 노이즈 범위가 0.2에서 0.4일 때 수익이 있을 확률이 높다. 또한 평균 값이 클수록 높다. 코스피보다 코스닥에서 수익이 있을 경우가 더 많다. 참고로 코스닥의 경우 30일과 50일 평균 노이즈를 추가로 구했다. 


결론적으로 노이즈 값과 수익이 있을 확률 사이에 어떠한 경향이 뚜렷하지만 나타나는 걸 알 수 있다. 이러한 경향성을 이용해 다음 포스트에서는 노이즈 특정 값에 기준한 변동성 돌파 매매의 누적 수익율을 계산하고 분석해보겠다. 




참고로 필자는 컴퓨터 공학과를 재학 중인 대학생입니다. 따라서 코드가 완벽할 수 없습니다. 알고리즘이나 코드가 비효율적이거나 오류가 있다면 댓글 달아주세요..

+ Recent posts