Ingest
Services pulling market and operational data on their own schedules, with gap detection and re-fetch for anything missed during an outage. Nothing downstream ever sees a vendor format directly.
The method is domain-agnostic — the same architecture works for logistics, industry, fintech or anything else that has outgrown a spreadsheet. What follows is what it looks like applied to energy-market trading analytics.
A platform that continuously ingests energy market and operational data, computes curves, signals and forecasts over it, and delivers the result to the people who trade on it — in the tools they already work in.
Analytical products of this kind usually start as research: a script that pulls data, a spreadsheet that computes something useful, a report sent round by mail. That is the right way to start, and it works until the thing has to run every day and be trusted with money.
At that point the same three failures appear every time. Nobody can reproduce yesterday's number. Every change touches everything else, so changes stop happening. And the answer arrives in a place the people who need it do not look.
We started with the questions rather than a specification: where each number comes from, who corrects it by hand, how bad late is, how bad wrong is, and where the people who act on it actually are during the day.
Those answers decided the stack — above all the storage, chosen for this data shape — and from there the system is a set of small services on Kubernetes, each with one job and a versioned contract, connected by an explicit data flow.
A forecasting service and a chat notifier were added months after the first release, and one early service was removed once its job turned out to belong somewhere else. None of it required touching the parts already running, and no contract broke.
That is the entire claim on the home page, stated as an event rather than a diagram: the cost of the fourteenth service was the cost of the fourth.
Services pulling market and operational data on their own schedules, with gap detection and re-fetch for anything missed during an outage. Nothing downstream ever sees a vendor format directly.
One canonical model for instruments, events and time, with schema validation that alarms when a source quietly changes format — the failure that otherwise goes unnoticed for days.
Chosen for this data specifically: long windows for research and narrow recent windows for the live view, with a clear line between what can be recomputed and what must never be lost.
Curves, indicators, signals and our own models — trained and predicting on the live stream — as separate services: Go where throughput matters, Python where the models live, each scaled on its own load. New computations arrive as new services, not as edits to existing ones.
The analytics interface for the people who want to look, and chat delivery for the people who want to be told — with every figure traceable back to the records that produced it.
Kubernetes underneath all of it: deployments for the steady stream, jobs and job pipelines for periodic work, metrics and logs from the platform, environments defined in code.
Streaming data, scheduled pipelines, computation that must be reproducible, models under supervision, answers delivered where people work — energy trading needs all of it, and so do a lot of industries that would never call themselves technical.
Turning a working spreadsheet or research codebase into a system that runs every day, reproducibly and safely — without discarding the work that proved the idea.
A system that has become too entangled to change, restructured into parts that can be added to and removed from again.
Inheriting a cluster nobody fully understands and making it legible, cheaper and safe to deploy to.
Describe the business, not the technology. If we are not the right people for it, we will say so — and usually point you at who is.