Paano gumagana ang circuit breakers para sa trading bots
Pinipigilan ng circuit breakers ang trading bot bago lumala ang talo. Alamin kung gaano kadalas ma-trigger ang daily loss limit at ang epekto ng volatility scaling.
Ang mga circuit breaker para sa mga trading bot ay ang mga panuntunan na nagpapatigil sa isang automated strategy sa pagpapadala ng mga order kapag naabot na ang itinakdang limitasyon. Nagsisilbi itong layer ng risk sa pagitan ng strategy at ng broker, at tumatakbo ang mga ito sa bawat order, sumang-ayon man ang strategy o hindi. Ang strategy ang nagpapasya kung ano ang i-trade. Ang risk layer naman ang nagpapasya kung matutuloy ang pag-trade.
Ang paghahating ito ang buong konsepto ng disenyo. Ang isang strategy na nagbabantay sa sarili nito ay walang independiyenteng pagsusuri sa sandaling mabigo ang sarili nitong mga assumption, na siya namang sandali kung kailan pinaka-kailangan ang ganitong pagsusuri.
Ano ang ginagawa ng circuit breaker sa isang trading bot
Ang risk layer ay may apat na bahagi, at ang bawat isa ay umiiral upang maiwasan ang isang tiyak at karaniwang pagkakamali.
- Hard caps sa laki ng position, notional exposure bawat symbol, at order rate. Nililimitahan nito ang pinsala mula sa isang bug na kung hindi ay magiging walang hanggan.
- Isang drawdown circuit breaker na humihinto sa mga bagong order kapag ang account ay lugi na ng itinakdang halaga sa session, o bumaba ng itinakdang halaga mula sa peak ng equity nito.
- Scaled order sizing, na nakabase sa kamakailang volatility o sa isang fraction ng Kelly bet sa halip na fixed na bilang ng share, na nagpapanatili sa risk bawat trade na halos steady habang nagbabago ang range ng merkado sa ilalim nito.
- Isang append-only audit log ng bawat desisyon, kabilang ang mga order na tinanggihan ng risk layer. Ito lamang ang artifact na naghihiwalay sa "mali ang estratehiya" mula sa "hindi tumakbo ang check".
Ang lahat ng nasa ibaba ay isa sa apat na ito, na ginawang konkreto.
Ano ang makatwirang daily loss limit para sa isang trading bot?
Ang daily loss limit ay nagpapatigil sa mga bagong order kapag ang lugi sa session ay lumampas sa isang threshold. Ang pagpili ng numerong ito ay usapin ng calibration, hindi ng personal na kagustuhan: kung ilalagay ito sa loob ng ordinaryong market noise, madalas na nakatigil ang bot linggo-linggo; kung ilalagay naman ito nang masyadong malayo, hindi ito kailanman gagana. Ang panimulang punto ay kung gaano kadalas nagkakaroon ang merkado ng down day na may partikular na laki.
Ang eksaktong SQL sa likod ng bawat numero
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 yearAng mga session na may 1% na pagbaba o higit pa ay umabot sa 15 noong 2019 at 45 noong 2020, mula sa humigit-kumulang dalawang daan at limampung trading days sa isang taon. Ang bilang ng 3% na pagbaba o higit pa ay ibang usapin: 0 noong 2019 laban sa 16 noong 2020. Ang huling row ng 9 ay sumasaklaw lamang sa mga session hanggang July 31, 2026.
Ang linyang ito ay hindi pantay kundi pa-bukol, at ang pagiging pa-bukol na ito ang basehan ng disenyo. Ang mga mahihirap na araw ay dumarating nang pangkatan. Ang isang bot na tumitigil sa unang araw ng isang grupo at nagpapatuloy sa ikalawang araw ay hindi tunay na tumigil.
Dalawang threshold ang gumaganap ng magkaibang tungkulin. Ang isang daily loss limit, na karaniwang dalawang porsyento ng account equity, ay nagtatapos sa session. Ang isang trailing drawdown limit na sinusukat mula sa equity high-water mark, na karaniwang nasa sampung porsyento, ay nagtatapos sa estratehiya habang naghihintay ng pagsusuri ng tao. Ang una ay routine, ang pangalawa ay dapat na bihira lamang, at ang isang bot na mayroon lamang ng una ay maaaring unti-unting ubusin ang account nang dalawang porsyento bawat pagkakataon nang hindi man lang nagti-trigger ng anumang limit.
Paano binabago ng volatility scaling ang laki ng posisyon?
Ang volatility targeting ay nagtatakda ng laki ng posisyon nang pabaligtad sa kamakailang realized volatility: kapag dumoble ang daily range, humahati ang laki ng posisyon upang mapanatiling halos pareho ang dollar risk sa bawat trade. Ang realized volatility dito ay ang annualized standard deviation ng daily returns, at mas malayo ang nararating nito kaysa sa inaasahan ng karamihan.
Ang eksaktong SQL sa likod ng bawat numero
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)Ang realized volatility ay nasukat nang 11.1% annualized noong 2024-01 at 12% noong 2026-07, sa loob ng 31 na buwan. Ang ikalawang column ay ginagawang posisyon ang bawat reading na kakayanin ng 12% volatility target, na may cap sa full line: 100% noong 2024-01 laban sa 99.7% noong 2026-07. Parehong estratehiya, parehong conviction, ngunit magkaibang-magkaiba ang bilang ng share.
Ang Kelly criterion ay tumitingin sa parehong problema mula sa kabilang dulo, kung saan ang pagtatakda ng laki ay base sa estimated edge at variance sa halip na sa volatility lamang. Karamihan sa mga systematic operator ay gumagamit lamang ng fraction nito, gaya ng half o quarter Kelly, dahil ang parehong inputs ay mga estimate lamang mula sa isang finite sample. Ang pagtatakda ng laki ng posisyon gamit ang Kelly criterion ay dumadaan sa aritmetikang iyon.
Bakit patuloy na pumapasok ang isang trading bot pagkatapos ng stop?
Nag-trigger ang stop. Isinara ang posisyon. Pagkalipas ng siyamnapung segundo, totoo na naman ang entry condition, muling papasok ang bot, kukunin ang parehong lugi, at uulitin ito. Walang sirang bahagi. Ginawa ng estratehiya ang nakasulat na dapat nitong gawin, ginawa ng stop ang nakasulat na dapat nitong gawin, at patuloy pa ring nauubos ang account sa bawat round trip.
Ang dalas nito ay direktang nagmumula sa galaw ng presyo. Binibilang ng panel na ito, kada session, kung ilang beses gumalaw ang SPY mula sa mahigit 0.1% na mas mataas sa opening price nito patungo sa mahigit 0.1% na mas mababa rito, o pabalik.
Ang eksaktong SQL sa likod ng bawat numero
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)Tumawid ang SPY sa band na iyon nang average na 0.7 beses kada session noong 2025-08 at 1.5 beses noong 2026-07, kung saan may isang session noong 2026-07 na nagtala ng 5 na pagtawid. Ang anumang panuntunan na nagbubukas sa isang panig ng level at nag-i-stop sa kabila ay may ganoon karaming pagkakataon na mag-fire sa loob ng isang araw.
Apat na mekanismo ang pumipigil dito.
- Isang cooldown pagkatapos ng bawat stop, na sinusukat sa mga minuto o bar, kung saan walang bagong order para sa simbolong iyon ang papasa sa risk layer.
- Isang limitasyon sa bilang ng trade kada simbolo sa bawat araw, na nagpapalit sa isang walang hanggang loop tungo sa isang may hangganan.
- Isang halt flag na naka-latch. Kapag na-trip ang daily loss limit, mananatili itong naka-trip hanggang sa i-clear ito ng isang tao.
- Persistence para sa flag na iyon sa labas ng process memory. Ang isang supervisor na nag-re-restart ng nag-crash na bot ay nagbibigay dito ng malinis na slate, at ang malinis na slate ang mismong dahilan kung bakit umiiral ang flag.
Ang huli ang nakakahuli sa mga taong ginawa nang tama ang lahat ng iba pa. Ang Grid trading bots ay naglalagay ng mga hagdan ng order ayon sa disenyo, na ginagawang mahalaga ang trade-count cap sa halip na palamuti lamang.
Ano ang nangyayari kapag ang bot ay nag-trade gamit ang stale price feed?
Ang quote na huminto sa pag-update ay mukhang numero pa rin. Binabasa ito ng bot, nagtatakda ng presyo para sa isang order base rito, at ipinapadala ang order na iyon sa isang merkado na gumalaw na. Tahimik ang pagkabigong ito: walang lumalabas na error, walang naitatala sa log, at ang mga fill ay magmumukhang kakaiba lamang pagkatapos ng transaksyon.
Ang malinaw na masusukat na bersyon nito ay ang overnight gap, kung saan ang isang kilalang presyo ay nananatiling hindi nagbabago sa loob ng ilang oras habang ang tradable price ay gumagalaw na.
Ang eksaktong SQL sa likod ng bawat numero
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 DESCAng pinakamalawak na pangalan ayon sa 95th-percentile gap ay TSLA sa 4.41%, laban sa 1% para sa KO. Ang mga karaniwang gabi ay mas tahimik: may median gap na 1.01% at 0.24% ayon sa pagkakasunod. Ang mga tail ang dahilan kung bakit binuo ang risk layer, at ang pinakamalaking single gap noong TSLA sa loob ng window ay umabot sa 14.57%. Iyan ang mga distansyang maaaring harapin ng isang bot na kumikilos base sa presyong nabasa nito noong nakaraang panahon. Ang Bakit nagkakaroon ng gap ang mga stock overnight ay tumatalakay sa mga mekanismo nito.
Mura lamang ang mga depensa. Magtakda ng maximum age sa bawat quote na gagamitin ng risk layer sa pagpepresyo, na karaniwang nasa ilang segundo para sa isang intraday strategy. Kumuha ng heartbeat mula sa feed nang hiwalay sa data, na naghihiwalay sa isang silent socket mula sa isang tahimik na merkado. Ituring ang nawawalang data bilang isang halt sa halip na hold, dahil ang isang bot na walang presyo ay hindi rin makakapag-evaluate ng mga exit nito.
Aling mga hard cap ang dapat nasa risk layer?
- Maximum notional bawat symbol bilang bahagi ng account equity. Ang 10% ceiling ay pumipigil sa isang masamang symbol na ubusin ang buong account.
- Maximum gross notional sa lahat ng bukas na posisyon. Ang pagtatakda nito sa 100% ng equity ay nangangahulugang walang leverage, isang desisyong mas mabuting gawin nang hayagan kaysa hayaan lang ang default ng broker.
- Maximum order rate, bawat minuto at bawat araw. Ang sampung order kada minuto ay maluwag na para sa karamihan ng retail strategies at nililimitahan pa rin ang isang runaway loop sa loob ng isang minuto.
- Maximum order size bilang bahagi ng average daily volume ng symbol. Ang 1% ceiling ang cap na pumipigil sa isang bot na galawin ang presyong sinusubukan nitong i-trade, at ang average daily volume ang nagsisilbing denominator.
Ang bawat isa sa mga ito ay dapat nasa risk layer sa halip na sa strategy, at ang bawat isa ay dumadaan sa parehong code path sa backtest, paper, at live. Ang limitasyon na umiiral lamang sa live ay limitasyong hindi pa nasusubukan ng sinuman.
Ano ang kailangan sa audit log ng isang trading bot?
Ang isang append-only log ay nagsusulat ng isang record bawat desisyon at hindi kailanman nag-e-edit o nagbubura. Ang bawat record ay naglalaman ng timestamp, ang quote na ginamit at ang edad nito, bawat limit check na tumakbo kasama ang resulta nito, ang order na ipinadala, at ang tugon ng broker. Ang mga rejected order ay isinusulat nang may parehong bigat gaya ng mga filled order.
Ang layunin nito ay reconstruction. Anim na linggo pagkatapos ng isang masamang session, ang tanong ay hindi kailanman kung ano ang P&L. Ang tanong ay kung anong check ang pumasa, base sa anong input. Kung walang nakatalang input, mauuwi ka sa muling pag-derive ng state ng bot mula sa market, na katulad na pagkakamali ng look-ahead bias sa backtesting: ang paggamit ng impormasyong wala sa system noong sandali ng desisyon.
Ang riskguard project ay isang open-source na implementasyon ng paghihiwalay na ito, kung saan ang mga limit check ay nasa isang component na tinatawag ng strategy sa halip na nakakalat ang logic sa loob mismo ng strategy. Isa lamang ito sa maraming disenyo, na mas mabuting basahin muna kaysa agad na gamitin. Anuman ang iyong gamitin, i-pin ang isang tagged release sa halip na default branch. Ang isang branch ay maaaring magbago sa pagitan ng dalawang takbo ng parehong backtest, at ang isang risk layer na tahimik na nagbago ay mas masama kaysa sa wala.
Bakit ang unang deployment ay tumatakbo sa isang paper broker
Ang broker adapter ay naka-default sa paper, at ang live trading ay nangangailangan ng tahasang flag na sinadyang i-set. Ang failure na iniiwasan nito ay simple lang: isang na-copy na config file, o isang environment variable na hindi na-override, na magpapadala ng totoong order gamit ang totoong pera.
Ang isang paper run ay gumagawa rin ng mahalagang artifact, isang decision log mula sa parehong risk layer gamit ang live prices, na nagpapakita kung aling mga limit ang nag-fire at kung alin ang hindi. Ito ay ebidensya tungkol sa risk layer, isang hiwalay na usapin mula sa kung kumikita ba ang estratehiya. Paper trading bago ang totoong pera ang tumatalakay sa kung ano ang napatutunayan at hindi napatutunayan ng isang paper record, at ang multi-agent AI trading systems ang nagpapakita kung bakit ang halt authority ay dapat nasa labas ng bawat agent kapag marami na sa kanila ang nakakapag-place ng order.
FAQ tungkol sa circuit breaker ng trading bot
Ano ang circuit breaker sa isang trading bot?
Ito ay isang panuntunan sa risk layer na nagpapatigil sa bot sa pagpapadala ng mga bagong order kapag naabot na ang itinakdang limitasyon, kadalasan ay ang daily loss threshold o drawdown mula sa peak equity ng account. Tumatakbo ito nang hiwalay sa estratehiya, sa bawat order, at mananatiling naka-trip hanggang sa may mag-clear nito.
Gaano kadalas nagkakaroon ang merkado ng 2% down day?
Ang SPY ay nagtala ng 5 na sesyon na may 2% na pagbaba o higit pa noong 2019 at 25 sa loob ng 2020, mula sa humigit-kumulang 250 trading days bawat taon. Ang spread na iyon sa pagitan ng isang kalmadong taon at ng isang taong may stress ang dahilan kung bakit ang loss limit ay kinakalibrate base sa kasaysayan at hindi sa kutob lamang.
Paano pipigilan ang bot na pumasok muli pagkatapos ng isang stop?
Ang cooldown window pagkatapos ng bawat stop at ang per-symbol daily trade cap ay nagpapabago sa isang unbounded loop tungo sa isang bounded na proseso. Ang halt flag ay dapat ding mag-latch at manatili sa labas ng process memory, dahil kung hindi, ang supervisor na nag-re-restart sa nag-crash na bot ay magbibigay lamang dito ng bago at hindi naka-halt na state.
Paano malalaman ng bot kung stale na ang price feed?
Sa pamamagitan ng pag-check sa edad ng bawat quote bago mag-presyo ng order base rito, at sa pagbabantay sa heartbeat mula sa feed nang hiwalay sa data. Ipinapakita ng mga overnight gap ang laki ng itinatago ng isang stale na presyo: ang 95th-percentile overnight move ay umabot sa 4.41% noong TSLA sa pagitan ng Enero 2024 at Hulyo 2026.
Kailangan ba talaga ng audit log ng isang maliit na trading bot?
Ang log ng mga fill ay nagtatala ng mga nangyari. Ang log ng mga desisyon ay nagtatala ng pinaniniwalaan ng bot na pinapayagan nitong gawin, na siyang tanging paraan upang matukoy ang pagkakaiba ng maling estratehiya sa isang risk check na hindi gumana. Ang append-only, kasama ang mga rejection, ang pinakamababang bersyon na kapaki-pakinabang.
Ang bawat figure sa itaas ay nagmula sa isang stored query sa mga minute bar, at ang bawat panel ay bumubukas sa SQL na nasa likod nito. Gamitin ang parehong mga query sa sarili mong listahan ng mga symbol sa Strasmore terminal.