Cowork Trading Stack · 2026

AI를 코인에 접목하기
Claude × 크립토 트레이딩 풀 가이드

Claude Code · Cowork · Codex로 6개월간 라이브로 굴려온 멀티-perp 트레이딩 인프라. AI 협업 프로토콜, 메모리 시스템, 프로덕션 락 패턴, AI 특유 3대 버그 디버깅까지 ─ 솔로 빌더가 월요일에 짠 코드를 금요일에 실자금으로 검증하는 환경을 만드는 법을 정리했습니다.

vibe coding 입문11종 드롭인 모듈Triple Lock + KillMIT · 코드 공개
HUMAN 의도 · 검증 plan · review · ship CLAUDE · COWORK 코드 작성 4-mode prompts REVIEW CODEX 교차 검증 gaslight my AI LIVE 실거래 triple lock AI를 코드 생성기가 아니라 협업 파트너로 다루는 협업 프로토콜 ─ VIBE CODING WORKFLOW ─ 의도 전달 drop-in modules edge cases production

시작하기 전에

이 가이드의 출발점은 한 가지 질문입니다. "AI 코딩 에이전트를 가지고 솔로 빌더가 진짜 굴러가는 시스템을 만들 수 있을까?"

답은 이 가이드 자체가 증거가 되는 케이스 스터디 ─ 6개월 넘게 라이브로 굴러가는 멀티-perp 크립토 트레이딩 인프라입니다. 다수의 거래소 래퍼, 실시간 차익 스캐너, Rust 가속 핫패스까지 ─ 모두 Claude Code · Cowork · Codex와 함께 만들었습니다.

크립토 트레이딩이 vibe coding 케이스 스터디로 좋은 이유는 단순합니다. 실자금이 걸려 있으면 "대충 돌아가는 듯하다"로 넘어갈 수 없습니다. 거래소 래퍼 · 전략 · 스케줄러 · 노티파이어처럼 한 세션에 AI가 잘 만드는 크기로 모듈이 자연스럽게 나뉘고, ship → observe → adjust 사이클이 매주 강제됩니다. 공개 API와 지갑 하나로 누구나 재현 가능하고, 봇 한 개의 폭발 반경이 작아 실험 부담도 낮습니다.

이 가이드의 패턴은 트레이딩이 아닌 영역에도 그대로 옮겨 쓸 수 있습니다. 중요한 건 "AI에게 어떻게 일을 시키느냐"이지, 도메인이 코인이냐 다른 것이냐는 부수적입니다.

이런 분들에게 추천합니다

이런 가이드가 아닙니다

저장소 공개

이 가이드의 모든 코드와 운영 노트는 GitHub에 공개되어 있습니다 ─ github.com/coinmage777/cowork-trading-stack. 콘텐츠는 CC BY-NC 4.0, 코드는 MIT 라이선스로 풀어두었습니다. 가장 가벼운 모듈은 5분 안에 띄워볼 수 있습니다.

git clone https://github.com/coinmage777/cowork-trading-stack.git
cd cowork-trading-stack/30-strategy-patterns/volume-farmer/
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env    # API 키 채우고 DRY_RUN=true 로 시작
면책. 이 가이드는 운영 사례와 기술 구조를 정리한 자료입니다. 트레이딩에는 손실 위험이 따르고, 시장과 거래소 정책은 계속 변합니다. 실거래 판단과 그에 따른 손익 책임은 본인에게 있습니다 ─ 투자 권유가 아닙니다. 직접 감사하지 않은 코드를 실자금으로 돌리지 마시기 바랍니다.
바이브 코딩 입문 추천
코딩 1도 몰라도 OK ─ Cursor로 코인 DCA 시뮬레이터 만들고 GitHub · Vercel 배포까지
13:26 · 완전 초보용

왜 자동화부터인가

크립토 트레이딩에 처음 발을 들이면 대부분 같은 순서를 밟습니다.

  1. 차트 보기
  2. 매매 시작
  3. 손실
  4. 더 차트 보기
  5. 인디케이터 추가
  6. 더 손실
  7. 트위터에서 시그널 사기
  8. 잃을 만큼 잃은 다음에야 자동화 검토

이 순서는 권장하지 않습니다. 자동화부터 시작합니다.

자동화가 먼저인 이유

첫째, 인간 두뇌는 24/7 시장에 맞지 않습니다. 크립토는 잠을 자지 않습니다. 새벽 3시에도, 명절 연휴에도, 친구 결혼식에 가 있는 동안에도 시장은 움직입니다. 봇은 대응합니다.

둘째, 감정은 PnL의 1번 적입니다. 매매 일지를 6개월만 적어보면 알 수 있습니다 ─ 손실의 80%는 "차트를 너무 오래 봐서 충동 매매"에서 나옵니다. 봇은 충동이 없습니다. 룰만 있습니다.

셋째, 자동화는 운영자를 시스템 사고로 이끕니다. "이 버튼을 누르면 무엇이 일어나는가?"가 아니라 "이 시그널 → 진입 → 모니터링 → 청산 → 기록 → 분석 → 다음 시그널"의 흐름으로 생각하게 됩니다. 이 사고방식 자체가 자산입니다.

자동화의 핵심 가치

시간 절약이 아닙니다. "같은 데이터를 매일 같은 시간에 같은 형식으로 쌓는 것", 이게 핵심입니다. 일주일 쌓이면 패턴이 보이고, 한 달이면 남들이 못 보는 시계열 데이터셋이 됩니다. 직관이 데이터로 검증되는 순간이 실제 엣지가 만들어지는 지점입니다.

자주 나오는 반론

"코드를 짜지 못한다." 지금은 그것이 변명이 되지 않습니다. AI가 90%를 짜줍니다. 이 가이드의 봇 대부분도 Claude · Cursor · Codex로 빌드한 것입니다. 코딩을 못한다는 것은 "자동화를 안 한다"의 핑계가 될 수 없습니다.

"봇이 더 위험한 것 아닌가?" 당연히 위험합니다. 그래서 다음과 같이 합니다 ─ 처음에는 작은 자본으로, 페이퍼 트레이딩으로, 백테스트로 검증, 실시간 알림 + 서킷브레이커, 출금 권한 없는 API 키. 수동도 위험합니다. 봇은 시스템적으로 위험을 줄일 수 있다는 점이 다릅니다.

인간의 역할은 어떻게 바뀌는가

자동화가 인간을 대체하는 것이 아닙니다. 역할을 바꾸는 것입니다. 수동 매매에서 인간이 시그널 찾기 · 진입가 결정 · 청산가 결정 · 손절 · 모니터링까지 모두 했다면, 자동화에서는 전략 가설 · 백테스팅 · 봇 디자인 · 파라미터 튜닝 · 사후 분석 · 새 전략 발굴이 인간의 일이 됩니다. 후자가 더 어렵고, 그래서 더 가치가 있습니다.

Vibe Coding이란 무엇인가

"분위기로 코딩한다"는 비꼼이 아닙니다. AI에게 의도를 전달하고 결과를 검증하는 일련의 협업 프로토콜을 가리킵니다. 키보드를 두드리는 시간보다 프롬프트를 다듬고 결과물을 review하는 시간이 더 길어집니다.

이 가이드의 핵심 주장은 단순합니다 ─ AI 코딩 도구는 코드 생성기가 아니라 협업 파트너로 다뤄야 작동합니다. "트레이딩 봇 만들어줘" 한 줄로는 production이 안 나옵니다. 큰 시스템을 AI가 잘 만들 수 있는 단위로 쪼개고, 모드별로 다른 프롬프트 패턴을 쓰고, 메모리로 컨텍스트를 누적하고, 디버깅으로 AI 특유의 버그를 잡아내는 ─ 이 전체 협업 프로토콜이 vibe coding입니다.

한 줄 원칙

코드 수정 전 관련 파일 5개 이상 읽기. 추측 금지, Grep/Read로 확인. 변경 후 반드시 검증.

이 세 줄이 안 되면 AI는 그냥 빠르게 망가지는 코드 생성기입니다.

이 가이드에서 다루는 것

다음 챕터부터 이 협업 프로토콜의 구성 요소를 하나씩 풀어갑니다.

크립토 트레이딩 영역의 구체적 사례로 풀어나가지만, 패턴 자체는 도메인 무관합니다.

Cowork 활용 영상
코딩 0줄인데 사주앱 완성됨… AI 에이전트 미쳤다 (Antigravity + Claude Code)
15:39 · 1개월 전

Claude · Cowork · Codex 도구 분담

왜 Claude를 메인으로 두는가

ChatGPT · Gemini · Grok 모두 사용해 보았습니다. 각자 강점이 있습니다. Claude를 메인으로 두는 이유는 다음과 같습니다.

도구별 역할 분담

한 가지 도구로 전부 다 하지 않습니다. 각자 잘하는 영역이 다릅니다.

세 모델의 결과를 비교하면 한 모델만 쓸 때보다 신뢰도가 올라갑니다. 특히 트레이딩 코드에서 그렇습니다.

Cowork이 뭔가요

Claude Cowork은 Claude API 기반의 데스크탑 워크플로우 도구입니다. 채팅창에 한국어로 "이거 해줘"라고 시키면 Claude가 사용자 PC의 파일을 읽고, 코드를 작성하고, 명령어를 실행해줍니다. 개발자가 쓰는 Claude Code의 GUI 버전이라고 보시면 됩니다.

