개발/Spring & Spring Boot

[Spring Boot] Spring Boot 한국투자증권 Open API (KIS Developers) 활용하기 - 1. 거래량순위[v1_국내주식-047]

seopport 2024. 3. 5. 23:25
728x90
반응형

Spring Boot 한국투자증권 Open API (KIS Developers) 활용하기 - 1. 거래량순위[v1_국내주식-047]
Spring Boot 한국투자증권 Open API (KIS Developers) 활용하기 - 1. 거래량순위[v1_국내주식-047]

이전 글에서는 초기 세팅을 하였습니다. 본격적으로 거래량순위 API를 활용해서 데이터를 가져오도록 하겠습니다. 아직 세팅이 안되신 분들은 아래 블로그 글을 참고해 주시면 감사하겠습니다.

 

2024.03.04 - [개발/Spring & Spring Boot] - [Spring Boot] Spring Boot 한국투자증권 Open API (KIS Developers) 활용하기 - 0. 초기 세팅

 

[Spring Boot] Spring Boot 한국투자증권 Open API (KIS Developers) 활용하기 - 0. 초기 세팅

한국투자증권 Open API(Kis Developer)를 사용하여 거래량 순위를 가져오는 프로젝트를 만들었습니다. 물론 실제 거래뿐만 아니라 다양한 정보도 얻을 수 있습니다. 필자는 거래량 순위만 가져오는 것

seodeveloper.tistory.com


한국투자증권 Open API - API 문서

한국투자증권 주식 관련 API를 활용하기 위한 홈페이지입니다. 여러 언어 별로 API샘플코드도 지원해주고 있어 누구나 쉽게 접근하고 사용할 수 있습니다.

 

한국투자증권 - API 문서

 

KIS Developers

WEBSOCKET 실시간 (웹소켓) 접속키 발급[실시간-000] 기본정보 Method POST 실전 Domain https://openapi.koreainvestment.com:9443 모의 Domain https://openapivts.koreainvestment.com:29443 URL /oauth2/Approval Format JSON Content-Type  개

apiportal.koreainvestment.com

접근토큰발급(P)

- 메뉴 : 한국투자증권 개발자센터 - API문서 - OAuth 인증 - 접근토큰발급(P)

 

본인 계좌에 필요한 인증 절차로, 인증을 통해 접근 토큰을 부여받아 오픈API 활용이 가능합니다.

'23.4.28 이후 지나치게 잦은 토큰 발급 요청건을 제어 하기 위해 신규 접근토큰발급 이후 일정시간 이내에 재호출 시에는 직전 토큰값을 리턴하게 되었습니다. 일정시간 이후 접근토큰발급 API 호출 시에는 신규 토큰값을 리턴합니다.

개인 고객 발급의 경우 유효기간은 하루(24H)입니다.

 

기본정보

Method POST
실전 Domain https://openapi.koreainvestment.com:9443/
모의 Domain https://openapivts.koreainvestment.com:29443/
URL /oauth2/tokenP
Format JSON
Content-Type application/json; charset=UTF-8

 

LAYOUT

Request

</> Body

Element 한글명 Type Required Length Description
grant_type 권한부여 Type String Y 18 client_credentials
appkey 앱키 String Y 36 한국투자증권 홈페이지에서 발급받은 appkey 
(절대 노출되지 않도록 주의해주세요.)
appsecret 앱시크릿키 String Y 180 한국투자증권 홈페이지에서 발급받은 appsecret 
(절대 노출되지 않도록 주의해주세요.)

 

Response

</> Body

Element 한글명 Type Required Length Description
access_token 접근토큰 String Y 350 OAuth 토큰이 필요한 API 경우 발급한 Access token
ex) "eyJ0eXUxMiJ9.eyJz…..................................."

- 일반개인고객/일반법인고객
1. Access token 유효기간 1일
2. 일정시간(6시간) 이내에 재호출 시에는 직전 토큰값을 리턴
3. OAuth 2.0의 Client Credentials Grant 절차를 준용

