포트폴리오 서비스(수익률 계산하기)

·2023년 12월 22일
0

Portfolio Backtest

목록 보기
13/31

새로운 브랜치 만들기

develop에서 feature/portfolio 브랜치를 생성하였다.

수익률 관련한 클래스 만들기

정리해보기

  • 유틸 클래스이다.
  • 주어진 입력에 수익률을 계산해서 반환한다.
  • 먼저 2개의 입력에 수익률을 계산하는 함수, 배열에 기간마다 수익률을 계산하는 함수가 필요하다.
  • 포트폴리오를 받아서 수익률을 계산하는 것도 고려하였지만, 수익률의 경우 따로 사용할 가능성이 있기때문에 이는 다른 클래스에서 구현한다.

-> public final class클래스로 만들어서 사용하자. 추가적인 확장이 없을 예정이기 때문이다.

수익률 구하는 법

수익률 = (현재 금액 - 구입 금액) / 구입 금액 * 100
로그 수익률 = ln(현재 금액) - ln(구입 금액)

RorCalcator 함수를 만들어 보자!

public final class RorCalculator {

    public static double getRor(double buyPrice, double sellPrice){
        return (sellPrice - buyPrice) / buyPrice * 100;
    }

    public static List<Double> getRorList(List<Double> priceList){
        List<Double> rorList = new ArrayList<>();
        for(int i=1; i<priceList.size(); i++){
            rorList.add(getRor(priceList.get(i-1), priceList.get(i)));
        }
        return rorList;
    }
    
        public static double getLogRor(double buyPrice, double sellPrice){
        return Math.log(sellPrice / buyPrice);
    }
}

추후 미국주식도 고려하기 위해서 double로 인자를 받기로 하였다. 로그 수익률의 경우 리스크 계산에서 사용할 수 있기때문에 추가하였다.

수익률 구해보기

먼저 데이터를 가져와서 수익률을 구해보자!

    List<StockPrice> priceList = stockPriceService.findByItmsNm("삼성전자");
    List<Double> clprList = priceList.stream()
            .map(stockPrice -> Double.valueOf(stockPrice.getClpr()))
            .collect(Collectors.toList());
    System.out.println(RorCalculator.getRorList(clprList));
    

해당 방식으로 먼저 DB에서 StockPrice를 가져온 후, clpr만을 배열로 만들어서 수익률을 구해보았다.



월초 데이터 가져오기

포트폴리오에서 가격을 월초 데이터를 기준으로 사용할 예정이다. 따라서, 월말 데이터를 가져와보자.

    public Long getPriceByItmsNmAndMonth(String itmsNm, int year, int month) {
        LocalDate startDate = LocalDate.of(year, month, 1);
        LocalDate endDate = startDate.withDayOfMonth(startDate.lengthOfMonth());
        List<StockPrice> stockPrices = stockPriceRepository.findByItmsNmAndBasDtBetween(itmsNm, startDate, endDate);
        if(stockPrices.size() > 0) {
            return stockPrices.get(0).getClpr();
        }
        return 0L;
    }

해당 방식을 통해 월초 데이터를 가져오고 년도를 입력받아서 반복문을 통해 해당 함수를 12번 호출하여 년도의 데이터를 가져오고자 했다. 하지만, 실제로 만들어 사용해 보니 속도가 너무 느린 문제가 발생하였다.
그래서 연도별 데이터를 가져와서 반복문을 통해 처리하였다.

    public List<StockPrice> findAllByItmsNmAndYear(String itmsNm, int year) {
        LocalDate startDate = LocalDate.of(year, 1, 1);
        LocalDate endDate = LocalDate.of(year, 12, 31);
        return stockPriceRepository.findByItmsNmAndBasDtBetween(itmsNm, startDate, endDate);
    }

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

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

        if (stockPrices != null && !stockPrices.isEmpty()) {
            Map<Integer, Long> firstMonthPrices = new HashMap<>();

            for (StockPrice stockPrice : stockPrices) {
                LocalDate basDt = stockPrice.getBasDt();
                int month = basDt.getMonthValue();

                if (!firstMonthPrices.containsKey(month)) {
                    firstMonthPrices.put(month, stockPrice.getClpr());
                }
            }

            for (int i = 1; i <= 12; i++) {
                Long clpr = firstMonthPrices.get(i);
                if (clpr != null) {
                    clprs.add(clpr);
                }
            }
        }

        return clprs;
    }

해당 방식이 훨씬 더 빨리 작동하였다. 이 부분에 대해서는 추후 좀 더 알아보아야 할 것 같다.

포트폴리오 수익률 계산 함수 만들기

포트폴리오 수익률 = (종목 수익률 * 종목 비중)의 합

배열로 종목별 수익률과 종목 비중을 받아서 계산하는 함수를 RorCalculator 클래스에 구현하였다.

    public static double getPortfolioRor(List<Double> rorList, List<Double> weightList){
        double portfolioRor = 0;
        for(int i = 0; i < rorList.size(); i++){
            portfolioRor += rorList.get(i) * weightList.get(i);
        }
        return portfolioRor;
    }

다음에 할일

  • 리밸런싱을 추가해보자!

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

0개의 댓글

관련 채용 정보