모의투자 관리 기능 추가

This commit is contained in:
Macbook
2026-05-31 03:47:07 +09:00
parent 9d7dddfa57
commit 16d0e2c226
78 changed files with 4688 additions and 972 deletions
@@ -0,0 +1,79 @@
package com.goldenchart.service;
import com.goldenchart.entity.GcAppSettings;
import com.goldenchart.entity.GcPaperAccount;
import com.goldenchart.entity.GcPaperSymbolAllocation;
import com.goldenchart.repository.GcPaperPositionRepository;
import com.goldenchart.repository.GcPaperSymbolAllocationRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.math.BigDecimal;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class PaperAllocationServiceTest {
@Mock private GcPaperSymbolAllocationRepository allocRepo;
@Mock private GcPaperPositionRepository positionRepo;
private PaperAllocationService service;
@BeforeEach
void setUp() {
service = new PaperAllocationService(allocRepo, positionRepo);
}
@Test
void validateBuy_rejectsWhenExceedsSymbolLimit() {
GcPaperAccount account = GcPaperAccount.builder()
.id(1L)
.cashBalance(BigDecimal.valueOf(10_000_000))
.reservedCash(BigDecimal.ZERO)
.initialCapitalSnapshot(BigDecimal.valueOf(10_000_000))
.build();
GcAppSettings app = new GcAppSettings();
app.setPaperAutoTradeBudgetPct(BigDecimal.valueOf(100));
GcPaperSymbolAllocation alloc = GcPaperSymbolAllocation.builder()
.accountId(1L)
.symbol("KRW-BTC")
.maxInvestKrw(BigDecimal.valueOf(100_000))
.isActive(true)
.build();
when(allocRepo.findByAccountIdAndSymbol(1L, "KRW-BTC")).thenReturn(Optional.of(alloc));
when(positionRepo.findByAccountIdAndSymbol(1L, "KRW-BTC")).thenReturn(Optional.empty());
assertThrows(IllegalStateException.class, () ->
service.validateBuy(account, app, "KRW-BTC", BigDecimal.valueOf(200_000), false));
}
@Test
void validateBuy_rejectsInactiveSymbol() {
GcPaperAccount account = GcPaperAccount.builder()
.id(1L)
.cashBalance(BigDecimal.valueOf(10_000_000))
.reservedCash(BigDecimal.ZERO)
.initialCapitalSnapshot(BigDecimal.valueOf(10_000_000))
.build();
GcAppSettings app = new GcAppSettings();
GcPaperSymbolAllocation alloc = GcPaperSymbolAllocation.builder()
.accountId(1L)
.symbol("KRW-BTC")
.maxInvestKrw(BigDecimal.valueOf(5_000_000))
.isActive(false)
.build();
when(allocRepo.findByAccountIdAndSymbol(1L, "KRW-BTC")).thenReturn(Optional.of(alloc));
assertThrows(IllegalStateException.class, () ->
service.validateBuy(account, app, "KRW-BTC", BigDecimal.valueOf(10_000), false));
}
}