Strasmore Research
Edukasi Matt ConnorOleh Matt Connor · Diperbarui 2026-08-04

Circuit Breaker untuk Trading Bot

Circuit breaker menghentikan trading bot sebelum kerugian sesi membesar. Pelajari pemicu batas kerugian harian dan dampak volatility scaling pada ukuran posisi.

Circuit breaker untuk trading bot adalah aturan yang menghentikan strategi otomatis mengirim order setelah batas yang ditetapkan tercapai. Circuit breaker berada pada lapisan risiko di antara strategi dan broker. Aturan ini berlaku untuk setiap order, terlepas dari apakah strategi menyetujuinya. Strategi menentukan apa yang akan diperdagangkan. Lapisan risiko menentukan apakah perdagangan dapat berlangsung sama sekali.

Pemisahan ini merupakan inti desainnya. Strategi yang mengawasi dirinya sendiri tidak memiliki pemeriksaan independen ketika asumsi strateginya mulai tidak berlaku. Justru pada saat itulah pemeriksaan paling diperlukan.

Fungsi circuit breaker pada trading bot

Lapisan risiko memiliki empat bagian. Masing-masing dirancang untuk mencegah kegagalan tertentu yang sederhana, tetapi dapat berdampak besar.

  • Batas maksimum untuk ukuran posisi, eksposur notional per simbol, dan laju order. Batas ini membatasi kerugian akibat bug yang jika tidak dikendalikan dapat menimbulkan kerugian tanpa batas.
  • Circuit breaker drawdown yang menghentikan order baru setelah akun mengalami penurunan sebesar jumlah tertentu selama sesi berjalan, atau turun sebesar jumlah tertentu dari puncak ekuitasnya.
  • Penentuan ukuran order secara berskala, berdasarkan volatilitas terkini atau sebagian dari taruhan Kelly, bukan jumlah saham tetap. Cara ini menjaga risiko per transaksi tetap relatif stabil ketika rentang pergerakan pasar berubah.
  • Audit log append-only yang mencatat setiap keputusan, termasuk order yang ditolak oleh lapisan risiko. Ini merupakan satu-satunya artefak yang dapat membedakan antara “strateginya salah” dan “pemeriksaannya tidak pernah dijalankan”.

Seluruh uraian di bawah ini merupakan penerapan konkret dari salah satu dari empat bagian tersebut.

Berapa batas kerugian harian yang wajar untuk trading bot?

Batas kerugian harian menghentikan order baru setelah kerugian selama sesi melewati ambang tertentu. Menentukan angkanya merupakan proses kalibrasi, bukan soal selera: jika ditetapkan di dalam kisaran fluktuasi pasar yang normal, bot akan berstatus halted hampir setiap minggu; jika ditetapkan terlalu jauh, batas tersebut tidak akan pernah terpicu. Titik awalnya adalah mengukur seberapa sering pasar itu sendiri mengalami penurunan harian dengan besaran tertentu.

