What Worked
SuccessesComplete message-driven path
CSV rows become canonical domain events, statistics, signal snapshots, decisions, and portfolio reports.
Same data, different outcomes
The strategy layer makes behavior visible: NYC buys aggressively, LON waits for volatility confirmation, TYO stays flat.
Patterns solve real seams
GoF patterns organize object behavior; EIPs organize message movement and routing responsibilities.
Failure handling stays explicit
Invalid market records are separated from valid flow, making data quality issues visible without blocking processing.
What Was Hard
Pain PointsCorrelation had to be precise
engineId:correlationId:symbol prevents statistics from different engines or symbols being aggregated together.Rolling-window warmup is non-obvious
Early ticks correctly produce no statistic until the window is full, which can look like missing output during a demo.
Topic granularity adds wiring
By-statistic topics make Selective Consumer clear, but they create more route definitions and endpoint mapping.
Asynchronous output needs discipline
Concurrent routes can interleave decisions and reports, so centralized recording is important for clear final summaries.