ProtocolEnglish
Events on the curve
Facts, the UNPRICED gap, and why no event moves a price
No event moves a price. Ever. The price is a function of supply. A goal, a red card, a release, an award is information placed on the curve, never a trigger.
A human reads the fact, decides, and clicks. That click moves the price, because a purchase moves the price. The fact does not.
Why this is the centre of the product, not a footnote
The interesting thing is never the goal. It is the gap between the fact and the market's reaction.
| What you see on a market | What it means |
|---|---|
| A marker, then the curve climbs | The market reacted. Nothing to do here. |
| A marker, then nothing | UNPRICED. The fact happened. The market did not move. |
The second row is the entire thesis. A talent performed, the performance is public and indisputable, and the price sat still. That is the window, and it is measured rather than asserted:
Threshold: under 2 % of market-cap movement in the 24 hours after the fact. Below it, the marker pulses green, the only animated element on the chart. No text says "buy". The chart says it.
This is how UNPRICED gives a reason to buy without ever giving advice to buy. Sport produces this content free, every weekend, forever. It is the only engine in the product that costs nothing and never stops.
The gap is computed, never stored
priceChangePct is recalculated at read time, from the same curve points the chart draws. It is never written to a table, so it never diverges from the graph next to it.
It returns null whenever the measurement is not honest:
- the fact predates the market's existence;
- fewer than 24 hours have elapsed.
The interface then says too early to tell. A fabricated 0 % is worse than an admitted blank.
What an event is made of
One fact, one row:
| Field | Meaning |
|---|---|
profile_id | The person. An event attaches to a profile, never to a market |
kind | goal, red_card, first_start |
occurred_at | When it happened, from the provider |
quantity | Identical facts in the same match. A brace is one marker with `quantity = 2`, not two dots stacked on each other |
competition, opponent | Context shown on the marker |
provider, provider_event_id | Idempotency key, fixture:player:kind |
An event carries no price, no multiplier, no weight, no payout. Attach a coefficient to it and the product stops being a market on a trajectory.
Row-level security is on with no policy: the table is read and written by the server alone. A client never touches it.
The source is an API. Never a user.
A fake goal posted by a holder moves a real market holding real money. Only the automated importer writes facts.
Guardrails, all enforced in the importer:
- Finished matches only (
FT,AET,PEN). A goal reversed by VAR after the fact becomes a false marker, and a marker does not retract cleanly. - Deduplication by provider id,
fixture:player:kind, never by name. Re-running the import over the same dates creates no second marker. - A player absent from the catalogue is skipped, silently. The event importer never creates a profile, and never creates a market.
- A request budget per run. The stop is clean and resumable.
If a user-authored feed ever ships, it lives visually apart from facts, without exception.
Scope
In: goals (own goals excluded) and red cards.
Everything else is out, deliberately:
| Out | Reason |
|---|---|
| Injuries, transfers | Building more before people click is building the wrong thing |
| Starting line-ups | 38 a season drown the curve. The one that carries meaning, a first professional start, is not served by the provider. The SQL enum keeps first_start reserved |
| Trophies, call-ups | The provider returns empty in practice. Another source answers this, not this one |
| Own goals | Not a performance by the scorer |
The daily pulse
One pass a day, 04:30 UTC, on a scheduled job protected by a shared secret.
Cost, measured: the provider accepts 20 fixtures per request and returns events, line-ups and statistics together. One request lists a day's fixtures worldwide, filtered down to the followed leagues; one request per batch of 20. A full day costs 2 requests. Quota is not a constraint.
Manual catch-up runs the same code path over an explicit date range.
Facts and calls
The chart carries two kinds of marker, both informational:
- Facts: a goal, a red card, a market opening. Sourced from the provider.
- Calls: a dated position taken by a named scout, showing what they held at that moment and whether they still hold it. A scout who sold everything is shown as having sold everything.
A call is a receipt, not a recommendation.
The distance between a dated call and a dated fact is the measurement that separates luck from sight. It is what a scout's record is built from.
Coverage
The provider covers major competitions well, and academies, college divisions and lower tiers thinly. A profile with no public data carries no marker.
That is consistent rather than missing: a talent nobody measures is, by definition, unpriced.
The line
A product that pays out on a sporting result is a bet on a match, and is regulated as one. There is no if he scored → +x %, no payout indexed on a result, no settlement, no oracle in the pricing path.
price = supply² / 720,000,000. Full stop.