Trade Journaling as Code: The Structured Log Format I Use for Every Trade
Trade Journaling as Code: The Structured Log Format I Use for Every Trade
Most trade journals are diaries. This one is a plain text file that fits every trade on a single line — timestamped, grade-tagged, and queryable with grep and Python. Here is the exact format, the parser, and the four ways it still fails.
Section 3 of Reading Charts After a Decade of Reading Code introduced the idea that trading logs benefit from the same constraints as git commit messages — one imperative line, no prose, structured. That post argued why. This post shows how, in enough detail that you could open a text file after reading and start logging today.
The claim is narrow and empirical. Over the last two years, the diary-style journal I kept was invisible to me the moment I stopped looking at it. The structured log I keep now — plain text, seven columns, one line per trade — has surfaced patterns I would not have found in prose, most of them uncomfortable. The tooling is negligible. The discipline is the entire product.
💡 Core idea: A trade log's format decides what patterns you can see. Free-form prose hides patterns behind mood. Structured plain text surfaces them — and stays legible five years from now, on a machine that does not exist yet, in an editor that has not been written.
- Why plain text beats every journaling app I have tried
- Anatomy of a single log entry — the seven fields, in order
- Turning the log into statistics — grep, awk, and a small Python parser
- The monthly review cadence that actually gets done
- Reality Check — where the structured log still fails
1. Why Plain Text Beats Every Journaling App I Have Tried
Over the last decade I have tried, in order, three commercial trade journaling apps, two spreadsheet templates, one Notion database, and one custom-built SQLite frontend that I wrote on a weekend. All of them are gone. The plain text file I started keeping in mid-2024 is still open in a tab as I type this. There is a reason.
Every journaling app makes the same three implicit promises: (a) capture will be fast, (b) analytics will be built-in, (c) the data will be portable if you ever leave. In practice, one of those promises breaks within six months. Capture becomes slow because the app requires seven clicks and a category dropdown before a trade can be saved. Analytics become misleading because the app's expectancy formula does not match yours. Data becomes trapped because the "CSV export" is an incomplete CSV export.
🧾 The three engineering properties I actually want: capture in under ten seconds, queryable with tools I already own (grep, awk, Python), and portable to any future machine because the format is bytes. Every commercial app fails at least one of these. A plain text file passes all three by default.
There is a fourth property no app can offer: the log outlasts the tool. Every journaling app I have used shut down, changed pricing, or migrated to a new schema that broke my old exports. A UTF-8 text file will open in vim, VS Code, TextEdit, Notepad, and every editor written between now and the heat death of the sun. If the trade journal is meant to be the memory of your trading career, the memory must be stored in a format that outlives every specific piece of software.
2. Anatomy of a Single Log Entry — Seven Fields, in Order
One line per trade. Seven fields, separated by two spaces (chosen because two-space is uncommon inside any single field, so an awk split on " " is unambiguous). Every field is required. Missing data is written as a literal dash -, never left blank, because grep-ability is downstream of format consistency.
Each field, and why it is there:
| # | Field | Why |
|---|---|---|
| 1 | ISO 8601 UTC timestamp | Sortable, unambiguous across time zones, no DST bugs |
| 2 | Instrument | Filterable per market; separates correlated exposures later |
| 3 | Setup grade (A+ / A / B / B+) | Enables per-grade expectancy analysis (see Section 3) |
| 4 | Thesis in ≤ 8 words | Forces the reason to be nameable; if it does not fit, the trade is probably too complex |
| 5 | Entry price | Ground-truth reference for slippage analysis |
| 6 | SL / TP prices | Fixes 1R and target R at entry — retroactive dispute impossible |
| 7 | Outcome — PASS/FAIL ± R | Single scalar per trade, aggregation-friendly, no ambiguity |
The R-multiple in field 7 is the entire reason the log becomes analytically useful. 1R is fixed at entry by fields 5 and 6, so the outcome expressed in R normalises across instruments and account sizes exactly as described in The Position Sizing Framework. Without the R column, the log is a diary of dollars. With it, the log becomes a distribution you can study.
2026-07-16T15:07Z MNQ B long 15m CHoCH, no HTF context @ 27620, SL 27590, TP 27710 → FAIL -1.0R
2026-07-17T08:41Z ES B+ short LDN close sweep, weak follow @ 5480, SL 5495, TP 5450 → FAIL -0.8R (early exit)
2026-07-22T14:15Z MNQ A+ long FVG mitigation, 5L confluence @ 28100, SL 28000, TP 28380 → PASS +2.8R
The parenthetical trailing note on the ES line ("early exit") is the one prose field allowed, and its length is deliberately constrained by the two-space separator: anything longer will visually break the column alignment, which is itself a signal that the exception deserves a longer note in a separate file, not a bloated log line. The log is a summary index, not a full narrative.
3. Turning the Log Into Statistics — grep, awk, and a Small Python Parser
Because the log is structured plain text, the query layer is whatever you already know. The three tools I use are ranked by frequency of use, from most to least.
① grep — filter first, always
"How many A-grade trades did I take last month?" is grep -c " A " journal.log. "How many losing MNQ trades were labelled B?" is grep "MNQ B" journal.log | grep "FAIL". Any question that starts with "how many" answers in one line.
② awk — sum before Python
Awk parses the R-multiple column and adds it. Total realised R for the year is awk '{r=substr($NF,1,index($NF,"R")-1); s+=r} END{print s}'. Ugly on paper, unbeatable in a terminal. Ninety percent of my monthly review sits in awk one-liners.
③ Python — only when I want a distribution
Python enters when the question is a shape, not a scalar. "What is the expectancy per grade?" is the shape question I run once per month. The parser is about forty lines and lives in the same folder as the log.
🔼 Figure 2: forty lines of Python replace every journaling app I have ever paid for. The stats are the same. The data stays mine.
The parser reads the log line-by-line, splits on the two-space separator, extracts the grade and outcome fields, and groups by grade. Per-grade statistics come out as a small table: sample size, win rate, average winning R, average losing R, expectancy in R. That table is the entire monthly review artefact — everything else is prose about the table.
🧮 The one metric that matters: per-grade expectancy in R. Not total P&L. Not win rate. Not maximum drawdown. Per-grade expectancy tells you whether the framework — Volume, structural, session — is still calibrated. When A-grade expectancy drops below +1R sustained, the setup definition has drifted, and every downstream decision is off.
For the mathematical foundation of expectancy and R-multiple thinking, Van Tharp's framing on Investopedia's expectancy overview is the shortest useful reference. The grade grouping in my parser is the discretionary layer on top of that math — the specific setup taxonomy comes from the Institutional Volume Framework.
4. The Monthly Review Cadence That Actually Gets Done
The best journal in the world is worthless if the review never happens. Everything I have described above optimises for the review being possible in thirty minutes at the end of the month — because that is the only cadence I have ever sustained past three months.
Minutes 0–5: run the parser, print the per-grade expectancy table, save the output as reviews/2026-08.txt.
Minutes 5–15: compare this month's expectancy against the trailing three-month average. Any grade whose expectancy dropped by more than 0.5R gets a note in a plain text file, one sentence.
Minutes 15–25: pull every FAIL that had a positive thesis but a losing outcome. Look for the same word appearing across losses — "chased," "no HTF," "news-adjacent," "reduced size." The recurring word is the pattern.
Minutes 25–30: write one sentence describing what will be different next month. If nothing changes, write "no change — pattern stable."
The single-sentence rule at the end is deliberate. A five-paragraph resolution I will not implement is worse than "no change — pattern stable," because the five-paragraph version fools me into thinking action was taken. A structured log deserves a structured resolution. Everything longer than one sentence belongs to a separate file — the log is the index, not the essay.
5. Reality Check — Where the Structured Log Still Fails
Structured logging is a necessary condition for honest review, not a sufficient one. Four failure modes I have hit personally, in the order I hit them.
① Retroactive editing to make losses look better
A structured log is not honest unless the entry is written before the outcome is known. Adding the thesis after a losing outcome contaminates the very field the review is supposed to check. My rule: fields 1–6 are typed before the order is submitted. Field 7 is appended at close. Any edit after close requires an inline dashed note explaining the correction — no silent rewrites.
② Grade inflation over time
Six months of A-grade setups that "obviously deserved A" is often three months of A-grades and three months of B-grades relabelled A because the trader wanted the higher risk band. Grade inflation is invisible until per-grade expectancy collapses — which is exactly what the monthly review is checking. If A-grade expectancy is drifting downward for three months in a row, the grade definition has drifted, not the market.
③ Missing trades — the trades you took but did not log
Every log I have kept has had gaps corresponding to trades I preferred to forget. The gap is itself the signal — a losing trade skipped in the log is exactly the trade the review needs. Cross-reference with the broker statement monthly. Any trade in the broker record that is not in the log gets appended with a dashed note. This is the single least fun part of the review and the single most useful.
④ Confusing correlation with causation across grades
A-grade expectancy being +2R last quarter does not mean A-grade will remain +2R next quarter. The market regime that rewarded a specific confluence stack may have changed. The log is descriptive of the past, not predictive of the future. Treating per-grade expectancy as a forward-looking probability is the exact mistake documented as Lesson 5 in Five Painful Lessons.
The four failure modes are not reasons to abandon the log. They are reasons to keep the log and keep the assumption bar low about what the log tells you. Structured data is a superior substrate for honesty. It does not create the honesty.
Trading logs kept as prose read beautifully and teach nothing. Trading logs kept as code read like a spreadsheet and, over years, teach the only things worth learning — that the setups you thought were A were often B, that the market regime that rewarded you last quarter is not this quarter's regime, and that the pattern you kept avoiding in the log was the pattern that mattered most.
📚 Related Reading on This Blog
The log sits between the framework upstream and the review downstream. The pieces around it:
- Engineering Discipline Shapes My Trading — Section 3 introduces why the git-log format matters
- The Position Sizing Framework — where 1R is fixed at entry and appears in log field 6
- The Institutional Volume Framework — the taxonomy that produces the grade tag in field 3
- Five Painful Lessons — the patterns a structured log surfaces after months, not moments
- Kill Zones Decoded — the session tag that becomes an implicit filter in the thesis field
⚠️ Disclaimer: This article is for educational and informational purposes only and does not constitute financial, investment, or trading advice. Trade journaling formats and review cadences should be adapted to individual circumstances, tax jurisdiction, and risk tolerance. Trading involves substantial risk of loss. Always consult a licensed financial advisor before making investment decisions. Read the full disclaimer →
About the Author
Dongmin Park is a software engineer with over 15 years in embedded systems (automotive and defense industries) and 10+ years of active trading across Korean equities, US options, MNQ futures, and crypto. He started trading on a Kiwoom Securities account in Seoul in 2016 and now lives in Ingolstadt, Germany, after relocating in 2022.
Coder Trader is an ongoing project to document where systematic engineering discipline meets discretionary trading. Say hi on X, look at the code on GitHub, or email hello@codertrader.com.


Comments
Post a Comment