← Terug naar wiki

🤖 AI-Agent Plannen

AI Trading Agent — EUR/USD 4H · Auto-order (paper) · 12-bar cooldown · Laatste update: 26 juni 2026

🤖 AUTO-TRADING ACTIEF (PAPER) Laatste update: 26 jun 2026 · Orders worden automatisch geplaatst · 12-bar cooldown actief · deepseek-v4-flash

🏗️ Architectuur

Orchestrator — single-agent autonoom

Eén Python script (orchestrator.py) dat alle taken combineert:

Draait 6× per dag via cron (03:05–23:05 NL, ma-vr) als no_agent watchdog. Model: deepseek-v4-flash.

📈 Zelflerend — wekelijkse WFA (zondag)

Elke zondag 08:00 NL draait een Walk-Forward Analysis via cron 45f0050b1328. Deze backtest de strategie over de nieuwste data en rapporteert:

Bij verslechtering beslist Hugo over parameter-aanpassing (SMA window, RSI drempel, ATR multipliers). Volledig geautomatiseerde parameter-tuning (optie B) is een toekomstige stap — voor nu is de feedback-loop: WFA → Hugo → aanpassing.

Koppelingen & Infrastructuur

🔌 IB Gateway — verbinding (Tailscale)

Hermes-container verbindt via Tailscale IP — geen Docker bridge of NAT nodig.

OnderdeelWaarde
Host100.108.36.111
API-poort PAPER4004
API-poort LIVE4002
ib_insyncib.connect('100.108.36.111', 4004, clientId=1, readonly=True)
Server-versie176
⚠️ Pitfall — poortconventie

De gnzsnz-image gebruikt een socat-relay: extern poort 4004 → intern 127.0.0.1:4002 (paper). Verbinden met 4002 extern = TCP open maar 0 bytes terug → TimeoutError. Gebruik altijd 4004 voor paper.

⚠️ Pitfall — jts.ini & TrustedIPs (opgelost 26 jun 2026)

De IB Gateway Java-applicatie overschrijft de [IBGateway] sectie van jts.ini bij elke login — ongeacht volume of template. De enige werkende aanpak: patch ná de login in de draaiende container, en herhaal dit automatisch.

Permanent opgelost: socat (poort 4004) forwardt naar 127.0.0.1:4002 — gateway ziet altijd 127.0.0.1 als source, TrustedIPs speelt geen rol. De watchdog hoeft geen TrustedIPs meer te patchen. API_PORT=4002 en SOCAT_PORT=4004 env-vars zijn vereist in het redeploy-script.

Bij herdeployment: bash /root/redeploy_ib_gateway.sh op de VPS — dit script start de container correct (volume + juiste poortmapping) en wacht op login.

# Handmatige noodpatch (als watchdog nog niet gedraaid heeft):
docker exec ib-gateway sed -i '/^\[IBGateway\]/,/^\[/ s/^TrustedIPs=.*/TrustedIPs=127.0.0.1,172.16.0.1,172.16.0.2,172.16.0.3,172.16.1.1,172.16.1.2/' /home/ibgateway/Jts/jts.ini

⚠️ De patch werkt alleen als de API-daemon hem nog niet heeft ingelezen. De daemon laadt TrustedIPs bij opstart — daarna heeft een live-patch geen effect totdat de daemon herstart. De socat-relay (poort 4004→intern 4002) omzeilt dit: socat forwardet verkeer als 127.0.0.1, wat altijd vertrouwd is.

⚠️ Pitfall — Redeploy mist API_PORT/SOCAT_PORT (opgelost 29 jun 2026)

Zonder -e API_PORT=4002 -e SOCAT_PORT=4004 env-vars start socat met lege waarden en luistert nergens op. Gevolg: poort 4004 is open maar geen relay → Error 162.

Permanent gefixt: /root/redeploy_ib_gateway.sh bevat nu deze env-vars. Na elke redeploy draait socat correct.

⚠️ Pitfall — Watchdog variabelen niet geïnterpoleerd (opgelost 28 jun 2026)

run_trade_watchdog.sh gebruikte enkele quotes in de bash -c call: '... $VENV ... $ORCHESTRATOR ...'. Variabelen binnen enkele quotes worden NIET geïnterpoleerd in bash — de orchestrator werd nooit aangeroepen. Gevolg: 3 dagen lang (24-27 jun) draaide de cron stil zonder dat de orchestrator het log bijwerkte.

Fix: enkele quotes vervangen door dubbele quotes: "... $VENV ... $ORCHESTRATOR ...".

🏗️ Systeemarchitectuur & Afhankelijkheden

