포트폴리오 서비스(DB 구조 바꾸기)

·2024년 2월 16일
0

Portfolio Backtest

목록 보기
20/31

DB 문제점

  • 우선 추가적으로 과거데이터를 확보해야한다.
  • 사용하는 데이터는 달에 한개인데 비해 저장하는 데이터가 많다.
  • 사용하지 않는 데이터 열이 너무 많다.

데이터 구조 바꾸기

    // 종목코드
    private String itmsNm;
    // 종목명
    private String srtnCd;
//    // 시가
//    private Long mkp;
    // 종가
    private Long clpr;
//    // 고가
//    private Long hipr;
//    // 저가
//    private Long lopr;
//    // 거래량
//    private Long trqu;
//    // 거래대금
//    private Long trPrc;
//    // 시가총액
//    private Long mrktTotAmt;
    // 기준일자
    private LocalDate basDt;

다음과 같이 사용하지 않는 열을 삭제하였다.

json 파일 가공해서 새로만들기

파이썬을 이용해서 새로운 json을 만들었다.
달별로 데이터를 가져와서 clpr(종가)의 평균값을 가지고 새로운 json을 만들었다.

import os
import json

def get_jsonfile(base_path, base_date):
    # 해당하는 파일들을 찾아옵니다.
    files_in_directory = os.listdir(base_path)  # 현재 디렉토리의 파일 목록을 가져옵니다.
    january_files = [file for file in files_in_directory if file.startswith(base_date)] 
    january_files.sort()
    dic = {}

    try:
        with open(base_path + january_files[-1], "r") as file:
            data = json.load(file)
            base_file = data
            january_files.pop()
    except Exception as e:
        print(f"Error: {e}")

    base_item = base_file.get("response").get("body").get("items").get("item")

    for item in base_item:
        add_dic = {}
        clpr_list = []
        clpr_list.append(int(item.get("clpr")))
        add_dic["clpr"] = clpr_list
        add_dic["itmsNm"] = item.get("itmsNm")
        add_dic["srtnCd"] = item.get("srtnCd")
        add_dic["basDt"] = item.get("basDt")[:6]
        dic[item.get("srtnCd")] = add_dic

    for file_name in january_files:
        file_path = base_path + file_name
        try:
            with open(file_path, "r") as file:
                data = json.load(file)
                items = data.get("response").get("body").get("items").get("item")
                for item in items:
                    if item.get("srtnCd") in dic:
                        dic[item.get("srtnCd")]["clpr"].append(int(item.get("clpr")))
                    else:
                        add_dic = {}
                        clpr_list = []
                        clpr_list.append(int(item.get("clpr")))
                        add_dic["clpr"] = clpr_list
                        add_dic["itmsNm"] = item.get("itmsNm")
                        add_dic["srtnCd"] = item.get("srtnCd")
                        add_dic["basDt"] = item.get("basDt")[:6]
                        dic[item.get("srtnCd")] = add_dic
        except Exception as e:
            print(f"Error: {e}")
            pass
        
    for key in dic:
        dic[key]["clpr"] = sum(dic[key]["clpr"]) / len(dic[key]["clpr"])

    # 저장
    file_path = "./new/"+ base_date + ".json"
    try:
        with open(file_path, "w") as file:
            json.dump(dic, file, indent=4)
            print(f"JSON 파일이 성공적으로 저장되었습니다: {file_path}")
    except Exception as e:
        print(f"Error: {e}")


for i in range(1, 13):
    month_str = f"2023{i:02d}"  # 두 자리 숫자로 포맷팅
    get_jsonfile('./stock/2023/',month_str)

다음과 같은 방식으로 json을 가공해서 새로운 json을 만들었다.

StockPriceService

    public List<Long> getPricesByItmsNmAndYear(String itmsNm, int year) {
        List<StockPrice> stockPrices = findAllByItmsNmAndYear(itmsNm, year);

        List<Long> clprs = new ArrayList<>();

        for(int i = 0 ; i < 12 ; i++) {
            clprs.add(0L);
        }

        stockPrices.forEach(stockPrice -> {
            clprs.set(stockPrice.getBasDt().getMonthValue() - 1, stockPrice.getClpr());
        });
        return clprs;
    }

기존의 모든 데이터를 불러온 후 달별로 한개의 데이터를 지정하는 방식에 비해 훨씬 효율적이고 미상장등으로 가격이 없는 경우에는 0L을 반환하는 방식으로 수정하였다.

수익률 계산에서

    public static double getRor(double buyPrice, double sellPrice){
        if(buyPrice == 0){
            return 0;
        }
        Double ror = (sellPrice - buyPrice) / buyPrice * 100;
        return Math.round(ror * 100) / 100.0;
    }

0으로 나누는 경우를 고려하지 않아 해당부분을 추가하였다.
0으로 나누는 케이스는 항상 고려하자

profile
백엔드 개발자가 꿈인 컴공과

0개의 댓글

관련 채용 정보