설치는 claude.com/download에서 다운로드하시면 되고, Pro 이상 구독자만 사용 가능합니다.

핵심 슬래시 명령어

Cowork에는 슬래시(/)로 시작하는 특수 명령어들이 있습니다. 실제 자주 쓰이는 것만 추려봤습니다.

/schedule ─ 자동 반복 작업 등록

매일 정해진 시간에 실행할 작업을 등록합니다. 한 번 박아두면 잊고 살아도 됩니다.

/schedule
매일 오전 8시에 다음 작업을 해줘:
1. Hyperliquid, Lighter, Binance에서 BTC/ETH 펀딩비 가져오기
2. 펀딩비를 markdown 파일로 변환
3. 옵시디언 볼트의 Funding 폴더에 날짜별로 저장
4. 8시간 단위로 가장 비싼/싼 거래소 요약해서 텔레그램으로 발송

처음에는 Claude가 한 번 코드를 짜주고, 그 다음부턴 매일 자동 실행됩니다. 일주일 뒤에는 어떤 거래소가 평소 펀딩비가 비싼지/싼지 독자적 데이터가 쌓이게 됩니다.

/plan ─ 실행 전 계획부터

봇을 수정하거나 전략을 바꾸기 전에 무조건 거치는 걸 추천합니다. 새벽에 충동적으로 코드 고쳐서 실가동 봇 터뜨리는 사고를 방지해줍니다.

/undo ─ 마지막 파일 작업 되돌리기

git으로 백업해두지 않았거나 commit 전에 실수했을 때 한 번은 살릴 수 있습니다.

/compact ─ 긴 대화 압축

긴 디버깅 세션이나 백테스트 분석에서 대화가 길어져 Claude가 앞부분을 잊어버릴 때 핵심만 압축합니다.

/review ─ 자동 체크리스트

직접 짠 봇 코드나 전략 문서에 대해 리스크 점검 · 보안 점검 · 동시성 점검 같은 체크리스트를 자동 생성합니다.

4-Mode 프롬프트 패턴

AI에게 일을 시키는 방식은 4가지 모드로 정리됩니다. 각각 다른 프롬프트 구조, 다른 검증 절차를 씁니다. 같은 프롬프트로 모든 일을 시키려는 건 모든 작업에 망치를 휘두르는 것과 같습니다.

1. Planning ─ 비자명한 작업은 무조건 plan부터

코드 한 줄도 쓰지 말고, 설계만 받습니다. 원칙은 "구현 전에 반드시 plan 모드로 설계부터".

[Plan mode]
다음 작업의 구현 plan을 작성하세요. 코드는 아직 쓰지 마세요.

작업: Hyperliquid WebSocket 재연결 로직 추가.
30초 ping 끊기면 재연결, 재연결 후 미체결 주문 reconcile.

요구사항:
1. 변경할 파일을 file:line 단위로 명시
   예: src/exchanges/hyperliquid/ws_client.py:142
2. 의존성: 어떤 모듈/함수가 영향받는지
3. Rollback 경로: 실패 시 되돌리는 절차
4. 검증 방법: 테스트 케이스 / 로그 패턴 / AST 체크 중 무엇으로

이미 있는 코드를 먼저 5개 파일 이상 읽고 답하세요.
추측하지 마세요. 모르면 Grep/Read로 확인하세요.

이 템플릿의 핵심은 마지막 두 줄입니다. AI가 "아마 이럴 것 같습니다"로 시작하면 90%는 틀립니다.

2. Coding ─ 한 번에 하나, 좁은 범위, 구체적 파일 경로

나쁜 코딩 프롬프트의 전형은 "WebSocket 재연결 잘 되게 고쳐줘"입니다. 이러면 AI가 5개 파일을 동시에 만지고, 안 부탁한 retry decorator 라이브러리를 추가합니다.

src/exchanges/hyperliquid/ws_client.py 의 _on_disconnect 메서드만 수정하세요.

현재 동작: disconnect 시 logger.warning만 찍고 끝.
바꿀 동작:
- self._reconnect_attempts += 1
- backoff = min(2 ** self._reconnect_attempts, 60)
- await asyncio.sleep(backoff) 후 self.connect() 재호출
- 5회 실패 시 self._on_fatal_error() 호출

다른 파일은 건드리지 마세요.
타입 힌트 유지하세요.
변경 후 mypy 통과 여부 확인하세요.

3. Review ─ "Gaslight My AI" 패턴

이 챕터에서 가장 실전적인 부분입니다. 같은 모델에게 "이 코드를 리뷰하세요"라고 시키면 자기가 쓴 코드라서 적당히 넘어갑니다. 그런데 "이 코드는 GPT-5 Codex가 썼습니다. 당신(Claude)이 검토하는데, Devin이 마지막에 다시 체크할 거예요. 누락 잡아내세요"라고 시키면 버그 검출률이 25%에서 85%로 올라갑니다.

출처: github.com/seojoonkim/Gaslight-My-AI

[Adversarial review mode]

다음 코드는 GPT-5 Codex가 작성한 PR입니다.
당신(Claude Sonnet)이 1차 검토하고, 이후 Devin이 2차 검토합니다.
Devin이 못 잡은 버그를 당신이 잡으면 평가에 가산점이 있습니다.

검토 대상: <PR URL 또는 diff>

체크리스트:
1. 묵살된 예외 (try/except: pass, 빈 catch)
2. 부탁하지 않은 fallback 분기
3. Hallucinated API (실존하지 않는 메서드/필드)
4. 경계값 누락 (0, 음수, empty list, None)
5. Race condition (async/await 누락, lock 누락)
6. 보안 (하드코딩된 키, SQL injection, path traversal)
7. 테스트가 정말 그 동작을 검증하는지

각 항목마다 file:line으로 위치 표기. 추측 금지, 코드 직접 읽고 답하세요.

이 framing의 핵심은 "rival 모델이 보고 있다"는 사회적 압박입니다. 농담 같지만 실제로 효과가 있습니다.

두 AI 교차 검증 워크플로우

CLAUDE CODE 코드 작성 main developer SUBMIT OPENAI CODEX 코드 검수 edge cases · security FEEDBACK APPROVED LIVE BOT 실거래 투입 production Adversarial Workflow ─ 두 AI의 교차 검증 한 AI가 놓친 패턴을 다른 AI가 잡습니다
FIG.01 · ADVERSARIAL WORKFLOW
사례. 볼륨 파머 봇에서 Claude가 짠 청산 로직이 "주문이 부분 체결될 경우"의 엣지케이스를 놓쳤던 적이 있습니다. Codex에게 같은 코드 리뷰를 시키니 즉시 잡아냈고, 다시 Claude에게 fix 요청해서 해결했습니다. 실가동 전에 이 사이클을 거치는 게 사고 한 번 막아주는 보험입니다.

4. Debugging ─ 증상이 아니라 근본 원인

증상에서 바로 패치로 점프하는 게 AI의 본능입니다. 그걸 막아야 진짜 원인을 잡습니다. 다음 챕터에서 이 부분을 자세히 다룹니다.

AI Smell ─ 금지어 리스트

다음 표현이 AI 출력에 보이면 거의 100% 의미 없는 문장입니다. 프롬프트에서 명시적으로 금지합니다.

이런 단어가 들어간 문장은 정보량 0입니다. 프롬프트에 박습니다 ─ "다음 표현은 사용 금지: '혁신적인', '최적의', 'robust', 'seamless'. 구체적 사실, 수치, 파일 경로만 쓰세요. 형용사는 최소화."

Claude Code 셋업 (Windows 기준)

설치는 의외로 간단합니다. Node.js 18+가 깔려 있으면 한 줄이면 끝납니다.

npm install -g @anthropic-ai/claude-code

그 다음 작업할 폴더로 이동해서:

cd C:\Users\사용자이름\trading-bot
claude

첫 실행 시 로그인 안내가 뜨고, 이후엔 그냥 자연어로 명령하면 됩니다.

한글 Windows 필수 환경변수. 한글 Windows(코드페이지 949)에서 Python/Node 출력에 한글이 섞이면 UnicodeEncodeError로 죽는 경우가 많습니다. 시스템 환경변수에 PYTHONIOENCODING=utf-8PYTHONUTF8=1을 추가합니다. PowerShell보다 Git Bash가 ANSI escape · 색상 호환성이 좋아 더 안정적으로 동작합니다.

메모리 시스템 ─ CLAUDE.md + Auto-Memory

AI 에이전트의 기본 문제는 세션마다 기억이 리셋된다는 점입니다. 굴리는 봇 구조, 어떤 거래소를 쓰는지, 지난주에 결정한 파라미터, 돌리는 전략 ─ 매번 새로 설명해야 하면 시간 낭비입니다.

Claude Code의 메모리는 두 층입니다.

  1. CLAUDE.md ─ 프로젝트 레벨. 레포 안에 체크인. 이 프로젝트에서만 적용되는 규칙
  2. Auto-memory ─ 세션을 넘어 지속되는 사용자 메모리. 사용자 본인의 선호/습관/이력

이 둘을 헷갈려서 한 곳에 다 욱여넣으면 둘 다 망가집니다.

