Position, track history, Charter Party compliance, weather-routed performance and demurrage exposure — voyage-level intelligence in one rolling view.
A voyage isn’t a single thing. It’s a sequence of legs — sea passage, port approach, port stay, cargo operation, departure, sea passage again. Each leg has its own performance shape, its own commercial implications, and its own way of going wrong. The vessel that arrives at Singapore three days late may have been below CP speed, or above CP speed but routed through bad weather, or stuck in a charterer-induced port delay — and the appropriate conversation is different for each.The Voyage Performance Surveillance pipeline reads the noon-report stream, the position track, and the Charter Party terms together, and produces a leg-by-leg performance view that resolves the ambiguity.
Position and weather come from external feeds (AIS, Stormglass, NAVTOR); operational data (FOC, sea/port time, voyage log) comes from the ERP and the vessel’s noon report stream. The Charter Party file lives in the vessel record and gets re-read on every analysis run so changes mid-voyage are reflected immediately.Two map views keep the position context honest:
Vessel detail
Fleet view
Single vessel with current position pinned and past 7 days of track history overlaid. Used when reviewing one voyage in detail.
All active vessels on one map with each vessel’s 7-day track. Used for fleet-wide reviews and when looking for spatial patterns (vessel cluster around a slow port, fleet-wide ECA exposure).
Most voyage analysis questions reduce to “is the vessel performing within Charter Party?” The CP defines a “good weather” envelope and a warranted speed-and-consumption profile within that envelope:
GOOD WEATHER ENVELOPE (typical CP) Wind: Beaufort scale ≤ 4 Sea: Douglas sea state ≤ 3 Current: ≤ ±0.5 knot favourable / adverse Swell: ≤ 2 mWARRANTED PERFORMANCE (within envelope) Speed: 14.0 kn (laden) / 14.5 kn (ballast) FOC at sea: 28.5 MT/day VLSFO FOC in port: 3.2 MT/day MGO
The pipeline filters every voyage leg to its good-weather subset, then computes the per-leg deviation:ΔV=Vactual−VCPΔFOC=FOCactual−FOCCPA negative speed deviation under good weather with a positive consumption deviation is the textbook under-performance pattern that drives owner-vs-charterer disputes. A negative speed deviation in bad weather isn’t a CP issue — the warranted speed doesn’t apply.
Naively averaging speed across an entire voyage produces meaningless numbers. A vessel that hit a Beaufort 8 storm for two days and ran at 9 knots will look like a CP underperformer even if it ran at 14.2 knots through every good-weather leg. The pipeline applies the filter first, then runs the maths:
def good_weather_legs(legs, cp_envelope): """Filter legs to those within CP good-weather definition.""" out = [] for leg in legs: if leg["wind_bf"] > cp_envelope["wind_max"]: continue if leg["sea_ds"] > cp_envelope["sea_max"]: continue if abs(leg["current_kn"]) > cp_envelope["current_max"]: continue if leg["swell_m"] > cp_envelope["swell_max"]: continue out.append(leg) return outdef cp_performance(good_legs, cp): """Compute mean deviation of speed and FOC under good-weather conditions.""" if not good_legs: return {"verdict": "Insufficient good-weather data", "coverage": 0.0} n = len(good_legs) delta_v = sum(leg["speed_kn"] - cp["warranted_speed"] for leg in good_legs) / n delta_foc = sum(leg["foc_mt"] - cp["warranted_foc"] for leg in good_legs) / n return { "delta_v": delta_v, "delta_foc": delta_foc, "good_legs": n, "coverage": n / len(legs), }
Coverage matters because a voyage with only 10% good-weather legs has too small a sample to support a CP claim either way. The pipeline reports coverage alongside the deviation — a TSI sees both.
A composite that combines the deviation magnitude, the good-weather coverage, and CP wording sensitivity:Pclaim=w1⋅∣ΔV∣+w2⋅∣ΔFOC∣+w3⋅(1−Cgood-wx)The third term is what protects against weak claims. Low good-weather coverage means the data is insufficient to support the deviation either way — the score reflects that.
Pclaim band
Action
Low
Routine — log and continue
Medium
Owner brief — document for next charter
High
Active claim or counter-claim risk — engage commercial
A vessel deliberately running below CP speed (typically owner-instructed for fuel saving). Looks like underperformance unless the CP allows slow-steaming. The pipeline checks the CP terms and the master’s voyage instructions — if both agree, the leg is excluded from the deviation calculation.
When a master chose a longer route to avoid weather. Shows up as a longer voyage at lower average speed. Cross-references the fuel oil pipeline for FOC over the routed leg vs the rhumb-line projection — sometimes a longer route is the lower-cost option even though it looks slower on the speed metric.
A voyage analysis without CP context misses the entire commercial dimension. A 0.5-knot deficit may or may not be a claim depending on CP wording — some CPs allow that as natural variation; others penalise it as breach of warranted speed. The pipeline reads the CP first, computes against the CP-defined envelope, and produces verdicts that map to the wording the lawyers will eventually argue over.
Voyage analysis is one of the few places where the same numbers are read by completely different audiences — owner, charterer, commercial operator, master, TSI. The pipeline keeps all of them in one document so when the dispute starts, everyone is reading from the same numbers.