Componenten & lijn

🌐 Hostinger VPS (srv1659405)
 └── 🐳 Docker
      ├── ib-gateway (gnzsnz/ib-gateway)
      │    └── Poort 4004 (Paper) via socat relay → intern 4002
      └── hermes-agent
           ├── 📊 Forex orchestrator.py (6× per dag, ma-vr)
           ├── ⏰ healthcheck_hourly (elk uur, stille poortcheck)
           ├── ⏰ forex rapport (21:10 UTC, dagelijks)
           └── 📱 Telegram → Hugo
    

Afhankelijkheidsvolgorde

  1. VPS staat aan — Hostinger infrastructuur
  2. Docker draait
  3. Tailscale is up (100.108.36.111)
  4. ib-gateway container — poort 4004 open
  5. hermes-agent container — draait crons
  6. Orchestrator (6× per dag op 4H candles) — verbindt met IB
  7. Telegram alert — naar Hugo (alleen bij trade/error)

⚠️ Eén haperende schakel = hele keten stil.

4H schema (ma-vr)

Tijd (NL zomer)WatCron
Elk uurIB Gateway poortcheck — alleen alert bij wijziging4b3ffc53d10d
Elk uur (:20)📊 Data pipeline check — échte data ophalen + validatie · Stil bij ok, alert bij 0 bars/verouderd/crash2788d5867414 (nieuw!)
03:05, 07:05, 11:05, 15:05, 19:05, 23:05Forex orchestrator — no_agent trade watchdog · Alleen melding bij trade/error/timeout · Incl. auto-patch TrustedIPs via SSH0ea6d4550bb1 (deepseek-v4-flash)
23:10Dagelijkse rapport — healthcheck + HTML status (merged)d0fe10245b00 (no_agent)

✅ Monitoring: 4 lagen — poort (elk uur), data pipeline (elk uur :20), trade watchdog (6×/dag), dagelijks rapport (21:10 UTC). Stil bij normaal, melding bij elk probleem.

Wekelijks schema (zondag)

Tijd (NL zomer)WatCron
08:00Walk-Forward Analysis — backtest 4H strategie, rapport naar Telegram45f0050b1328 (deepseek-v4-flash)

Referentiewaarden (live 24 jun 2026): OOS +5,30% · 14 trades/jr · WR 37,5% · PF 1,61. Bij verslechtering ⚠️ — Hugo beslist over aanpassing (optie A, geen auto-aanpassing).

🔧 Troubleshooting & Herstel

IB Gateway offline

Symptoom: Poort 4004 onbereikbaar. Telegram alert "IB Gateway Offline".

Oplossing — SSH naar VPS:

docker start ib-gateway
timeout 3 bash -c "echo >/dev/tcp/100.108.36.111/4004" && echo "OPEN" || echo "DICHT"

Bij twijfel: docker logs ib-gateway --tail 20

Hele stack herstarten

Bij VPS-reboot of container-crash — één commando op de VPS:

bash /root/redeploy_ib_gateway.sh

Start de gateway opnieuw met correct volume + poortmapping, wacht op IBC login, patcht TrustedIPs. Hermes-crons draaien daarna automatisch door.

Hostkey gewijzigd (SSH weigert)

ssh-keygen -R srv1659405
ssh-keygen -R 100.108.36.111

Error 162 — "connected from a different IP address"

Symptoom: Account info werkt via poort 4004, maar reqHistoricalData retourneert 0 bars met stille Error 162 in de TWS logs.

Oorzaak 1 — TrustedIPs: De IB Gateway Java-applicatie overschrijft [IBGateway] in jts.ini bij elke login — volume en template-patch hebben geen effect.

Oorzaak 2 — IBKR live sessie (ontdekt 29 jun 2026): Als je ergens anders bent ingelogd op IBKR (telefoon-app, desktop TWS), vergrendelt dat de marktdata voor andere sessies. De error is exact hetzelfde als TrustedIPs — je ziet het verschil alleen aan de gateway-logs.

Fix Oorzaak 2: Log uit bij IBKR op alle apparaten → Client Portal → Uitloggen → daarna gateway herstarten.

Permanente oplossing: socat (poort 4004) forwardt naar 127.0.0.1:4002 — TrustedIPs is altijd correct mits API_PORT=4002 en SOCAT_PORT=4004 env-vars in de container staan.

Herdeployment (bij VPS-reboot of container-crash):

bash /root/redeploy_ib_gateway.sh

Dit script op de VPS: stop/rm oude container → start nieuw met volume + alle 4 poorten (4004:4004) + -e API_PORT=4002 -e SOCAT_PORT=4004 → wacht 90s op IBC login.