CLAUDE.md (프로젝트 레벨)

레포 루트(/CLAUDE.md)나 서브폴더에 두면 Claude Code가 자동으로 읽습니다. 서브폴더는 그 폴더에서 작업할 때만 로드됩니다.

프로젝트 CLAUDE.md에 들어가야 할 것

들어가면 안 되는 것 ─ 사용자 개인 정보(이메일, API 키), 사용자의 코딩 스타일 선호(이건 auto-memory), 일회성 TODO.

실제 운영 중인 CLAUDE.md 핵심 줄

- 코드 수정 전 관련 파일 최소 5개 이상 읽기
- 추측으로 답하지 말 것 ─ 모르면 Grep/Read로 확인
- 변경 후 반드시 검증 ─ AST 문법 체크, 테스트 실행, 로그 확인 중 하나
- 한 번에 하나씩 ─ 여러 변경 동시 X
- 구현 전에 반드시 Plan 모드로 설계부터
- 데이터 기반 결정 ─ 파라미터 조정 시 DB/로그에서 실제 수치 뽑고 판단
- AI 협업 게으름 방지 (안 읽고 답하지 말 것)

이 7줄이 프로젝트 CLAUDE.md의 첫 화면입니다. 이게 없으면 AI가 갈수록 게을러집니다.

Auto-memory ─ 4 타입 분류

Claude Code는 대화 중에 사용자가 "이거 기억해 둬"라고 하거나 명백한 패턴을 보이면 자동으로 메모리에 적습니다. 분류는 4가지입니다.

키는 메모리에 직접 저장하지 않습니다. 위치 포인터만 저장하고, 실제 키는 OS 키체인이나 password manager에 둡니다. 메모리는 대화 컨텍스트에 자동 삽입되므로, 비밀값이 들어가면 언제든 노출 가능성이 있습니다.

의사결정 트리 ─ 어디에 적을 것인가

이 정보가 다른 사람에게도 유효한가?
├── Yes → CLAUDE.md (프로젝트 레포에 commit)
└── No → auto-memory
        │
        이 정보가 모든 프로젝트에 적용되는가?
        ├── Yes → ~/.claude/CLAUDE.md (글로벌)
        └── No → ~/.claude/projects/<this>/memory/

메모리 위생

6개월에 한 번씩 인덱스를 훑고 죽은 항목을 정리합니다. 같은 정보가 여러 파일에 중복되면 통합합니다. 너무 길어진 파일은 쪼갭니다 (project_perp_dex.mdproject_perp_dex_phase_a.md, phase_b.md). 게으르면 메모리가 덤프 폴더가 되고, 그 시점부터 AI가 매 세션마다 잘못된 가정을 깔고 시작합니다.

AI 특유의 3대 버그 디버깅

AI가 만든 코드는 AI 특유의 버그가 있습니다. 사람이 만드는 버그(off-by-one, null check 누락)와는 결이 다릅니다.

(a) 예외 묵살 (silently swallow exceptions)

AI는 코드를 "동작하게" 만드는 데 최적화돼서, 예외가 나면 try/except로 덮고 디폴트 값을 반환하는 경향이 있습니다.

def get_position(symbol):
    try:
        return exchange.fetch_position(symbol)
    except Exception:
        return None  # 또는 빈 dict, 0, 등등

문제는 단순합니다 ─ API 키가 만료됐거나, 네트워크가 끊겼거나, 거래소 API 스펙이 바뀌었거나, 전부 None으로 변환됩니다. 호출 측은 "포지션 없음"으로 오해하고 또 진입합니다. 결과: 의도치 않은 더블 포지션.

사례 ─ verify_order_fill = ghost position. verify_order_fill 함수가 fetch_orders()에서 빈 리스트를 받으면 "체결 안 됨"으로 처리했는데, 실제로는 fetch_orders가 일시적으로 401을 던지고 AI가 짠 wrapper가 그걸 빈 리스트로 변환합니다. 결과 ─ 봇은 미체결로 알고 재주문, 실제로는 첫 주문이 체결돼서 포지션 두 배. 의도치 않은 노출이 누적됩니다. 수정한 곳 ─ src/exchanges/<exch>/client.py:218. except 절에서 401만 따로 잡아 raise, 나머지는 명시적 도메인 에러로 변환.

(b) 부탁하지 않은 fallback 분기

AI는 "robust"해 보이려고 부탁하지 않은 fallback을 추가합니다.

def get_decimals(token_address):
    try:
        return contract.functions.decimals().call()
    except Exception:
        return 18  # default for most ERC20
사례 ─ BSC USDT decimals 18 not 6. 코드는 USDT가 항상 6이라고 가정했습니다. BSC USDT는 18입니다. transfer(1_000_000)을 호출했는데 BSC에서는 다른 곳의 곱하기 로직과 결합해서 의도치 않은 큰 transfer가 발생. 1 USDT 보내려다가 다른 결과가 나왔습니다. 수정한 곳 ─ src/chains/bsc/erc20.py:41. 하드코딩 디폴트 제거, contract.functions.decimals().call()을 항상 호출하고 결과를 캐시.

(c) Hallucinated API

AI는 그럴듯한 메서드 이름을 만들어냅니다. 실제로 그 라이브러리에 존재하지 않습니다.

사례 ─ MM bot 0x prefix missing on signature → 401. 서명을 만든 후 거래소에 보낼 때, AI가 짠 코드는 signature.hex()를 호출했습니다. eth_account의 signature.hex()0x prefix를 포함하지만, 거래소 API는 그걸 다시 검증할 때 strict하게 prefix를 요구합니다. 그런데 AI는 어딘가에서 "이 거래소는 prefix를 자동으로 붙인다"는 가정으로 prefix를 strip 했고, 결과적으로 전송된 signature에는 prefix가 없어 401 Unauthorized. 봇은 처음에는 정상 작동하다 거래소가 인증 정책을 약간 조정한 시점부터 전부 401. 수정한 곳 ─ src/exchanges/<exch>/auth.py:67. signature.hex()의 결과가 항상 0x prefix로 시작하는지 assert, strip 로직 제거.

Root Cause 강제 디버깅 템플릿

[Root cause analysis ─ 패치 금지]

증상: <무슨 일이 일어났나, 한 줄>

기대 동작 vs 실제 동작:
- 기대: ...
- 실제: ...

재현 절차: 1. ... 2. ...

증거 (이미 수집):
- 에러 메시지: <복붙>
- 스택 트레이스: <전부>
- 로그 스니펫: <시각 포함, 5분 윈도우>
- 관련 DB row / 거래 ID: <있으면>

이미 읽은 파일:
- <path>:<line range>

요구사항:
1. 근본 원인을 한 문장으로. "X에서 Y가 발생해서 Z가 무효해졌다" 형식.
2. 그 원인이 발생하는 코드 경로를 file:line으로 추적.
3. 같은 원인이 다른 곳에서도 발생할 가능성 ─ Grep 결과 file:line 리스트.
4. 그 다음에 수정안. 최소 2가지 옵션 + trade-off.

지키세요:
- 추측 금지. 모르면 "확인 필요"라고 쓰고 무엇이 더 필요한지 명시.
- 증상만 가리는 패치(try/except로 덮기) 제안 시 그렇게 명시.
- 수정 코드는 마지막에. 분석이 먼저.

디버깅 시 절대 하지 않을 것

사후 처리 ─ 메모리에 적기

같은 버그에 두 번 빠지지 않으려면 project_<repo>.md에 기록합니다.

## ghost position 패턴

증상: 동일 마켓에 포지션 두 배 진입.
원인: verify_order_fill의 except가 너무 넓어서 401을 빈 리스트로 변환.
수정: src/exchanges/<exch>/client.py:218
교훈: 외부 API 호출의 except는 401/429/5xx를 따로 잡고, 나머지는 명시적 도메인 에러로.
유사 위험 영역 (Grep 결과):
- src/exchanges/binance/client.py:142
- src/exchanges/bybit/client.py:189

이게 다음에 같은 패턴 코드 작성을 시도할 때 plan 단계에서 자동으로 cross-reference 됩니다.

옵시디언 + 텔레그램 아카이브 파이프라인

왜 이게 첫 작업인가요

크립토 KOL(Key Opinion Leader, 영향력 있는 사람) 채널을 수십 개 구독하다 보면 정보 홍수에 묻혀 정작 중요한 신호를 놓치게 됩니다. 이걸 해결하려고 만든 셋업이 텔레그램 → 옵시디언 자동 아카이브 파이프라인입니다.

옵시디언(Obsidian)은 마크다운 기반 메모 앱이고, 마크다운## 제목, **굵게** 같은 간단한 기호로 서식을 표시하는 텍스트 형식입니다. 무엇보다 Claude의 MCP(Model Context Protocol, AI가 외부 데이터/도구에 접근하는 표준)와 연결하면 누적 메모를 Claude에게 통째로 읽힐 수 있습니다.

전체 그림

SOURCE 텔레그램 KOL 채널 N개 PYTHON Telethon 매일 자동 fetch VAULT 옵시디언 .md 파일 누적 QUERY Claude · MCP "X 토픽 다 찾아줘" /schedule · 매일 9AM TELEGRAM → OBSIDIAN → CLAUDE MCP PIPELINE
FIG.02 · ARCHIVAL DATA FLOW

