원문: https://github.com/jarrodwatts/jev-trader · 수집일: 2026-09-19

개요

Jarrod Watts가 만든 오픈소스 트레이딩 봇. TypeSafe Jev가 Monad 블록마다 Kuru MON-USDC 오더북을 보고 매수·매도 판단을 내리고, 매 블록 포스트-온리 리밋 오더를 터치보다 1틱 안쪽에 게시한다. taker가 체결하면 스프레드를 버는 구조이며, 봇 자체는 가스만 내고 수익을 내는 방향으로 설계되어 있다.

핵심 한 줄: Monad 블록 주기(~300ms) 안에 eth_call 1회(오더북) + eth_sendRawTransaction 1회(주문)로 의사결정을 완료하는 2-RPC 핫루프. Jev는 experimental_evaluate로 동작하며 기본값은 모멘텀 휴리스틱 mock.

구조

src/config.ts   env
src/chain.ts    block feed (WebSocket newHeads + polling backstop, newest block only), raw RPC
src/book.ts     one-eth_call order book reader (decodes getL2Book, merges the AMM vault)
src/market.ts   Kuru: read book, hand-encoded batchUpdate (cancel + post-only place), margin deposits, local nonce, async confirmation
src/model.ts    Model interface, JevModel (AI SDK experimental_evaluate), MockModel
src/trader.ts   the loop: one in flight, hold when late, position and P&L accounting
src/server.ts   Bun.serve: snapshot, history, SSE
  • Bun 런타임 기반. 서버는 Bun.serve로 스냅샷·히스토리·SSE 이벤트 제공.
  • 모델 교체 가능: MODEL=jev + TYPESAFE_AI_API_KEY → Jev, 아니면 mock(기본).

300ms 예산

한 블록 안에 판단과 주문이 모두 끝나야 하므로 핫루프 경로는 딱 두 RPC로 제한된다:

  1. eth_call로 오더북 조회 (public RPC READ_RPC_URL 기준 ~18ms p50)
  2. eth_sendRawTransaction으로 주문 전송 (RPC_URL, tx 수용 즉시 반환)

경로에서 제외된 것들: eth_estimateGas (Monad은 gas limit 기준 과금 → limit은 하드코드/시작 시 유도), eth_sendRawTransactionSync (Proposed까지 블록하므로 제외), gas price 조회 (정적 type-2 수수료: MAX_FEE_GWEI 캡, 2 gwei priority → 실효가 = base + priority). 영수증·수수료 추정·금고 확인은 이후 블록에서 오프-핫패스로 처리.

dry run + mock 모델 실측: read p50 18ms, 전체 루프 p50 100ms(그중 80ms는 mock 추론 대체재).

주문 전략 (최신 커밋 기준, 2026-09-17)

  • 매 블록마다 Jev가 선택한 측에 포스트-온리 리밋 오더 1개 게시, 터치보다 1틱 안쪽 가격 (스프레드가 너무 좁으면 터치로 clamp).
  • 단일 Kuru batchUpdate로 이전 주문 취소 + 새 주문 게시 동시 처리.
  • 체결은 내 트랜잭션이 아니라 taker가 내 휴식 중 주문을 치는 방식 → Trade 로그 피드(eth_getLogs poll)에서 내 주소(메이커)로 들어오는 fills를 포착.
  • 시작 시 마진 계정 입금.
  • 히스테리시스·주기적 결정 제거, 포지션 캡은 감소 측으로만 유도.
  • 대시보드에 블록별 휴식 중 호가 + FILL 행 표시.

핫루프에는 한 번에 하나의 주문만 in-flight 상태로 유지되며, 늦으면 hold(hold는 decision.late: true일 때만 등장).

이벤트 흐름 (SSE)

배포된 엔드포인트(https://jev-trader-production.up.railway.app/, dry run, mock)에서 SSE로 다음 이벤트 스트리밍:

  • snapshot — 연결 시 전송
  • block — 블록마다 전송, 블록 이벤트 구조체에 intent 포함 (status: “sent”, gasMon = gasLimit × (마지막 알려진 base fee + priority), Monad은 limit 기준 과금이므로 실제 비용)
  • quote — 영수증 도착 시 (status: “placed” + orderId 또는 “reverted” 또는 10블록 무영수증 시 “lost”)
  • fill — taker가 내 주문을 친 경우, 별도 SSE 이벤트로 position·realizedUsd·fills 갱신

dry run 시 quote는 status: "sim" — 1블록 휴식 후 실제 print가 교차 가격 체결 (simulated: true).

관련