Wat is 'Graceful Shutdown' en hoe programmeer je dit in Python?

Portret van Alex de Vries, Quantitatief Analist & Algo-Trading Expert
Alex de Vries
Quantitatief Analist & Algo-Trading Expert
Foutmeldingen & Debugging Live Bots · 2026-02-15 · 9 min leestijd

Stel je voor: je bot draait al een paar uur soepel, de API-connectie met Interactive Brokers of Alpaca is stabiel, en je positie loopt mooi in de groen. Dan plotseling — stroomuitval of een crash op je VPS.

Geen tijd om netjes af te sluiten. Je orders blijven openstaan, je risicomanagement script kan zijn werk niet doen, en je portefeuille loopt onnodige schade op. Dat is precies waarom je een ‘Graceful Shutdown’ nodig hebt.

Het is je digitale veiligheidsnet. Je sluit je bot af zonder chaos te creëren.

Je positie wordt netjes afgesloten of beveiligd, de connectie met je broker wordt correct verbroken, en je logbestanden worden keurig opgeslagen. Zo blijf je in controle, zelfs als je laptop uitgaat.

Wat je nodig hebt voordat je begint

Je hebt een werkende Python-omgeving nodig, bijvoorbeeld versie 3.10 of nieuwer. Gebruik een virtuele omgeving via venv of Conda, zodat je packages niet in de knoop raken. Voor trading bots werk je meestal met bibliotheken als ccxt, ib_insync of de officiële Alpaca API.

Voor backtesting en logging zijn pandas, structlog en loguru goede keuzes. Een VPS vanaf €5 per maand (bij DigitalOcean, Hetzner of AWS Lightsail) is praktisch voor live bots.

Je broker-API-sleutels (bijvoorbeeld van Interactive Brokers of Kraken) moet je veilig opslaan, bijvoorbeeld via environment-variables of een tool als python-dotenv. Zorg dat je een testaccount gebruikt met nepgeld.

Bij Alpaca is dat gratis, bij Interactive Brokers kun je een paper account aanmaken. Test altijd eerst op een aparte testbot die dezelfde logica gebruikt als je live bot. Houd een aparte map voor logs, bijvoorbeeld ./logs en een map voor backups van je configuratie.

Reken op ongeveer 2 uur voor de basisopzet en 1 uur voor testen en fine-tunen.

Een fout die je vaak ziet: direct in production testen zonder fallback — dat is als je remmen testen op de snelweg.

Stap 1: Begrijp wat een Graceful Shutdown doet

Een Graceful Shutdown is een gecontroleerd afsluiten. Je bot stopt niet zomaar; hij voert eerst een checklist uit.

Je sluit openstaande posities af of plaatst stop-losses, je verbreekt de API-verbinding netjes, en je slaat je laatste staat op.

Zo voorkom je dat de markt je onbeschermd vindt. Denk aan een stop-loss order van 2% onder de huidige prijs, of een market order om een positie van 100 aandelen direct te sluiten. Je logt wat er gebeurt, zodat je later kunt zien waarom de bot stopte.

Veel traders verwarren een graceful shutdown met een simpele sys.exit(). Dat is te snel en te bruut. Je hebt tijd nodig — soms 5 tot 30 seconden — om netjes af te ronden. Bij high-frequency bots beperk je die tijd tot enkele seconden, bij swing-trading bots mag het wat langer.

Je wilt geen openstaande orders vergeten, en je wilt zeker weten dat je broker de sluiting bevestigt.

Dit is pure risicomanagement: je beperkt je exposure tijdens het afsluiten.

Een graceful shutdown is als een nette closing time in een café: je ruimt op, sluit de kassa, en doet het licht uit zonder klanten buiten te sluiten.

Stap 2: Kies je signalen en triggers

Je moet duidelijke triggers hebben voor het afsluiten. Gebruik een combinatie van systeem- en marktsignalen.

Voorbeeld: een interrupt (Ctrl+C) vanuit je terminal, een SIGTERM-signaal van je VPS, of een timer die je bot na 8 uur draaien automatisch stopt. Voeg daar marktsignalen aan toe: als de portfolio-waarde met meer dan 5% daalt, of als de API-latentie boven de 500 ms uitkomt. Je kunt ook een heartbeat gebruiken: je bot stuurt elke 10 seconden een ping naar een health-check endpoint. Als die 3 keer faalt, start de shutdown.

Bij live trading met Interactive Brokers is het slim om een maximum aantal fouten in te stellen. Bijvoorbeeld: als de API 3 keer binnen 1 minuut een timeout geeft, start je shutdown.