- 제휴법인
1. Access token 유효기간 3개월
2. Refresh token 유효기간 1년
3. OAuth 2.0의 Authorization Code Grant 절차를 준용
token_type 접근토큰유형 String Y 20 접근토큰유형 : "Bearer"
※ API 호출 시, 접근토큰유형 "Bearer" 입력. ex) "Bearer eyJ...."
expires_in 접근토큰 유효기간 Number Y 10 유효기간(초)
ex) 7776000
acess_token_token_expired 접근토큰 유효기간(일시표시) String Y 50 유효기간(년:월:일 시:분:초)
ex) "2022-08-30 08:10:10"

 

POSTMAN 호출 이미지

POSTMAN(포스트맨) 을 활용하여 접근토큰을 발급합니다. 추후 접근토큰발급 관련 코드도 추가할 예정입니다.

접근토큰발급 POSTMAN
접근토큰발급 POSTMAN

거래량순위[v1_국내주식-047]

- 메뉴 : 한국투자증권 개발자센터 - API문서 - 국내주식시세 - 거래량순위

 

국내주식 거래량순위 API 입니다. 한국투자 HTS(eFriend Plus) > [0171] 거래량 순위 화면의 기능을 API로 개발한 사항으로, 해당 화면을 참고하시면 기능을 이해하기 쉽습니다.

 

기본정보

Method GET
실전 Domain https://openapi.koreainvestment.com:9443/
모의 Domain 모의투자 미지원
URL /uapi/domestic-stock/v1/quotations/volume-rank
Format JSON
Content-Type application/json; charset=UTF-8

 

LAYOUT

Request

</> Header

Element 한글명 Type Required Length Description
content-type 컨텐츠타입 String Y 40 application/json; charset=utf-8
authorization 접근토큰 String Y 40 OAuth 토큰이 필요한 API 경우 발급한 Access token

일반고객(Access token 유효기간 1일, OAuth 2.0의 Client Credentials Grant 절차를 준용)

법인(Access token 유효기간 3개월, Refresh token 유효기간 1년, OAuth 2.0의 Authorization Code Grant 절차를 준용)
appkey 앱키 String Y 36 한국투자증권 홈페이지에서 발급받은 appsecret 
(절대 노출되지 않도록 주의해주세요.)
appsecret 앱시크릿키 String Y 180 한국투자증권 홈페이지에서 발급받은 appsecret 
(절대 노출되지 않도록 주의해주세요.)
personalseckey 고객식별키 String N 180 [법인 필수] 제휴사 회원 관리를 위한 고객식별키
tr_id 거래ID String Y 13 FHPST01710000
tr_cont 연속 거래 여부 String N 1 공백 : 초기 조회
custtype 고객 타입 String Y 1 B : 법인
P : 개인
seq_no 일련번호 String N 2 [법인 필수] 01
mac_address 맥주소 String N 12 법인고객 혹은 개인고객의 Mac address 값
phone_number 핸드폰번호 String N 12 [법인 필수] 제휴사APP을 사용하는 경우 사용자(회원) 핸드폰번호 
ex) 01011112222 (하이픈 등 구분값 제거)
ip_addr 접속 단말 공인 IP String N 12 [법인 필수] 사용자(회원)의 IP Address
hashkey 해쉬키 String N 256 [POST API 대상] Client가 요청하는 Request Body를 hashkey api로 생성한 Hash값

* API문서 > hashkey 참조
gt_uid Global UID String N 32 [법인 필수] 거래고유번호로 사용하므로 거래별로 UNIQUE해야 함

 

</> Query Parameter