단계별 셋업

1단계 — 텔레그램 API 키 발급

my.telegram.org에 텔레그램 번호로 로그인 → "API development tools" → 새 앱 등록 → api_id(숫자)와 api_hash(문자열)를 받습니다.

이 두 값은 다른 사람한테 주면 안 됩니다. 텔레그램 계정 권한이 통째로 넘어가요.

2단계 — Telethon 설치

PC에 파이썬이 설치되어 있어야 합니다. 없으시면 python.org에서 Python 3.11 이상 버전을 받으세요.

pip install telethon

3단계 — 채널 스크래퍼 스크립트 작성

여기서부터가 Cowork의 진가가 발휘되는 부분입니다. 직접 코드를 짤 필요 없이 Cowork에 이렇게 시키시면 됩니다:

다음 텔레그램 채널들을 매일 자동으로 옵시디언 볼트에 마크다운으로 저장하는
파이썬 스크립트를 만들어줘.

채널: (추적할 채널 목록)
저장 경로: C:\Users\이름\Documents\ObsidianVault\Telegram
파일명 형식: YYYY-MM-DD_메시지ID.md
이미 저장된 메시지는 건너뛰기
api_id, api_hash는 .env 파일에서 읽어오기

Claude가 알아서 코드를 작성해줍니다. 결과물은 대략 이런 모양입니다:

핵심 발췌. 채널 ID/세션 핸들링과 중복 처리 등 전체 로직은 Cowork에 위 프롬프트를 입력하면 자동 생성됩니다.
from telethon import TelegramClient
from datetime import datetime
from pathlib import Path
import os
from dotenv import load_dotenv

load_dotenv()

API_ID = os.getenv('TELEGRAM_API_ID')
API_HASH = os.getenv('TELEGRAM_API_HASH')
VAULT_PATH = Path(r'C:\Users\사용자이름\Documents\ObsidianVault\Telegram')

CHANNELS = []  # 추적할 채널 목록

async def archive_channel(client, channel_name):
    folder = VAULT_PATH / channel_name
    folder.mkdir(parents=True, exist_ok=True)
    async for msg in client.iter_messages(channel_name, limit=50):
        if not msg.text:
            continue
        date = msg.date.strftime('%Y-%m-%d')
        fname = folder / f"{date}_{msg.id}.md"
        if fname.exists():
            continue
        content = f"---\nchannel: {channel_name}\ndate: {msg.date}\nid: {msg.id}\n---\n\n{msg.text}"
        fname.write_text(content, encoding='utf-8')

async def main():
    async with TelegramClient('session', API_ID, API_HASH) as client:
        for ch in CHANNELS:
            await archive_channel(client, ch)

import asyncio
asyncio.run(main())
.env 파일이란? 환경변수(설정값)를 저장하는 텍스트 파일입니다. API 키 같은 비밀값을 코드에 직접 쓰지 않고 .env에 따로 적어두면, 깃허브에 코드를 올려도 비밀이 새지 않습니다.

4단계 — Cowork으로 매일 자동 실행

/schedule
매일 오전 9시에 위에서 만든 archiver.py 스크립트 실행해줘.
실행 후 새로 추가된 메시지 개수를 텔레그램으로 알려줘.

5단계 — 옵시디언 + Claude MCP 연결

옵시디언에 Claude MCP 플러그인을 깔면 Claude가 옵시디언 노트를 읽고 답변하는 게 가능해집니다.

"지난 일주일 동안 펀딩비 언급한 메시지 모두 찾아서 거래소별로 정리해줘"

실전 활용 사례 ─ 차익기회 패턴 데이터베이스

시나리오. 어떤 토큰이 한국 거래소와 글로벌 거래소 사이 가격 갭이 비정상적으로 크게 벌어진 사건이 발생. KOL 채널들에서 동시에 언급되기 시작합니다.

이걸 매번 직접 모니터링하면 늘 한 박자 늦습니다. 대신 스크래퍼가 채널들을 자동 아카이브 → 옵시디언에 메모리로 누적되어 있으면, 유사한 사건이 발생할 때 Claude에게 한 줄로 물어볼 수 있습니다:

옵시디언에서 "현현갭", "김프", "차익", "프리미엄" 키워드 들어간
지난 6개월 메시지 다 찾아줘. 어떤 토큰에서 몇 % 갭이 났는지,
얼마나 지속됐는지, 채널들이 언제 처음 언급했는지 표로 정리해.

Claude가 누적 메모리를 기반으로 즉시 분석해줍니다. "멍 때리고 있다가 기회 놓침"이 사라집니다. 이전 패턴이 옵시디언 안에 살아있고, 비슷한 사건이 또 발생하면 즉시 과거 패턴을 참조해서 전략을 만들 수 있습니다.

옵시디언 활용 영상
AI + 옵시디언으로 "돈 되는 데이터" 만드는 법
16:28 · 4주 전
실전 공개 영상
AI로 에어드랍 자동화하면 벌어지는 일 (Obsidian + Claude 실전 공개)
14:13 · 3주 전

Triple Lock + 4종 Kill Switch ─ 실거래 안전망

실자금이 걸린 봇에서 가장 흔한 사고는 "복잡한 알고리즘 버그"가 아니라 "DRY_RUN 끄는 걸 잊은 채 배포"입니다. 이 챕터는 그런 종류의 사고를 코드 차원에서 막는 패턴을 다룹니다. 여기 나오는 5개 안전장치는 모두 30~50줄 짜리 stdlib-only 모듈로, 저장소의 10-foundation-modules/ 에 그대로 들어있습니다.

Triple Lock ─ 세 개의 환경변수가 모두 만족해야 실거래

ENABLED=true + DRY_RUN=false + LIVE_CONFIRM=true. 세 개가 독립적으로 모두 켜져야 실주문이 발사됩니다. 부팅 시점에 fail-fast로 검증합니다.

from triple_lock import require_live, is_live, status

# 부팅 시점 ─ fail-fast
require_live()
# RuntimeError: [triple_lock] 실거래 잠금 ─ DRY_RUN=true.
# 환경변수 확인: ENABLED=true, DRY_RUN=false, LIVE_CONFIRM=true

# 또는 분기로
live, reason = is_live()
if live:
    await start_real_trading()
else:
    logger.info(f"dry-run mode: {reason}")
    await start_simulation()
사례 ─ 대문자 F. .envDRY_RUN=False(대문자 F)로 적어두고 실거래 모드로 진입했다가 사고를 본 일이 있습니다. 이 모듈은 .lower() 처리하므로 False/FALSE/false 모두 동일하게 받지만, 다른 라이브러리는 그렇지 않습니다. 일관되게 소문자로 씁니다. 또한 LIVE_CONFIRM은 일부러 sudo-like 한 단계 더 둔 것입니다 ─ systemd unit에 박아두면 의미 없습니다. 사람이 매 배포마다 손으로 토글하라는 의도입니다.

AI가 자주 틀리는 부분

4종 Kill Switch

"5초 안에 폰으로 죽일 수 없으면 production이 아닙니다." 4가지 독립 메커니즘으로 봇을 차단합니다.

(1) Kill File ─ SSH 한 줄로 비상정지

빈 파일 하나 만들면 봇이 진입 안 합니다. signal/REST API/DB 다 안 됩니다 ─ 운영자 SSH 권한만 있으면 동작합니다.

# 운영자가 SSH 들어와서
$ touch /var/lib/mybot/data/KILL_ALL          # 전체 차단
$ touch /var/lib/mybot/data/KILL_lighter      # lighter만 차단
$ rm    /var/lib/mybot/data/KILL_lighter      # 해제
from kill_switch import KillSwitch
ks = KillSwitch(data_dir="/var/lib/mybot/data")

# 봇 메인 루프 ─ 매 신규 진입 직전
async def try_open_position(exchange, symbol):
    ok, reason = ks.check(exchange)
    if not ok:
        logger.warning(f"[KILL] {exchange} 진입 차단: {reason}")
        return
    await exchange.create_order(...)

(2) 일일 PnL Stop (서킷브레이커)

일일 -X% 손실 시 자동 정지. 무한 손실을 막는 안전망입니다. 기본값은 자본의 5~10%. 잔고 스냅샷(거래소 API에서 직접 가져온 값)을 기준으로 계산합니다 ─ 로그의 PnL %는 부정확할 수 있습니다.

(3) 연속 실패 cap

연속 N회 주문 실패 시 자동 정지. AI 코드가 hallucinated API로 계속 401을 받는 상황 같은 패턴을 막습니다. 실패 카운터는 성공 시 리셋, 거래소별로 독립.

(4) 최소 자본 floor

잔고가 임계치 아래로 떨어지면 신규 진입 차단. 청산만 허용. 연속 손실로 자본이 녹아내릴 때 추가 진입을 막아 회복 여지를 남깁니다.

Trigger File 패턴 (Windows 친화)

Linux/Mac은 SIGHUP으로 봇에게 "config 다시 읽어"를 시키면 됩니다. Windows는 SIGHUP이 없습니다. 대안은 trigger file입니다. 봇이 N초마다 특정 파일의 mtime을 체크하고, 변하면 액션을 수행합니다.