Gebruik een status-flag in je code: is_shutting_down = False. Zodra een trigger vuurt, zet je die op True.

Alle andere threads en processen checken deze flag en stoppen hun werk netjes. Houd rekening met een reactietijd van 1-2 seconden voor je bot om te schakelen naar shutdown-modus. Veelgemaakte fout: te veel triggers zonder prioriteit, waardoor je bot in een beslissings-loze modus blijft hangen.

Kies 2-3 duidelijke triggers en documenteer ze. Test ze apart, bijvoorbeeld door een script te schrijven dat een SIGTERM simuleert en kijkt of je bot netjes reageert.

Stap 3: Bouw een shutdown-handler in Python

Je bouwt een shutdown-handler die signalen vangt en je bot in de juiste modus zet. Gebruik de signal-module voor Unix-achtige systemen (Linux/macOS) en de threading-module voor een event-driven aanpak.

import signal
import sys
import time
import threading
from datetime import datetime

# Status-flag
is_shutting_down = threading.Event()

def handle_signal(signum, frame):
    print(f"Signaal {signum} ontvangen. Start graceful shutdown.")
    is_shutting_down.set()

# Registreer signalen
signal.signal(signal.SIGINT, handle_signal)  # Ctrl+C
signal.signal(signal.SIGTERM, handle_signal) # Docker/K8s/VPS stop

def graceful_shutdown(bot):
    """
    Voer je shutdown-checklist uit:
    1) Stop nieuwe orders
    2) Sluit open posities netjes af
    3) Verbreed API-verbinding
    4) Sla logs op
    """
    print("Shutdown gestart om", datetime.utcnow())
    bot.stop_accepting_orders = True

    # Sluit open posities af (voorbeeld voor Alpaca)
    try:
        positions = bot.api.list_positions()
        for p in positions:
            qty = int(p.qty)
            if qty != 0:
                # Plaats een market order om te sluiten
                side = "sell" if qty > 0 else "buy"
                qty_abs = abs(qty)
                bot.api.submit_order(
                    symbol=p.symbol,
                    qty=qty_abs,
                    side=side,
                    type="market",
                    time_in_force="gtc"
                )
                print(f"Sluit positie {p.symbol} x {qty_abs}")
    except Exception as e:
        print(f"Fout bij sluiten posities: {e}")

    # Wacht kort tot orders bevestigd zijn
    time.sleep(5)

    # Verbreed API-netjes (voorbeeld ib_insync)
    try:
        if hasattr(bot, "ib") and bot.ib.isConnected():
            bot.ib.disconnect()
            print("IB API disconnected")
    except Exception as e:
        print(f"Fout bij disconnect: {e}")

    # Sla laatste staat op
    try:
        bot.save_state()
        print("State opgeslagen")
    except Exception as e:
        print(f"State opslaan mislukt: {e}")

    print("Shutdown voltooid.")
    sys.exit(0)

# Gebruik in je hoofdloop
if __name__ == "__main__":
    # Je bot-initialisatie hier
    bot = ...  # vul in

    # Start een watchdog-thread die de flag checkt
    def watchdog():
        while not is_shutting_down.wait(timeout=1.0):
            # Check health metrics hier
            pass

    threading.Thread(target=watchdog, daemon=True).start()

    # Hoofdloop
    try:
        while not is_shutting_down.is_set():
            bot.run_cycle()
            time.sleep(1.0)
    finally:
        graceful_shutdown(bot)

Hieronder een voorbeeld dat je kunt integreren in je bot. Pas de handelslogica aan naar je broker en strategie. Pas de broker-specifieke calls aan.

Voor Interactive Brokers via ib_insync gebruik je ib.disconnect() en eventueel ib.sleep() om bevestiging af te wachten.

Voor ccxt bij crypto-brokers zoals Binance of Kraken check je of je open orders hebt en sluit je die met cancel_all_orders en eventueel een market order. Houd rekening met een extra wachttijd van 5-10 seconden voor bevestigingen. Test dit op een testaccount, niet op je live account. Veelgemaakte fout: geen try/except om je shutdown-logica heen.

Een fout tijdens het afsluiten kan je bot in een half-open staat laten. Omring elke stap met foutafhandeling en log wat er misgaat. Gebruik log niveaus: INFO voor normale stappen, WARNING voor vertragingen, ERROR voor echte problemen.

Stap 4: Integreer met je broker-API en risicomanagement

Je shutdown-logica moet naadloos aansluiten op je broker-API. Bij Alpaca kun je posities uitlezen en market orders plaatsen zonder veel latency.

