Releases: Bogzx/ftmo-calendar
v0.8.0 — Granular events + stats
Granular events (grounded in FTMO history) + self-hosted stats.
Seven event types replace the coarse four: maintenance, crypto_closure, holiday_closure, early_close, late_open, symbol_event, other. Derived from sampling FTMO's announcement archive. Verified live on DeepSeek: the Memorial Day post extracts as 8 correctly-typed events:
maintenance Sat 17:00-21:00 Platform Maintenance - MT4, MT5, cTrader, DXtrade
holiday_closure Mon all day Closed All Day - UK100, HK50, Equities I, Agriculture
early_close Mon 20:00 Early Close - JP225, US30, US100, US500, US2000
early_close Mon 20:30 Early Close - UKOIL
early_close Mon 21:30 Early Close - Metals, USOIL, HEATOIL, NATGAS
early_close Mon 23:00 Early Close - GER40
late_open Tue ->16:35 Late Open - CORN, SOYBEAN, WHEAT
late_open Tue ->03:05 Late Open - UK100
- Event titles carry affected symbols via a new
affectedextraction field; consensus merges partial lists - Seven filter chips on the landing page; old state files stay compatible
- Anonymous usage stats in serve mode: page views, unique visitors (random-id first-party cookie, no third parties), feed pulls, unique feed clients. Footer summary + GET /stats JSON with 30-day history.
v0.7.0 — Per-interest feeds
Subscribe to only what you trade.
- Type-filtered feeds: /feed.ics?types=crypto_closure (any combination of maintenance, crypto_closure, holiday_hours, other). Each distinct URL behaves as its own calendar in Google/Apple/Outlook.
- Landing page filter chips: untick event types and the subscribe URL + webcal link rebuild live.
- Filtered calendars are named after their filter; unknown types return a 400 listing valid ones.
- State v3: tracked events carry their event type (older state files load transparently).
Verified live: filtered endpoint returns only matching events; UI chips rebuild the URL in a real browser.
v0.6.0 — Landing page
A real website for hosted deployments (e.g. calendar.yourdomain.com).
The served / page is now a designed, self-contained landing page - trading-terminal aesthetic, zero external requests:
- Live countdown to the next trading interruption (switches to "ends in" while one is in progress, "ALL CLEAR" when nothing is scheduled)
- Every time rendered in the visitor's own timezone
- One-click feed subscribe: copy-URL button + webcal:// open, with per-app instructions for Google/Apple/Outlook
- Upcoming / in-progress (LIVE) / past schedule, sync health in the footer
- Works without JavaScript, responsive down to phones, ~16 KB single response
v0.5.0 — Deterministic extraction
Always reports the same thing — verified live on DeepSeek via OpenRouter.
- Consensus voting (
[llm] consensus_runs, default 3): each changed post is extracted N times, majority events kept. Hosted APIs are not deterministic at temperature 0 (OpenRouter routes one model id across providers); voting makes the result stable. Live proof: 4 consecutive consensus extractions of a real FTMO post -> identical event sets, identical event keys. - Prompt rule excluding Client Area/IT maintenance — the one borderline case that flickered between runs
- Consensus identity merges timezone-attribution variants (explicit offset wins) so the vote never splits on equivalent events
seedhint on OpenAI-compatible calls
v0.4.0 — Feed-first hosting
Run a public feed for a whole trading group with just an LLM key.
- Feed-only mode (
[calendar] enabled = false): no Google account needed anywhere — one host runs a container, everyone else subscribes to/feed.ics --dry-runworks before any Google setup- Status page is now a shareable landing page: next event, sync health, per-app subscribe instructions
/healthzreportsnext_runfor overdue-sync detection; DockerHEALTHCHECKincluded- ICS feed: refresh hints (
REFRESH-INTERVAL) and per-event source links - DeepSeek/OpenRouter hardening:
<think>blocks and prose-wrapped JSON handled
Fixed: UTF-8 BOM configs (Notepad/PowerShell) parse correctly; feed serves last-good data immediately after restart; identical persistent errors notify once, not every interval.
v0.3.0 — Notifications, ICS feed, hosted mode, Docker
Reach & visibility.
- Discord webhook and Telegram bot notifications: new/removed events, run failures, optional heartbeat
- ICS feed export: subscribe from any calendar app with zero OAuth setup
ftmo-calendar serve: periodic sync + HTTP server exposing/feed.ics,/status,/healthz- Docker support:
docker compose up -druns serve mode with a./datavolume - State v2: tracked events carry display data; v1 state files load transparently
v0.2.0 — Trustworthy sync core
Complete rewrite as a professional package.
ftmo-calendarCLI:run(with--dry-run),auth(with--check),status- Provider-agnostic LLM parsing: Gemini or any OpenAI-compatible endpoint
- Service-account auth mode: no browser, no token expiry
- Reconcile sync: rescheduled/withdrawn announcements update or remove their calendar events
- Multi-post scraping matching FTMO's redesigned site
- Content-hash caching: unchanged posts cost zero LLM calls
- Event reminders, validation, timezone normalization
- Tests, ruff, mypy, GitHub Actions CI, TOML config
Fixed: expired OAuth tokens no longer hang cron with a browser prompt; documented the 7-day Testing-status token expiry.