Orchestrator fallback — "Insufficient data points"

Symptoom: De dagelijkse cron-run toont "Insufficient data points" ondanks dat de gateway online is (poort 4004 open).

Oorzaken (twee mogelijk):

Fix toegepast 23 jun 2026 in /opt/data/orchestrator.pyDataPipeline.get_market_data() probeert 4 durations met fallback, en past de SMA window dynamisch aan op basis van beschikbare bars.

📊 Evaluatie Checkpoint — 24 juni 2026

Basislijn vastgelegd vóór eerste live paper trade. Hier meten we wekelijks tegenaan.

Strategie

ParameterWaarde baseline
EntryClose > MA200 + RSI(14) < 30
Stop-loss2× ATR
Trail activatie≥3× ATR winst → peak − 1× ATR
Time exit60 bars (10 dagen)
Cooldown12 bars (48 uur)
WeekendVrijdag 19:05: BE trades → stop naar entry
Max risico/trade2%
Max drawdown5%

Backtest baseline

MetriekWaarde
Periode2013–2026 (13 jaar, Brownian Bridge 4H gesimuleerd)
Trades208
Trades/jaar~14
Rendement+64,1%
Winrate26,4%
Sharpe ratio0,47
Max drawdown−5,4%
Profit factor3,13

Infrastructuur

ComponentStatus
AccountDUQ630468 (paper) · poort 4004
Orchestrator/opt/data/orchestrator.py · auto-order + exits
Cronjobs3 forex (gemerged) · deepseek-v4-flash
Watchdogno_agent · alleen melding bij actie
WFAZondag 08:00 NL · rapport voor evaluatie
Wikiai-agent-plannen.html · up to date

Evaluatie-momenten

WanneerWat checken
Zondag 28 junEerste WFA · eerste live trades · bugs?
Zondag 5 jul2 weken live · short leg toevoegen?
Elke zondagWFA vs baseline — verslechtering?

⏱️ Signaal Timing & 4H Schema

4H candles — timing

EUR/USD 4H candles sluiten op UTC: 01:00, 05:00, 09:00, 13:00, 17:00, 21:00. De orchestrator draait op :05 na elke close om de net afgesloten candle te analyseren.

Signalen worden direct na candle-close berekend en uitgevoerd. Geen vertraging — market order op de eerstvolgende beschikbare prijs.

✅ Voltooide Acties

10-jaar backtest (2013–2023)
Sharpe ratio: 1.06 · Winrate: 58.3% · Max drawdown: -4.9%
Walk-Forward Validatie
5 cycli (2 jaar in-sample, 1 jaar out-of-sample) · 100% positieve OOS periodes · OOS Sharpe 1.06
WFA Python Engine ontwerp
Inclusief frictiekostenberekening
Docker-implementatie op VPS
Volledig geïsoleerde containers · Tailscale beveiligde toegang
IB Gateway container actief & verbonden
09 jun 2026 · Schone redeploy · API-handshake werkt op poort 4004 · Account DUQ630468 (~€1M) · readonly geverifieerd
Smoke test write-pipeline geslaagd
09 jun 2026 · MarketOrder BUY 10.000 EUR/USD · Status: Filled · Gateway terug op readonly=True
Data pipeline (geïntegreerd in orchestrator.py)
250 dagen EUR/USD BID_ASK (4H) · SMA_200 · Wilder's RSI(14) · Wilder's ATR(14) · clientId=10 readonly · fallback durations 250D→100D→50D→30D
Risk manager (geïntegreerd in orchestrator.py)
Dynamische HWM via /opt/data/trading_state.json · 5% circuit breaker · 2% regel · 2×ATR stop-loss · clientId=11 readonly
Orchestrator (orchestrator.py) — master script
Integreert data pipeline + strategie (2 condities: prijs > MA200 + RSI < 30) + risicobeheer + Telegram-rapportage · 6× per dag 4H cron (ma-vr)
Automatische rapportage (Telegram + lokale logs)
Lichtgewicht via requests (geen extra dependencies) · Heartbeat bij geen signaal · Alert bij signaal of fout · Logrotate 30 dagen · /opt/data/trading_logs/
Passieve monitoringfase gestart
09 jun 2026 · readonly=True dwingend actief · Dagelijkse analyse zonder orderuitvoering · Tot 18 juni 2026
Orchestrator persistentie & herstel (13 jun)
Script naar /opt/data/orchestrator.py (blijft bij rebuilds) · Python venv /opt/data/trading-venv/ met auto-recovery bij cron · Watchdog om 23:10 NL controleert of orchestrator heeft gedraaid · Logs naar /opt/data/trading_logs/
Healthchecks & pre-checks (13 jun)
Pre-check in orchestrator.py: poorttest vóór IB connectie · healthcheck_hourly: elk uur, alleen alert bij statuswijziging · healthcheck_daily: volledig overzicht (poort, cron, errors, koers) · IB host gewijzigd naar Tailscale IP (100.108.36.111) · restart_trading.sh: 1-commando herstart op VPS

