Trade Bot Dictionary · Space

launch_anchor

launch_anchor is a master switch wired to the world's rocket launch schedule. Every three hours we pull the list of upcoming launches — who's flying, what rocket, when, and whether the time is confirmed — and you pick a condition off it: "only when a SpaceX launch is within 7 days", "only when any launch is confirmed-Go within 3 days". While your condition holds, the bot trades. While it doesn't, the bot places no trades at all that cycle, in any market. It gates the whole bot, not just space markets.

Bots using it
1 (out-of-sample; none live)
Data source
Launch Library 2 · thespacedevs
Refresh
Every 3 hours (0 */3 * * *)
Rows stored
63 upcoming launches forward-looking only
Backtest-replayable
No — see catch #10
Anchor module
quants/launch_anchor.py

That is the tidy version, and it is the version the builder sells you. Here is what we found when we followed the wires, and it is the least flattering thing in this dictionary so far: the one bot built on this signal has placed 93 trades, and 85 of them have nothing to do with rockets. They are crypto token launches — "Will Base launch a token by December 31, 2027?", "GRVT FDV above $500M one day after launch?" — reached because the bot picks markets by looking for the word launch in the title. Meanwhile the rocket gate that is supposed to be the whole idea has been open on every single one of the 62 days the bot has been running.

A switch that is always on is not a switch. This page is mostly about what that means, and what the signal would need in order to be worth using.