QueryJumlah hari penurunan SPY berdasarkan besaran, per tahun, 2018 hingga Juli 2026
SQL tepat di balik setiap angka
WITH daily AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d,
           argMax(toFloat64(close), window_start) AS close_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2017-12-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY d
),
with_prev AS (
    SELECT d,
           close_px,
           any(close_px) OVER (ORDER BY d ASC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS prev_close
    FROM daily
)
SELECT toYear(d) AS year,
       countIf(close_px / prev_close - 1 <= -0.01) AS down_1pct_days,
       countIf(close_px / prev_close - 1 <= -0.02) AS down_2pct_days,
       countIf(close_px / prev_close - 1 <= -0.03) AS down_3pct_days
FROM with_prev
WHERE prev_close > 0
  AND d >= toDate('2018-01-01')
GROUP BY year
ORDER BY year
Run this yourself

Sesi dengan penurunan sebesar 1% atau lebih berjumlah 15 pada 2019 dan 45 pada 2020, dari sekitar 250 hari perdagangan per tahun. Jumlah sesi dengan penurunan sebesar 3% atau lebih merupakan hal yang berbeda: 0 pada 2019 dibandingkan dengan 16 pada 2020. Baris terakhir pada 9 hanya mencakup sesi hingga 31 Juli 2026.

Pola tersebut tidak merata, melainkan bergerombol. Justru inilah hal yang perlu diperhitungkan dalam desain. Hari-hari dengan penurunan besar dapat terjadi secara beruntun. Bot yang berhenti pada hari pertama dalam suatu rangkaian, lalu kembali aktif pada hari kedua, pada praktiknya belum benar-benar berhenti.

Kedua ambang tersebut memiliki fungsi yang berbeda. Batas kerugian harian, yang umumnya ditetapkan sebesar 2% dari ekuitas akun, mengakhiri sesi. Batas trailing drawdown yang diukur dari titik tertinggi ekuitas, umumnya sekitar 10%, menghentikan strategi hingga dilakukan peninjauan oleh manusia. Batas pertama bersifat rutin, sedangkan batas kedua dirancang agar jarang terpicu. Bot yang hanya memiliki batas pertama dapat terus menggerus akun sebesar 2% setiap kali tanpa pernah memicu penghentian apa pun.

Bagaimana volatility scaling mengubah ukuran posisi?

Volatility targeting menentukan ukuran posisi secara berbanding terbalik dengan volatilitas terealisasi terbaru: ketika kisaran harian berlipat dua, posisi kurang lebih berkurang setengahnya. Dengan begitu, risiko dalam nilai dolar per trade tetap mendekati konstan. Volatilitas terealisasi di sini adalah deviasi standar annualized dari return harian, dan perubahannya lebih besar daripada yang diperkirakan kebanyakan orang.

QueryVolatilitas terealisasi SPY per bulan, dan posisi yang akan dibawa oleh target volatilitas 12%
SQL tepat di balik setiap angka
WITH daily AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d,
           argMax(toFloat64(close), window_start) AS close_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2023-12-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY d
),
rets AS (
    SELECT d,
           close_px / any(close_px) OVER (ORDER BY d ASC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) - 1 AS ret
    FROM daily
)
SELECT formatDateTime(toStartOfMonth(d), '%Y-%m') AS month,
       round(stddevSamp(ret) * sqrt(252) * 100, 1) AS realized_vol_pct,
       round(least(100.0, 1200.0 / (stddevSamp(ret) * sqrt(252) * 100)), 1) AS vol_target_size_pct
FROM rets
WHERE d >= toDate('2024-01-01')
  AND isFinite(ret)
GROUP BY toStartOfMonth(d)
HAVING count() >= 15
ORDER BY toStartOfMonth(d)
Run this yourself

Volatilitas terealisasi yang diukur 11.1% annualized pada 2024-01 dan 12% pada 2026-07, selama 31 bulan. Kolom kedua mengubah setiap pembacaan menjadi posisi yang akan dibawa oleh target volatilitas 12%, dengan batas maksimum sebesar seluruh garis: 100% pada 2024-01 dibandingkan dengan 99.7% pada 2026-07. Strateginya sama, keyakinannya sama, tetapi jumlah sahamnya sangat berbeda.

Kelly criterion mendekati masalah yang sama dari sisi lain. Ukuran posisi ditentukan berdasarkan estimasi edge dan varians, bukan hanya volatilitas. Sebagian besar operator sistematis menggunakan sebagian dari ukuran tersebut—half Kelly atau quarter Kelly—karena kedua input itu merupakan estimasi yang berasal dari sampel terbatas. Ukuran posisi dengan Kelly criterion menjelaskan perhitungannya.

Mengapa trading bot terus masuk kembali setelah stop?

Stop terpicu. Posisi ditutup. Sembilan puluh detik kemudian kondisi entry kembali terpenuhi, bot masuk lagi, mengalami kerugian yang sama, lalu mengulanginya. Tidak ada satu pun komponen yang rusak. Strategi berjalan sesuai perancangannya, stop bekerja sesuai fungsinya, tetapi saldo akun terus terkikis melalui satu round trip demi satu round trip.

Frekuensinya terlihat langsung dari jalur harga. Panel ini menghitung, per sesi, berapa kali SPY bergerak dari lebih dari 0,1% di atas harga pembuka ke lebih dari 0,1% di bawahnya, atau sebaliknya.

