테스트 강화 및 코드 품질 개선

This commit is contained in:
2025-12-17 00:01:46 +09:00
parent 37a150bd0d
commit 00c57ddd32
51 changed files with 10670 additions and 217 deletions

View File

@@ -0,0 +1,662 @@
# AutoCoinTrader Code Review Report (v5)
## 1. 개요 (Overview)
본 보고서는 `AutoCoinTrader` 프로젝트의 **전체 코드베이스**에 대한 **v5 종합 심층 분석**입니다. v4 리포트 이후의 변경사항을 반영하고, **Python 전문가****전문 암호화폐 트레이더** 관점에서 단계별로 꼼꼼하게 검토하였습니다.
**분석 범위**:
- 14개 핵심 소스 모듈 (총 ~5,500줄)
- 15개 테스트 파일
- 아키텍처, 코드 품질, 성능, 안정성, 트레이딩 로직, 리스크 관리
**분석 방법론**:
1. 정적 코드 분석 (Static Analysis)
2. 논리 흐름 추적 (Control Flow Analysis)
3. 동시성 패턴 검토 (Concurrency Review)
4. 트레이딩 전략 유효성 검토 (Strategy Validation)
---
## 2. 🚨 긴급 수정 필요 사항 (CRITICAL Issues)
### CRITICAL-001: `order.py` 구문 오류 (Syntax Error)
**파일**: `src/order.py` (라인 789-792)
**문제점**:
```python
# 현재 코드 (오류)
if attempt == max_retries:
raise
time.sleep(ORDER_RETRY_DELAY)
continue # ← IndentationError: 들여쓰기 오류
except (requests.exceptions.RequestException, ValueError, TypeError, OSError) as e:
```
**영향**:
- **Python 인터프리터 오류**: 이 파일을 import하면 `IndentationError` 발생
- **전체 시스템 작동 불가**: 매도 주문 기능 완전 실패
**수정 방안**:
```python
# 수정된 코드
if attempt == max_retries:
raise
time.sleep(ORDER_RETRY_DELAY)
continue
except (requests.exceptions.RequestException, ValueError, TypeError, OSError) as e:
```
**우선순위**: 🔴 **즉시 수정 필수** (P0)
---
### CRITICAL-002: `holdings.py` 중복 return 문
**파일**: `src/holdings.py` (라인 510-513)
**문제점**:
```python
if not new_holdings_map:
return {}
return {} # ← 접근 불가능한 코드 (dead code)
```
**영향**:
- 코드는 실행되지만, 죽은 코드(dead code)가 존재
- 유지보수 혼란 및 코드 품질 저하
**수정 방안**: 중복 `return {}` 제거
**우선순위**: 🟡 **빠른 수정 권장** (P1)
---
## 3. Python 전문가 관점 분석 (Technical Review)
### 3.1 아키텍처 및 디자인 패턴 ⭐⭐⭐⭐⭐
#### ✅ 우수한 점
| 패턴 | 적용 내용 | 평가 |
|------|-----------|------|
| **단일 책임 원칙 (SRP)** | 각 모듈이 명확한 역할 수행 (`order.py`=주문, `signals.py`=신호, `holdings.py`=보유관리) | Excellent |
| **불변 설정 객체** | `RuntimeConfig` dataclass (frozen=True)로 설정 불변성 보장 | Best Practice |
| **상태 분리** | `StateManager`로 봇 상태와 거래소 캐시 분리 | v4 대비 개선 |
| **원자적 파일 쓰기** | 임시 파일 → `os.replace()``os.fsync()` 패턴 일관 적용 | Production Ready |
#### ⚠️ 개선 필요 영역
**1. 순환 의존성 잠재 리스크 (Medium)**
```mermaid
graph TD
A[order.py] --> B[holdings.py]
A --> C[signals.py]
A --> D[common.py]
B --> E[state_manager.py]
C --> A
C --> B
```
- `order.py``signals.py` 간 상호 참조 존재
- `TYPE_CHECKING`으로 런타임 순환 회피 중이나, 리팩토링 시 주의 필요
**2. 모듈 크기 불균형 (Low)**
| 모듈 | 라인 수 | 권장 |
|------|---------|------|
| `order.py` | 1,289 | ⚠️ 500~700 권장 (분할 고려) |
| `signals.py` | 960 | ⚠️ 분할 고려 |
| `holdings.py` | 700 | ✅ 적정 |
| `common.py` | 413 | ✅ 적정 |
**권장**: `order.py``order_buy.py`, `order_sell.py`, `order_monitor.py`로 분할
---
### 3.2 코드 품질 및 스타일 ⭐⭐⭐⭐
#### ✅ 우수한 점
**1. 타입 힌팅 (Type Hinting) - 95%+ 커버리지**
```python
def place_buy_order_upbit(market: str, amount_krw: float, cfg: RuntimeConfig) -> dict:
```
**2. 정밀도 관리 (Precision Handling)**
```python
# Decimal 사용으로 부동소수점 오차 방지
getcontext().prec = 28
d_price = Decimal(str(price))
volume = (d_amount / d_price).quantize(Decimal("0.00000001"), rounding=ROUND_DOWN)
```
**3. 방어적 프로그래밍 (Defensive Programming)**
```python
# None-safe 포매팅
def _safe_format(value, precision: int = 2, default: str = "N/A") -> str:
if value is None:
return default
if pd.isna(value):
return default
```
#### ⚠️ 개선 필요 영역
**1. 광범위한 Exception 처리 (High)**
현재 여러 곳에서 `Exception` 전체를 catch하고 있음:
```python
# 문제점: 예상치 못한 버그를 숨길 수 있음
except Exception as e:
logger.error("오류: %s", e)
return None
```
**권장**: 구체적 예외 타입 지정
```python
except (requests.exceptions.RequestException, json.JSONDecodeError, ValueError) as e:
logger.error("알려진 오류: %s", e)
except Exception as e:
logger.exception("예상치 못한 오류 - 재발생: %s", e)
raise # 또는 특정 처리
```
**영향 범위**:
- `holdings.py`: 9개소
- `order.py`: 12개소
- `signals.py`: 7개소
**2. 매직 넘버 하드코딩 (Medium)**
```python
# 현재
time.sleep(0.5) # 무슨 의미?
if len(calls) >= 590: # 왜 590?
# 권장
TELEGRAM_RATE_LIMIT_DELAY = 0.5 # Telegram API 초당 제한 대응
UPBIT_MINUTE_RATE_LIMIT = 590 # Upbit 분당 600회 제한의 안전 마진
```
**3. 일관성 없는 로그 포맷 (Low)**
```python
# 혼재된 스타일
logger.info("[INFO] [%s] 매수 성공", symbol) # [INFO] 중복
logger.info("[%s] 매수 성공", symbol) # 권장 스타일
logger.info(f"[{symbol}] 매수 성공") # f-string 스타일
```
---
### 3.3 동시성 및 스레드 안전성 ⭐⭐⭐⭐⭐
#### ✅ 우수한 점
**1. 리소스별 Lock 분리 (Best Practice)**
```python
# 각 리소스에 전용 Lock 할당 → 데드락 위험 최소화
holdings_lock = threading.RLock() # holdings.json 보호
_state_lock = threading.RLock() # bot_state.json 보호
_cache_lock = threading.Lock() # 가격/잔고 캐시 보호
_pending_order_lock = threading.Lock() # 대기 주문 보호
krw_balance_lock = threading.RLock() # KRW 잔고 조회 직렬화
recent_sells_lock = threading.RLock() # recent_sells.json 보호
```
**2. KRW 예산 관리자 (Token 기반)**
```python
class KRWBudgetManager:
"""동일 심볼 다중 주문도 안전하게 지원"""
def allocate(self, symbol, amount_krw, ...) -> tuple[bool, float, str | None]:
# 고유 토큰으로 각 주문 구분
token = secrets.token_hex(8)
```
**3. Rate Limiter (Token Bucket)**
```python
# 초당 8회 + 분당 590회 동시 제한
api_rate_limiter = RateLimiter(
max_calls=8,
period=1.0,
additional_limits=[(590, 60.0)]
)
```
#### ⚠️ 개선 필요 영역
**1. Lock 획득 순서 미문서화 (Medium)**
여러 Lock을 동시에 획득하는 경우가 있으나, 획득 순서가 문서화되지 않음.
```python
# 잠재적 데드락 시나리오
# Thread A: holdings_lock → _state_lock
# Thread B: _state_lock → holdings_lock
# 권장: Lock 획득 순서 규약 문서화
# 1. holdings_lock
# 2. _state_lock
# 3. _cache_lock
```
**2. 캐시 만료 시 경합 (Low)**
```python
# 캐시 TTL 만료 시 여러 스레드가 동시에 API 호출 가능
if (now - ts) > PRICE_CACHE_TTL:
# 여러 스레드가 이 조건을 동시에 통과할 수 있음
price = pyupbit.get_current_price(market)
```
**권장**: Double-checked locking 또는 cache stampede prevention
---
### 3.4 예외 처리 및 회복력 ⭐⭐⭐⭐⭐
#### ✅ 우수한 점
**1. Circuit Breaker 패턴**
```python
class CircuitBreaker:
"""API 장애 시 자동 차단"""
STATES = ["closed", "open", "half_open"]
# 연속 3회 실패 → 5분 차단 → 점진적 복구
```
**2. 지수 백오프 재시도 (Exponential Backoff with Jitter)**
```python
sleep_time = base_backoff * (2 ** (attempt - 1))
sleep_time += random.uniform(0, jitter_factor * sleep_time)
```
**3. ReadTimeout 복구 로직**
```python
except requests.exceptions.ReadTimeout:
# 1단계: 중복 주문 확인
is_dup, dup_order = _has_duplicate_pending_order(...)
if is_dup:
return dup_order # 중복 방지
# 2단계: 최근 주문 조회
found = _find_recent_order(...)
if found:
return found # 이미 체결된 주문 반환
```
#### ⚠️ 개선 필요 영역
**1. 중복 주문 검증 정확도 (Medium)**
```python
# 현재: 수량/가격만으로 중복 판단
if abs(order_vol - volume) < 1e-8:
if price is None or abs(order_price - price) < 1e-4:
return True, order
# 문제: 다른 사유로 동일 수량/가격 주문이 존재할 수 있음
# 권장: UUID 캐시 또는 client_order_id 사용
```
---
### 3.5 테스트 커버리지 분석 ⭐⭐⭐⭐
#### ✅ 테스트 파일 현황 (15개)
| 테스트 파일 | 대상 모듈 | 커버리지 |
|------------|----------|---------|
| `test_order.py` | `order.py` | 핵심 기능 |
| `test_evaluate_sell_conditions.py` | `signals.py` | 매도 조건 |
| `test_krw_budget_manager.py` | `common.py` | 예산 관리 |
| `test_concurrent_buy_orders.py` | 동시성 로직 | 경합 조건 |
| `test_circuit_breaker.py` | `circuit_breaker.py` | 복구 로직 |
| `test_state_reconciliation.py` | `holdings.py`/`state_manager.py` | 상태 동기화 |
| `test_boundary_conditions.py` | 다수 | 경계값 |
| `test_critical_fixes.py` | 다수 | 주요 버그픽스 |
| `test_recent_sells.py` | `common.py` | 재매수 방지 |
| `test_holdings_cache.py` | `holdings.py` | 캐시 로직 |
| ... | | |
#### ⚠️ 개선 필요 영역
**1. 통합 테스트 부재 (High)**
- 현재: 대부분 단위 테스트
- 권장: 매수→보유→매도 전체 플로우 통합 테스트
**2. 엣지 케이스 미커버 (Medium)**
- 네트워크 단절 중 여러 주문 동시 발생
- API Rate Limit 도달 시 동작
- 파일 시스템 권한 오류
**3. 모킹 의존도 높음 (Low)**
- `pyupbit` 모킹으로 실제 API 동작 검증 불가
- 권장: 별도 샌드박스 환경 테스트
---
## 4. 전문 트레이더 관점 분석 (Trading Logic Review)
### 4.1 진입 전략 (Entry Strategy) ⭐⭐⭐⭐
#### ✅ 복합 매수 조건 (Triple Confirmation)
```mermaid
graph TD
A[매수조건1] -->|MACD 상향 돌파| B{SMA5 > SMA200}
B -->|Yes| C{ADX > 25}
C -->|Yes| D[매수 신호]
E[매수조건2] -->|SMA 골든크로스| F{MACD > Signal}
F -->|Yes| G{ADX > 25}
G -->|Yes| D
H[매수조건3] -->|ADX 상향 돌파| I{SMA5 > SMA200}
I -->|Yes| J{MACD > Signal}
J -->|Yes| D
```
**분석**:
- ✅ 다중 확인으로 False Signal 감소
- ✅ ADX 필터로 추세 확인 (횡보장 회피)
- ⚠️ 보수적 접근으로 진입 기회 감소 가능
#### ✅ 재매수 방지 (Rebuy Cooldown)
```python
def can_buy(symbol: str, cooldown_hours: int = 24) -> bool:
"""매도 후 24시간 쿨다운"""
```
**장점**: 감정적 재진입 방지, Pump & Dump 피해 최소화
#### ⚠️ 개선 필요 영역
**1. 볼륨 확인 부재 (High)**
현재 MACD/SMA/ADX만 확인하고 **거래량 확인 없음**:
```python
# 현재
cross_macd_signal = prev_macd < prev_signal and curr_macd > curr_signal
# 권장: 거래량 동반 확인
volume_surge = curr_volume > sma_volume * 1.5 # 평균 대비 150%
valid_signal = cross_macd_signal and volume_surge
```
**2. 시장 상태 필터 부재 (Medium)**
```python
# 권장: 비트코인 방향성 확인
def is_btc_bullish():
btc_data = fetch_ohlcv("KRW-BTC", "1d", 20)
return btc_data["close"].iloc[-1] > btc_data["close"].rolling(20).mean().iloc[-1]
```
**3. 진입 가격 최적화 부재 (Low)**
- 현재: 신호 발생 시 시장가/지정가 즉시 매수
- 권장: VWAP 또는 지지선 근처 지정가 대기
---
### 4.2 청산 전략 (Exit Strategy) ⭐⭐⭐⭐⭐
#### ✅ 계층적 트레일링 스탑 (Tiered Trailing Stop)
```python
# 구간별 차등 스탑 설정
저수익 구간 (< 10%): 최고점 대비 -5% 전량 매도
중간 구간 (10~30%): 수익률 10% 이하 복귀 전량 매도
또는 최고점 대비 -5% 전량 매도
고수익 구간 (> 30%): 수익률 30% 이하 복귀 전량 매도
또는 최고점 대비 -15% 전량 매도
```
**분석**:
- ✅ 수익 구간별 차등 보호 (전문가 수준)
- ✅ 상승 여력 확보하면서 수익 보호
- ✅ max_price 영구 저장으로 재시작 시에도 유지
#### ✅ 분할 매도 (Partial Profit Taking)
```python
# 10% 달성 시 50% 부분 익절 (1회 제한)
if not partial_sell_done and profit_rate >= 10.0:
return {"status": "stop_loss", "sell_ratio": 0.5, "set_partial_sell_done": True}
```
**분석**:
- ✅ 리스크 감소 + 나머지로 큰 수익 추구
-`partial_sell_done` 플래그로 중복 방지
- ✅ 최소 주문 금액 미만 시 자동 전량 매도 전환
#### ✅ 손절 즉시 실행
```python
# is_stop_loss 플래그로 확인 절차 건너뜀
bypass_confirmation = not confirm_via_file or (final_is_stop_loss and not confirm_stop_loss)
```
#### ⚠️ 개선 필요 영역
**1. ATR 기반 동적 스탑 미적용 (Medium)**
```python
# 현재: 고정 퍼센티지
drawdown_1 = 5.0 # 모든 코인에 동일
# 권장: ATR 기반 동적 스탑
def calculate_dynamic_stop(symbol, atr_multiplier=2.0):
atr = ta.atr(df["high"], df["low"], df["close"], length=14).iloc[-1]
current_price = df["close"].iloc[-1]
stop_distance = (atr / current_price) * atr_multiplier * 100
return max(3.0, min(stop_distance, 15.0)) # 3~15% 범위 제한
```
**2. 시간 기반 청산 미적용 (Low)**
- 현재: 가격 조건만 확인
- 권장: 장기 횡보 시 기회비용 고려 청산
---
### 4.3 리스크 관리 (Risk Management) ⭐⭐⭐⭐
#### ✅ 우수한 점
| 리스크 관리 항목 | 구현 상태 | 평가 |
|----------------|----------|------|
| API 장애 대응 (Circuit Breaker) | ✅ | Excellent |
| KRW 잔고 경쟁 방지 | ✅ | Excellent |
| 부분 매수 지원 | ✅ | Good |
| Rate Limiting | ✅ | Excellent |
| 슬리피지 관리 | ✅ | Good |
| 최소 주문 금액 검증 | ✅ | Excellent |
#### ⚠️ 개선 필요 영역
**1. 최대 보유 종목 수 제한 없음 (High)**
```python
# 현재: symbols.txt의 모든 심볼 매수 가능
# 문제: 과도한 분산 투자 → 관리 어려움
# 권장: 최대 보유 종목 수 제한
MAX_HOLDINGS = 5
def can_open_new_position(holdings):
return len(holdings) < MAX_HOLDINGS
```
**2. 포트폴리오 손실 한도 부재 (High)**
```python
# 권장: 일일/주간 손실 한도 모니터링
def check_portfolio_drawdown(holdings, initial_balance):
current_value = calculate_portfolio_value(holdings)
drawdown = (current_value - initial_balance) / initial_balance * 100
if drawdown <= -20: # 20% 손실 시
logger.error("포트폴리오 손실 한도 도달: %.2f%%", drawdown)
# 신규 매수 차단 또는 전량 청산
```
**3. 심볼별 상관관계 미고려 (Medium)**
- 현재: 각 심볼 독립적으로 처리
- 문제: BTC 하락 시 대부분 알트코인 동반 하락
- 권장: 상관관계 높은 종목 그룹화하여 동시 보유 제한
**4. 변동성 기반 포지션 사이징 미적용 (Medium)**
```python
# 현재: 고정 금액
buy_amount_krw = 50000
# 권장: 변동성 역비례 사이징
def calculate_position_size(symbol, base_amount, max_volatility=5.0):
volatility = calculate_volatility(symbol) # ATR 기반
if volatility > max_volatility:
return base_amount * (max_volatility / volatility)
return base_amount
```
---
## 5. v4 → v5 변경사항 및 신규 발견
### 🟢 v4 이후 확인된 개선사항
1. **StateManager 안정화**: `max_price` 영구 저장 안정적 동작
2. **Stop-Loss 즉시 실행**: `is_stop_loss` 플래그 정상 작동
3. **KRW 예산 관리**: 토큰 기반 독립 할당으로 동시 주문 안전
4. **테스트 커버리지 증가**: 15개 테스트 파일
### 🔴 v5에서 새로 발견된 문제
| ID | 심각도 | 문제 | 영향 |
|----|--------|------|------|
| CRITICAL-001 | 🔴 Critical | `order.py` 구문 오류 | 시스템 작동 불가 |
| CRITICAL-002 | 🟡 High | `holdings.py` 중복 return | 죽은 코드 |
| HIGH-001 | 🟡 High | 광범위한 Exception 처리 | 버그 은폐 가능 |
| HIGH-002 | 🟡 High | 최대 보유 종목 수 제한 없음 | 과도한 분산 |
| HIGH-003 | 🟡 High | 포트폴리오 손실 한도 부재 | 대손 리스크 |
| HIGH-004 | 🟡 High | 볼륨 확인 부재 (매수) | False Signal |
| MEDIUM-001 | 🟠 Medium | Lock 획득 순서 미문서화 | 잠재적 데드락 |
| MEDIUM-002 | 🟠 Medium | 매직 넘버 하드코딩 | 유지보수 어려움 |
| MEDIUM-003 | 🟠 Medium | ATR 동적 스탑 미적용 | 비최적 청산 |
---
## 6. 코드 품질 지표 요약
| 항목 | v4 평가 | v5 평가 | 변화 |
|------|---------|---------|------|
| 아키텍처 설계 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 유지 |
| 타입 안전성 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 유지 |
| 예외 처리 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 유지 (개선 필요) |
| 동시성 안전성 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 유지 |
| 테스트 커버리지 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 유지 (15개 파일) |
| 코드 품질 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⬇️ (구문 오류 발견) |
| 트레이딩 로직 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⬇️ (볼륨 미확인) |
| 리스크 관리 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⬇️ (포트폴리오 관리 부재) |
**종합 평가**: ⭐⭐⭐⭐ (4.2/5.0) - v4 대비 0.5점 하락 (구문 오류 발견으로 인한 감점)
---
## 7. 우선순위별 권장사항
### 🚨 즉시 수정 (P0 - 24시간 이내)
1. **CRITICAL-001 수정**: `order.py` 구문 오류 해결
2. **CRITICAL-002 수정**: `holdings.py` 중복 return 제거
### 🔴 긴급 개선 (P1 - 1주 이내)
3. **최대 보유 종목 수 제한** 추가 (`MAX_HOLDINGS = 5`)
4. **포트폴리오 손실 한도** 모니터링 추가
5. **광범위한 Exception 처리** 구체화
### 🟡 단기 개선 (P2 - 1개월 이내)
6. **거래량 확인** 로직 추가 (매수 신호)
7. **ATR 기반 동적 스탑** 구현
8. **Lock 획득 순서** 문서화
9. **통합 테스트** 추가
### 🟢 중장기 개선 (P3 - 분기 이내)
10. **`order.py` 모듈 분할** (1,289줄 → 3개 파일)
11. **백테스팅 프레임워크** 구축
12. **매직 넘버 상수화**
13. **심볼 상관관계 분석** 추가
---
## 8. 파일별 상세 분석
### 핵심 모듈 (Critical Path)
| 파일 | 라인 수 | 역할 | 품질 | 주요 이슈 |
|------|---------|------|------|----------|
| `order.py` | 1,289 | 주문 실행 | ⚠️ | 구문 오류, 크기 과대 |
| `signals.py` | 960 | 신호 분석 | ✅ | 크기 적정 초과 |
| `holdings.py` | 700 | 보유 관리 | ✅ | 중복 return 문 |
| `state_manager.py` | 106 | 상태 관리 | ✅✅ | 없음 |
| `common.py` | 413 | 공통 유틸 | ✅✅ | 없음 |
| `config.py` | 328 | 설정 관리 | ✅✅ | 없음 |
### 보조 모듈
| 파일 | 라인 수 | 역할 | 품질 |
|------|---------|------|------|
| `indicators.py` | 172 | 기술 지표 | ✅✅ |
| `notifications.py` | 183 | 알림 전송 | ✅ |
| `circuit_breaker.py` | 79 | 장애 복구 | ✅✅ |
| `retry_utils.py` | 62 | 재시도 유틸 | ✅✅ |
| `constants.py` | 60 | 상수 정의 | ✅✅ |
| `threading_utils.py` | 207 | 스레드 유틸 | ✅ |
| `metrics.py` | 30 | 메트릭 수집 | ⚠️ (미사용) |
| `main.py` | 388 | 엔트리포인트 | ✅ |
---
## 9. 결론
### ✅ 강점
- **아키텍처**: 모듈화, 단일 책임 원칙, 상태 분리 우수
- **동시성**: RLock, 토큰 기반 예산 관리, Rate Limiter 완비
- **정밀도**: Decimal 기반 계산, 원자적 파일 쓰기
- **복구력**: Circuit Breaker, 지수 백오프, ReadTimeout 복구
### ⚠️ 개선 필요
- **긴급**: 구문 오류 수정 필수 (시스템 작동 불가)
- **리스크 관리**: 포트폴리오 레벨 관리 부재
- **트레이딩**: 거래량 확인 및 동적 스탑 미적용
- **코드 품질**: 광범위한 Exception, 모듈 크기 과대
### 🎯 최종 권장사항
1. **즉시**: CRITICAL-001/002 수정 후 재배포
2. **1주 내**: 최대 보유 종목 및 손실 한도 추가
3. **1개월 내**: 거래량 확인 및 통합 테스트 추가
4. **장기**: 백테스팅으로 전략 검증 후 파라미터 최적화
---
**보고서 작성일**: 2025-12-10
**작성자**: AI Code Reviewer (Python Expert + Crypto Trader Perspective)
**버전**: v5.0