How launch_anchor gets from the Launch Library launch schedule to a trade decision, what its only bot actually bought, and how far our stored copy of the schedule has drifted from the live feed The top band traces the data path. The source is Launch Library 2, run by thespacedevs, at ll.thespacedevs.com — free, no key, no account, with a free tier of roughly fifteen requests an hour. For each upcoming launch it returns the provider, the rocket, the scheduled time called NET, a status abbreviation such as Go, TBD or TBC, and a net_precision field saying whether that time is accurate to the second, the minute, the hour, the day or only the month. Our poller, predictive slash space underscore launch underscore poller dot py, runs on a cron of zero star slash three, meaning every three hours. It requests the next fifty launches, keeps the provider, rocket, time and status, and discards net_precision entirely. It is currently dead: its last eleven consecutive runs have all died with a SQLite database-is-locked error, and the newest successful write is from 21:00 UTC on the ninth of August 2026. Two hundred and forty-six runs have crashed that way in the poller's lifetime against two hundred and sixty-five successes. It writes to the space_launches table in predictive.db, which holds sixty-three rows. Forty-seven of those sixty-three have a time of exactly midnight, and forty-four of them pile onto month-end dates — twenty on the thirtieth of September alone — because that is how the feed encodes "sometime this month", a distinction we threw away. Twelve of the sixty-three have not been refreshed since before the ninth of August; the oldest was last touched on the first of July. The gate function in quants slash launch underscore anchor dot py asks a single question: is there any row whose scheduled time falls between now and now plus your chosen number of days, and which matches your optional provider, rocket and status filters. There is no freshness check of any kind. Pass means the bot scans markets as normal; fail means the bot places no trades at all that cycle. An empty table fails closed, but a stale table full of future-dated launches fails open. The bottom left panel shows what the only bot using this signal actually bought. Of ninety-three fills, eight were about rockets — all of them SpaceX Starship flight tests. Twenty-seven were markets asking whether a crypto project will launch a token by some date. Fifty-five were markets asking whether a crypto token's fully diluted valuation will exceed some figure one day after its launch. Three were about whether OpenAI will launch a consumer hardware product. That is eighty-five of ninety-three, or ninety-one percent, with no connection to rockets at all. The bottom right panel compares our stored copy of the schedule against the live feed as read at 08:30 UTC on the eleventh of August 2026. Of our six nearest launches, five are now wrong. We show a Long March 7A as Go when it in fact failed. We show a Starlink mission on the tenth of August when it has slipped to the eleventh. We show an H3 rocket as Go when it has already flown successfully. We show a Zhuque-3 as Go for the tenth of August when it has slipped three weeks and reverted to month-only precision. We still hold a Starlink mission that flew on the eighth of August and should have been deleted. Only the sixth row, a Starlink mission on the twelfth of August, is approximately right — and that single row is the one currently holding the bot's gate open. The bottom strip shows the duty cycle. A real launch occurred within three days on sixty-one of the bot's sixty-two live days, and the engine produced trade candidates on all sixty-two of them. SOURCE POLLER TABLE GATE DECISION Launch Library 2 ll.thespacedevs.com free · no key · ~15 req/hour PER LAUNCH IT RETURNS provider · rocket net (scheduled T-0) status Go / TBD / TBC net_precision SEC · MIN · HOUR · DAY · MONTH fetched, then thrown away → catch #5 space_launch_poller predictive/ 0 */3 * * * 8×/day asks for next 50 only upserts · never re-reads rows that drop out freeze ✕ DEAD — db locked 11 runs in a row failed 246 crashes lifetime last write 9 Aug 21:00 UTC space_launches predictive.db 63 rows upcoming only · no history 47 at exactly midnight 44 on month-end dates 12 stale > 2 days month-end pile-up 30 Sep ×20 31 Aug ×10 launch_anchor.py quants/ is any row's T-0 between now and now + N days, matching provider / rocket / status? NO freshness check of any kind → catch #4 empty table → closed stale table → OPEN PASS bot scans all its markets as normal FAIL no trades at all this cycle, any market whole-bot switch WHAT THE ONE BOT ACTUALLY BOUGHT 93 fills, picked by title_contains: ["launch"] 8 rockets (8.6%) 8 SpaceX Starship flight tests 27 "Will X launch a token by …?" 55 "X FDV above $N one day after launch?" 3 "Will OpenAI launch consumer hardware?" 85 of 93 fills (91%) have nothing to do with rockets OUR TABLE vs THE LIVE FEED · 11 AUG 08:30 UTC LAUNCH WE STORED ACTUALLY Long March 7A 10 Aug · Go FAILED Starlink 10-19 10 Aug 14:49 11 Aug 14:54 H3-22 Michibiki 7 10 Aug · Go already flew Zhuque-3 Flight 2 10 Aug · Go 31 Aug · TBD Starlink 17-38 8 Aug · Success not pruned Starlink 17-49 12 Aug 02:00 12 Aug 04:46 5 of our 6 nearest rows are wrong — and the 1 that isn't is holding the gate open HOW OFTEN IS THE SWITCH ON? · 11 JUN – 11 AUG 2026 Days a real launch occurred within 3 days 61 / 62 98.4% Days the engine produced trade candidates 62 / 62 100% Engine runs that produced candidates 16,737 / 17,426 96.0% 6.4 real launches per week, worldwide 4 days longest gap between launch days 65 launches in the 71-day window 0 days the gate is known to have shut
Every figure here was read from production on 11 August 2026. The launch counts on the bottom strip come from Launch Library's own historical endpoint, fetched from the production host; the candidate counts come from the bot's run records in quants.db. The right-hand panel is a direct comparison of our stored rows against the live feed at 08:30 UTC that morning.

Where the data comes from

One place: Launch Library 2, the open launch database run by The Space Devs. It is free, needs no key and no account, and the free tier allows roughly fifteen requests an hour — which is why we poll every three hours rather than every five minutes. The exact call is https://ll.thespacedevs.com/2.2.0/launch/upcoming/?limit=50, made by predictive/space_launch_poller.py on cron 0 */3 * * *, landing in the space_launches table in predictive.db.