QuerySeberapa sering SPY melintasi kembali harga pembukaannya sendiri, per sesi, berdasarkan bulan
SQL tepat di balik setiap angka
WITH mins AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d,
           window_start AS ts,
           toFloat64(close) AS px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2025-08-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
),
opens AS (
    SELECT d, argMin(px, ts) AS open_px
    FROM mins
    GROUP BY d
),
zoned AS (
    SELECT m.d AS d,
           m.ts AS ts,
           multiIf(m.px >= o.open_px * 1.001, 1,
                   m.px <= o.open_px * 0.999, -1,
                   0) AS zone
    FROM mins AS m
    INNER JOIN opens AS o ON m.d = o.d
),
flips AS (
    SELECT d,
           zone,
           any(zone) OVER (PARTITION BY d ORDER BY ts ASC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS prev_zone
    FROM zoned
    WHERE zone != 0
),
per_day AS (
    SELECT d, countIf(prev_zone != 0 AND zone != prev_zone) AS crossings
    FROM flips
    GROUP BY d
)
SELECT formatDateTime(toStartOfMonth(d), '%Y-%m') AS month,
       round(avg(crossings), 1) AS avg_crossings_per_session,
       max(crossings) AS max_crossings_in_a_session
FROM per_day
GROUP BY toStartOfMonth(d)
ORDER BY toStartOfMonth(d)
Run this yourself

SPY menembus rentang tersebut rata-rata 0.7 kali per sesi pada 2025-08 dan 1.5 kali pada 2026-07. Dalam satu sesi pada 2026-07, tercatat 5 penembusan. Setiap aturan yang membuka posisi di satu sisi level dan menempatkan stop di sisi lainnya memiliki sebanyak itu peluang untuk terpicu dalam satu hari.

Empat mekanisme dapat membatasi hal ini.

  • Cooldown setelah setiap stop, yang diukur dalam menit atau bar. Selama periode ini, tidak ada order baru untuk simbol tersebut yang dapat melewati lapisan risiko.
  • Batas jumlah trade harian per simbol. Batas ini mengubah loop yang tidak terbatas menjadi loop yang memiliki batas.
  • Flag penghentian yang bersifat latched. Setelah batas kerugian harian terpicu, statusnya tetap aktif sampai dihapus secara manual.
  • Persistensi flag tersebut di luar memori proses. Supervisor yang me-restart bot yang crash akan memberinya kondisi awal yang bersih. Kondisi awal yang bersih justru ingin dicegah oleh flag ini.

Poin terakhir sering luput dari perhatian, meskipun semua hal lainnya sudah dilakukan dengan benar. Bot trading grid memang dirancang untuk menempatkan ladder order, sehingga batas jumlah trade menjadi komponen penting, bukan sekadar hiasan.

Apa yang terjadi ketika bot bertransaksi berdasarkan feed harga yang kedaluwarsa?

Kutipan harga yang sudah berhenti diperbarui tetap terlihat seperti sebuah angka. Bot membacanya, menetapkan harga order berdasarkan angka tersebut, lalu mengirimkan order ke pasar yang sudah bergerak. Kegagalannya berlangsung tanpa disadari: tidak ada pengecualian, tidak ada log kesalahan, dan kejanggalan pada hasil eksekusi baru terlihat setelahnya.

Versi yang dapat diukur dengan jelas adalah overnight gap, ketika harga yang diketahui tetap tidak berubah selama berjam-jam sementara harga yang dapat diperdagangkan bergerak.

QueryGap overnight dari penutupan sebelumnya ke pembukaan berikutnya: enam nama, Jan 2024 hingga Jul 2026
SQL tepat di balik setiap angka
WITH daily AS (
    SELECT ticker,
           toDate(toTimeZone(window_start, 'America/New_York')) AS d,
           argMin(toFloat64(open), window_start) AS open_px,
           argMax(toFloat64(close), window_start) AS close_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY', 'KO', 'MSFT', 'AAPL', 'NVDA', 'TSLA')
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2024-01-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY ticker, d
),
gaps AS (
    SELECT ticker,
           d,
           open_px,
           any(close_px) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS prev_close
    FROM daily
)
SELECT ticker,
       round(quantileDeterministic(0.5)(abs(open_px / prev_close - 1) * 100, cityHash64(ticker, d)), 2) AS median_gap_pct,
       round(quantileDeterministic(0.95)(abs(open_px / prev_close - 1) * 100, cityHash64(ticker, d)), 2) AS p95_gap_pct,
       round(max(abs(open_px / prev_close - 1) * 100), 2) AS max_gap_pct
FROM gaps
WHERE prev_close > 0
GROUP BY ticker
ORDER BY p95_gap_pct DESC
Run this yourself

Instrumen dengan gap persentil ke-95 terbesar adalah TSLA sebesar 4.41%, dibandingkan dengan 1% untuk KO. Pada malam-malam biasa, pergerakannya jauh lebih tenang: median gap masing-masing sebesar 1.01% dan 0.24%. Risiko pada ekor distribusi adalah alasan risk layer diperlukan, dan gap tunggal terbesar pada TSLA dalam periode pengukuran mencapai 14.57%. Itulah jarak pergerakan yang dapat dihadapi bot ketika bertindak berdasarkan harga yang dibacanya beberapa waktu sebelumnya. Mengapa saham mengalami gap overnight membahas mekanismenya.

Perlindungannya murah. Tetapkan usia maksimum untuk setiap quote yang akan digunakan risk layer sebagai dasar penetapan harga, biasanya beberapa detik untuk strategi intraday. Ambil sinyal heartbeat dari feed secara terpisah dari datanya. Dengan begitu, socket yang tidak aktif dapat dibedakan dari pasar yang sedang sepi. Perlakukan data yang hilang sebagai penghentian perdagangan, bukan sebagai kondisi untuk menahan posisi, karena bot tanpa harga juga tidak dapat mengevaluasi exit-nya.

Batas keras apa yang harus ditempatkan di lapisan risiko?

  • Notional maksimum per simbol sebagai proporsi ekuitas akun. Batas 10% mencegah satu simbol yang berkinerja buruk menghabiskan seluruh akun.
  • Notional bruto maksimum untuk seluruh posisi terbuka. Menetapkannya pada 100% ekuitas berarti tidak menggunakan leverage. Keputusan ini sebaiknya ditetapkan secara eksplisit, bukan mengikuti pengaturan default broker.
  • Laju order maksimum, per menit dan per hari. Sepuluh order per menit cukup longgar untuk sebagian besar strategi ritel, sekaligus membatasi loop yang berjalan tidak terkendali dalam waktu satu menit.
  • Ukuran order maksimum sebagai proporsi volume harian rata-rata simbol. Batas 1% mencegah bot menggerakkan harga yang sedang diperdagangkannya, dan volume harian rata-rata menjadi penyebutnya.

Semua batas ini harus ditempatkan di lapisan risiko, bukan di strategi. Semuanya juga harus menjalankan jalur kode yang sama dalam backtest, paper trading, dan live trading. Batas yang hanya ada dalam live trading adalah batas yang belum pernah diuji.

Apa yang diperlukan dalam log audit trading bot?

Log append-only menulis satu rekaman untuk setiap keputusan dan tidak pernah mengubah atau menghapusnya. Setiap rekaman memuat timestamp, kuotasi yang digunakan beserta usianya, setiap pemeriksaan limit yang dijalankan beserta hasilnya, order yang dikirim, dan balasan broker. Order yang ditolak dicatat dengan bobot yang sama seperti order yang terisi.

Tujuannya adalah rekonstruksi. Enam minggu setelah sesi yang buruk, pertanyaannya bukan berapa P&L yang dihasilkan. Pertanyaannya adalah pemeriksaan mana yang lolos dan berdasarkan input apa. Tanpa input yang direkam, Anda akan mencoba menurunkan kembali kondisi bot dari kondisi pasar. Itu merupakan kesalahan yang sama seperti look-ahead bias dalam backtesting: menggunakan informasi yang belum dimiliki sistem saat keputusan dibuat.

Proyek riskguard merupakan salah satu implementasi open-source yang memisahkan fungsi tersebut. Pemeriksaan limit ditempatkan dalam komponen yang dipanggil oleh strategi, bukan disebarkan di seluruh logika strategi. Ini hanya salah satu dari beberapa desain dan layak dibaca sebelum diadopsi. Apa pun yang Anda gunakan, kunci pada tagged release, bukan default branch. Branch dapat berubah di antara dua proses backtest yang sama. Lapisan risiko yang berubah secara diam-diam lebih buruk daripada tidak memiliki lapisan risiko sama sekali.

Mengapa deployment pertama menggunakan broker paper

Adapter broker secara default menggunakan paper, sedangkan trading live memerlukan flag eksplisit yang ditetapkan dengan sengaja. Ini mencegah kegagalan yang sederhana tetapi berisiko: file konfigurasi yang disalin, atau variabel lingkungan yang tidak pernah dioverride, mengirimkan order nyata dengan uang sungguhan.

Paper run juga menghasilkan artefak yang penting, yaitu log keputusan dari risk layer yang sama berdasarkan harga live. Log ini menunjukkan limit mana yang terpicu dan mana yang tidak. Ini menjadi bukti mengenai risk layer, yang merupakan pertanyaan terpisah dari apakah strategi menghasilkan uang. Trading paper sebelum menggunakan uang sungguhan membahas hal-hal yang dapat dan tidak dapat dibuktikan oleh catatan paper, sedangkan sistem trading AI multi-agen menjelaskan mengapa kewenangan untuk menghentikan trading harus berada di luar setiap agen setelah beberapa agen dapat menempatkan order.

FAQ circuit breaker untuk trading bot

Apa yang dimaksud dengan circuit breaker dalam trading bot?

Circuit breaker adalah aturan dalam lapisan risiko yang menghentikan bot mengirim order baru setelah batas tertentu tercapai. Batas ini biasanya berupa ambang kerugian harian atau drawdown dari puncak ekuitas akun. Aturan ini berjalan secara independen dari strategi pada setiap order, dan tetap aktif sampai di-reset.

Seberapa sering pasar mengalami penurunan harian sebesar 2%?

SPY mencatat 5 sesi dengan penurunan 2% atau lebih pada 2019, dan 25 sesi pada 2020, dari sekitar 250 hari bursa setiap tahun. Perbedaan antara tahun yang tenang dan tahun yang penuh tekanan menunjukkan mengapa batas kerugian perlu dikalibrasi berdasarkan data historis, bukan intuisi.

Bagaimana cara mencegah bot masuk kembali setelah stop?

Cooldown setelah setiap stop dan batas jumlah trade harian per simbol mengubah loop yang tidak terbatas menjadi loop yang memiliki batas. Flag penghentian juga harus tetap aktif dan disimpan di luar memori proses. Tanpa itu, supervisor yang me-restart bot yang crash akan memberikan status baru yang belum dihentikan.

Bagaimana bot dapat mengetahui bahwa price feed sudah tidak diperbarui?

Bot dapat memeriksa usia setiap quote sebelum menggunakannya untuk menetapkan harga order. Bot juga perlu memantau heartbeat dari feed secara terpisah dari datanya. Gap overnight menunjukkan besarnya risiko yang dapat tersembunyi di balik harga yang sudah stale: pergerakan overnight pada persentil ke-95 mencapai 4.41% pada TSLA antara Januari 2024 dan Juli 2026.

Apakah trading bot kecil benar-benar memerlukan audit log?

Log fill mencatat apa yang terjadi. Log keputusan mencatat apa yang diyakini bot boleh dilakukan. Ini satu-satunya cara untuk membedakan strategi yang salah dari pemeriksaan risiko yang tidak pernah berjalan. Versi minimum yang berguna adalah log append-only yang juga mencatat rejection.


Setiap angka di atas berasal dari stored query atas minute bars, dan setiap panel dapat dibuka untuk melihat SQL di baliknya. Jalankan query yang sama dengan daftar simbol Anda sendiri di terminal Strasmore.

#risk-management#trading-bots#drawdown#position-sizing#automation