주가 데이터 분석하기

R Analytics

주가 데이터를 수집하는 방법을 알아본다.

유충현
2016-04-08

주가 데이터 수집하기

국내 주가데이터 수집

종목코드 데이터 수집

그래서 우선 KRX의 상장회사검색(http://marketdata.krx.co.kr/mdi#document=040601) 메뉴에서 국내 상장 주식회사의 종목코드 정보를 수집하였음. 각각의 코드는 다음의 excel 파일로 저장함.

종목코드 데이터 적재

library(xlsx)

path <- "./meta"

KOSPI <- "KRX_KOSPI_CODE.xls"
KOSDAQ <- "KRX_KOSDAQ_CODE.xls"
KONEX <- "KRX_KONEX_CODE.xls"

fKOSPI <- paste(path, KOSPI, sep="/")
fKOSDAQ <- paste(path, KOSDAQ, sep="/")
fKONEX <- paste(path, KONEX, sep="/")

KOSPI <- read.xlsx(fKOSPI, sheetIndex = 1, encoding = "UTF-8")
KOSDAQ <- read.xlsx(fKOSDAQ, sheetIndex = 1, encoding = "UTF-8")
KONEX <- read.xlsx(fKONEX, sheetIndex = 1, encoding = "UTF-8")

KOSPI <- KOSPI[, -1]
names(KOSPI) <- c("symbols", "company" ,"industry_cd",
                  "industry_nm", "stock_cnt", "capital",
                  "face_value", "currency", "phone", "address")

KOSPI$symbols <- as.character(KOSPI$symbols)
KOSPI$stock_cnt <- as.numeric(gsub(",", "", KOSPI$stock_cnt))
KOSPI$capital <- as.numeric(gsub(",", "", KOSPI$capital))
KOSPI$face_value <- as.integer(gsub(",", "", KOSPI$face_value))

KOSDAQ <- KOSDAQ[, -1]
names(KOSDAQ) <- c("symbols", "company" ,"industry_cd",
                  "industry_nm", "stock_cnt", "capital",
                  "face_value", "currency", "phone", "address")

KOSDAQ$symbols <- as.character(KOSDAQ$symbols)
KOSDAQ$stock_cnt <- as.numeric(gsub(",", "", KOSDAQ$stock_cnt))
KOSDAQ$capital <- as.numeric(gsub(",", "", KOSDAQ$capital))
KOSDAQ$face_value <- as.integer(gsub(",", "", KOSDAQ$face_value))

KONEX <- KONEX[, -1]
names(KONEX) <- c("symbols", "company" ,"industry_cd",
                  "industry_nm", "stock_cnt", "capital",
                  "face_value", "currency", "phone", "address")

KONEX$symbols <- as.character(KONEX$symbols)
KONEX$stock_cnt <- as.numeric(gsub(",", "", KONEX$stock_cnt))
KONEX$capital <- as.numeric(gsub(",", "", KONEX$capital))
KONEX$face_value <- as.integer(gsub(",", "", KONEX$face_value))

KOSPI[KOSPI$symbols == "088350", ]
    symbols  company industry_cd industry_nm stock_cnt     capital
717  088350 한화생명      116501      보험업 868530000 4.34265e+12
    face_value currency       phone                      address
717       5000  원(KRW) 02-789-5114 서울특별시 영등포구 63로 50 

종목별 거래정보 가져오기

종목별 거래정보는 시스템을 구축할 경우에는 적재된 종목코드 데이터의 첫번째 코드부터 마지막 코드까지 반복(iteration) 수행을 통해 개별개별 데이터를 가져와서 쌓아야 함

본 종목별 거래정보 가져오기 예제에서는 야후에서 가져옴. 실제로 구글에 비해서 야후의 데이터가 더 많은 기간의 데이터를 수용하고 있음. 다음 예제는 KOSPI의 첫 3종목의 주가 정보를 가져오는 예제임.

library("quantmod")

# getting stock data which 1st KOSPI code from Yahoo
symbols <- paste(KOSPI$symbols[1], "KS", sep = ".")
KOSPI_STOCKS <- getSymbols(symbols, from = '1990-01-01', auto.assign = FALSE)
KOSPI_STOCKS <- data.frame(date = index(KOSPI_STOCKS), symbols = KOSPI$symbols[1], 
                Open = as.vector(KOSPI_STOCKS[, 1]), 
                High = as.vector(KOSPI_STOCKS[, 2]), 
                Low = as.vector(KOSPI_STOCKS[, 3]), 
                Close = as.vector(KOSPI_STOCKS[, 4]), 
                Volume = as.vector(KOSPI_STOCKS[, 5]), 
                Adjusted = as.vector(KOSPI_STOCKS[, 6]))
row.names(KOSPI_STOCKS) <- NULL

n <- length(KOSPI[1:3])
  
# getting stock data which 2nd, 3rd KOSPI code from Yahoo
for (i in 2:n) {
  symbols <- paste(KOSPI$symbols[i], "KS", sep = ".")
  x <- getSymbols(symbols, from = '1990-01-01', auto.assign = FALSE)
  x <- data.frame(date = index(x), symbols = KOSPI$symbols[i], 
                  Open = as.vector(x[, 1]), High = as.vector(x[, 2]), 
                  Low = as.vector(x[, 3]), Close = as.vector(x[, 4]), 
                  Volume = as.vector(x[, 5]), Adjusted = as.vector(x[, 6]))
  row.names(x) <- NULL
  
  KOSPI_STOCKS <- rbind(KOSPI_STOCKS, x)
}

head(KOSPI_STOCKS)
        date symbols Open High  Low Close  Volume Adjusted
1 2015-08-21  095570 6180 7300 5600  7100 9970110 6097.747
2 2015-08-24  095570 6700 6940 6240  6480 1964155 5565.268
3 2015-08-25  095570 6610 6730 6190  6220 1213650 5341.969
4 2015-08-26  095570 6260 7760 6260  7090 3518605 6089.158
5 2015-08-27  095570 7240 8060 6960  7570 2499565 6501.400
6 2015-08-28  095570 7660 7840 7090  7140  956575 6132.101
tail(KOSPI_STOCKS)
           date symbols  Open  High   Low Close Volume Adjusted
7735 2021-09-30  006840 26700 27500 26650 26950  11868    26950
7736 2021-10-01  006840 27100 27100 25000 26800  27891    26800
7737 2021-10-05  006840 26900 27300 26300 27250  38909    27250
7738 2021-10-06  006840 26950 27500 25800 26300  29122    26300
7739 2021-10-07  006840 26300 26800 26300 26400  12902    26400
7740 2021-10-08  006840 26350 26850 25950 26300  13620    26300

관심종목 거래정보 가져오기

삼성전자 거래정보 가져오기

삼성전자의 종목코드는 0059301이다. 이 종목의 거래정보를 Yahoo로부터 가져오기 위해서 종목코드를 005930.KS로 변환 후 조회한다.

symbols <- "005930"
symbols <- paste(symbols, "KS", sep = ".")
symbols
[1] "005930.KS"
samsung.electric <- getSymbols(symbols, from = '1990-01-01', to = '2016-03-31',
                               auto.assign = FALSE)

tail(samsung.electric)
           005930.KS.Open 005930.KS.High 005930.KS.Low
2016-03-24          25580          25800         25320
2016-03-25          25660          25800         25560
2016-03-28          25760          26000         25760
2016-03-29          25880          26000         25700
2016-03-30          26200          26420         26040
2016-03-31          26120          26280         25960
           005930.KS.Close 005930.KS.Volume 005930.KS.Adjusted
2016-03-24           25640         10939750           22097.96
2016-03-25           25760          7172300           22201.38
2016-03-28           25880          6060900           22304.80
2016-03-29           25800          8622700           22235.85
2016-03-30           26160         13380250           22546.12
2016-03-31           26240         19130750           22615.06

삼성전자 거래정보 시각화

주가 거래정보를 시각화하기 위해서는 quantmod 패키지의 chartSeries() 함수를 사용한다. 삼성전자의 주가를 주가 그래프로 즐겨보는 candle sticks chart를 그려보면 그림 1과 같다.

chartSeries(samsung.electric, subset = "2016-01-01::2016-03-31", 
            theme = chartTheme('white', up.col = 'red', dn.col = 'blue'))
삼성전자 candle sticks chart

Figure 1: 삼성전자 candle sticks chart

한화생명/삼성생명 거래정보 가져오기

한화생명과 삼성생명의 종목코드는 각각 088350032830이다. 이 종목의 거래정보를 Yahoo로부터 가져오기 위해서 종목코드를 088350.KS, 032830.KS로 변환 후 조회한다.

symbols <- "088350"
symbols <- paste(symbols, "KS", sep = ".")
symbols
[1] "088350.KS"
hli <- getSymbols(symbols, from = '1990-01-01', to = '2016-03-31',
                  auto.assign = FALSE)

tail(hli)
           088350.KS.Open 088350.KS.High 088350.KS.Low
2016-03-24           6600           6640          6550
2016-03-25           6580           6680          6540
2016-03-28           6680           6680          6580
2016-03-29           6670           6720          6630
2016-03-30           6700           6830          6650
2016-03-31           6820           6830          6700
           088350.KS.Close 088350.KS.Volume 088350.KS.Adjusted
2016-03-24            6570           769252           6061.213
2016-03-25            6650           370720           6135.018
2016-03-28            6640           230891           6125.792
2016-03-29            6700           567218           6181.146
2016-03-30            6800          1192238           6273.402
2016-03-31            6700          1137339           6181.146
symbols <- "032830"
symbols <- paste(symbols, "KS", sep = ".")
symbols
[1] "032830.KS"
sli <- getSymbols(symbols, from = '1990-01-01', to = '2016-03-31',
                  auto.assign = FALSE)

tail(sli)
           032830.KS.Open 032830.KS.High 032830.KS.Low
2016-03-24         114000         115000        113000
2016-03-25         114000         116500        113500
2016-03-28         116000         117500        115000
2016-03-29         116000         116000        113500
2016-03-30         115000         116500        114500
2016-03-31         115500         118500        115000
           032830.KS.Close 032830.KS.Volume 032830.KS.Adjusted
2016-03-24          113500           224176           100142.6
2016-03-25          116000           217698           102348.3
2016-03-28          116000           249460           102348.3
2016-03-29          114500           257648           101024.9
2016-03-30          115000           220132           101466.0
2016-03-31          117500           478731           103671.8

한화생명/삼성생명 거래정보 시각화

주가 거래정보를 시각화하기 위해서 chartSeries() 함수로 그린 한화생명과 삼성생명의 candle sticks chart는 각각 그림 2와 그림 3과 같다.

chartSeries(hli, subset = "2016-01-01::2016-03-31", 
            theme = chartTheme('white', up.col = 'red', dn.col = 'blue'))
한화생명 candle sticks chart

Figure 2: 한화생명 candle sticks chart

chartSeries(sli, subset = "2016-01-01::2016-03-31", 
            theme = chartTheme('white', up.col = 'red', dn.col = 'blue'))
삼성생명 candle sticks chart

Figure 3: 삼성생명 candle sticks chart

해외 주가데이터 수집

미국 종목코드 데이터 수집

TTR 패키지를 이용해서 미국의 AMEX, NASDAQ, NYSE 시장의 종목코드를 가져온다.

stock_symbols <- TTR::stockSymbols()

AMEX <- stock_symbols[stock_symbols$Exchange %in% "AMEX", ]
NASDAQ <- stock_symbols[stock_symbols$Exchange %in% "NASDAQ", ]
NYSE <- stock_symbols[stock_symbols$Exchange %in% "NYSE", ]

dim(AMEX)
[1] 305  17
dim(NASDAQ)
[1] 5101   17
dim(NYSE)
[1] 3601   17
head(NYSE)
     Symbol
7692      A
7693     AA
7694    AAC
7695 AAC-UN
7696 AAC-WT
7697   AAIC
                                                                                                                                               Name
7692                                                                                                        Agilent Technologies, Inc. Common Stock
7693                                                                                                                Alcoa Corporation Common Stock 
7694                                                                                           Ares Acquisition Corporation Class A Ordinary Shares
7695                     Ares Acquisition Corporation Units, each consisting of one Class A ordinary share, and one-fifth of one redeemable warrant
7696 Ares Acquisition Corporation Redeemable Warrants, each whole warrant exercisable for one Class A ordinary share at an exercise price of $11.50
7697                                                                                                  Arlington Asset Investment Corp Class A (new)
     LastSale MarketCap IPOyear Sector Industry Exchange Test.Issue
7692       NA        NA      NA     NA       NA     NYSE      FALSE
7693       NA        NA      NA     NA       NA     NYSE      FALSE
7694       NA        NA      NA     NA       NA     NYSE      FALSE
7695       NA        NA      NA     NA       NA     NYSE      FALSE
7696       NA        NA      NA     NA       NA     NYSE      FALSE
7697       NA        NA      NA     NA       NA     NYSE      FALSE
     Round.Lot.Size   ETF Market.Category Financial.Status
7692            100 FALSE            <NA>             <NA>
7693            100 FALSE            <NA>             <NA>
7694            100 FALSE            <NA>             <NA>
7695            100 FALSE            <NA>             <NA>
7696            100 FALSE            <NA>             <NA>
7697            100 FALSE            <NA>             <NA>
     Next.Shares ACT.Symbol CQS.Symbol NASDAQ.Symbol
7692          NA          A          A             A
7693          NA         AA         AA            AA
7694          NA        AAC        AAC           AAC
7695          NA      AAC.U      AAC.U          AAC=
7696          NA      AAC.W     AAC.WS          AAC+
7697          NA       AAIC       AAIC          AAIC

관심종목 거래정보 가져오기

애플 거래정보 가져오기

애플의 종목코드는 AAPL이다. 이 종목의 거래정보를 Yahoo로부터 가져오자.

NASDAQ[grep("Apple", NASDAQ$Name), ]
     Symbol                      Name LastSale MarketCap IPOyear
2599   AAPL Apple Inc. - Common Stock       NA        NA      NA
     Sector Industry Exchange Test.Issue Round.Lot.Size   ETF
2599     NA       NA   NASDAQ      FALSE            100 FALSE
                   Market.Category Financial.Status Next.Shares
2599 NASDAQ Global Select MarketSM Normal (Default)          NA
     ACT.Symbol CQS.Symbol NASDAQ.Symbol
2599       <NA>       <NA>          AAPL
symbols <- NASDAQ[grep("Apple", NASDAQ$Name), "Symbol"]

apple <- getSymbols(symbols, from = '1990-01-01', to = '2016-03-31',
                    auto.assign = FALSE)

tail(apple)
           AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume
2016-03-22   26.3125   26.8225  26.3025    26.6800   129777600
2016-03-23   26.6200   26.7675  26.4750    26.5325   102814000
2016-03-24   26.3675   26.5625  26.2225    26.4175   104532000
2016-03-28   26.5000   26.5475  26.2650    26.2975    77645600
2016-03-29   26.2225   26.9475  26.2200    26.9200   124760400
2016-03-30   27.1625   27.6050  27.1500    27.3900   182404400
           AAPL.Adjusted
2016-03-22      24.73616
2016-03-23      24.59941
2016-03-24      24.49279
2016-03-28      24.38153
2016-03-29      24.95867
2016-03-30      25.39443

애플 거래정보 시각화

애플의 candle sticks chart는 그림 4와 같다.

chartSeries(apple, subset = "2016-01-01::2016-03-31", 
            theme = chartTheme('white', up.col = 'red', dn.col = 'blue'))
apple candle sticks chart

Figure 4: apple candle sticks chart

수익률 분석

한화생명 수익률 분석

주식 분할 및 배당 정보를 반영한 종가인 Adjusted 변수로 간단한 수익률 분석을 수행한다.

최고가/최저가

2010-03-17 이후 2016-03-31까지의 한화생명이 최고가를 친 날은 2015-11-03로 8,090.575원이다. 반대로, 최저가를 친 날은 2011-09-23로 4,688.99원이다.

hli1 <- hli[, "088350.KS.Adjusted"]
hli1[which.max(hli1)]
           088350.KS.Adjusted
2015-11-03           7705.852
hli1[which.min(hli1)]
           088350.KS.Adjusted
2011-09-23           4466.019

단순 수익률/복리 수익률

매일매일의 단순 수익률과 복리 수익률은 각각 다음과 같이 구한다.

ret.simple <- diff(hli1) / stats::lag(hli1, k = -1) * 100
tail(ret.simple)
           088350.KS.Adjusted
2016-03-24         -1.3533827
2016-03-25          1.2048267
2016-03-28         -0.1492616
2016-03-29          0.8823524
2016-03-30          1.4925524
2016-03-31                 NA
ret.cont <- diff(log(hli1)) * 100
tail(ret.cont)
           088350.KS.Adjusted
2016-03-24         -1.3605645
2016-03-25          1.2103096
2016-03-28         -0.1504970
2016-03-29          0.8995559
2016-03-30          1.4815234
2016-03-31         -1.4815234

단순 수익률을 요약하면 다음과 같다. 가장 큰 일일 손실율은 2013-02-26의 약 -10.8%이고, 가장 큰 일일 수익율은 2011-11-01의 약 10.69%이다. 그런데 평균 일일 수익율은 -0.01975%이다.

summary(coredata(ret.simple))
 088350.KS.Adjusted 
 Min.   :-10.81831  
 1st Qu.: -1.03488  
 Median :  0.00000  
 Mean   : -0.01976  
 3rd Qu.:  0.93771  
 Max.   : 10.68815  
 NA's   :2          
ret.simple[which.min(ret.simple)]
           088350.KS.Adjusted
2013-02-26          -10.81831
ret.simple[which.max(ret.simple)]
           088350.KS.Adjusted
2011-11-01           10.68815

일일 단순 손실율의 분포를 히스토그램으로 그리면 그림 5와 같다. 결과를 보면 0% 근접의 마이너스(-) 수익률의 비율이 가장 높음을 알 수 있다.

par(family='NanumGothic')
hist(ret.simple, breaks=100, freq = FALSE, 
     main = "한화생명 - Histogram of Simple Returns", xlab="%")
한화생명 일일 단순 손실율의 분포를 히스토그램

Figure 5: 한화생명 일일 단순 손실율의 분포를 히스토그램

Value-at-Risk

일일 99% Value-at-Risk 값을 과거 자료로 분석하면 일일 손실율이 4.426724% 이상의 확률은 1% 가량 발생한다. 즉, working day 기준 일년에 약 2.5번 정도가 최대 손실율인 4.426724%가 발생한다는 것을 의미한다.

quantile(ret.simple, probs = 0.01, na.rm = TRUE)
       1% 
-4.426712 

복합 연간 성장률

C.A.G.R. : 복합 연간 성장률 (CAGR, 연평균성장률)을 구하면 다음과 같다.

periodReturn(hli, period = 'yearly') 
           yearly.returns
2010-12-30    -0.08620690
2011-12-29    -0.06918239
2012-12-28     0.04864865
2013-12-30    -0.02190722
2014-12-30     0.09222661
2015-12-30    -0.10856454
2016-03-31    -0.09336942

삼성생명 수익률 분석

주식 분할 및 배당 정보를 반영한 종가인 `Adjusted’ 변수로 간단한 수익률 분석을 수행한다.

최고가/최저가

2010-05-12 이후 2016-03-31까지의 삼성생명이 최고가를 친 날은 2014-12-04로 115,989.5원이다. 반대로, 최저가를 친 날은 2012-01-16로 70,075.63원이다.

sli1 <- sli[, "032830.KS.Adjusted"]
sli1[which.max(sli1)]
           032830.KS.Adjusted
2014-12-04           108537.7
sli1[which.min(sli1)]
           032830.KS.Adjusted
2012-01-16           65573.59

단순 수익률/복리 수익률

매일매일의 단순 수익률과 복리 수익률은 각각 다음과 같이 구한다.

ret.simple <- diff(sli1) / stats::lag(sli1, k = -1) * 100
tail(ret.simple)
           032830.KS.Adjusted
2016-03-24         -0.8620682
2016-03-25          2.1551704
2016-03-28          0.0000000
2016-03-29         -1.3043467
2016-03-30          0.4255240
2016-03-31                 NA
ret.cont <- diff(log(sli1)) * 100
tail(ret.cont)
           032830.KS.Adjusted
2016-03-24         -0.8771978
2016-03-25          2.1787334
2016-03-28          0.0000000
2016-03-29         -1.3015356
2016-03-30          0.4357224
2016-03-31          2.1506263

단순 수익률을 요약하면 다음과 같다. 가장 큰 일일 손실율은 2015-02-13의 -8.415846%이고, 가장 큰 일일 수익율은 2010-05-26의 11.00918%이다. 그런데 평균 일일 수익율은 -0.003446%이다.

summary(coredata(ret.simple))
 032830.KS.Adjusted 
 Min.   :-8.415844  
 1st Qu.:-0.930230  
 Median : 0.000000  
 Mean   :-0.003452  
 3rd Qu.: 0.909096  
 Max.   :11.009166  
 NA's   :2          
ret.simple[which.min(ret.simple)]
           032830.KS.Adjusted
2015-02-13          -8.415844
ret.simple[which.max(ret.simple)]
           032830.KS.Adjusted
2010-05-26           11.00917

일일 단순 손실율의 분포를 히스토그램으로 그리면 그림 6과 같다. 결과를 보면 0% 근접의 마이너스(-) 수익률의 비율이 가장 높음을 알 수 있다.

par(family='NanumGothic')
hist(ret.simple, breaks=100, freq = FALSE, 
     main = "삼성생명 - Histogram of Simple Returns", xlab="%")
삼성생명 일일 단순 손실율의 분포를 히스토그램

Figure 6: 삼성생명 일일 단순 손실율의 분포를 히스토그램

Value-at-Risk

일일 99% Value-at-Risk 값을 과거 자료로 분석하면 일일 손실율이 3.886695% 이상의 확률은 1% 가량 발생한다. 즉, working day 기준 일년에 약 2.5번 정도가 최대 손실율인 3.886695%가 발생한다는 것을 의미한다. 한화생명보다는 리스크가 작다.

quantile(ret.simple, probs = 0.01, na.rm = TRUE)
       1% 
-3.886696 

복합 연간 성장률

복합 연간 성장률 (CAGR, 연평균성장률)을 구하면 다음과 같다.

periodReturn(sli, period = 'yearly') 
           yearly.returns
2010-12-30    -0.14225941
2011-12-29    -0.21073171
2012-12-28     0.16563659
2013-12-30     0.10286320
2014-12-30     0.12019231
2015-12-30    -0.05579399
2016-03-31     0.06818182

Citation

For attribution, please cite this work as

유충현 (2016, April 8). Dataholic: 주가 데이터 분석하기. Retrieved from https://choonghyunryu.github.io/posts/2016-04-08-Stock/

BibTeX citation

@misc{유충현2016주가,
  author = {유충현, },
  title = {Dataholic: 주가 데이터 분석하기},
  url = {https://choonghyunryu.github.io/posts/2016-04-08-Stock/},
  year = {2016}
}