Incremental Bot Development: M1 → M2 → M3 Milestones

🌐 한국어

Building a bot as "trading-ready from day one" fails ninety percent of the time. Untested signals under order logic means you won't know what's broken. I used a three-milestone framework for my ETF gap bot that kept risk low and learning high.

⚠️ This is educational material, not investment advice. Investment losses are your responsibility.

Core Principle: Delay Live Trades as Long as Possible

One rule: code that moves money comes last, when most validated. So I split milestones:

  • M1 — Data flow visibility (no trading)
  • M2 — Trading logic (micro live)
  • M3 — Operational stability (dashboards, alerts, forced-close)

M1: Visualize, Don't Trade

Goal: confirm data flows correctly by eye. Strategy and order functions are stubs—they log but don't execute.

// M1: strategy and order functions just log, clear channels

func strategyEngine() {

    for gap := range gapCh {

        logCh <- fmt.Sprintf("[M1 stub] gap=%+v", gap) // no logic

    }

}

M1 work:

  • Subscribe to WebSocket symbol quotes and fills
  • Capture daily opening prices
  • Parse ticks and validate values (current, open, change %) visible on REST or screen

Validation isn't flashy: does go build pass? Do empty symbols auto-skip? Does health-check respond? Do first raw messages match documentation? No trading logic at all, but I won't move forward without confidence in data.

M2: Attach Calculation and Orders (Micro)

Only after M1 proves data is trustworthy do I wire signals to execution. M2 adds:

  • Opening price persistence — state survives restart/stop within same trading day
  • Gap calculation — pure function, unit-tested (normal, edge cases: zero open, stale data, theory mismatch)
  • Strategy engine — trigger entry if gap_sum > threshold, exit if narrows
  • Order execution — first real REST orders appear here

Safe M2 approach: first dry-run (block orders) to validate signals, then deploy micro live with tiny amounts on 1–2 pairs for 1–2 weeks observation.

Pure gap calculation as a standalone function pays dividends here—testable outside market hours:

got := ComputeGap(...)

if got.GapSum != want {

    t.Fatalf("gapSum=%v want %v", got.GapSum, want)

}

M3: Run Long-Term Safely

Once trading works, next goal: repeat safely day after day. M3 adds:

  • Forced liquidation — defined time-of-day for mandatory close (separate goroutine from strategy)
  • Alerts — entry/exit/error/liquidation-fail notifications
  • Token auto-refresh — daily auth token reissue, bot stops on failure
  • Dashboard — pair status, gap gauge, gap history charts at a glance

M3 isn't a feature; it's turning a trading bot into a bot you can leave alone. It detects problems and alerts you or self-corrects, running 24 without babysitting.

Why This Order Is Safe

Each stage validates preconditions for the next:

  1. If M1 doesn't guarantee data reliability → M2 signals are garbage
  2. If M2 doesn't validate signals → M3 stability means repeating a broken strategy

And crucially, real money only moves after stages 1 and 2 pass. Even if you abandon the strategy after M1, you've lost time, not capital.

Summary

Visibility (M1) → trading (M2) → endurance (M3). Feels slow, but each stage is the safety net for the next. The fastest trading bot starts with bulletproof data, not order code. Build trust first; scale after.

This is educational material, not investment advice. Investment losses are your responsibility.

댓글

이 블로그의 인기 게시물

한국투자증권 KIS API로 실시간 시세 받기 (WebSocket 실전)

파이썬으로 업비트 API 연동하기 — 시세 조회부터 주문까지 기초

Go로 자동매매 신호봇 프레임워크 설계하기