For each of the next fifty launches the feed gives a provider ("SpaceX", "Arianespace", "China Aerospace Science and Technology Corporation"), a rocket ("Falcon 9", "Electron", "Starship"), a scheduled T-0 called net — "no earlier than" — and a status. We keep those four. The status is stored as the feed's short code, and the ones that actually appear in our table are Go, TBC, TBD and Success. In the feed's own words, Go means "current T-0 confirmed by official or reliable sources". Hold on to that sentence; catch #9 is about what it does and does not promise.

There is a fifth field, net_precision, and we throw it away. That is catch #5.

Two things the registry gets wrong about this signal

Our own quants/signal_registry.py is the tool that resolves every signal's provenance from the code rather than from anyone's memory, and it reports this one as source: "undocumented" with a poller called db and no cron schedule. Both are artefacts, and both are worth explaining because they will show up again:

And the familiar one: the registry's "live bots" column counts bots whose status is oos or live. Its "1" here is one out-of-sample bot and no live ones — the sixth signal running where that number has not meant what it says.

What it means for your bot

Practically: launch_anchor turns your entire bot on and off on a calendar. It is not a filter that finds space markets for you, and it does not check that the market you are about to buy has anything to do with the launch that opened the gate. It answers one question — "is a launch matching my description scheduled in the next N days?" — and if the answer is yes, every other rule in your bot proceeds exactly as it would have anyway.

That distinction is the whole story of this page, so it is worth being blunt about it. The gate's window is measured from now. The market's outcome is measured from its own resolution date. Nothing connects the two. A bot can be switched on because a Falcon 9 is flying on Thursday, and spend that permission buying a contract that resolves in December 2027. Our one bot does this ninety-one times out of ninety-three.

You configure it three ways, and you must supply at least one of the first three or the gate refuses to open at all:

The catch

Ten of them, worst first. The first three are why we would not build on this signal as it stands.

#1 🔴 The gate is about rockets. The bot is not.

The one bot using this signal, Launch Go Rider, finds its markets with title_contains: ["launch"], which the engine turns into UPPER(title) LIKE '%LAUNCH%'. That is a plain substring search on the market title, and on Polymarket the word "launch" overwhelmingly belongs to crypto.

Of its 93 fills: 27 are "Will X launch a token by <date>?", 55 are "X FDV above $N one day after launch?", 3 are about OpenAI shipping consumer hardware, and 8 are about an actual rocket. Eighty-five of ninety-three — 91% — are markets where a rocket schedule is not merely a weak signal but a completely unrelated one.

This is not the anchor's bug; the anchor did what it was asked. It is what happens when a whole-bot switch is paired with a market filter that was never checked against it. But it means that whatever this bot has been measuring for two months, it has not been measuring launch_anchor.

#2 🔴 The switch has never been observed to turn off.

The bot asks for {any: true, within_days: 3, status: "Go"} — is any launch, anywhere on Earth, confirmed-Go in the next three days? The honest answer is: essentially always.

We measured it two independent ways. From our own engine records: over 17,426 runs since 11 June, the bot produced trade candidates on every one of its 62 days, and in 96.0% of individual runs. From Launch Library's historical endpoint, fetched fresh: there were 65 orbital launch attempts in 71 days — about 6.4 a week — falling on 45 distinct days, with a longest quiet stretch of 4 days. A real launch occurred within three days on 61 of the bot's 62 live days.

Be careful with that 98.4%: it measures "a launch actually happened within three days", which is not the same as "a launch showing status Go was listed within three days". It is a proxy, and it can drift in both directions — a mission can sit at Go and then slip, and a TBD mission can fly. But it points the same way our engine records do, and the two together are as close to a duty-cycle measurement as this signal permits.

The consequence: a gate that is open ~100% of the time is indistinguishable from no gate at all. We cannot attribute any part of this bot's results to launch_anchor, because we have never seen it decline anything. That would take an ablation — the same bot run with the gate forced off — and we have not run one.

#3 🔴 Its own kill rule has fired, and nothing was listening.