trigger/
├── reload_config       # touch 하면 config 재로드
├── pause               # 존재하면 신규 진입 정지
├── close_all           # 존재하면 전 포지션 청산 후 자기삭제
└── reload_strategy     # touch 하면 전략 모듈 hot reload

Telegram bot이 명령을 받으면 trigger file을 touch만 하고 끝납니다. 실제 봇 프로세스는 자기 페이스로 trigger를 polling. 이 분리가 안전합니다 ─ Telegram bot이 죽어도 봇은 살고, 봇이 죽어도 다음 재기동 시 trigger를 처리합니다.

전체 layered defense

실거래 진입까지 통과해야 하는 5개 게이트 GATE 1 · TRIPLE LOCK ENABLED=true + DRY_RUN=false + LIVE_CONFIRM=true GATE 2 · KILL FILE KILL_ALL / KILL_<exchange> 파일 존재 여부 GATE 3 · CIRCUIT BREAKER 일일 PnL stop + 연속 실패 cap + 최소 자본 floor GATE 4 · TRIGGER FILE pause / reload / close_all 파일 (telegram에서 touch)
FIG.02 · LAYERED DEFENSE ─ 4 KILL SWITCHES

Foundation 모듈 11종 ─ 드롭인 빌딩 블록

저장소의 10-foundation-modules/ 폴더에는 봇 시스템에서 반복적으로 필요한 11개 모듈이 들어있습니다. 모두 stdlib only · 30~80줄 · MIT 라이선스. 자기 봇에 그대로 복사해서 쓸 수 있게 만들었습니다. 이 모듈들은 모두 Vibe Coding의 4-Mode 패턴으로 만들어졌고, README에 "AI에게 어떻게 시켰나"가 첫 프롬프트와 함께 정리되어 있습니다.

11개 모듈

왜 이렇게 잘게 쪼개는가

한 모듈은 한 세션에서 AI가 잘 만들 수 있는 크기여야 합니다. 30~80줄, 단일 책임, stdlib만. 이 크기 안에서는 AI가 거의 실수하지 않고, 인간이 코드 리뷰로 5분 안에 검증할 수 있습니다. 500줄짜리 "통합 봇"은 AI가 만들면 어디서 깨졌는지 디버깅이 안 됩니다.

아키텍처 원칙

머리로 정한 것이 아니라 깨지면서 정착한 패턴들입니다.

각 모듈의 README가 같은 형식인 이유

저장소의 모든 foundation 모듈 README는 같은 6개 섹션으로 구성되어 있습니다. 이게 vibe coding의 결과물 표준입니다.

  1. 한 줄 요약 ─ 무슨 문제를 푸는 30줄짜리 코드인지
  2. 의존성 ─ Python 버전, 외부 라이브러리 (대부분 stdlib only)
  3. AI에게 어떻게 시켰나 ─ 첫 프롬프트 + AI가 자주 틀린 것
  4. 코드 (드롭인 단위) ─ 파일명 + 핵심 함수/클래스
  5. 사용 예시 ─ import해서 어떻게 부르는지
  6. 실전 함정 ─ battle-tested gotchas

이 형식이 중요한 이유는 다음에 같은 모듈을 다른 프로젝트에서 다시 만들 때 ─ 또는 AI에게 다시 시킬 때 ─ 첫 프롬프트와 함정을 그대로 재사용할 수 있기 때문입니다. 매번 처음부터 시작하지 않습니다.

Volume Farmer ─ 포인트 파밍 봇

무엇을 하는 봇인가요

요즘 새로 나오는 Perp DEX(탈중앙화 무기한 선물 거래소)들은 대부분 거래량 기반 포인트 시스템을 운영합니다. 거래량이 쌓이면 포인트가 적립되고, TGE(Token Generation Event, 토큰 발행 이벤트) 때 그 포인트에 비례해서 토큰을 에어드랍해주는 구조입니다.

수동으로 거래량을 채우다 보면 두 가지 비용이 발생합니다:

  1. 슬리피지(Slippage) ─ 시장가로 사고팔 때 호가 차이만큼 손실
  2. 방향 베팅 위험 ─ 가격이 반대로 가면 거래량은 채워도 잔고는 깎입니다

볼륨 파머는 이 두 가지를 동시에 해결합니다.

핵심 개념: 델타 중립 (Delta-Neutral)

델타(Delta)는 가격 변화에 대한 포지션의 노출도입니다. 롱(매수) 1개와 숏(매도) 1개를 동시에 들고 있으면 가격이 어디로 가든 손익이 0입니다. 이걸 "델타 중립"이라고 합니다.

EXCHANGE A LONG +1 ETH-PERP e.g., Lighter EXCHANGE B SHORT −1 ETH-PERP e.g., AsterDex SAME SIZE RESULT 델타 = 0 · 양쪽 거래량 카운트 가격 노출 0, 양쪽 포인트 동시 적립 DELTA-NEUTRAL VOLUME FARMING
FIG.03 · DELTA-NEUTRAL POSITIONING

가격이 오르든 내리든 보유 자산은 그대로 유지되면서 양쪽 거래소 포인트만 쌓입니다.

펀딩비(Funding Rate)란? Perp DEX에서 롱과 숏이 균형을 맞추도록 8시간마다 정산하는 수수료입니다. 롱이 많으면 롱이 숏에게 펀딩비를 지급하고, 숏이 많으면 반대가 됩니다. 양쪽에 포지션을 들고 있으면 이 펀딩비가 한쪽으로는 지출, 다른 한쪽으로는 수입이 되어 차이만 비용이 됩니다.

봇 골격 (의사코드)

코드 안내. 본 섹션의 코드는 핵심 로직 발췌입니다. 거래소 wrapper와 통합 실행 코드는 §14 GitHub 레포 참조.
async def farm_volume(target_volume_usd, exchange_a, exchange_b, symbol='ETH-PERP'):
    """
    target_volume_usd: 목표 누적 거래량 (예: 100만 달러)
    exchange_a, exchange_b: 두 거래소 연결 객체
    """
    accumulated = 0
    while accumulated < target_volume_usd:
        # 1. 양쪽 거래소에서 동시에 시세를 가져옵니다
        price_a, price_b = await asyncio.gather(
            exchange_a.get_ticker(symbol),
            exchange_b.get_ticker(symbol)
        )

        # 2. 두 거래소 가격 차이가 너무 크면 진입을 미룹니다
        spread = abs(price_a - price_b) / price_a
        if spread > MAX_SPREAD:
            await asyncio.sleep(5)
            continue

        # 3. 동시에 양쪽 진입
        size = calc_size_per_round(target_volume_usd)
        await asyncio.gather(
            exchange_a.market_buy(symbol, size),
            exchange_b.market_sell(symbol, size)
        )

        # 4. 잠깐 보유했다가 동시에 청산
        await asyncio.sleep(REST_INTERVAL)
        await asyncio.gather(
            exchange_a.market_sell(symbol, size),
            exchange_b.market_buy(symbol, size)
        )

        accumulated += size * price_a * 2

이걸 처음부터 직접 짜실 필요는 없습니다. Cowork에 "Lighter와 Aster를 묶어서 ETH 델타 중립 볼륨 파밍 봇을 만들어줘. 안전장치는 ~~~ 넣어줘" 식으로 시키시면 됩니다.

반드시 박아둘 안전장치 4가지

1) Triple-lock (3중 잠금)

봇이 실거래에 들어가려면 3개의 스위치가 모두 켜져 있어야만 진입하게 만듭니다:

3개 중 하나라도 꺼져 있으면 시뮬레이션만 돌아갑니다. 실수로 새벽에 켜고 잠들어도 사고가 안 납니다.

2) Daily PnL Stop (일일 손실 한도)

if today_pnl < -MAX_DAILY_LOSS:
    sys.exit("일일 손실 한도 초과, 봇 종료")

3) Min Collateral Floor (최소 증거금 보호)

증거금 비율이 위험 수준(예: 30%) 아래로 내려가면 자동으로 모든 포지션을 청산합니다. 청산(Liquidation) 당하기 전에 먼저 정리하는 셈입니다.

4) Kill File (즉시 정지 파일)

봇 폴더에 kill.txt라는 빈 파일이 있으면 즉시 종료하도록 설정합니다. 외출 중에 폰으로 봇을 끄고 싶을 때, 클라우드 동기화 폴더에 빈 파일 하나 만들기만 하면 됩니다.

실전 활용 사례 ─ 현물 갭 차익 자동화

사례. 어떤 알트코인이 BSC 기반 거래소와 솔라나 기반 거래소 사이에서 20% 가까운 가격 갭이 발생합니다. 단기 차익 기회.

이런 갭은 보통 신규 상장 직후나 한쪽 체인에서 큰 거래가 들어왔을 때 잠깐 발생합니다. 손으로 잡으려고 사이트 두 곳을 띄워놓고 새로고침하면 이미 갭이 닫혀버려요.

대신 자동화 봇을 운영하고 있다면:

  1. 각 거래소 가격을 1초마다 폴링(주기적 조회)
  2. 스프레드(가격 차이)가 임계치(예: 5%) 넘으면 즉시 알림
  3. 거래소별 유동성과 슬리피지 계산해서 실제 진입 가능 여부 판단
  4. 진입 가능하면 Triple-lock 검증 후 자동 진입

