8.9 KiB
8.9 KiB
AutoCoinTrader Code Review Report (v3)
1. 개요 (Overview)
본 보고서는 AutoCoinTrader 프로젝트의 전체 코드베이스를 Python 전문가 및 전문 암호화폐 트레이더 관점에서 심층 분석한 결과입니다. 현재 코드의 구조, 안정성, 트레이딩 로직의 건전성, 그리고 잠재적인 위험 요소를 식별하고 개선 방안을 제시합니다.
2. Python 전문가 관점 분석 (Technical Review)
2.1 아키텍처 및 디자인 패턴
- 모듈화 (Good):
main.py,order.py,signals.py,holdings.py,config.py등 역할별로 파일이 잘 분리되어 있습니다. 모듈 간 의존성이 비교적 명확하며, 순환 참조를 방지하기 위한TYPE_CHECKING사용도 적절합니다. - 설정 관리 (Good):
RuntimeConfigdataclass를 사용하여 설정값을 객체로 관리하는 방식은 매우 훌륭합니다. 환경변수와 JSON 설정을 결합하고 검증 로직(build_runtime_config)까지 갖추어 견고합니다. - 동시성 제어 (Warning):
src/holdings.py등에서threading.RLock을 사용하여 스레드 안전성을 확보하려는 시도는 좋습니다.- 그러나 파일 기반 상태 관리(
holdings.json등)는 본질적으로 느리고 경쟁 조건(Race Condition)에 취약할 수 있습니다.holdings_lock이 메모리 상의 접근은 막아주지만, 다중 프로세스(혹은 사용자가 수동으로 파일을 수정하는 경우) 환경에서는 파일 덮어쓰기 등의 문제가 발생할 수 있습니다. - Windows 환경에서
os.replace는 원자적(atomic)이려고 노력하지만, 파일 핸들이 열려있을 경우(백신 프로그램, 인덱싱 등)PermissionError가 발생할 가능성이 여전히 존재합니다.
2.2 코드 품질 및 스타일
- 타입 힌팅 (Excellent): 대부분의 함수에 Type Hinting이 적용되어 있어 가독성이 좋고 IDE 지원을 받기 유리합니다.
- 예외 처리 (Good but Broad):
try-except Exception as e패턴이 광범위하게 사용되고 있습니다. 프로그램이 죽지 않고 계속 도는 것(Robustness)에는 유리하지만, 어떤 에러가 났는지 정확히 파악하기 어렵게 만들거나(Swallowing errors), 의도치 않은 버그를 숨길 위험이 있습니다. - 로깅 (Excellent):
setup_logger및CompressedRotatingFileHandler를 통해 로그 로테이션과 압축을 구현한 점은 프로덕션 레벨의 훌륭한 구현입니다.
2.3 성능 및 리소스
- IO Bound 처리:
ThreadPoolExecutor를 사용한 병렬 처리는 네트워크 요청(API call)이 주된 작업인 봇 특성상 적절합니다. - 폴링 루프 (Polling Loop):
main.py의while루프와time.sleep방식은 단순하지만 효과적입니다. 다만, 루프 내 작업 시간이 길어질 경우 주기가 밀리는(Drift) 현상을wait_seconds = max(10, interval_seconds - elapsed)로직으로 잘 보정하고 있습니다.
3. 전문 트레이더 관점 분석 (Trading Logic Review)
3.1 진입 및 청산 로직 (Signals)
- 전략 건전성 (Standard): MACD, SMA, ADX 조합은 전형적인 추세 추종 전략입니다.
- MACD: 추세의 방향과 모멘텀 파악
- SMA (5/200): 골든크로스/데드크로스를 통한 장기/단기 추세 확인
- ADX: 추세의 강도 확인 (횡보장 필터링)
- 평가: 기본기에 충실한 논리입니다. 다만, 4시간봉(
4h)을 주로 사용하는 것으로 보아 스윙 트레이딩 성향이 강한데, 이는 노이즈를 줄이는 데 효과적입니다.
- 복합 매도 로직 (Advanced):
- 단순 손절(-5%) 외에, **트레일링 스탑(Trailing Stop)**과 분할 매도(Partial Profit Taking) 로직이 구현된 점이 매우 인상적입니다.
- 특히 수익 구간별(10% 미만, 10~30%, 30% 이상)로 다른 트레일링 스탑 기준(5%, 15% 등)을 적용하는 것은 수익을 극대화하면서 리스크를 관리하는 고급 기법입니다.
3.2 리스크 관리 (Risk Management)
- 서킷 브레이커 (Circuit Breaker): API 오류 연속 발생 시 주문을 차단하는 로직(
circuit_breaker.py)은 훌륭한 안전장치입니다. - 최소 주문 금액 방어: Upbit의 최소 주문 금액(5,000원) 미만 주문을
skipped_too_small로 방어하는 로직은 필수적이며 잘 구현되어 있습니다. - 슬리피지(Slippage) 관리: 시장가 주문 위주이나, 설정(
buy_price_slippage_pct)에 따라 지정가 주문으로 전환하는 로직이order.py에 존재합니다. 급락/급등 시 시장가 주문은 체결 오차가 클 수 있으므로 지정가 변환 옵션은 유용합니다.
3.3 주문 집행 (Execution)
- 주문 확인 파일 (Manual Confirmation):
confirm_{token}파일을 생성해야 매도가 실행되는 로직(execute_sell_order_with_confirmation)은 양날의 검입니다.- 장점: 봇의 오작동으로 인한 대량 매도를 물리적으로 방지합니다.
- 단점: 급락장(Flash Crash)에서 빠른 대응(손절)을 방해하여 손실을 키울 수 있습니다. 자동매매의 본질인 '감정 배제와 신속성'을 해칠 수 있습니다.
4. 주요 문제점 및 개선 권장사항 (Findings & Recommendations)
🔴 Critical (심각)
- Race Condition in
trade_mode="auto_trade":src/signals.py에서 매수 신호 발생 시get_upbit_balances로 잔고를 확인하고execute_buy_order를 실행합니다. 그러나 멀티 스레드(max_threads > 1) 환경에서 여러 심볼이 동시에 매수 신호를 보내면, 서로 같은 KRW 잔고를 바라보고 동시에 주문을 넣어 잔고 부족 오류가 발생할 수 있습니다.- 개선안:
execute_buy_order진입 시 KRW 잔고 사용에 대한 전역 Lock(또는 Semaphore)을 걸거나, 할당 가능한 예산을 미리 배분해야 합니다.
🟡 High (중요)
-
보유 상태(Sync)의 불일치 위험:
process_symbols_and_holdings함수에서fetch_holdings_from_upbit로 Upbit 잔고를 가져와 로컬 파일(holdings.json)을 덮어씁니다.- 이때 로컬에서 계산된
max_price(트레일링 스탑의 기준점)가 Upbit에서 가져온 데이터에는 없으므로, 로직 상fetch함수가 기존 로컬 파일의max_price를 읽어서 보존하려 노력(src/holdings.py:376)합니다. - 하지만 이 과정이 복잡하여, 만약 API 장애나 파일 읽기 오류 등 예외 상황에서
max_price가 초기화(현재가 또는 매수가)되어버릴 위험이 있습니다. 이는 트레일링 스탑 로직을 무력화시킬 수 있습니다. - 개선안:
max_price등의 봇 전용 상태값은 별도 DB(SQLite 등)나 별도 파일로 분리하여 관리하거나, 병합 로직에 대한 강력한 단위 테스트가 필요합니다.
-
파일 기반 주문 확인 (Confirmation via File):
- 위에서 언급했듯, 빠른 손절이 필요한 상황에서 파일 생성 방식은 대응이 느립니다.
- 개선안: 텔레그램 버튼(Inline Keyboard)을 이용한 승인 방식을 도입하거나, 손절(Stop Loss)에 한해서는 확인 없이 즉시 실행하도록 예외를 두는 것이 안전합니다.
🟢 Medium/Low (참고)
-
하드코딩된 전략 파라미터:
- MACD(12, 26, 9) 등의 상수가 코드 내 기본값으로 박혀 있거나
config에서 불러오지만, 전략을 유연하게 변경하기 어렵습니다. - 개선안: 전략을 클래스화(
Strategy패턴)하여 config에서 전략 이름을 선택하고 파라미터를 통째로 주입받는 구조로 발전시키면 좋습니다.
- MACD(12, 26, 9) 등의 상수가 코드 내 기본값으로 박혀 있거나
-
테스트 커버리지:
test_order.py외에signals.py의 복잡한 매도 조건 로직에 대한 단위 테스트가 부족해 보입니다. (예: 수익률 10.1% 찍고 9.9%로 떨어지면 파는가? 등의 경계값 테스트)- 개선안:
pytest를 활용하여 시나리오별 매도 신호 발생 여부를 검증하는 테스트 케이스를 추가하세요.
5. 결론 (Conclusion)
AutoCoinTrader는 상당히 완성도 높은 개인용 트레이딩 봇입니다. 특히 로깅, 설정 관리, 안전장치(서킷브레이커, 드라이런) 등의 엔지니어링 품질이 뛰어납니다.
트레이더 입장에서 가장 우려되는 점은 '파일 기반 승인 절차'로 인한 손절 지연과 멀티 스레드 매수 시 KRW 잔고 경쟁 문제입니다. 이 두 가지만 해결된다면 실전 운용에 무리가 없을 것으로 판단됩니다.
추천 우선순위:
- KRW 잔고 동시 접근 방어 로직 추가
- 손절(Stop Loss) 조건 발동 시에는 '사용자 승인'을 건너뛰고 즉시 매도하도록 옵션 추가