Every house bot ships with a pre-registered falsifier — the condition, written before it traded, under which we agreed to retire it. This one's reads: "kill if Go-gated entries settle YES <80% over 20 trades, or avg fill >0.87." It has settled 27 trades at 66.7% YES. The first clause is met, comfortably.

We have a tool for exactly this, quants/falsifier_watch.py, which reads each bot's falsifier and evaluates the machine-checkable part. Run today it flags Launch Go Rider as the only tripped bot of the nine that carry a falsifier. It is also not in the crontab. Nobody has run it, so nobody knew.

This one is a process failure rather than a code defect, and it is a platform-wide finding rather than something peculiar to this signal — but it belongs on this page, because it is the reason a bot whose gate is a no-op has been quietly filling for two months. See the record section below for the complication: by expectancy, this bot is not actually losing.

#4 🔴 The feed is dead, and a dead feed props the gate open.

The poller's last eleven consecutive runs have all died with sqlite3.OperationalError: database is locked — 246 such crashes in its lifetime, against 265 successful runs. The newest row in the table was written at 21:00 UTC on 9 August; this page was assembled at 08:30 UTC on 11 August, so the schedule the gate is reading is 35 hours old. This is the sixth job we have found wedged on the same shared predictive.db write contention, after resolution_buckets, sentiment_poller, eia_poller and tropical_poller.

On its own that would be ordinary bad luck. What makes it a design problem is that launch_anchor_satisfied() has no freshness check of any kind — no FRESH_SECS, no _STALE_DAYS, nothing. Every other anchor we have written up has one. And because launches are stored with future dates, a table that stops updating does not go quiet: it keeps asserting that launches are coming, for days. The docstring's promise, "fails closed if no matching launch", is true only of an empty table. A stale table fails open.

That is not hypothetical. Compared against the live feed this morning, five of our six nearest launches are wrong: we carry a Long March 7A as Go when it in fact failed; a Starlink mission dated 10 August that slipped to the 11th; an H3 that has already flown; a Zhuque-3 we still show as Go for 10 August which has slipped three weeks and reverted to month-only precision; and a mission from 8 August that should have been deleted two days ago but wasn't, because the delete is in the same transaction that keeps crashing. The single row still approximately correct — Starlink 17-49 on 12 August — is, by coincidence, the one row currently holding the bot's gate open.

#5 "Sometime in September" is stored as 30 September, 00:00:00

Launch Library is careful about this and we are not. Every launch carries a net_precision field — SEC, MIN, HOUR, DAY or MONTH — saying how much of that timestamp to believe. Our poller fetches it and never stores it.

The result is that a launch known only to the month arrives as a precise-looking timestamp on the last day of that month. 47 of our 63 rows sit at exactly midnight, and 44 pile onto month-end dates — twenty on 30 September, ten on 31 August, seven on 31 December. A within_days window that happens to reach one of those cliffs does not see one launch; it sees twenty, none of which are real appointments.

For this bot the damage is limited, because month-precision rows arrive as TBD and it filters for Go. Any config without a status filter — including the docstring's own example {"rocket":"Starship","within_days":14} — eats them whole.

#6 A launch that drops out of the top 50 is frozen forever

The poller asks for the next fifty launches and upserts them. It never re-reads anything outside that window, and it only deletes rows whose date is more than two days past. So a launch sitting further out than 50th place keeps whatever schedule and status it had the last time it was inside — indefinitely.

Right now 12 of our 63 rows have not been refreshed since before 9 August, and the oldest was last touched on 1 July, 41 days ago. If one of those has slipped, been cancelled, or already flown, we will not find out until its stale date rolls past and the prune eventually eats it.

#7 Two configs that validate cleanly and can never open

within_days below 1 collapses to zero. The window is built with int(within), so within_days: 0.5 becomes "+0 days" and the gate asks for a launch in the next zero seconds. We ran it: 0.5 returns False against a launch six hours away that 1 accepts. Meanwhile validate_config() explicitly permits floats — it checks isinstance(x, (int, float)) — so the builder tells you the config is fine. Negative numbers pass validation too, and never open.