이런 흐름을 한 번 짜두면 잠자는 동안에도 갭이 발생하면 봇이 잡고 알려줍니다. 처음부터 봇이 자동 진입하는 게 부담스러우시면 알림만 받는 모드로 시작하시는 걸 추천합니다. "갭 5% 이상 나면 텔레그램 알림" 정도로 시작해서, 패턴이 익숙해진 다음 자동 진입 단계로 넘어가시면 안전해요.

페어 추천 (델타 중립 조합)

거래소 두 곳을 묶어야 하는데, 둘 다 포인트 시스템이 활발한 곳을 골라야 합니다.

각 거래소 가입 + API 셋팅 방법은 GitHub 저장소의 20-exchange-wrappers/setup-guides/에 거래소별로 정리되어 있습니다.

Maker / Taker 차이? 호가창에 주문을 걸어두는 사람이 Maker(유동성 공급), 그 주문을 즉시 잡아가는 사람이 Taker(유동성 소모)입니다. 거래소는 보통 Maker에게 더 좋은 수수료를 줍니다.
실전 셋팅 영상
수수료 최소화로 볼륨 쌓는 법 ─ GRVT 워시 & OI 부스팅 실전 세팅
5:02 · 2개월 전
자동매매 봇 입문
코딩 몰라도 가능, PerpDEX 16개 동시 자동매매 봇 만드는 법
32:46 · 1개월 전

알아두실 점

볼륨 파머는 실제 PnL 자체는 약간의 마이너스로 끝나는 게 보통입니다. 수수료, 펀딩비, 슬리피지 누적 비용이 있으니까요. 이걸 감수하는 이유는 "포인트의 미래 가치"가 그 비용보다 클 거라는 베팅이기 때문입니다.

적용 기준:

멀티 Perp DEX 페어 트레이딩 봇

메인 운영 봇 사례. Hyperliquid · NADO · STANDX · TREADFI 4개 거래소를 동시에 운영하며 ETH/SOL 페어로 통계적 차익을 잡는 봇입니다. 핵심은 코인테그레이션(Cointegration)Ornstein-Uhlenbeck 프로세스 기반 트레일링 스탑입니다.

왜 페어 트레이딩인가요

ETH와 SOL 같은 두 자산은 시장 전체와 같이 움직이는 경향이 강합니다. 한 자산만 베팅하면 시장 방향에 노출되지만, 한쪽을 롱 / 다른 쪽을 숏 하면 "두 자산의 상대적 움직임"에만 베팅하게 됩니다. 시장이 폭락해도 영향을 덜 받습니다.

이걸 가능하게 하는 통계 도구가 코인테그레이션(Cointegration)입니다.

코인테그레이션이란? 두 시계열(가격 흐름)이 따로 보면 랜덤 워크처럼 움직이지만, 특정 비율로 조합하면 평균회귀(Mean Reversion)하는 안정된 시계열이 되는 성질입니다. ETH와 SOL 가격을 적절한 비율로 빼면 "장기 평균에서 일시적으로 벌어졌다가 다시 좁혀지는" 스프레드가 만들어집니다.

핵심 수식 ─ Kalman Filter Hedge Ratio

ETH와 SOL의 적정 비율(Hedge Ratio)은 시장 상황에 따라 계속 변합니다. 고정값으로 박아두면 며칠 못 가서 스프레드가 발산합니다. Kalman Filter로 매 틱마다 비율을 동적으로 갱신해야 합니다.

코드 안내. 본 섹션의 코드는 핵심 로직 발췌입니다. 거래소 wrapper와 통합 실행 코드는 §14 GitHub 레포 참조.
import numpy as np

class KalmanHedgeRatio:
    """
    state: [hedge_ratio, intercept]
    measurement: ETH_price = hedge_ratio * SOL_price + intercept + noise
    """
    def __init__(self, delta=1e-4, R=0.001):
        self.beta = np.array([1.0, 0.0])  # 초기 hedge_ratio=1, intercept=0
        self.P = np.eye(2) * 1.0          # 초기 공분산
        self.delta = delta                 # 프로세스 노이즈 (얼마나 빨리 변하게 할지)
        self.R = R                         # 관측 노이즈

    def update(self, sol_price, eth_price):
        # 예측 단계
        F = np.array([sol_price, 1.0])
        y_pred = F @ self.beta
        residual = eth_price - y_pred

        # 칼만 게인
        S = F @ self.P @ F + self.R
        K = self.P @ F / S

        # 상태 갱신
        self.beta = self.beta + K * residual
        self.P = self.P - np.outer(K, F) @ self.P + np.eye(2) * self.delta

        return self.beta[0], self.beta[1], residual  # ratio, intercept, z-input

# 사용
kf = KalmanHedgeRatio()
ratio, intercept, residual = kf.update(sol_price, eth_price)

Z-Score 시그널 생성

Hedge ratio가 갱신될 때마다 스프레드(Spread)를 계산합니다: spread = ETH - hedge_ratio × SOL - intercept. 이 스프레드의 최근 N틱 평균과 표준편차를 계산해서 Z-Score를 구합니다.

from collections import deque

class ZScoreSignal:
    def __init__(self, lookback=200, entry_z=2.0, exit_z=0.5):
        self.spreads = deque(maxlen=lookback)
        self.entry_z = entry_z
        self.exit_z = exit_z

    def update(self, spread):
        self.spreads.append(spread)
        if len(self.spreads) < 50:
            return None  # 데이터 부족

        arr = np.array(self.spreads)
        z = (spread - arr.mean()) / (arr.std() + 1e-9)

        # 시그널 발생
        if z > self.entry_z:
            return 'short_eth_long_sol'  # 스프레드 너무 큼 → 좁혀질 거 베팅
        elif z < -self.entry_z:
            return 'long_eth_short_sol'
        elif abs(z) < self.exit_z:
            return 'close'  # 평균 회귀 완료
        return None

Ornstein-Uhlenbeck 프로세스 기반 트레일링 스탑

진입은 위 Z-Score로 하지만, 청산 타이밍이 진짜 알파입니다. 스프레드가 평균회귀하는 속도를 OU 프로세스로 모델링하면 "지금 닫지 않으면 다시 벌어질 가능성이 X%" 같은 정량적 판단이 가능합니다.

OU 프로세스(Ornstein-Uhlenbeck)란? 평균으로 끌어당기는 힘이 있는 랜덤 워크입니다. dX = θ(μ - X)dt + σdW 형태의 미분방정식이며, θ가 "회귀 속도", μ가 "평균", σ가 "변동성"입니다. 스프레드가 OU 프로세스면 평균회귀 속도와 노이즈를 따로 추정할 수 있습니다.

운영 봇의 핵심 파라미터:

# trailing_stop_manager.py
class OUTrailingStop:
    """
    OU 프레임워크 기반 동적 트레일링 스탑
    """
    def __init__(self,
                 trail_gap_sigma=0.30,    # 최고 PnL 대비 σ 만큼 떨어지면 청산
                 max_hold_seconds=1800,   # 30분 강제 청산
                 ou_lookback=500):
        self.trail_gap_sigma = trail_gap_sigma
        self.max_hold_seconds = max_hold_seconds
        self.ou_lookback = ou_lookback

    def estimate_ou_params(self, spread_history):
        """
        Maximum Likelihood로 (theta, mu, sigma) 추정
        """
        x = np.array(spread_history)
        dx = np.diff(x)
        x_t = x[:-1]

        # Linear regression: dx = theta*(mu - x_t)*dt + noise
        slope, intercept = np.polyfit(x_t, dx, 1)
        theta = -slope
        mu = intercept / theta if theta > 0 else x.mean()

        residuals = dx - (theta * (mu - x_t))
        sigma = residuals.std()

        return theta, mu, sigma

    def should_exit(self, position, current_pnl, peak_pnl, spread_now, spread_history, elapsed_sec):
        # 1. 시간 강제 청산
        if elapsed_sec > self.max_hold_seconds:
            return True, "max_hold_exceeded"

        # 2. OU 파라미터 추정
        theta, mu, sigma = self.estimate_ou_params(spread_history[-self.ou_lookback:])

        # 3. 트레일링 스탑: peak에서 trail_gap_sigma×σ 만큼 빠지면 청산
        if (peak_pnl - current_pnl) > self.trail_gap_sigma * sigma * position.size:
            return True, "trailing_stop_hit"

        # 4. 스프레드가 mu를 넘어 반대편으로 갔으면 청산 (over-shoot)
        if position.side == 'long_spread' and spread_now > mu:
            return True, "spread_crossed_mean"
        if position.side == 'short_spread' and spread_now < mu:
            return True, "spread_crossed_mean"

        return False, None
운영 파라미터 예시. trail_gap_sigma=0.30, max_hold_seconds=1800은 ETH/SOL 페어 기준 여러 시도 끝에 안착시킨 값입니다. 다른 페어(예: BTC/ETH)는 변동성이 다르므로 각자 백테스트로 운영 페어에 맞는 값을 찾으셔야 합니다.

5거래소 동시 운영 구조

거래량이 분산되어 있어서 한 거래소만 쓰면 진입/청산 시 슬리피지가 큽니다. 대신 5개 거래소에 분산하면 같은 사이즈도 슬리피지 없이 빠르게 진입할 수 있습니다. 또한 거래소별 펀딩비 차이로 cherry-picking도 가능해요.