⚠️ Openstaande Acties

Omgevingsvariabelen gekoppeld in Docker
TELEGRAM_TOKEN + TELEGRAM_CHAT_ID via source /opt/data/trading_secrets.env · Script draait nu direct (geen docker exec) · Eerste notificatie ontvangen: RSI 40.92, Close 1.15654
Cronjob geactiveerd (Hermes scheduler)
Job ID: 0ea6d4550bb1 · 6× per dag (01:05, 05:05, 09:05, 13:05, 17:05, 21:05 UTC, ma-vr) · no_agent watchdog · script: run_trade_watchdog.sh
Logrotate configureren op host
/opt/data/trading_logs/*.log · daily · rotate 30 · compress
Paper trading fase — live-gang
18 jun 2026 · readonly=False op clientId=11 · has_open_position() guard actief · Cron rapport check omgezet naar no_agent · Eerste echte orders na HWM-bevestiging
has_open_position() guard
18 jun 2026 · clientId=13 readonly check vóór trade execution · Voorkomt dubbele entries
Auto-order placement (paper)
24 jun 2026 · execute_trade() in orchestrator.py · MarketOrder BUY + StopOrder op 2x ATR · clientId=14 · Log met order status (Submitted/Filled)
12-bar cooldown na exit
24 jun 2026 · detect_exit() vergelijkt had_position vs huidige positie · cooldown_until in trading_state.json · check_cooldown() voor entry · RiskManager _save_hwm() behoudt cooldown velden
Model gepind op cronjobs (deepseek-v4-flash)
24 jun 2026 · Alle 3 forex cronjobs (0ea6d4550bb1, 351d6c831017, 45f0050b1328) expliciet op deepseek/deepseek-v4-flash
Cronjobs omgezet naar no_agent watchdog
24 jun 2026 · run_trade_watchdog.sh · Alleen output bij trade of error · Geen LLM tokenkosten · Exit code check voor timeout/crash
Cronjobs gemerged — 6 → 3
24 jun 2026 · 21:45 job verwijderd (21:05 toegevoegd aan 4H run) · healthcheck + rapportcheck + HTML status gemerged in daily_forex_report.sh · 6 forex crons → 3 over

📱 Duiding van de dagelijkse Telegram-rapporten

De watchdog stuurt alleen een bericht bij een relevante event: trade geplaatst, fout, timeout of trade geblokkeerd. Geen melding = passief, alles normaal.

1. Passief rapport — standaard status

📊 4H Update
Status: Passive
RSI(14): 60.08
Close: 1.14155
SMA200: 1.15592

Het systeem functioneert correct, maar de markt voldoet niet aan de twee instapeisen (prijs > MA200 én RSI < 30). Geen actie vereist.

2. Goedgekeurd signaal — AUTO-TRADE

⚡️ TRADE — Auto-order
• 12,500 EUR/USD BUY @ 1.14250
• Stop-loss: 1.13550 (2x ATR)
🚀 Order Submitted

Alle condities ✅ + cooldown verstreken + risk goedgekeurd → orchestrator plaatst automatisch een market buy + stop-loss op paper account. Geen handmatige actie nodig. Het rapport dat je ontvangt is een bevestiging, geen vraag om toestemming.

3. Geblokkeerd risico-rapport — noodrem actief

⛔️ Trade Blocked
Risk limits exceeded

Een signaal was aanwezig, maar de RiskManager heeft ingegrepen. Dit treedt op in twee scenario's:

Actie: Controleer de lokale logs via de terminal om te zien welk risico-attribuut de blokkade heeft getriggerd:
tail -50 /opt/data/trading_logs/daily.log | grep RISK

4. Cooldown — 48 uur pauze na stop-out

Cooldown — 9 bars remaining

Na een stop-out (of handmatige sluiting) start een 12-bar cooldown (48 uur). De orchestrator detecteert de exit door had_position in trading_state.json te vergelijken met de huidige positie. Zelfs als condities meteen weer ✅ zijn, wordt er pas na 48 uur weer een entry overwogen. Voorkomt whipsaw na stop-loss.

AI & LLM Code & Development Docker & VPS Skills & Tools