Bij Interactive Brokers is het slim om een lichte wachttijd in te bouwen voordat je disconnect, zodat je orderbevestigingen binnenkomen. Bij crypto-brokers via ccxt let je op rate-limits: je wilt niet net voor shutdown een limiet overschrijden. Zet een fallback klaar: als een market order faalt, probeer een limit order op een veilig niveau, bijvoorbeeld 1% onder de huidige prijs voor een long.

Koppel je risicomanagement aan de shutdown. Als je bot een max drawdown kent van 5%, en die wordt overschreden, moet de shutdown direct starten.

Je kunt een aparte risico-module bouwen die je portfolio-waarde elke seconde checkt.

Als de drawdown boven de drempel komt, zet je de is_shutting_down flag. Voeg een ‘circuit breaker’ toe: na 3 mislukte API-call pogingen in 1 minuut, start je de shutdown. Dit voorkomt dat je bot blijft proberen terwijl de broker down is. Veelgemaakte fout: geen bevestiging van orders vragen.

Je bot denkt dat een order is geplaatst, maar de broker geeft een error. Check altijd de response-code en log die. Voorkom veelgemaakte Python-fouten door met een klein bedrag, bijvoorbeeld €10 tot €50, je sluitingslogica te valideren zonder groot risico.

Stap 5: Test je shutdown net als je live bot

Test je shutdown in een gecontroleerde omgeving. Gebruik een aparte testbot die dezelfde code draait, maar met een paper account.

Simuleer een crash door je script te onderbreken met Ctrl+C en check of je bot netjes afsluit. Test ook een SIGTERM: op Linux gebruik je kill -15 PID.

Op Windows kun je een aparte testscript schrijven dat een interrupt simuleert. Monitor de logs: zie je “Shutdown gestart” en “Shutdown voltooid”? Zijn je posities gesloten? Voer een stress-test uit: zet een timer die je bot na 30 minuten automatisch laat stoppen.

Check of alle bestanden zijn opgeslagen, inclusief je laatste staat en je logfiles. Zorg er bovendien voor dat je altijd een requirements.txt of poetry file gebruikt voor een reproduceerbare omgeving.

Gebruik een tool zoals loguru of structlog voor gestructureerde logs, zodat je makkelijk terugvindt wat er gebeurde. Tijdens testen mag je bot 2-5 seconden nodig hebben om af te sluiten; bij high-frequency bots mik je op 1-2 seconden. Veelgemaakte fout: alleen testen als alles goed gaat.

Test ook foutpaden: wat als de API tijdelijk down is? Wat als een order wordt afgewezen?

Je shutdown moet dan alsnog doorgaan, eventueel met een fallback-order. Zorg dat je een ‘safe mode’ hebt: een minimale set acties die altijd worden uitgevoerd, zoals het plaatsen van een stop-loss order.

Verificatie-checklist

Gebruik deze lijst na elke aanpassing. Vink elk item af voordat je live gaat. Als je alle items afgevinkt hebt, kun je je bot voorzichtig live zetten.

  • De bot reageert op Ctrl+C en start een graceful shutdown.
  • De bot reageert op SIGTERM en start een graceful shutdown.
  • Open posities worden gesloten met een market order of veilige limit order.
  • De API-verbinding wordt netjes verbroken.
  • Logs worden opgeslagen in ./logs met datum en tijd in de bestandsnaam.
  • De laatste staat wordt opgeslagen (portfolio, open orders, configuratie).
  • De shutdown duurt maximaal 5 seconden (of je ingestelde limiet).
  • Fouten tijdens shutdown worden gelogd en leiden niet tot een crash.
  • Je risicomanagement-drempels triggeren de shutdown correct.
  • Testaccount is gebruikt voor alle tests; live account is nog niet actief.

Begin met een klein bedrag, bijvoorbeeld €100 tot €500, en monitor de eerste uren nauwkeurig.

Zet alerts op je telefoon voor errors of shutdowns. Zo blijf je altijd bovenop je risicomanagement en kun je met een emergency dashboard al je posities direct sluiten om onnodige verliezen te voorkomen.

Portret van Alex de Vries, Quantitatief Analist & Algo-Trading Expert
Over Alex de Vries

Alex is een ervaren quantitatief analist en Python-ontwikkelaar die complexe trading concepten vertaalt naar begrijpelijke, praktische handleidingen voor zowel beginners als gevorderden.

Volgende stap
Bekijk alle artikelen over Foutmeldingen & Debugging Live Bots
Ga naar overzicht →