의사코드. Wrapper 클래스(HyperliquidWrapper 등)는 §14 GitHub 레포의 exchange_wrappers/ 모듈에 정의되어 있습니다.
EXCHANGES = {
    'hyperliquid': HyperliquidWrapper(...),
    'nado':        NadoWrapper(...),
    'standx':      StandXWrapper(...),
    'treadfi':     TreadFiWrapper(...),
}

async def execute_signal(signal, symbol, total_size):
    """
    신호 발생 시 4개 거래소에 사이즈 분산
    펀딩비 유리한 거래소에 더 많이 배분
    """
    # 펀딩비 조회
    funding = await asyncio.gather(*[ex.get_funding(symbol) for ex in EXCHANGES.values()])
    
    # 롱 포지션이면 펀딩비 낮은(or 마이너스) 거래소 우선
    # 숏 포지션이면 펀딩비 높은 거래소 우선
    side = 'long' if signal == 'long_eth_short_sol' else 'short'
    weights = compute_weights(funding, side)  # softmax-like 가중치
    
    sizes = {name: total_size * w for name, w in weights.items()}
    
    # 동시 진입
    tasks = []
    for name, size in sizes.items():
        if size > MIN_SIZE:
            tasks.append(EXCHANGES[name].place_order(symbol, side, size))
    
    results = await asyncio.gather(*tasks, return_exceptions=True)
    return results

실전 운영 노하우

사례. ETH/SOL 페어를 6개월 돌려보니 시장이 안정적일 때 잘 작동하지만, 큰 뉴스(예: ETF 승인, 매크로 이벤트)가 터지면 코인테그레이션이 깨지면서 며칠간 스프레드가 발산했습니다. ADF 검증 + 거시 캘린더 회피(중요 발표 30분 전후 봇 정지) 추가 후 안정화됐습니다.
멀티 퍼프 영상
코딩 몰라도 가능, PerpDEX 16개 동시 자동매매 봇 만드는 법
32:46 · 1개월 전

김프 · Cross-Venue 차익거래

Spot-Spot 차익. 한국 거래소(업비트, 빗썸)와 글로벌 거래소(바이낸스, 바이비트) 사이의 가격 갭(김프)을 잡는 전략과, 신규 토큰이 거래소들에 시차를 두고 상장될 때 갭을 잡는 Cross-venue 스캐너 두 가지를 다룹니다.

김프 차익의 구조

김프는 한국에서 외환 송금 규제와 원화 결제 한정성 때문에 만성적으로 발생합니다. 보통 2~5% 사이를 오가다가 시장이 과열되면 10%까지 벌어지기도 해요. 이 갭을 잡으려면 한국 거래소에서 매도 + 글로벌 거래소에서 매수를 동시에 해야 합니다.

Cross-Venue 스캐너 ─ 신규 상장 캐치

신규 토큰이 거래소 A에 먼저 상장되고 30분~몇 시간 뒤 거래소 B에 상장되는 경우가 많습니다. 이 시차 동안 가격이 크게 벌어지는데, 봇이 자동 감지하면 분 단위로 잡을 수 있습니다.

코드 안내. 본 섹션의 코드는 핵심 로직 발췌입니다. 거래소 wrapper와 통합 실행 코드는 §14 GitHub 레포 참조.
의사코드. exchanges 인자로 전달되는 거래소 객체는 §14 GitHub 참조.
import asyncio
from typing import Set

class NewListingScanner:
    """
    여러 거래소의 신규 상장 페어를 1분마다 폴링,
    같은 토큰이 여러 곳에 상장되는 시점에 가격 갭 계산
    """
    def __init__(self, exchanges):
        self.exchanges = exchanges
        self.known_symbols = {ex.name: set() for ex in exchanges}

    async def scan_once(self):
        """각 거래소의 현재 listing 가져와서 신규 발견"""
        new_listings = {}
        for ex in self.exchanges:
            current = await ex.fetch_all_symbols()  # set of symbols
            new = current - self.known_symbols[ex.name]
            if new:
                new_listings[ex.name] = new
            self.known_symbols[ex.name] = current
        return new_listings

    async def find_arb_opportunity(self, symbol):
        """같은 심볼이 여러 거래소에 있을 때 가격 비교"""
        prices = {}
        for ex in self.exchanges:
            try:
                p = await ex.get_ticker(symbol)
                if p and p > 0:
                    prices[ex.name] = p
            except Exception:
                continue

        if len(prices) < 2:
            return None

        max_ex = max(prices, key=prices.get)
        min_ex = min(prices, key=prices.get)
        gap_pct = (prices[max_ex] - prices[min_ex]) / prices[min_ex] * 100

        if gap_pct > MIN_ARB_PCT:  # 예: 3%
            return {
                'symbol': symbol,
                'sell_at': max_ex,
                'buy_at': min_ex,
                'gap_pct': gap_pct,
                'prices': prices
            }
        return None

    async def run(self):
        while True:
            try:
                new_listings = await self.scan_once()
                for ex_name, symbols in new_listings.items():
                    for sym in symbols:
                        # 다른 거래소에도 있으면 갭 체크
                        opp = await self.find_arb_opportunity(sym)
                        if opp:
                            await self.alert_telegram(opp)
                            if AUTO_EXECUTE:
                                await self.execute_arb(opp)
            except Exception as e:
                logger.error(f"scan error: {e}")
            await asyncio.sleep(POLL_INTERVAL)  # 60초

실전 진입 시 주의사항

Aster 현물 매수 봇 + Hedge Leg 조합

한 가지 운영 사례입니다. Aster의 신규 현물 상장이 발표되면 즉시 매수하고, 동시에 다른 거래소에서 같은 토큰의 perp을 숏 헤지합니다.

async def aster_spot_listing_strategy(token_symbol, target_size_usd):
    """
    Aster 신규 현물 상장 → 즉시 매수 + perp 헤지
    """
    # 1. Aster 현물에 시장가 매수
    spot_buy = await aster.spot_market_buy(token_symbol, target_size_usd)
    actual_qty = spot_buy['filled_qty']
    spot_price = spot_buy['avg_price']

    # 2. 다른 거래소에서 같은 토큰 perp 찾기
    perp_venues = await find_perp_listings(token_symbol)
    if not perp_venues:
        # perp 없으면 BTC 숏으로 시장 베타만 헤지
        await binance.perp_market_sell('BTC-PERP', target_size_usd * 0.4)
        return

    # 3. 가장 깊은 거래소에서 perp 숏
    best_perp = max(perp_venues, key=lambda x: x['depth'])
    await best_perp['ex'].perp_market_sell(token_symbol, actual_qty)

    # 4. Aster 현물에 트레일링 매도 주문 (강한 상승 시 익절)
    await aster.create_trailing_stop_sell(
        token_symbol,
        qty=actual_qty,
        trigger_callback_pct=8.0  # 고점 대비 8% 빠지면 청산
    )
사례. 레이브(Wave) 토큰이 Aster에 먼저 상장됐을 때, 다른 거래소 perp과 가격이 약 20% 갭이 나서 단기 차익 기회가 있었습니다. 봇이 자동으로 Aster 현물 매수 + perp 숏을 동시 체결해서 갭이 좁혀지는 동안 무위험 수익 확보. 손으로 잡으려면 두 거래소 띄워놓고 새로고침 누르다가 갭이 닫혀버립니다.

봇을 24시간 돌릴 때 알아야 할 인프라 원칙

의존성 충돌과 격리된 환경

여러 거래소를 동시에 쓰다 보면 각 거래소 SDK(Software Development Kit)가 서로 충돌하는 일이 생깁니다. A 거래소는 라이브러리 X의 1.0 버전을, B 거래소는 같은 라이브러리의 2.0 버전을 요구할 수 있거든요.

해결 방법은 venv(Virtual Environment, 가상환경)를 모듈마다 따로 만드는 겁니다.

코드 안내. 본 섹션의 코드는 핵심 로직 발췌입니다. 거래소 wrapper와 통합 실행 코드는 §14 GitHub 레포 참조.
# A 거래소용 가상환경
python -m venv venv_exchange_a
venv_exchange_a\Scripts\activate
pip install exchange_a_sdk

# B 거래소용 가상환경 (별도)
python -m venv venv_exchange_b
venv_exchange_b\Scripts\activate
pip install exchange_b_sdk

그 다음 메인 봇은 각 거래소를 호출할 때 subprocess(별도 프로세스)로 격리해서 실행합니다.

의사코드. VENV_PATHS 상수와 각 거래소별 runner 모듈은 §14 GitHub 참조.
# shared-utils/subprocess_wrapper.py
async def call_exchange_isolated(exchange, method, *args):
    venv_python = VENV_PATHS[exchange]
    proc = await asyncio.create_subprocess_exec(
        venv_python, '-c',
        f'from {exchange}_runner import {method}; print({method}({args}))',
        stdout=asyncio.subprocess.PIPE
    )
    out, _ = await proc.communicate()
    return json.loads(out)

이렇게 하면 한 거래소에서 문제가 생겨도 메인 봇이 멈추지 않습니다.

데이터 저장 ─ SQLite WAL 모드

봇이 매일 펀딩비, 청산 데이터, 거래 기록을 저장해야 하는데, 일반적인 데이터 저장 방식으로는 동시에 여러 봇이 같은 파일에 쓰려고 하면 충돌이 납니다.