Element 한글명 Type Required Length Description
FID_COND_MRKT_DIV_CODE 조건 시장 분류 코드 String Y 2 J
FID_COND_SCR_DIV_CODE 조건 화면 분류 코드 String Y 5 20171
FID_INPUT_ISCD 입력 종목코드 String Y 12 0000(전체) 기타(업종코드)
FID_DIV_CLS_CODE 분류 구분 코드 String Y 2 0(전체) 1(보통주) 2(우선주)
FID_BLNG_CLS_CODE 소속 구분 코드 String Y 2 0 : 평균거래량 1:거래증가율 2:평균거래회전율 3:거래금액순 4:평균거래금액회전율
FID_TRGT_CLS_CODE 대상 구분 코드 String Y 32 1 or 0 9자리 (차례대로 증거금 30% 40% 50% 60% 100% 신용보증금 30% 40% 50% 60%)
ex) "111111111"
FID_TRGT_EXLS_CLS_CODE 대상 제외 구분 코드 String Y 32 1 or 0 6자리 (차례대로 투자위험/경고/주의 관리종목 정리매매 불성실공시 우선주 거래정지)
ex) "000000"
FID_INPUT_PRICE_1 입력 가격 1 String Y 12 가격 ~
ex) "0"

전체 가격 대상 조회 시 FID_INPUT_PRICE_1, FID_INPUT_PRICE_2 모두 ""(공란) 입력
FID_INPUT_PRICE_2 입력 가격 2 String Y 12 ~ 가격
ex) "1000000"

전체 가격 대상 조회 시 FID_INPUT_PRICE_1, FID_INPUT_PRICE_2 모두 ""(공란) 입력
FID_VOL_CNT 거래량 수 String Y 12 거래량 ~ 
ex) "100000"

전체 거래량 대상 조회 시 FID_VOL_CNT ""(공란) 입력
FID_INPUT_DATE_1 앱시크릿키 String Y 10 ""(공란) 입력

 

Response

</> Header

Element 한글명 Type Required Length Description
content-type 컨텐츠타입 String Y 40 application/json; charset=utf-8
tr_id 거래ID String Y 13 요청한 tr_id
tr_cont 연속 거래 여부 String N 1 공백 : 초기 조회
N : 다음 데이터 조회 (output header의 tr_cont가 M일 경우)
gt_uid Global UID String N 32 [법인 필수] 거래고유번호로 사용하므로 거래별로 UNIQUE해야 함

 

</> Body

Element 한글명 Type Required Length Description
rt_cd 성공 실패 여부 String Y 1  
msg_cd 응답코드 String Y 8  
msg1 응답메세지 String Y 80  
Output 응답상세 Object Array Y   Array
-hts_kor_isnm HTS 한글 종목명 String Y 40  
-mksc_shrn_iscd 유가증권 단축 종목코드 String Y 9  
-data_rank 데이터 순위 String Y 10  
-stck_prpr 주식 현재가 String Y 10  
-prdy_vrss_sign 전일 대비 부호 String Y 1  
-prdy_vrss 전일 대비 String Y 10  
-prdy_ctrt 전일 대비율 String Y 82  
-acml_vol 누적 거래량 String Y 18  
-prdy_vol 전일 거래량 String Y 18  
-lstn_stcn 상장 주수 String Y 18  
-avrg_vol 평균 거래량 String Y 18  
-n_befr_clpr_vrss_prpr_rate N일전종가대비현재가대비율 String Y 82  
-vol_inrt 거래량 증가율 String Y 84  
-vol_tnrt 거래량 회전율 String Y 82  
-nday_vol_tnrt N일 거래량 회전율 String Y 8  
-avrg_tr_pbmn 평균 거래 대금 String Y 18  
-tr_pbmn_tnrt 거래대금회전율 String Y 82  
-nday_tr_pbmn_tnrt N일 거래대금 회전율 String Y 8  
-acml_tr_pbmn 누적 거래 대금 String Y 18  

 

POSTMAN 호출 이미지

거래량 순위 API는 저장한 접근토큰, APP Key, APP Secret Key를 헤더에 넣고, 파라미터들을 사용하여 호출할 수 있습니다. 

Headers

거래량순위 Headers
거래량순위 Headers

Params

