Safety Mechanisms in Trading Bots

🌐 한국어

In trading bots, safety mechanisms come before strategy. A bad strategy loses a little; missing safety loses the whole account. Here are the guards I learned to build into live bots.

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

1. Force Liquidation — Never Hold Overnight

The first rule of intraday strategies: don't carry positions into the next day. Overnight gaps destroy overnight risk. So run a completely separate liquidation goroutine:

strategy engine    : enter/exit on gap signals

force liquidate    : 15:20 single check → market-order-close all open positions

Separate it as an independent goroutine because it must run at a fixed time regardless of strategy state. Quotes thin before close, so orders may fail. Retry up to 3 times at 1-minute intervals with market orders. Failure triggers immediate alert.

2. Duplicate Entry Guard — Three Layers

Real-time signals fire multiple times per second. Without guards, you'll open the same position twice or thrice. Layer three defenses:

posMu.Lock()          // 1) Mutex blocks concurrent entries

defer posMu.Unlock()

if pos.IsOpen {        // 2) Already open → skip immediately

    return

}

if time.Since(pos.LastOrderTime) < debounce {  // 3) Debounce (e.g., 30 sec)

    return

}

// After order sent, immediately mark IsOpen=true → next signal is blocked

The trick: immediately mark IsOpen=true after sending the entry order, before the broker responds. If the next signal arrives while you're waiting for fill confirmation, the lock already blocks it.

3. Pre-Entry Gates — Multiple Guards

Before sending an order, pass multiple checkpoints:

  • Time gate: Skip first 5 min after open (quotes unstable) and last 10 min before close.
  • Extreme move gate: If underlying moved ±15%, treat as anomaly; skip.
  • Quote depth gate: If ask-side liquidity × price < half your order size, likely to fail; skip.
  • Data freshness gate: If last fill received > 10 sec ago, don't trust the signal.

Philosophy: "Better miss a good opportunity than take a bad entry." These gates implement that.

4. State Persistence — Survive Restarts

Bots crash, deploy, or need maintenance. If state lives only in memory, restart loses what positions are open. Persist core state to JSON files:

bot_state.json    : bot running state (running Y/N)

positions.json    : open positions (qty, entry, time, IsOpen)

baseline.json     : today's opening price baseline (includes trading date)

On restart, read these files to recover. Date checking is critical: if baseline.json's trading date differs from today, discard it and re-capture. Otherwise you'd calculate today's gaps against yesterday's open—disaster.

if saved.TradingDate != today {

    baselines = map[string]*BaselineSnapshot{} // date mismatch → wipe

}

If you restart during market hours with open positions and forced-close time has passed, immediately queue those positions for liquidation.

5. Credential Protection — No Plaintext

API keys and secrets never exist in plaintext. Encrypt them with AES-GCM:

gcm, _ := cipher.NewGCM(block)

nonce := make([]byte, gcm.NonceSize())

io.ReadFull(rand.Reader, nonce)

ciphertext := gcm.Seal(nonce, nonce, []byte(plaintext), nil)

Validate input too. If a symbol isn't six digits, don't pass it to the order path—last defense against orders to wrong symbols.

Summary

Safety isn't glamorous but determines bot lifespan. Forced close-out stops overnight risk. Three-layer duplicate guards prevent accidental multi-entry. Pre-entry gates filter bad fills. State files survive crashes. Encrypted credentials block leaks.

None of these are optional for live trading. Without all five, don't move real capital into the bot.

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

댓글

이 블로그의 인기 게시물

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

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

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