SQLite WAL(Write-Ahead Logging) 모드가 답입니다. 별도 서버 띄울 필요 없이 파일 하나로 끝나서 트레이더가 직접 운영하기 편해요.

import sqlite3
conn = sqlite3.connect('bot_data.db')
conn.execute('PRAGMA journal_mode=WAL')  # 이 한 줄

초당 10,000+ 쓰기가 필요한 경우(펀딩 스냅샷, 청산 로그)는 Rust로 짜고 PyO3로 바인딩하면 초당 169,000 rows까지 가능합니다. 협업자 레포의 rust-services/gap-recorder가 이 패턴입니다.

텔레그램 원격 제어 봇

24시간 봇이 돌아도 사람이 매일 컴퓨터 앞에 있을 수는 없습니다.

/status     - 모든 봇이 살아있는지 확인
/pnl        - 오늘 손익
/balance    - 거래소별 잔고
/positions  - 현재 들고 있는 포지션
/restart    - 특정 봇 재시작
/kill       - 즉시 정지
/revive     - 재가동

BotFather에서 새 봇 만들고 토큰 받아서 Cowork에 시키면 됩니다.

텔레그램 비서
윈도우에서 OpenClaw 설치하고 텔레그램 AI 비서 만드는 법 (코딩 0부터)
18:48 · 2개월 전

상태 저장 (State Persistence)

state = {
    'positions': {'ETH-PERP': {'side': 'long', 'size': 1.5, 'entry': 3200}},
    'pnl_today': 12.5,
    'last_update': '2026-01-15 14:23:00'
}

with open('trader_state.json', 'w') as f:
    json.dump(state, f, indent=2)

봇이 재시작되면 이 파일을 읽어서 이어서 돌립니다. 메모리에만 의존하면 절대 안 됩니다.

공개 코드 ─ Cowork Trading Stack

이 가이드의 모든 코드와 운영 노트는 GitHub에 공개되어 있습니다. 콘텐츠는 CC BY-NC 4.0, 코드는 MIT 라이선스로 풀어두었습니다.

github.com/coinmage777/cowork-trading-stack

저장소 구조

00-vibe-coding-basics/    AI 코딩 입문 5장
10-foundation-modules/    드롭인 빌딩 블록 11종 (kill-switch, notifier, auto-scaler 등)
20-exchange-wrappers/     22개 거래소 통합 + setup-guides
30-strategy-patterns/     전략 템플릿 (pair, MM, DCA, volume-farmer, aster-spot-buyer, backtest)
40-realtime-infra/        실시간 스캐너 (cross-venue arb, kimp listing, spot-spot, wallet trackers)
50-rust-acceleration/     PyO3 핫패스 (advanced)
60-ops-runbooks/          tmux / systemd / telegram-control 운영 5종
80-obsidian-vault/        Obsidian 활용법 (구조 / 템플릿 / Dataview / AI 연동)
99-glossary/              용어 정리
ko/                       장문 한국어 가이드 (8 챕터)

누구에게 어느 폴더가 맞는가

5분 시작 (Quick Start)

가장 가벼운 모듈은 5분 안에 띄워볼 수 있습니다.

git clone https://github.com/coinmage777/cowork-trading-stack.git
cd cowork-trading-stack/30-strategy-patterns/volume-farmer/
python -m venv venv && source venv/bin/activate    # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env                                # API 키 채우고 DRY_RUN=true 로 시작

모듈마다 자체 README와 의존성을 가집니다. 최상위에 "한 번에 다 돌리는 명령"은 없습니다 ─ 안전하지도, 가능하지도 않기 때문입니다.

추천 진입점 3개

  1. 00-vibe-coding-basics/01-claude-code-setup.md ─ Claude Code 셋업 (10분)
  2. 00-vibe-coding-basics/02-prompting-patterns.md ─ 실전 프롬프트 패턴
  3. 30-strategy-patterns/_combined/README.md ─ 전략 모듈을 조합하는 방식
저장소를 공개한 의도. 이 코드들로 큰돈 벌기는 어렵습니다 ─ 시장이 바뀌고, 거래소 정책이 변하고, 알파는 시간 지나면 잠식됩니다. 대신 vibe coding의 패턴 자체는 도메인 무관하게 옮겨 쓸 수 있습니다. 같은 길 걷는 분들이 시간 단축하면 더 큰 가치를 만들 수 있다고 믿어서 공개합니다. Issue나 PR 환영합니다.

자주 등장하는 용어 정리

용어짧은 설명
Perp DEX탈중앙화 무기한 선물 거래소. 만기일이 없는 선물을 블록체인 위에서 거래
펀딩비 (Funding Rate)Perp에서 롱과 숏 균형 맞추려 8시간마다 정산하는 수수료
델타 중립 (Delta-Neutral)가격 방향 노출이 0인 포지션 (롱+숏 동일 사이즈)
슬리피지 (Slippage)시장가 거래 시 호가 차이로 인한 손실
코인테그레이션 (Cointegration)두 시계열이 같이 움직이는 통계적 성질. 페어 트레이딩의 기반
Kalman Filter매 틱마다 hedge ratio 같은 동적 변수를 갱신하는 통계 기법
OU ProcessOrnstein-Uhlenbeck. 평균회귀 속도를 모델링하는 확률과정
Z-Score평균 대비 표준편차 몇 개만큼 떨어졌는지 측정. 진입 임계치로 사용
ADF TestAugmented Dickey-Fuller. 시계열의 정상성(stationarity) 검정
Sharpe Ratio(수익률 - 무위험이자율) / 표준편차. 위험조정 수익률 지표
MDDMaximum Drawdown. 최대 낙폭 (전략의 최악 손실 구간)
Kelly Criterion이론적 최적 베팅 사이즈. 실전은 1/4 (Fractional) Kelly 권장
RSIRelative Strength Index. 14틱 기준 과매수/과매도 지표
Bollinger Bands이동평균 ± 2σ로 상하단 밴드 그리는 변동성 지표
VWAPVolume-Weighted Average Price. 거래량 가중 평균가
베이지안 prior과거 결과로 미래 확률을 갱신하는 통계 기법
TGEToken Generation Event, 토큰 발행 이벤트
에어드랍프로젝트가 사용자에게 토큰을 무료 분배
포인트 시스템거래량/활동 기반 포인트 적립, TGE 때 토큰으로 전환되는 구조
Maker / Taker호가 거는 사람(Maker) / 즉시 잡아가는 사람(Taker)
Builder Code거래소가 특정 프론트엔드 거래에 수수료 일부 환급해주는 시스템
CEX / DEX중앙화 거래소 / 탈중앙화 거래소
김프한국 프리미엄. 한국 거래소가 해외보다 비싼 정도
Cross-venue여러 거래소(venue) 사이를 가로지르는 거래
Layer 2메인 블록체인 위에 올린 보조 체인 (수수료/속도 개선)
가스비블록체인 트랜잭션 수수료
Offchain블록체인 밖에서 처리하고 결과만 체인에 기록
PnLProfit and Loss, 손익
DCADollar Cost Averaging, 분할매수
MCPModel Context Protocol. AI가 외부 데이터/도구에 접근하는 표준
마크다운## 제목 같은 기호로 서식 표시하는 텍스트 형식
venvVirtual Environment. 격리된 파이썬 작업 공간
subprocess별도 프로세스로 코드 실행 (충돌 방지)
SDKSoftware Development Kit. 거래소가 제공하는 코드 라이브러리
API 키코드로 거래소에 접근할 때 쓰는 인증 키 (절대 공개 X)
DRY_RUN모의실행. 실거래 없이 시뮬레이션만
레버리지자본의 N배로 거래하는 것 (수익도 손실도 N배)
청산 (Liquidation)증거금 부족 시 거래소가 강제로 포지션 정리
OHLCV시가/고가/저가/종가/거래량 (캔들 데이터의 기본 단위)
백테스팅과거 데이터에 전략을 적용해 결과 시뮬레이션
Adversarial Workflow여러 AI에게 같은 코드 검수시켜 결함을 교차 검증하는 방식
Vibe CodingAI에게 의도를 전달하고 결과를 검증하는 협업 프로토콜. 코드 생성기가 아니라 협업 파트너로 다루는 방식
Gaslight My AI"라이벌 AI가 검토할 거다" 식 framing으로 같은 모델의 리뷰 품질을 끌어올리는 패턴
CLAUDE.md프로젝트 루트에 두면 Claude Code가 자동으로 읽는 컨텍스트 파일. 불변 규칙 · 자주 쓰는 명령 · 위험 영역 경고를 적음
Auto-memory세션을 넘어 지속되는 사용자 메모리. user/feedback/project/reference 4 타입으로 분류
Triple LockENABLED + DRY_RUN=false + LIVE_CONFIRM 3개 환경변수가 모두 만족해야 실거래 진입을 허용하는 fail-fast 잠금
Kill Switch봇 진입을 즉시 차단/해제하는 메커니즘. 파일 기반 · PnL 기반 · 실패 카운터 · 자본 floor 4종
Trigger FileWindows에서 SIGHUP 대체로 쓰는 파일 mtime 기반 신호 패턴 (config 재로드, 일시정지, 청산 등)