The status must be the feed's short code, not its name. Matching is exact (both sides upper-cased), so "Go", "GO" and "go" all work — but "Go for Launch", which is what the feed calls that status in plain English and what a reasonable person would type, matches nothing, forever, silently. validate_config() does not check the status against any list of valid values.

#8 The English the builder shows you is broken

Every signal renders itself into a sentence for the builder. Fed this bot's exact live config, the renderer produces: "only when a Go any launch is within 3 days". The any: true case falls through to the literal string "any" and lands in the middle of the sentence.

Small, but this is the copy on the page where somebody decides whether to fork the bot — and it is precisely the config a forker inherits.

#9 "Go" is a statement about the schedule, not about the rocket

The bot's stated thesis is that "a confirmed Go status within 72h is live ops info… so confirmed-Go missions ≤0.85 may be underpriced". But Go means, in the feed's own words, that the T-0 is confirmed by official or reliable sources. It is a claim about whether the countdown is real. It is not a claim about whether the vehicle will reach orbit.

For a market asking "will this rocket launch by date X", that distinction mostly doesn't matter, and the thesis is coherent. For the markets this bot actually buys — will a token launch, what will its valuation be the day after — it is not a signal about anything. Our own table demonstrates the gap: we carried a Long March 7A at Go right up to a launch that failed.

#10 The backtester cannot replay it — and here the excuse is half fair

launch_anchor sits in _UNSUPPORTED_ENTRY in quants/backtest.py. A backtest of a bot using it runs without the gate and still returns a curve, flagging unsupported_rules. If you backtest this bot, you are not testing this signal.

The code's stated reason is that these anchors "need a forward-captured series we don't have retroactively". With energy_anchor we said that excuse was simply wrong, because the vendor serves decades of history on the endpoint we already call. Here it is half right, and the distinction matters. Launch Library does keep history — 7,586 past launches on the same free API — so a gate written purely on provider, rocket and within_days could be replayed today. But a historical row records the outcome (Success, Failure) and the time it actually flew, not the Go-or-TBD status it was showing three days beforehand. This bot's gate is keyed on exactly that status, and that as-of view is genuinely gone unless we start storing it. Half of this signal is replayable now; the half this bot uses is not.

The real record

Launch Go Rider (id 43, house bot, status oos) has been armed since 11 June 2026. It buys YES between 40¢ and 85¢ on markets with the word "launch" in the title and at least 1,000 contracts of 24-hour volume, $5 flat, at most 3 fills a day, holding to expiry. It is configured for both Kalshi and Polymarket; all 93 fills are Polymarket.

11 Jun – 11 Aug 2026SettledAvg entryYES ratevs break-evenP&L
All settled trades2766.1¢66.7%+0.6 pp+$3.82
Rocket markets (Starship)664.2¢50.0%−14.2 pp−$8.03
Everything else2166.7¢71.4%+4.7 pp+$11.85
Still open (not counted above)6661.3¢$330 staked

Read the "vs break-even" column, not the YES rate. A binary bought at 66.1¢ needs to settle YES 66.1% of the time just to stand still — so a 66.7% hit rate is not a two-thirds success story, it is six-tenths of a percentage point of daylight. On $135 staked that is +$3.82, and our own falsifier_watch puts the expectancy at +$0.14 per trade with a spread of ±$1.53 — statistically indistinguishable from zero.

