개발 공부/프로젝트

이상 거래 탐지 시스템 설계 - 금융권은 어떻게 이상 거래를 막는가? (클로드 코드)

baby-t 2026. 4. 24. 10:26

가상 자산 거래 플랫폼을 개발하면서 실제 금융권에서 중요하게 다루는 이상 거래 탐지 기능을 구현해봤습니다. 단순히 기능을 추가하는 것이 아니라, 실제 금융 서비스에서 어떤 패턴을 이상 거래로 보는지 먼저 조사하고 설계했습니다.


1. 왜 가상 자산 거래 플랫폼에서 이상 거래 탐지가 중요한가?

가상 자산 거래 플랫폼은 송금 서비스가 아니지만, 오히려 익명성이 높고 변동성이 커서 이상 거래 탐지가 더 중요한 도메인입니다. 실제 업비트, 빗썸 같은 거래소들도 이런 기능을 갖추고 있어요.

조사한 이상 거래 패턴들:

  • 단시간 과다 주문 → 시세 조작 방지
  • 고액 단일 거래 → 자금 세탁 방지 (AML)
  • 심야 고액 거래 → 계정 탈취 의심
  • 거래 패턴 급격한 변화 → 보이스피싱, 계정 도용

이 중에서 현재 프로젝트에서 구현 가능한 것들을 추려서 이렇게 결정했습니다.

  • 단시간 과다 주문 (1분 5건 초과) ➔ 차단
  • 고액 단일 주문 (잔고 80% 이상 매수) ➔ 이메일 알림
  • 심야 고액 거래 (새벽 1~5시 + 잔고 50% 이상 매수) ➔ 이메일 알림
  • 1천만원 이상 거래이메일 알림

차단과 알림을 구분한 이유가 있습니다. 반복적인 이상 패턴(과다 주문)은 차단이 맞지만, 고액 거래는 사용자가 실제로 원해서 하는 거래일 수 있어요. 보안성과 사용자 경험의 트레이드오프를 고려해서 단계를 나눴습니다.

2. 예외 처리 설계

먼저 이상 거래 감지 시 사용할 예외 클래스와 에러코드를 추가했습니다.

Java
public class AbnormalTradeException extends RuntimeException {
    public AbnormalTradeException(String message) {
        super(message);
    }
}
Java
ABNORMAL_TRADE(HttpStatus.FORBIDDEN, "T001", "비정상적인 거래가 감지되었습니다."),

기존 U001, U002 패턴에서 거래 관련은 T001로 분리했습니다. HTTP 상태코드는 409 Conflict가 아닌 403 Forbidden을 선택했어요. 이상 거래 차단은 데이터 충돌이 아니라 시스템 차원의 접근 거부에 가깝기 때문입니다.

3. StringRedisTemplate이란?

이상 거래 탐지 로직 구현 전에 StringRedisTemplate을 먼저 이해해야 합니다. Spring에서 Redis를 쓰는 방법은 크게 두 가지예요.

  • @Cacheable, @CacheEvict 어노테이션 방식
    • 메서드 결과를 자동으로 캐싱
    • 조회 성능 최적화에 적합
    • (이 프로젝트에서는 주식 시세 캐싱에 사용 중)
  • StringRedisTemplate 직접 방식
    • TTL, 키 구조 등 세밀한 제어 가능
    • 저장/삭제/조회를 직접 컨트롤
    • (Refresh Token 저장, 이상 거래 카운팅에 사용)
Java
// 저장 (TTL 설정)
redisTemplate.opsForValue().set("key", "value", Duration.ofSeconds(60));

// 조회
String value = redisTemplate.opsForValue().get("key");

// 삭제
redisTemplate.delete("key");

// Sorted Set에 추가 (Sliding Window용)
redisTemplate.opsForZSet().add("key", "member", score);

이번 이상 거래 탐지에서는 opsForZSet()을 사용했는데, 이게 Sliding Window 구현의 핵심입니다. 다음 편에서 자세히 다루겠습니다.