본문 바로가기

Data Mining & R

sample ) 주가예측 프로그램

http://anch0vy.tistory.com/6


제목만 보고 낚여서 들어오신분이 휜이 보인다 ㅋㅋ


주가 예측 프로그램은 맞지만 그 예측의 정확도가 많이 떨어진다


이 프로그램을 만들게 된 계기는 ANN(인공 신경망)을 알고 나서부터다


인공신경망은 간단하게 말하자면 어떤 입력이 들어오면 사람의 신경망과 똑같은 매커니즘으로 작동하는 방식이다.


이에 대한건 나중에 써야 할 문서도 있어서 나중에 블로그에 올릴 생각이다.


하여간 이 인공신경망의 특징은 오류에 강하고 '학습' 이 가능하다는 것이다.


그래서 주식 몇년치를 학습시키고 '내일주식은?' 이런걸 물어볼 수 있다는 이야기


하여간 이게 허무맹랑해 보일지 모르겠지만 이에 대한 연구는 꽤 많았었다.


내가 봤던 논문중 가장 괜찮았던 것이 '판별분석, 인공신경망, SVM을 이용한 수익률 성능 비교 연구 : KOSPI 200지수' 이였다.


이 논문을 보면 인공신경망에 대해서도 간단하게 설명을 해주고 입력값으로 뭘 넣는지도 상세히 나온다.


논문에선 85개의 변수를 가지고 주식을 예측하여 6% 정도의 수익률을 냈다.


하지만 난 진짜 수익을 낼 목적보다는 그냥 인공신경망을 이렇게 활용하는 거다... 식으로 공부하는게 목적이여서 매우 간단하게 만들어 봤다.


활용 지표는 종가(비율),거래량(최대최소),거래회전율(거래대금/시가총액,최대최소) 이렇게 딱 3개만 썻다.


인공신경망은 bpnn 이라는 파이썬 라이브러리를 가져다 약간 수정해서 사용하였다.


결과는 매우 환상적(ㅋㅋㅋㅋㅋㅋ)




보면 알겠지만 대부분의 주가가 떨어진다고(그것도 하한선까지!) 예측한다. ㅋㅋㅋ


어떤건 내려갈수 있는 최대 값인 15%를 넘어 16~18%까지 떨어진다고 나온다. ㅋㅋㅋㅋ


고로 fail!