거래량순위 Params
거래량순위 Params

반응형

소스 코드

본격적으로 코드를 작성해보도록 하겠습니다. 모든 파일의 코드를 작성하지 않고 일부 로직의 코드만 추출하여, 설명하도록 하겠습니다. 전체 코드를 확인하시고 싶으시다면, 맨 아래 Github를 참고해주시면 감사하겠습니다.

 

application.properties

호출하여 사용할 값들을 저장합니다. 해당 변수 명들을 자유롭게 변경하셔도 상관 없습니다.

예) appkey -> app-key

# server port
server.port=8090

# log level
logging.level.root=debug

# api key
appkey= APP-KEY
appsecret= APP-SecretKey
# token
access_token= Access-Token

 

KisController.java

  • Controller 파일에 매핑할 url을 작성합니다.
  • localhost:8090/volume-rank 호출 시, 거래량 정보를 불러오도록 세팅합니다. 
package com.seopport.kisvolumerank.controller;

import com.seopport.kisvolumerank.dto.ResponseOutputDTO;
import com.seopport.kisvolumerank.service.KisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.util.List;

@RestController
public class KisController {

    private KisService kisService;

    @Autowired
    public KisController(KisService kisService) {
        this.kisService = kisService;
    }

    @GetMapping("/volume-rank")
    public Mono<List<ResponseOutputDTO>> getVolumeRank() {
        return kisService.getVolumeRank();
    }
}

 

KisService.java

단계적으로 서비스를 설명하도록 하겠습니다. 서비스에서는 본격적으로 거래량순위 API를 호출하여 데이터를 가져옵니다.

 

HttpHeaders

HttpHeaders에 각 값들을 세팅해 줍니다. 상단에 변수로 선언된 값들은 application.properties 파일에 작성한 값을 가져옵니다.

@Value("${appkey}")
private String appkey;

@Value("${appsecret}")
private String appSecret;

@Value("${access_token}")
private String accessToken;


private HttpHeaders createVolumeRankHttpHeaders() {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.setBearerAuth(accessToken);
    headers.set("appkey", appkey);
    headers.set("appSecret", appSecret);
    headers.set("tr_id", "FHPST01710000");
    headers.set("custtype", "P");
    return headers;
}

 

getVolumeRank()

거래량순위 API 호출에서는 Get 형식을 사용하므로, Params를 설정해 줍니다.

public Mono<List<ResponseOutputDTO>> getVolumeRank() {
    HttpHeaders headers = createVolumeRankHttpHeaders();

    return webClient.get()
            .uri(uriBuilder -> uriBuilder.path("/uapi/domestic-stock/v1/quotations/volume-rank")
                    .queryParam("FID_COND_MRKT_DIV_CODE", "J")
                    .queryParam("FID_COND_SCR_DIV_CODE", "20171")
                    .queryParam("FID_INPUT_ISCD", "0002")
                    .queryParam("FID_DIV_CLS_CODE", "0")
                    .queryParam("FID_BLNG_CLS_CODE", "0")
                    .queryParam("FID_TRGT_CLS_CODE", "111111111")
                    .queryParam("FID_TRGT_EXLS_CLS_CODE", "000000")
                    .queryParam("FID_INPUT_PRICE_1", "0")
                    .queryParam("FID_INPUT_PRICE_2", "0")
                    .queryParam("FID_VOL_CNT", "0")
                    .queryParam("FID_INPUT_DATE_1", "0")
                    .build())
            .headers(httpHeaders -> httpHeaders.addAll(headers))
            .retrieve()
            .bodyToMono(String.class)
            .flatMap(response -> parseFVolumeRank(response));

}

 

parseFVolumeRank(String response)

response를 받아서, DTO 객체에 각 값들을 넣어줍니다. 메서드 명들을 자유롭게 사용하시면 됩니다.

