Skip to content

Commit

Permalink
[refactor] 포트폴리오 엔티티 개선 (#491)
Browse files Browse the repository at this point in the history
* feat: 포트폴리오의 이름 및 증권사 관련된 기능들을 디테일로 이전

* refactor: 메서드명 변경

* fix: 오타 수정

* feat: CookieDomainProvider 인터페이스 선언 및 구현클래스 추가 (#489)

- 프로파일 환경별 도메인 이름을 제공하는 인터페이스 추가

* [fix] 테스트 컴파일 에러 해결 (#490)

* feat: CookieDomainProvider 인터페이스 선언 및 구현클래스 추가

- 프로파일 환경별 도메인 이름을 제공하는 인터페이스 추가

* fix: 테스트 컴파일 에러 해결

* feat: PortfolioFinancial 임베딩 클래스 추가 및 테스트 추가

* test: 테스트 추가

* test: 예외케이스 테스트 추가

* feat: change 메서드 추가

* refactor: PortfolioFinancial 임베딩 클래스로 대체

* fix: 테스트 삭제 및 음수 조건 삭제

* feat: 음수가 아닌지 검증하는 검증문 추가

* feat: 포트폴리오 추가/수정 요청에서 예외 번역 처리

* test: 예외 연쇄 테스트 추가

* style: 불필요한 예외 클래스 삭제

* feat: 불필요한 생성자 제거 및 APiRequestException 추가

- ApiRequestException은 API 요청 실패시 사용할 수 있는 예외

* feat: 예외 연쇄할 수 있도록 throwable 인스턴스 전달

* feat: 포트폴리오 추가/수정 요청시 예외발생하면 연쇄되도록 처리

* feat: 예외 타입 변경

* docs: javadoc 문서 추가

* feat: 포트폴리오 디테일 매개변수 예외 추가

* feat: 포트폴리오 정보 관련 매개변수 예외 추가

* feat: active 메서드 호출하는 클라이언트의 매개변수 감소

* fix: 오타 수정

* feat: Equals 애노테이션 추가

* feat: 포트폴리오 알림 개인설정 임베딩 클래스 추가

* style: 사용하지 않는 코드 제거

* rename: 메서드명 변경

* feat: PortfolioCalculator 클래스 생성 및 calTotalGain 메서드 구현

* refactor: Portfolio 클래스의 calculateTotalGain 제거

* refactor: Portfolio 클래스 메서드 제거

- calculateTotalGainRate 메서드 제거
- PortfolioCalculator 클래스에 calTotalGainRate 메서드로 이동

* refactor: calculateDailyGain 메서드에 totalInvestement 매개변수 추가

* refactor: 투자배디 연간 배당율 계산 메서드의 매개변수 totalInvestment 추가

* refactor: isCashSufficientForPurchase 메서드 인수 증가

* refactor: isExeedBudgetByPurchasedAmount 메서드 매개변수 변경

* refactor: Portfolio.calculateTotalInvestmentAmount 메서드 제거

* refactor: totalAsset 인수로 변경

* refactor: calculateTotalCurrentValuation 메서드 제거

* refactor: createPieChart 메서드 매개변수 변경

* refactor: calculateTotalAsset 메서드 제거

* refactor: calBalance 메서드 개선

* refactor: createPortfolioGainHistory 메서드 개선

* refactor: calculateDailyGain 메서드 제거 및 calculator로 이전

* refactor: calculateCurrentMontlyDividend 메서드 제거

* refactor: calculateAnnualDividendYield 메서드 제거

* refactor: calculateMaximumLossRate 메서드 개선

* refactor: calculateTargetGainRate 메서드 개선

* refactor: calCashWeight 메서드 개선

* refactor: 파이 차트 생성 메서드 매개변수 개선

* refactor: 섹터 차트 메서드 개선

* refactor: 목표수익금액 도달 검사 메서드 개선

* refactor: 최대손실금액 도달 검사 메서드 개선

* refactor: 파이차트 생성 메서드를 Portfolio에서 PieChart로 이동 및 개선

* refactor: createPortfolioGainHistory를 PortfolioGainHistory 엔티티 객체로 이동

* fix: 돈이 충분한지 검사하는 메서드 버그 수정

- 잔고와 구매금액을 비교하도록 변경

* refactor: 변수 인라인

* comment: javadoc 추가

* feat: Portfolio의 createDividendChart 메서드를 DividendChart로 이동

* rename: 메서드명 변경

* refactor: 메서드 제거

* refactor: 전송 이력 확인 메서드 개선

- manager에서 시작하도록 변경

* refactor: 포트폴리오 목표수익금액 알림 활성화 변경 서비스 개선

* fix: 컴파일 오류 제거

* comment: javadoc 설명 추가

* refactor: 포트폴리오 최대손실금액 알림 활성화 변경 서비스 개선

* refactor: getter 메서드 이름 변경

* refactor: 섹터 차트 메서드 개선
  • Loading branch information
yonghwankim-dev authored Oct 10, 2024
1 parent 6c7b8f5 commit 7117e01
Show file tree
Hide file tree
Showing 73 changed files with 1,772 additions and 645 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public int compareTo(@NotNull Expression expression) {
Money m2 = bank.reduce(expression, currency);
return m1.amount.compareTo(m2.amount);
}

@Override
public boolean equals(Object object) {
if (this == object) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,9 @@ public int compareTo(@NotNull Expression o) {
Money won2 = Bank.getInstance().toWon(o);
return won1.compareTo(won2);
}

@Override
public String toString() {
return String.format("Subtraction(augend=%s, addend=%s)", augend, addend);
}
}
5 changes: 5 additions & 0 deletions src/main/java/co/fineants/api/domain/common/money/Sum.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,9 @@ public int compareTo(@NotNull Expression o) {
Money won2 = Bank.getInstance().toWon(o);
return won1.compareTo(won2);
}

@Override
public String toString() {
return String.format("Sum(augend=%s, addend=%s)", augend, addend);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import java.time.format.DateTimeFormatter;

import co.fineants.api.domain.BaseEntity;
import co.fineants.api.domain.common.money.Bank;
import co.fineants.api.domain.common.money.Expression;
import co.fineants.api.domain.common.money.Money;
import co.fineants.api.domain.common.money.MoneyConverter;
import co.fineants.api.domain.portfolio.domain.calculator.PortfolioCalculator;
import co.fineants.api.domain.portfolio.domain.entity.Portfolio;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
Expand All @@ -17,12 +19,14 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@EqualsAndHashCode(of = {"totalGain", "dailyGain", "cash", "currentValuation", "portfolio"}, callSuper = false)
public class PortfolioGainHistory extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down Expand Up @@ -83,4 +87,25 @@ public String getLineChartKey() {
public Expression calculateTotalPortfolioValue() {
return cash.plus(currentValuation);
}

/**
* 새로운 포트폴리오 손익 내역을 생성 후 반환.
*
* @param calculator 포트폴리오 계산기 객체
* @return 새로운 포트폴리오 손익 내역
*/
public PortfolioGainHistory createNewHistory(PortfolioCalculator calculator) {
Bank bank = Bank.getInstance();
Money newTotalGain = bank.toWon(calculator.calTotalGainBy(portfolio));
Money newDailyGain = bank.toWon(calculator.calDailyGain(this, portfolio));
Money newCash = bank.toWon(calculator.calBalanceBy(portfolio));
Money newTotalCurrentValuation = bank.toWon(calculator.calTotalCurrentValuationBy(portfolio));
return PortfolioGainHistory.create(newTotalGain, newDailyGain, newCash, newTotalCurrentValuation, portfolio);
}

@Override
public String toString() {
String format = "PortfolioGainHistory(id=%d, totalGain=%s, dailyGain=%s, cash=%s, totalCurrentValuation=%s)";
return String.format(format, id, totalGain, dailyGain, cash, currentValuation);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import co.fineants.api.domain.gainhistory.domain.entity.PortfolioGainHistory;
import co.fineants.api.domain.gainhistory.repository.PortfolioGainHistoryRepository;
import co.fineants.api.domain.kis.repository.CurrentPriceRedisRepository;
import co.fineants.api.domain.portfolio.domain.calculator.PortfolioCalculator;
import co.fineants.api.domain.portfolio.domain.entity.Portfolio;
import co.fineants.api.domain.portfolio.repository.PortfolioRepository;
import lombok.RequiredArgsConstructor;
Expand All @@ -31,7 +32,7 @@ public class PortfolioGainHistoryService {
public PortfolioGainHistoryCreateResponse addPortfolioGainHistory() {
List<Portfolio> portfolios = portfolioRepository.findAll();
List<PortfolioGainHistory> portfolioGainHistories = new ArrayList<>();

PortfolioCalculator calculator = new PortfolioCalculator();
for (Portfolio portfolio : portfolios) {
portfolio.applyCurrentPriceAllHoldingsBy(currentPriceRedisRepository);
PortfolioGainHistory latestHistory =
Expand All @@ -40,7 +41,7 @@ public PortfolioGainHistoryCreateResponse addPortfolioGainHistory() {
.stream()
.findFirst()
.orElseGet(() -> PortfolioGainHistory.empty(portfolio));
PortfolioGainHistory history = portfolio.createPortfolioGainHistory(latestHistory);
PortfolioGainHistory history = latestHistory.createNewHistory(calculator);
portfolioGainHistories.add(repository.save(history));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@

import java.time.LocalDate;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Component;

import co.fineants.api.domain.common.money.Bank;
import co.fineants.api.domain.common.money.Currency;
import co.fineants.api.domain.common.money.Expression;
import co.fineants.api.domain.common.money.Money;
import co.fineants.api.domain.holding.domain.dto.response.PortfolioDividendChartItem;
import co.fineants.api.domain.kis.repository.CurrentPriceRedisRepository;
import co.fineants.api.domain.portfolio.domain.calculator.PortfolioCalculator;
import co.fineants.api.domain.portfolio.domain.entity.Portfolio;
import lombok.RequiredArgsConstructor;

Expand All @@ -16,8 +22,19 @@ public class DividendChart {

private final CurrentPriceRedisRepository manager;

public List<PortfolioDividendChartItem> createBy(Portfolio portfolio, LocalDate currentLocalDate) {
public List<PortfolioDividendChartItem> createItemsBy(Portfolio portfolio, LocalDate currentLocalDate) {
portfolio.applyCurrentPriceAllHoldingsBy(manager);
return portfolio.createDividendChart(currentLocalDate);
PortfolioCalculator calculator = new PortfolioCalculator();
Map<Integer, Expression> totalDividendMap = calculator.calTotalDividendBy(portfolio, currentLocalDate);

Bank bank = Bank.getInstance();
Currency to = Currency.KRW;
return totalDividendMap.entrySet().stream()
.map(entry -> {
int month = entry.getKey();
Money dividend = entry.getValue().reduce(bank, to);
return PortfolioDividendChartItem.create(month, dividend);
})
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import co.fineants.api.domain.holding.domain.dto.response.PortfolioPieChartItem;
import co.fineants.api.domain.kis.repository.CurrentPriceRedisRepository;
import co.fineants.api.domain.portfolio.domain.calculator.PortfolioCalculator;
import co.fineants.api.domain.portfolio.domain.entity.Portfolio;
import lombok.RequiredArgsConstructor;

Expand All @@ -15,8 +16,9 @@ public class PieChart {

private final CurrentPriceRedisRepository manager;

public List<PortfolioPieChartItem> createBy(Portfolio portfolio) {
public List<PortfolioPieChartItem> createItemsBy(Portfolio portfolio) {
portfolio.applyCurrentPriceAllHoldingsBy(manager);
return portfolio.createPieChart();
PortfolioCalculator calculator = new PortfolioCalculator();
return calculator.calCurrentValuationWeight(portfolio);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package co.fineants.api.domain.holding.domain.chart;

import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Component;

import co.fineants.api.domain.common.money.Bank;
import co.fineants.api.domain.common.money.Currency;
import co.fineants.api.domain.common.money.Expression;
import co.fineants.api.domain.common.money.Money;
import co.fineants.api.domain.common.money.Percentage;
import co.fineants.api.domain.holding.domain.dto.response.PortfolioSectorChartItem;
import co.fineants.api.domain.kis.repository.CurrentPriceRedisRepository;
import co.fineants.api.domain.portfolio.domain.calculator.PortfolioCalculator;
import co.fineants.api.domain.portfolio.domain.entity.Portfolio;
import lombok.RequiredArgsConstructor;

Expand All @@ -16,6 +23,20 @@ public class SectorChart {

public List<PortfolioSectorChartItem> createBy(Portfolio portfolio) {
portfolio.applyCurrentPriceAllHoldingsBy(manager);
return portfolio.createSectorChart();
PortfolioCalculator calculator = new PortfolioCalculator();
Expression totalAsset = calculator.calTotalAssetBy(portfolio);

Map<String, List<Expression>> sector = calculator.calSectorChartBy(portfolio);
return sector.entrySet().stream()
.map(entry -> {
Expression currentValuation = entry.getValue().stream()
.reduce(Money.wonZero(), Expression::plus);

Percentage weightPercentage = calculator.calCurrentValuationWeight(currentValuation, totalAsset)
.toPercentage(Bank.getInstance(), Currency.KRW);
return PortfolioSectorChartItem.create(entry.getKey(), weightPercentage);
})
.sorted(PortfolioSectorChartItem::compareTo)
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import co.fineants.api.domain.common.money.Bank;
import co.fineants.api.domain.common.money.Currency;
import co.fineants.api.domain.common.money.Expression;
import co.fineants.api.domain.common.money.Money;
import co.fineants.api.domain.common.money.Percentage;
import co.fineants.api.domain.gainhistory.domain.entity.PortfolioGainHistory;
import co.fineants.api.domain.portfolio.domain.calculator.PortfolioCalculator;
import co.fineants.api.domain.portfolio.domain.entity.Portfolio;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
Expand All @@ -26,12 +28,18 @@ public class PortfolioDetailRealTimeItem {

public static PortfolioDetailRealTimeItem of(Portfolio portfolio, PortfolioGainHistory history) {
Bank bank = Bank.getInstance();
PortfolioCalculator calculator = new PortfolioCalculator();
Expression totalGain = calculator.calTotalGainBy(portfolio);
Expression totalGainRate = calculator.calTotalGainRateBy(portfolio);
Expression totalCurrentValuation = calculator.calTotalCurrentValuationBy(portfolio);
Expression dailyGain = calculator.calDailyGain(history, portfolio);
Expression dailyGainRate = calculator.calDailyGainRateBy(history, portfolio);
return new PortfolioDetailRealTimeItem(
portfolio.calculateTotalCurrentValuation().reduce(bank, Currency.KRW),
portfolio.calculateTotalGain().reduce(bank, Currency.KRW),
portfolio.calculateTotalGainRate().toPercentage(Bank.getInstance(), Currency.KRW),
portfolio.calculateDailyGain(history).reduce(bank, Currency.KRW),
portfolio.calculateDailyGainRate(history).toPercentage(Bank.getInstance(), Currency.KRW),
totalCurrentValuation.reduce(bank, Currency.KRW),
totalGain.reduce(bank, Currency.KRW),
totalGainRate.toPercentage(Bank.getInstance(), Currency.KRW),
dailyGain.reduce(bank, Currency.KRW),
dailyGainRate.toPercentage(Bank.getInstance(), Currency.KRW),
Money.zero()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import co.fineants.api.domain.common.money.Bank;
import co.fineants.api.domain.common.money.Currency;
import co.fineants.api.domain.common.money.Expression;
import co.fineants.api.domain.common.money.Money;
import co.fineants.api.domain.common.money.Percentage;
import co.fineants.api.domain.gainhistory.domain.entity.PortfolioGainHistory;
import co.fineants.api.domain.portfolio.domain.calculator.PortfolioCalculator;
import co.fineants.api.domain.portfolio.domain.entity.Portfolio;
import co.fineants.api.global.common.time.LocalDateTimeService;
import lombok.AccessLevel;
Expand Down Expand Up @@ -46,31 +48,42 @@ public static PortfolioDetailResponse from(Portfolio portfolio, PortfolioGainHis
LocalDateTimeService localDateTimeService) {
Bank bank = Bank.getInstance();
Currency to = Currency.KRW;
PortfolioCalculator calculator = new PortfolioCalculator();
Expression totalGain = calculator.calTotalGainBy(portfolio);
Expression totalGainRate = calculator.calTotalGainRateBy(portfolio);
Expression totalInvestment = calculator.calTotalInvestmentBy(portfolio);
Expression totalCurrentValuation = calculator.calTotalCurrentValuationBy(portfolio);
Expression balance = calculator.calBalanceBy(portfolio);
Expression dailyGain = calculator.calDailyGain(history, portfolio);
Expression dailyGainRate = calculator.calDailyGainRateBy(history, portfolio);
Expression annualDividend = calculator.calAnnualDividendBy(localDateTimeService, portfolio);
Expression annualDividendYield = calculator.calAnnualDividendYieldBy(localDateTimeService, portfolio);
Expression annualInvestmentDividendYield = calculator.calAnnualInvestmentDividendYieldBy(localDateTimeService,
portfolio);
Expression targetGainRate = calculator.calTargetGainRateBy(portfolio);
Expression maximumLossRate = calculator.calMaximumLossRateBy(portfolio);
return PortfolioDetailResponse.builder()
.id(portfolio.getId())
.securitiesFirm(portfolio.getSecuritiesFirm())
.name(portfolio.getName())
.securitiesFirm(portfolio.securitiesFirm())
.name(portfolio.name())
.budget(portfolio.getBudget())
.targetGain(portfolio.getTargetGain())
.targetReturnRate(portfolio.calculateTargetReturnRate().toPercentage(Bank.getInstance(), to))
.targetReturnRate(targetGainRate.toPercentage(Bank.getInstance(), to))
.maximumLoss(portfolio.getMaximumLoss())
.maximumLossRate(portfolio.calculateMaximumLossRate().toPercentage(Bank.getInstance(), to))
.currentValuation(portfolio.calculateTotalCurrentValuation().reduce(bank, to))
.investedAmount(portfolio.calculateTotalInvestmentAmount().reduce(bank, to))
.totalGain(portfolio.calculateTotalGain().reduce(bank, to))
.totalGainRate(portfolio.calculateTotalGainRate().toPercentage(Bank.getInstance(), to))
.dailyGain(portfolio.calculateDailyGain(history).reduce(bank, to))
.dailyGainRate(portfolio.calculateDailyGainRate(history).toPercentage(Bank.getInstance(), to))
.balance(portfolio.calculateBalance().reduce(bank, to))
.annualDividend(portfolio.calculateAnnualDividend(localDateTimeService).reduce(bank, to))
.annualDividendYield(
portfolio.calculateAnnualDividendYield(localDateTimeService).toPercentage(Bank.getInstance(), to))
.annualInvestmentDividendYield(
portfolio.calculateAnnualInvestmentDividendYield(localDateTimeService)
.toPercentage(Bank.getInstance(), to))
.maximumLossRate(maximumLossRate.toPercentage(Bank.getInstance(), to))
.currentValuation(totalCurrentValuation.reduce(bank, to))
.investedAmount(totalInvestment.reduce(bank, to))
.totalGain(totalGain.reduce(bank, to))
.totalGainRate(totalGainRate.toPercentage(Bank.getInstance(), to))
.dailyGain(dailyGain.reduce(bank, to))
.dailyGainRate(dailyGainRate.toPercentage(Bank.getInstance(), to))
.balance(balance.reduce(bank, to))
.annualDividend(annualDividend.reduce(bank, to))
.annualDividendYield(annualDividendYield.toPercentage(Bank.getInstance(), to))
.annualInvestmentDividendYield(annualInvestmentDividendYield.toPercentage(Bank.getInstance(), to))
.provisionalLossBalance(Money.zero())
.targetGainNotify(portfolio.getTargetGainIsActive())
.maxLossNotify(portfolio.getMaximumLossIsActive())
.targetGainNotify(portfolio.targetGainIsActive())
.maxLossNotify(portfolio.maximumLossIsActive())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ public class PortfolioDetails {
private String name;

public static PortfolioDetails from(Portfolio portfolio) {
return new PortfolioDetails(portfolio.getId(), portfolio.getSecuritiesFirm(), portfolio.getName());
return new PortfolioDetails(portfolio.getId(), portfolio.securitiesFirm(), portfolio.name());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
import co.fineants.api.domain.common.money.Percentage;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@ToString
@EqualsAndHashCode
public class PortfolioPieChartItem {
private String name;
private Money valuation;
Expand Down Expand Up @@ -41,4 +41,9 @@ public static PortfolioPieChartItem cash(Percentage weight, Money balance) {
balance,
weight);
}

@Override
public String toString() {
return String.format("PortfolioPieChartItem(name=%s, valuation=%s, totalGain=%s)", name, valuation, totalGain);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ public void applyCurrentPrice(CurrentPriceRedisRepository manager) {
this.currentPrice = stock.getCurrentPrice(manager).reduce(bank, to);
}

public RateDivision calculateWeightBy(Expression portfolioAsset) {
public RateDivision calCurrentValuationWeight(Expression totalAsset) {
Expression currentValuation = calculateCurrentValuation();
return currentValuation.divide(portfolioAsset);
return currentValuation.divide(totalAsset);
}

public PortfolioPieChartItem createPieChartItem(RateDivision weight) {
Expand Down
Loading

0 comments on commit 7117e01

Please sign in to comment.