아래는 주가 얻어오는 소스와(http://www.krx.co.kr 에서 얻어옴) 그걸 해석하는 코드이다.



 
# -*- coding: cp949 -*-

import urllib
import re
import os

def parsing(a,b,c,d,e):
    print 'start parsing:' + d
    f = open(e+'\\stock_'+a+'_'+b+'_'+c+'.txt' ,'w')
    get_url = 'http://www.krx.co.kr/por_kor/corelogic/process/sto/stc_d_011.xhtml?data-only=true&isu_cd='+ a +'&fr_work_dt=' + b + '&to_work_dt=' + c
    data = urllib.urlopen(get_url).read()
    data = data.replace('','\n')
    data = data.replace('','')
    data = data.replace('\xec\x83\x81\xec\x8a\xb9','') #상승
    data = data.replace('\xed\x95\x98\xeb\x9d\xbd','') #하락
#없는 데이터    data = data.replace('','')
    data = data.replace('\xec\x83\x81\xed\x95\x9c','') #상한
    data = data.replace('\xed\x95\x98\xed\x95\x9c','') #하한
    data = data.replace('','')
    data = data.replace('','')
    data = data.replace(',','')
    data = data.replace('',',')
    data = data.replace('','')
    data = data.replace(' ','')
    f.write(data)
    f.close()


start_date = str(raw_input('start date: '))
end_date = str(raw_input('end date: '))
stock_list = str(raw_input('stock list: '))
folder = str(raw_input('folder: '))

f = open(stock_list,'r')
while 1:
    line = f.readline()
    if not line:
        break
    stock_info = line.split(',')
    stock_name, stock_id = stock_info
    stock_id = stock_id.replace('\n','')
    parsing(stock_id,start_date,end_date,stock_name,folder)



 
# -*- coding: cp949 -*-
# 입력 형식: 날자,종가,대비,거래량(주),거래대금(원),시가,고가,저가,시가총액(백만),상장주식수(주)
# 출력 형식: 종가(비율),거래량(최대최소),거래회전율??(거래대금/시가총액,최대최소)


from bpnn import *
import os
import pprint

def WTF1(list_,n):
    #최대 최소값 계산
    min_ = float(list_[0][n])
    max_ = float(list_[0][n])
    for day in range(0,7):
        if min_ > float(list_[day][n]):
            min_ = float(list_[day][n])
        if max_ < float(list_[day][n]):
            max_ = float(list_[day][n])
    return max_,min_

def WTF2(list_,n,m):
    #거래회전율 계산
    min_ = float(list_[0][n])/float(list_[0][m])
    max_ = float(list_[0][n])/float(list_[0][m])
    for day in range(0,7):
        if min_ > float(list_[day][n])/float(list_[day][m]):
            min_ = float(list_[day][n])/float(list_[day][m])
        if max_ < float(list_[day][n])/float(list_[day][m]):
            max_ = float(list_[day][n])/float(list_[day][m])
    return max_,min_


def WTF4(list_,new,max_3,min_3,max_48,min_48):
    #데이터 변환
    for day in range(1,8):
        new[day-1] =[(float(list_[day][1])/float(list_[day-1][1])*10/3)-(0.85*10/3),(float(list_[day][3])-min_3)/(max_3-min_3),(float(list_[day][4])/float(list_[day][8])-min_48)/(max_48-min_48)]
    #pprint.pprint(new)#debug

def join(l_input,l_output):
    tmp = []
    for n in range(6,-1,-1):
        tmp.extend(l_input[n])
    return [[tmp,l_output]]


dir_stock = raw_input('stock folder: ')
stock_num = int(raw_input('stock num: '))
stock_list = os.listdir(dir_stock)
ann = NN(3*7, 30, 1)
#print 'debug info [1]'#debug
for stock_file in stock_list:
    #print 'start training at' + stock_file #debug
    #raw_input()#debug
    f_old   = open(dir_stock +'\\'+ stock_file,'r')
    #print 'debug info [2]'#debug
    trash = f_old.readline().split #예측할 날 버리기 
    day_result = f_old.readline().split(',')   #숫자가 크면 오늘에 가깝고 작으면 과거에 가까움
    day_7 = f_old.readline().split(',')
    day_6 = f_old.readline().split(',')
    day_5 = f_old.readline().split(',')
    day_4 = f_old.readline().split(',')
    day_3 = f_old.readline().split(',')
    day_2 = f_old.readline().split(',')
    day_1 = f_old.readline().split(',')
    day_0 = f_old.readline().split(',')
    day = [day_7,day_6,day_5,day_4,day_3,day_2,day_1,day_0,day_result]
    day_new = [[],[],[],[],[],[],[]]
    try:
        #print 'debug info [3]'#debug
        while 1:
            if not day_0:
                print stock_file + 'end'
                break
            #값 처리 시작
            max_3,min_3 = WTF1(day,3)
            max_48,min_48 = WTF2(day,4,8)
            #print 'debug info [4]'#debug
            #print max_3,min_3,max_48,min_48 #debug
            WTF4(day,day_new,max_3,min_3,max_48,min_48) #계산! day_new에 처리한 값 들거가있음!
            result = [(float(day[0][1])/float(day[1][1])*10/3)-(0.85*10/3)] #예측한 값(결과값)
            trainer = join(day_new,result) #입력에 맞춤
            #print trainer #debug
            #print 'start training...' + day[0][0] #debug
            ####################################################################
            ann.train(trainer,iterations=100,N=0.0001,M=0.00005) #오차 무지 큼
            #ann.train(trainer,iterations=10,N=0.001,M=0.05) #더큼
            #ann.train(trainer,iterations=2,N=0.0001,M=0.00005)
            ####################################################################
            #값 처리 끝
            day_result = day_7[:] #날자 이동하고...
            day_7 = day_6[:]
            day_6 = day_5[:]
            day_5 = day_4[:]
            day_4 = day_3[:]
            day_3 = day_2[:]
            day_2 = day_1[:]
            day_1 = day_0[:]
            day_0 = f_old.readline().split(',')
            if not day_0:
                print stock_file + 'end'
                break
            day = [day_7,day_6,day_5,day_4,day_3,day_2,day_1,day_0,day_result]
            #pprint.pprint(day) #debug
            #raw_input('pause') #debug
            #print 'debug info [5]'#debug
    except IndexError:
        print 'err at' + day[0][0]
f_old.close()        
#print 'save mattrix...'
#mat = open('C:\\Users\\USER\\Desktop\\stock\\mattrix', "w")
#mat.write(showMatrix(ann.wi))
#mat.write(showMatrix(ann.wo))
#mat.close()
print 'THE END!!!!!!!'
#테스트 시작
print 'start test\ngood luck!'
dir_stock = raw_input('test stock folder: ')
stock_num = int(raw_input('test stock num: '))
stock_list = os.listdir(dir_stock)
for stock_file in stock_list:
    f_old = open(dir_stock +'\\'+ stock_file,'r')
    day_result = f_old.readline().split(',')   #숫자가 크면 오늘에 가깝고 작으면 과거에 가까움
    day_7 = f_old.readline().split(',')
    day_6 = f_old.readline().split(',')
    day_5 = f_old.readline().split(',')
    day_4 = f_old.readline().split(',')
    day_3 = f_old.readline().split(',')
    day_2 = f_old.readline().split(',')
    day_1 = f_old.readline().split(',')
    day_0 = f_old.readline().split(',')
    day = [day_7,day_6,day_5,day_4,day_3,day_2,day_1,day_0,day_result]
    day_new = [[],[],[],[],[],[],[],[]]
    max_3,min_3 = WTF1(day,3)
    max_48,min_48 = WTF2(day,4,8)
    #print 'debug info [4]'#debug
    #print max_3,min_3,max_48,min_48 #debug
    WTF4(day,day_new,max_3,min_3,max_48,min_48) #계산! day_new에 처리한 값 들거가있음!
    result = [(float(day[0][1])/float(day[1][1])*10/3)-(0.85*10/3)] #예측한 값(결과값)
    tester = join(day_new,result)
    ann.test_custom(tester,day_7[1],day_result[1],day_7[1])
    #ann.test(tester)


주가예측.zip