# The prompt behind TradeOS Honest answer first: there wasn't one. This grew over months, across dozens of sessions, driven mostly by bug reports from the two people using it. Anyone hoping to paste one prompt and get this back will be disappointed. But the question is still worth answering, because almost everything that went wrong was a **definition** problem, not a feature problem. The model can write screens all day. What it gets wrong — silently, and in a way you only notice weeks later when a number looks odd — is what the numbers mean. So this is the brief I'd write if I were starting today. It's short on features and long on definitions, deliberately. --- ## The prompt Build me a trading journal for one person. Not a product, no customers, never more than a handful of users. It runs on my own machine or a small server. **Before you build a single screen, lock down these definitions. Getting them wrong is how this fails silently.** **R is the unit.** One R is a fixed amount of money I set once in settings — not the risk I happened to take on a given trade. A trade that made twice that unit is +2R whether I sized it large or small. This is deliberate: if R means "a multiple of whatever this trade risked", the measure rescales itself to the size taken and oversizing becomes invisible. A trade four times too large that lost must read −4R, not −1R. **An outcome has four states, not three.** Win, loss, scratch, and not yet scored. The fourth matters most: a trade still running has no result, and treating that as zero makes it read as a deliberate break-even. One function decides this, everywhere. Nothing else is allowed its own opinion about what a win is. **Live, paper and backtest are separate.** Reports must never mix them. **A trading day is not a calendar day.** Everything happens in exchange time; I read it from a different timezone. Session boundaries and daily grouping follow the exchange, not UTC. **Three rules that prevent the bugs you will otherwise write:** 1. A field that cannot say "not answered" will say something else, and that something gets counted. Every judgement field needs an unanswered state, and it must be excluded from both numerator and denominator. 2. A screen never writes a field it does not show. If an edit form posts `field: null` for something it has no input for, it silently erases data on every save. 3. Each statistic is computed in exactly one place. Two functions that both calculate win rate will disagree within a month. **Tests should scan, not list.** A test built from a hand-written list of fields only catches what I already thought of. Write tests that walk the routes and screens themselves and assert a property — then a file added next month is covered without anyone remembering. And give every scanning test a check that proves it saw something, or a scanner that matches nothing will report a clean sweep. **Comments explain why, not what.** When you make a non-obvious choice, write down the failure it prevents. Build the smallest thing that lets me log a trade and read back my win rate, profit factor and expectancy honestly. Then stop and show me. Do not build every screen before I have used one. --- ## Two things worth knowing if you try this **The definitions above are not guesses — each one is a bug that happened.** R was a multiple of per-trade risk at first, which meant the one thing I most wanted to catch (taking too much size) was the one thing the journal could not see. The missing fourth outcome state turned open trades into break-evens. The `null`-on-save problem cost data twice before it got caught and locked down with a test, which then immediately found four more places doing the same thing. **Expect the useful work to come from use, not from prompting.** The features were the easy half. The half that made it trustworthy came from someone logging real trades and saying "this number is wrong" — then tracing why.