private Mono<List<ResponseOutputDTO>> parseFVolumeRank(String response) {
    try {
        List<ResponseOutputDTO> responseDataList = new ArrayList<>();
        JsonNode rootNode = objectMapper.readTree(response);
        JsonNode outputNode = rootNode.get("output");
        if (outputNode != null) {
            for (JsonNode node : outputNode) {
                ResponseOutputDTO responseData = new ResponseOutputDTO();
                responseData.setHtsKorIsnm(node.get("hts_kor_isnm").asText());
                responseData.setMkscShrnIscd(node.get("mksc_shrn_iscd").asText());
                responseData.setDataRank(node.get("data_rank").asText());
                responseData.setStckPrpr(node.get("stck_prpr").asText());
                responseData.setPrdyVrssSign(node.get("prdy_vrss_sign").asText());
                responseData.setPrdyVrss(node.get("prdy_vrss").asText());
                responseData.setPrdyCtrt(node.get("prdy_ctrt").asText());
                responseData.setAcmlVol(node.get("acml_vol").asText());
                responseData.setPrdyVol(node.get("prdy_vol").asText());
                responseData.setLstnStcn(node.get("lstn_stcn").asText());
                responseData.setAvrgVol(node.get("avrg_vol").asText());
                responseData.setNBefrClprVrssPrprRate(node.get("n_befr_clpr_vrss_prpr_rate").asText());
                responseData.setVolInrt(node.get("vol_inrt").asText());
                responseData.setVolTnrt(node.get("vol_tnrt").asText());
                responseData.setNdayVolTnrt(node.get("nday_vol_tnrt").asText());
                responseData.setAvrgTrPbmn(node.get("avrg_tr_pbmn").asText());
                responseData.setTrPbmnTnrt(node.get("tr_pbmn_tnrt").asText());
                responseData.setNdayTrPbmnTnrt(node.get("nday_tr_pbmn_tnrt").asText());
                responseData.setAcmlTrPbmn(node.get("acml_tr_pbmn").asText());
                responseDataList.add(responseData);
            }
        }
        return Mono.just(responseDataList);
    } catch (Exception e) {
        return Mono.error(e);
    }
}

 

ResponseOutputDTO.java

response를 담을 객체를 생성해 줍니다.

package com.seopport.kisvolumerank.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@NoArgsConstructor
@ToString
public class ResponseOutputDTO {
    // HTS 한글 종목명
    private String htsKorIsnm;

    // 유가증권 단축 종목코드
    private String mkscShrnIscd;

    // 데이터 순위
    private String dataRank;

    // 주식 현재가
    private String stckPrpr;

    // 전일 대비 부호
    private String prdyVrssSign;

    // 전일 대비
    private String prdyVrss;

    // 전일 대비율
    private String prdyCtrt;

    // 누적 거래량
    private String acmlVol;

    // 전일 거래량
    private String prdyVol;

    // 상장 수주
    private String lstnStcn;

    // 평균 거래량
    private String avrgVol;

    // N일전종가대비현재가대비율
    private String nBefrClprVrssPrprRate;

    // 거래량 증가율
    private String volInrt;

    // 거래량 회전율
    private String volTnrt;

    // N일 거래량 회전율
    private String ndayVolTnrt;

    // 평균 거래 대액
    private String avrgTrPbmn;

    // 거래대금회전률
    private String trPbmnTnrt;

    // N일 거래대금 회전율
    private String ndayTrPbmnTnrt;

    // 누적 거래 대금
    private String acmlTrPbmn;
}

 

결과 출력

실제 스프링 부트 실행 후 localhost:8090/volume-rank 접근 화면입니다.

API 호출 결과 출력
API 호출 결과 출력

 

GITHUB PAGE

Github - kisvolumerank

 

GitHub - SeoYounSeok/kisvolumerank: 한국투자증권 Open API 거래량 순위를 활용한 분석 💹

한국투자증권 Open API 거래량 순위를 활용한 분석 💹. Contribute to SeoYounSeok/kisvolumerank development by creating an account on GitHub.

github.com

728x90
반응형