Do not read the rocket row as "rockets lose". Those six settled trades are not six bets. They are one rocket seen six ways: every one is SpaceX Starship Flight Test 13, bought at six different deadlines — will it fly by 15 July, by 20 July, by 23 July, by 25 July, by 26 July, by 31 July. Starship Flight 13 flew successfully at 22:51 UTC on 24 July (confirmed against Launch Library's historical record), which settled the first three NO and the last three YES. It is a single event, and a sample of one tells you nothing about whether the launch thesis works. What it does tell you is that in two months of running, the bot found exactly one real rocket story to bet on.

Also note the shape of the book: 66 of the 93 fills are still open, most of them in token markets resolving in 2027. Just under a third of this bot's history has actually settled. The +$3.82 is a real number about a small, unfinished, and mostly-not-about-rockets sample.

The case for the defence

In fairness to the bot, and against our own headline: it was created as an explicitly "lowest-confidence cheap experiment", it is out-of-sample and has never touched a live account, and by expectancy it is very slightly up rather than down. Its falsifier trips on a hit-rate threshold of 80%, which at an average entry of 66¢ was never the right bar — a 66.7% hit rate at those prices is roughly break-even, not a failure. If you retired it today you would be retiring it for missing a target that was mis-specified when it was written.

And "crypto token launch" markets are, linguistically, launches. If the bot were honestly described as "buy YES on launch-ish markets in the 40–85¢ band", its behaviour would match its label and it would be an unremarkable little momentum bot. The problem is not that it does something incoherent. The problem is that the thing it does has no relationship to the signal on the tin — and it is the tin that gets forked.

How to actually use it

Never pair it with any: true and a short window. That is a constant, not a condition. If you want the gate to mean something, name a provider or a rocket: {"rocket": "Starship", "within_days": 7} is a genuine question, because Starship flies a handful of times a year. {"any": true, "within_days": 3} is the string "true" with extra steps.

Make sure your markets are about the launch you gated on. Nothing in the platform enforces it, and title_contains: ["launch"] will hand you the entire crypto token calendar. If you mean rockets, say so — title_contains: ["STARSHIP"] or ["SPACEX"] — and accept that you will find very few markets, because there are very few.

Watch the resolution date, not just the price. This anchor's window starts now. A market resolving in eighteen months cannot be informed by a rocket flying on Thursday, no matter how confidently the gate opens. The signal is only meaningful on markets whose own deadline sits near the launch.

Use whole numbers for within_days, and the short code for status. Because of catch #7, 0.5 and "Go for Launch" both produce a gate that is silently welded shut.

Treat a quiet table as suspect, not as calm. Until the anchor learns a freshness rule, the only way to know whether the schedule is current is to look at when the poller last wrote. A gate that is open because the feed died looks exactly like a gate that is open because a rocket is flying.

Where to go next

eco_anchor is the closest relative — the other pure calendar gate, and the other signal whose value is entirely "is it that time yet". It is the interesting contrast, too: eco_anchor's window opens for about 1% of the clock, this one's for roughly all of it, and neither number is obviously the right one. tropical_anchor is the mirror image of this page's failure: another switch on a live event feed, another dead poller on the same locked database, but one whose bot has never traded at all rather than trading the wrong thing. energy_anchor is where the backtest-history argument in catch #10 gets its harder version.

If you want the signal this one is often confused with: there isn't one. Rockets are the only space data in the library, and launch_anchor is the only gate that reads it.

Written 11 August 2026. Every number on this page was read from production that day — the live host at /var/www/tinycorp.ai, not a local mirror: the output of quants/signal_registry.py, the source of quants/launch_anchor.py and predictive/space_launch_poller.py, the live crontab and the poller's log, read-only queries against space_launches in predictive.db and the bot's run and trade records in quants.db, a run of quants/falsifier_watch.py, and Launch Library's own upcoming and historical endpoints fetched directly from that same host. The gate behaviours in catches #7 and #8 were confirmed by running the real anchor functions against synthetic in-memory rows — no production data was written. Two things the registry reports about this signal are wrong and are corrected above: the poller resolves as db with no schedule, and the source resolves as "undocumented" when the poller's docstring names Launch Library outright. Its "live bots" column counts status oos and live together, so the 1 it reports is one out-of-sample bot and no live ones — the sixth signal running where that count has not meant "live". All TinyCorp bots trade simulated money. Nothing on this page is a projection.