Trading journal — spreadsheet, statistics and performance review
A complete guide to building a journal spreadsheet in around 20 minutes (an indicative time for someone familiar with spreadsheet basics; the first import and data checks may take longer): 26 columns with technical names consistent with article 15.9, row formulas and a dashboard of nine metrics in two variants (Polish and English Excel; cloud spreadsheet settings are covered below), plus a starter CSV file generated in your browser. You can download the ready-made XLSX or build the spreadsheet yourself using the full instructions below. Learning the formulas helps you understand the calculations and fix them yourself; thanks to the shared column names, a CSV export from this journal, with the correct delimiter, encoding and date format selected, works with the ready-made S1–S3 script from add-on I and the script from prompt P5; audits P6–P7 require two additional columns (below).
- 26 columns in five groups: identification, context, plan vs execution, costs and results, process — with formulas only where figures are derived from other fields (slippage, r_net, execution_drag)
- A dashboard of nine formulas: trade count, win rate, profit factor, expectancy, total R, maximum drawdown in R, average MAE/MFE, clean execution rate — performance metrics calculated from r_net and process metrics from separate columns; the scope of MAE/MFE is explained below
- Two formula variants: Excel PL (ŚREDNIA, LICZ.JEŻELI, semicolons) and Excel EN (AVERAGE, COUNTIF, commas) — a switch and copy buttons for each block
- Metrics describe the sample from the first entry: around 50 trades is an example review point used in the course, not a universal minimum or proof of an edge. Conclusions depend on dispersion, dependence between results and the test plan. Limit breaches or data errors require an immediate response; changing strategy rules requires a separate hypothesis and validation
Ready-made XLSX journal
Download the trading journal — XLSX EN
The file has three sheets: Statistics, Journal and Instructions, 999 prepared rows, and formulas for net P&L, R, slippage and drawdown. Columns A–Z retain the format described below; the file also includes AA–AC (self-assessment from 15.9), AD (notes), AE–AF (equity curve and drawdown) and AG (clean execution) — CSV exports for the scripts cover A:Z. Yellow cells accept data; do not overwrite calculated columns with a broker export. If swap or commission is genuinely zero, enter 0 — missing data remains missing.
The examples in this guide do not feed into the file’s statistics. Drawdown includes the starting point of 0 R: an initial loss of −1 R produces a drawdown of 1 R. Arrange trades chronologically by closing time; keep a consistent order when closing times are identical. Do not sort column C alone — the fields of each record must stay together. After reordering rows, check that AE/AF still accumulate from row 2. The additional helper column coded_clean does not treat a blank error code as clean execution.
The spreadsheet shows average MAE and MFE for all entered measurements (including zeros), while additional variants for analysing winners and losers remain below. The file calculates profit factor in R, rather than in the account currency. Fill in planned P&L in column T only for the same type of exit: compare a planned SL with an executed SL, and TP with TP. Leave it blank for an exit with no equivalent.
The PL version uses PLN in its *_pln fields. The English version has the same column order and neutral monetary field names without the _pln suffix; you specify the account currency in its instructions. When transferring CSV files between languages, map the headers and check the currency. Changing the currency label alone does not convert any values.
Ready-made spreadsheet or build your own
- Two routes to the same journal: the ready-made XLSX contains visible formulas, and the full guide lets you recreate the spreadsheet yourself. The file has no macros or broker connection. The starter CSV is still generated locally in your browser. You will find the file version on the Instructions sheet (currently 1.2, dated 21 September 2026; the article has a separate version number).
- You know a spreadsheet you build yourself inside out: when a formula returns an error years later (a new pair, a different export format), it is easier to identify the cause because you know what it calculates. A “magic” template breaks silently — and a journal that lies is worse than no journal.
- Column names are shared throughout the course: the headers come from the mini CSV specification in 15.9 (the spreadsheet covers around 20 of the 29 numbered logical fields in 15.9 — missing fields are listed under Sources), and the same names are expected by the ready-made S1–S3 script from add-on I and the script from prompt P5; audits P6–P7 in the AI workshop also need a plan-compliance status and a state note — add these: status = “plan” for error_code 0, “breach” for codes 1–9, and either omit rows with code 10 (infrastructure) from the P6 export or label their status “infrastructure” and explain this in the prompt; derive the state note from the self-assessment fields (AA–AC). One format, minimal data translation between tools.
- The cloud is convenient, but these are account data: position sizes, results, process errors. Make a deliberate choice between cloud and local storage — use the same criteria as when pasting data into AI models (the data hygiene section in add-on H).
Structure: 26 columns in 5 groups
The column letters (A–Z) match the layout used by the formulas below — if you change the order, update the references. Keep the technical headers in English: this allows the CSV export to work with the P5 script without mapping. You can add three self-assessment fields (mental_state, sleep_hours, decision_quality from 15.9) as optional columns AA–AC (already included in the file) — the formulas do not require them.
| Col. | Header | Group 1: identification | Example |
|---|---|---|---|
| A | trade_id | sequential number or platform ID | 2026-041 |
| B | open_time_utc | opening date and time in UTC — MT4/MT5 exports use the broker’s server time (e.g. GMT+2/+3 — check the broker’s specification); convert from the server time zone (15.9); format YYYY-MM-DD HH:MM | 2026-07-08 07:42 |
| C | close_time_utc | closing date and time in UTC (as in B); an actual date/time value in the spreadsheet, not text. Blank = open trade, excluded from the metrics; an invalid date or a close earlier than the entered opening time produces no R | 2026-07-08 13:15 |
| D | pair | instrument — 6 characters without a separator or broker suffix (EURUSD, not EUR/USD or EURUSD.m); the pip formula applies only to FX pairs (a pip is 0.0001, or 0.01 for JPY pairs — identified by the ending); for other instruments, enter the pip size from the specification and change the multiplier | EURUSD |
| E | direction | long / short (lowercase — the slippage formula compares text) | long |
| Col. | Header | Group 2: context | Example |
|---|---|---|---|
| F | setup | setup name from the playbook (add-on E) | asia-london-breakout |
| G | setup_class | A+ / A / B / C — playbook class at entry; the list in the file follows 15.9. Do not assign a class based on the subsequent outcome | A+ |
| H | session | entry session (Asia / London / NY / overlap) | London |
| Col. | Header | Group 3: plan vs execution | Example |
|---|---|---|---|
| I | planned_entry | planned entry (recorded BEFORE placing the order) | 1.0850 |
| J | actual_entry | actual fill from the platform | 1.0852 |
| K | planned_sl | planned stop-loss | 1.0820 |
| L | planned_tp | planned take-profit | 1.0910 |
| M | actual_exit | actual closing price | 1.0907 |
| N | spread_pips | spread at entry | 0.7 |
| O | slippage_entry_pips | formula — entry slippage in pips, positive = worse fill | 2.0 |
| Col. | Header | Group 4: costs and results | Example |
|---|---|---|---|
| P | swap | signed swap amount in the account currency (a cost is negative) | −3.20 |
| Q | commission | commission as a non-negative cost; 0 if there is no commission. Convert a negative cost in the broker’s export to a positive value so the formula does not add it to profit | 7.00 |
| R | broker_gross_pnl | gross P&L from the platform: after spread and price execution, before swap and commission | 201.67 |
| S | broker_net_pnl | formula (or enter manually if the broker reports net P&L) | 191.47 |
| T | planned_gross_pnl | planned P&L for the same type of exit (amount): planned TP for a TP exit, planned SL for a stop exit; leave blank for a manual or time-based exit — the file then leaves W blank, while 15.9 calculates drag as the sum of entry slippage, commission and swap in R: (O × pip value + Q − P) / U, where swap P retains its sign (negative = cost) — calculated manually, outside the formula | 220.00 |
| U | planned_risk | planned risk in the account currency (USD in the examples; distance from planned entry → planned SL in pips × pip value for the planned volume). This is the fixed R denominator for the trade, with no subsequent adjustment to match the loss. It is not a guaranteed maximum loss: gaps, slippage and costs can increase it | 110.00 |
| V | r_net | formula — net P&L in R; the column feeding the performance metrics | 1.74 |
| W | execution_drag_R | formula — the difference between planned gross P&L and actual net P&L in R; it can be negative when the result is better than planned | 0.26 |
| Col. | Header | Group 5: process | Example |
|---|---|---|---|
| X | mae_r | maximum adverse price excursion during the life of the position, in R (definition: 15.9, section 7) | 0.35 |
| Y | mfe_r | maximum favourable price excursion during the life of the position, in R | 2.10 |
| Z | error_code | 0 = clean execution; 1–9 = decision error codes; 10 = infrastructure error (catalogue: 15.9) | 0 |
Row formulas — calculated columns
Formula variant:
Settings: the PL variant uses Polish function names and semicolons; EN uses English names and commas. The delimiter depends on regional settings; in Google Sheets, the function language is set separately. On import, set B/C to date and time, then check =CZY.LICZBA(C2) (EN: =ISNUMBER(C2)): the correct result is PRAWDA/TRUE. Changing the cell’s appearance alone is not enough.
Enter the formulas in row 2 and fill down (or copy them to a range). The ranges extend to row 1000 — for a longer journal, extend the row formulas, validation and every dashboard range, including the completeness checks.
=JEŻELI(ORAZ(CZY.LICZBA(I2);CZY.LICZBA(J2);DŁ(D2)=6;LUB(E2="long";E2="short"));JEŻELI(E2="long";J2-I2;I2-J2)*JEŻELI(PRAWY(D2;3)="JPY";100;10000);"")
=IF(AND(ISNUMBER(I2),ISNUMBER(J2),LEN(D2)=6,OR(E2="long",E2="short")),IF(E2="long",J2-I2,I2-J2)*IF(RIGHT(D2,3)="JPY",100,10000),"")
=JEŻELI(ORAZ(ILE.LICZB(P2:R2)=3;Q2>=0);R2+P2-Q2;"")
=IF(AND(COUNT(P2:R2)=3,Q2>=0),R2+P2-Q2,"")
=JEŻELI(ORAZ(CZY.LICZBA(C2);CZY.LICZBA(S2);CZY.LICZBA(U2));JEŻELI(ORAZ(C2>=1;C2<2958466;U2>0;LUB(B2="";ORAZ(CZY.LICZBA(B2);B2>=1;B2<=C2)));S2/U2;"");"")
=IF(AND(ISNUMBER(C2),ISNUMBER(S2),ISNUMBER(U2)),IF(AND(C2>=1,C2<2958466,U2>0,OR(B2="",AND(ISNUMBER(B2),B2>=1,B2<=C2))),S2/U2,""),"")
=JEŻELI(ORAZ(CZY.LICZBA(V2);CZY.LICZBA(T2));(T2-S2)/U2;"")
=IF(AND(ISNUMBER(V2),ISNUMBER(T2)),(T2-S2)/U2,"")
Dashboard: 9 metrics and how to interpret them
Paste the metrics on a separate sheet (as in the file: prefix each range with the sheet name, e.g. 'Journal'!V2:V1000) or above the table — in that case, the headers move from row 1 and you need to adjust the references. Copying a block gives you several formulas on separate lines; place each in the appropriate cell. AE2, AF2 and AG2 belong on the Journal sheet, not the Statistics sheet.
An empty journal gives N = 0, total R = 0 and maximum drawdown = 0; WR, PF, expectancy and averages without measurements remain blank. PF is also blank when there are no losses, because the ratio then has no finite value. Results in R require net P&L in S, positive U and a numeric date/time in C within Excel’s date range. If B is filled in, it must be a recognised date no later than C. Excel stores dates as numbers; cell formatting neither converts text into a date nor checks whether the time was actually entered in UTC.
File version 1.2 uses Stop-style validation for dates, direction, class, commission cost, risk, MAE/MFE and code. Pasting data can bypass validation — this is why V rejects text dates and non-positive risk, S rejects negative commission costs, and AG accepts only integer codes 0–10. Checks in rows 16–19 of Statistics show entered closes without R, trades with R but no valid code, and invalid MAE and MFE measurements. A date formula returning empty text is treated as a missing close, not an invalid closed trade. Any count above zero needs to be explained before assessing the full sample.
Performance metrics use V. Average MAE/MFE across all entered measurements use a separate sample: they include non-negative numbers, including zero, even when V is still blank. A negative number, text (including “0.5” stored as text), a space or a Boolean value in a measurement column blocks its average until resolved, instead of silently distorting the result. You will find the invalid-cell count in Statistics B18 for MAE and B19 for MFE; an error in one column does not block a valid average in the other. Do not automatically compare their sample sizes with the number of closed trades. Enter non-negative measurements for the same defined period of a position’s life; leave missing measurements blank. The winner/loser variants below select a subset based on V.
Trade count: =ILE.LICZB(V2:V1000) Win rate: =JEŻELI(ILE.LICZB(V2:V1000)=0;"";LICZ.JEŻELI(V2:V1000;">0")/ILE.LICZB(V2:V1000)) Profit factor: =JEŻELI(LICZ.JEŻELI(V2:V1000;"<0")=0;"";SUMA.JEŻELI(V2:V1000;">0")/-SUMA.JEŻELI(V2:V1000;"<0")) Expectancy (R): =JEŻELI(ILE.LICZB(V2:V1000)=0;"";ŚREDNIA(V2:V1000)) Total R: =SUMA(V2:V1000)
Trade count: =COUNT(V2:V1000) Win rate: =IF(COUNT(V2:V1000)=0,"",COUNTIF(V2:V1000,">0")/COUNT(V2:V1000)) Profit factor: =IF(COUNTIF(V2:V1000,"<0")=0,"",SUMIF(V2:V1000,">0")/-SUMIF(V2:V1000,"<0")) Expectancy (R): =IF(COUNT(V2:V1000)=0,"",AVERAGE(V2:V1000)) Total R: =SUM(V2:V1000)
AE2 (curve): =JEŻELI(CZY.LICZBA(V2);SUMA($V$2:V2);"") AF2 (drawdown): =JEŻELI(CZY.LICZBA(AE2);MAX(0;$AE$2:AE2)-AE2;"") Max drawdown (R): =MAX(AF2:AF1000)
AE2 (curve): =IF(ISNUMBER(V2),SUM($V$2:V2),"") AF2 (drawdown): =IF(ISNUMBER(AE2),MAX(0,$AE$2:AE2)-AE2,"") Max drawdown (R): =MAX(AF2:AF1000)
Avg. MAE (all): =JEŻELI(WIERSZE(X2:X1000)-LICZ.PUSTE(X2:X1000)-ILE.LICZB(X2:X1000)+LICZ.JEŻELI(X2:X1000;"<0")>0;"";JEŻELI(ILE.LICZB(X2:X1000)=0;"";ŚREDNIA(X2:X1000))) (as in the file, B11) Avg. MFE (all): =JEŻELI(WIERSZE(Y2:Y1000)-LICZ.PUSTE(Y2:Y1000)-ILE.LICZB(Y2:Y1000)+LICZ.JEŻELI(Y2:Y1000;"<0")>0;"";JEŻELI(ILE.LICZB(Y2:Y1000)=0;"";ŚREDNIA(Y2:Y1000))) (as in the file, B12) Avg. MAE of winners: =JEŻELI(WIERSZE(X2:X1000)-LICZ.PUSTE(X2:X1000)-ILE.LICZB(X2:X1000)+LICZ.JEŻELI(X2:X1000;"<0")>0;"";JEŻELI.BŁĄD(ŚREDNIA.JEŻELI(V2:V1000;">0";X2:X1000);"")) Avg. MFE of losers: =JEŻELI(WIERSZE(Y2:Y1000)-LICZ.PUSTE(Y2:Y1000)-ILE.LICZB(Y2:Y1000)+LICZ.JEŻELI(Y2:Y1000;"<0")>0;"";JEŻELI.BŁĄD(ŚREDNIA.JEŻELI(V2:V1000;"<0";Y2:Y1000);"")) AG2 (coded_clean): =JEŻELI(ORAZ(CZY.LICZBA(V2);CZY.LICZBA(Z2));JEŻELI(ORAZ(Z2>=0;Z2<=10;Z2=LICZBA.CAŁK(Z2));JEŻELI(Z2=0;1;0);"");"") Clean execution: =JEŻELI(ILE.LICZB(AG2:AG1000)=0;"";ŚREDNIA(AG2:AG1000)) Avg. execution drag: =JEŻELI(ILE.LICZB(W2:W1000)=0;"";ŚREDNIA(W2:W1000)) (optional, not in the file)
Avg. MAE (all): =IF(ROWS(X2:X1000)-COUNTBLANK(X2:X1000)-COUNT(X2:X1000)+COUNTIF(X2:X1000,"<0")>0,"",IF(COUNT(X2:X1000)=0,"",AVERAGE(X2:X1000))) (as in the file, B11) Avg. MFE (all): =IF(ROWS(Y2:Y1000)-COUNTBLANK(Y2:Y1000)-COUNT(Y2:Y1000)+COUNTIF(Y2:Y1000,"<0")>0,"",IF(COUNT(Y2:Y1000)=0,"",AVERAGE(Y2:Y1000))) (as in the file, B12) Avg. MAE of winners: =IF(ROWS(X2:X1000)-COUNTBLANK(X2:X1000)-COUNT(X2:X1000)+COUNTIF(X2:X1000,"<0")>0,"",IFERROR(AVERAGEIF(V2:V1000,">0",X2:X1000),"")) Avg. MFE of losers: =IF(ROWS(Y2:Y1000)-COUNTBLANK(Y2:Y1000)-COUNT(Y2:Y1000)+COUNTIF(Y2:Y1000,"<0")>0,"",IFERROR(AVERAGEIF(V2:V1000,"<0",Y2:Y1000),"")) AG2 (coded_clean): =IF(AND(ISNUMBER(V2),ISNUMBER(Z2)),IF(AND(Z2>=0,Z2<=10,Z2=INT(Z2)),IF(Z2=0,1,0),""),"") Clean execution: =IF(COUNT(AG2:AG1000)=0,"",AVERAGE(AG2:AG1000)) Avg. execution drag: =IF(COUNT(W2:W1000)=0,"",AVERAGE(W2:W1000)) (optional, not in the file)
Close without R: =WIERSZE(C2:C1000)-LICZ.PUSTE(C2:C1000)-ILE.LICZB(V2:V1000) R without a code: =ILE.LICZB(V2:V1000)-ILE.LICZB(AG2:AG1000) Invalid MAE: =WIERSZE(X2:X1000)-LICZ.PUSTE(X2:X1000)-ILE.LICZB(X2:X1000)+LICZ.JEŻELI(X2:X1000;"<0") Invalid MFE: =WIERSZE(Y2:Y1000)-LICZ.PUSTE(Y2:Y1000)-ILE.LICZB(Y2:Y1000)+LICZ.JEŻELI(Y2:Y1000;"<0")
Close without R: =ROWS(C2:C1000)-COUNTBLANK(C2:C1000)-COUNT(V2:V1000) R without a code: =COUNT(V2:V1000)-COUNT(AG2:AG1000) Invalid MAE: =ROWS(X2:X1000)-COUNTBLANK(X2:X1000)-COUNT(X2:X1000)+COUNTIF(X2:X1000,"<0") Invalid MFE: =ROWS(Y2:Y1000)-COUNTBLANK(Y2:Y1000)-COUNT(Y2:Y1000)+COUNTIF(Y2:Y1000,"<0")
| Metric | How to read the results and their limitations |
|---|---|
| Win rate | On its own, it says nothing about an edge — see the chart below. It is blank when there are no closed trades; 0% means a sample with no winners. Use it to compare results with the playbook’s assumptions, not to judge “am I good at this?” |
| Profit factor | Below 1.0 = a negative result in R for the sample under review; it is meaningful only alongside trade count and drawdown. No losses in the sample means division by zero, not an “infinite edge” |
| Expectancy (R) | The journal’s most important number: average net result per trade. A positive value after costs describes this sample but does not, by itself, prove an edge. Assess dispersion, dependence between results, stability of conditions and validation results according to the testing protocol (N). The figure of 50 is an example review point, and a decision to scale up also requires compliance with the risk plan |
| Max drawdown (R) | A measure of the full history: AF calculates drawdown from the curve’s highest peak, so it is not the week’s loss. The plan’s weekly limit (add-on E) is expressed in the plan’s base R or as a percentage of capital. Do not compare it directly with total r_net if trades had different U values. With a constant base R in the account currency, the period’s result in the plan’s unit is the sum of net P&L in S for that period divided by the base R amount. For a percentage limit, use the capital base specified in the plan. AF describes the path of cumulative trade R, not drawdown in account balance or equity. Unusual drawdown calls for a check of the data, conditions and test assumptions |
| Avg. MAE of winners | Low (e.g. < 0.4R) = a hypothesis that the stop is wider than necessary — to be tested on a new sample, not tightened immediately (15.9); close to 1R = winners experienced an adverse move close to the full amount of risk — check entries and stop placement before concluding that this is an execution problem |
| Avg. MFE of losers | High = trades moved in your favour and then reversed — audit exit and partial profit-taking rules |
| Execution drag (avg.) | An optional formula (above), calculated only from trades with T filled in. A persistently high value indicates a gap between planned gross P&L and actual net P&L for comparable exits: it includes costs and differences in execution prices. Manual/early exits without an equivalent do not enter this average. Do not combine it with the simplified cost estimate for those exits |
| Clean execution | The percentage of closed trades with error_code = 0 (column AG counts only trades with valid R and an integer code from 0 to 10; a missing code does not count as clean execution). Around 90% may be a working threshold in a particular plan, not a quality standard. Check the number of assessed trades and missing codes: 100% from one code 0 and many blank codes does not describe the entire journal. A critical breach requires action regardless of the percentage. Metrics from trades that break the rules are not a clean test of those rules |
Starter CSV and import
The button creates the CSV file entirely in your browser, without sending data or making a separate network request: 26 headers plus two example rows — a winner and a loser — so the formulas have data to demonstrate how they work. The PL variant uses semicolons and a decimal comma (select the delimiter explicitly when importing; double-click behaviour depends on system settings), while EN uses commas and a decimal point. After importing, replace the calculated columns (O, S, V, W) in the example rows with the formulas from the section above, and delete the examples before making your first entry (or keep them in a separate file). A CSV export may save the precision displayed by the program; in XLSX 1.2, columns V and W use six decimal places. The starter CSV also uses six decimal places, calculated from the amounts in each row. With this rounding, the error in an individual R value does not exceed 0.0000005 R; PF can be more sensitive when the sum of losses is very small. A result with an absolute value below 0.0000005 R may round to zero, changing its win/loss classification and the win rate; for such data, increase precision before exporting. For analysis that requires greater precision, increase it before export, not just later in the script.
yyyy-mm-dd hh:mm (a Polish interface may display rrrr-mm-dd gg:mm), and V/W to at least six decimal places, with no thousands separator. Save as CSV UTF-8. Before combining files, check that trade_id values are unique: script S1 does not remove duplicates. Aggregate partial fills of one position according to your chosen trade unit (including costs), retaining its original U; do not count the same trade both as several fills and as a single summary. Open a copy in a text editor: check for 26 fields per record, the delimiter, UTC dates and numbers. CSV contains values, not formulas or the other sheets — keep the original XLSX. For S1, set PL: CSV_SEP=";", DECIMAL=","; EN: CSV_SEP=",", DECIMAL=".". UTF-8 with a BOM can be read as utf-8-sig.Checking the two examples: net P&L of USD 191.47 with risk of USD 110 gives 1.740636 R; net P&L of −USD 113.10 with risk of USD 105 gives −1.077143 R. From these six-decimal values, the script should produce N = 2, WR = 50%, total 0.663493 R, expectancy 0.3317465 R, PF of approximately 1.615974852 and max DD of 1.077143 R. S2 prints rounded figures: WR 0.5; PF 1.62; expectancy 0.332 R; total 0.66 R; max DD 1.08 R. The full XLSX formulas calculate from unrounded ratios, so the last digits may differ. S1 stops the analysis on an invalid closed trade; P5 instructs the script to exclude and report that record. Compare metrics only after reconciling the sample. P5 is an instruction to generate a script, not a ready-made file with a guaranteed result.
Build it step by step
- Create a blank spreadsheet in Excel or LibreOffice Calc; a cloud spreadsheet will also work — but these are account data, so make a deliberate choice.
- Import the starter CSV (or copy the headers from the structure tables). Check that numbers have been imported as numbers — if “1.0850” appears as text, the delimiter variant does not match your system settings.
- Paste the row formulas into O2, S2, V2 and W2, and fill down through a reserve of rows.
- Paste the dashboard (metrics 1–9) above the table or on a separate sheet; fill helper columns AE, AF and AG down in the same way as the row formulas, to the last prepared row.
- Set a routine: make an entry after each closed trade (the EOD checklist in add-on J includes this), read the metrics at your weekly review, and make playbook decisions quarterly (add-on E).
FAQ
Excel, LibreOffice or a cloud spreadsheet?
The formulas use basic functions available in Excel, LibreOffice Calc and Google Sheets. However, the choice of function names and delimiters depends on the program and file settings: the PL variant shows Polish names and semicolons, while EN shows English names and commas. A cloud spreadsheet may require English names with semicolons. We do not claim to have tested every version of these programs. The real distinction is elsewhere: the journal contains position sizes, results and a catalogue of your errors — in the cloud, these data are subject to the provider’s policies and stored outside your own drive. This section’s rule is to keep account data local by default; use the cloud deliberately and export a backup. It is the same decision that the data hygiene section of add-on H asks you to make before pasting a journal into a chat.
How many trades do you need before the metrics mean anything?
Metrics describe the sample from the first trade; around fifty is an example working point for the first system review, not a significance threshold — earlier on, expectancy and win rate change markedly after each run and say more about that recent run than about the system; dispersion and dependence between results also matter (which is why the same number appears in add-on E’s playbook as an A+ class threshold). This does not mean the journal is useless before then: process metrics work from the first entry — clean execution rate and completeness of entries — and they determine whether the system’s figures will ever be reliable. The order is always the same: process first, then the sample, and finally system assessment.
Why have an error_code column when the result is already visible?
Because outcome and decision quality are separate dimensions: there are profitable trades that break the plan (the most dangerous case — a rewarded breach becomes reinforced) and exemplary execution that ends in a loss. Error_code 0–10 lets you calculate expectancy SEPARATELY for clean execution: if the system makes money after breaches are filtered out, that suggests the problem lies in execution rather than the rules — a difference between subgroups does not yet prove the cause; it only shows where to look. Keep code 10 (infrastructure error) separate from decision errors; procedures for these cases are in add-on K, while the catalogue of codes 1–9 is in 15.9.
My Excel will not accept the formulas — what should I check?
It is almost always one of three things. First, the variant: function language and argument delimiter are separate settings. The switch provides two common combinations (PL: Polish names + semicolons; EN: English names + commas), but check your regional settings. In Google Sheets, also check the option to use English function names. Second, the decimal separator: a system using a decimal comma will read “1.0850” as text — hence the two CSV variants. Third, quotation marks: copying through messaging apps can replace straight quotes with typographic ones — copy using the button on this page, without an intermediary. If something still will not calculate, prompt P3 from add-on H can review formulas just as readily as code.
Related course material
- 15.9 Journal and metrics — the full field catalogue (including error codes 0–10), MAE/MFE definitions and advanced metrics (SQN, Sortino)
- 15.10 Strategy audit — what can be inferred from metrics, and from what sample
- Add-on I — code kit — a ready-made, tested S1–S3 script: reads this spreadsheet’s CSV export (A–Z), calculates metrics and plots the equity curve
- Add-on H, prompts P5–P7 — a script to calculate metrics from this spreadsheet’s CSV export, plus pattern audits (P6–P7: add plan-compliance status and a state note; P7 expects weekly metrics — copy rows closed during that week to a separate sheet and calculate the same formulas there; an auto-filter alone does not change COUNT/SUM/AVERAGE results)
- Add-on E — plan template — a playbook calibrated quarterly using figures from this journal
- Add-on J — checklists — the EOD/EOW routine that keeps the journal in use
Sources
- Van K. Tharp, Trade Your Way to Financial Freedom, 2nd ed., McGraw-Hill 2007 — the concepts of R-multiples and expectancy as core system metrics, on which the r_net column and dashboard are based.
- Internal: 15.9 Journal and metrics (field structure, error codes, MAE/MFE) and 15.10 Strategy audit (disciplined inference from a sample) — 26 columns A–Z plus 3 self-assessment fields give 29 columns in the file, but the spreadsheet covers around 20 of the 29 numbered logical fields in 15.9; missing fields are regime, actual_tp, slippage_exit_pips and four that 15.9 itself asks you to add (“the spreadsheet predates this section”): lots, pip_value_at_open, strategy_version, evidence_link — if you use the script from 15.9, add these as optional columns from AH onwards to avoid overwriting existing columns AA–AG; for scripts expecting A:Z, continue to export only that range.
- Documentation: Microsoft — argument delimiter and CSV, Microsoft — importing and exporting CSV, Google Sheets — locale and function language. Checked on 21 September 2026; these are configuration rules, not a claim that every application has been tested.
- NIST — uncertainty of the mean: dependence on sample size and dispersion; this does not justify a universal threshold of 50 trades. Checked on 21 September 2026.
Map a signed broker charge before calculating R
This fresh worksheet case uses PLN in both languages so changing a label never stands in for a currency conversion. All amounts are invented. The original spreadsheet and download controls remain above; the case does not populate them.
Distinguish the export sign from the destination convention
Decision J21 has price P&L+60 PLN, a signed broker commission −4 PLN and signed financing −1 PLN. Its initial recorded risk is 50 PLN. Decision J22 has price P&L−30 PLN, commission −3 PLN, financing +1 PLN and initial risk 40 PLN. The source signs describe cash effects. The destination journal uses a positive commission-cost field and signed financing. Map those conventions before copying columns; do not subtract a negative source commission and turn a charge into income.
Reconcile each complete decision once
For J21, net cash is 60−4−1=55 PLN and R=55/50=1.1. For J22, net cash is −30−3+1=−32 PLN and R=−32/40=−0.8. Enter positive commission costs 4 and 3 in the corresponding destination field. The signed financing values remain −1 and +1. Spread already reflected in the supplied price results is not deducted again. These are complete invented decisions, not separate partial exits counted as extra trades.
Keep a missing denominator unresolved
A third closed decision, J23, has net cash −8 PLN, but its initial risk is missing. Its R cannot be reconstructed from that number alone. Do not enter zero, invent a convenient risk or quietly omit the closed decision while labelling the rest the complete sample. The two valid R values sum to 0.3R and average 0.15R; these describe only that labelled subset. Complete cash across all three decisions is 55−32−8=15 PLN. Different coverage must remain visible.
Check the import before interpreting a dashboard
Retain the original export, mapping, units and explanation of unresolved rows. Use the spreadsheet’s completeness checks and verify the relevant date, numeric and risk fields. Import formatting does not establish that a text value became the intended number or that a risk amount came from a pre-entry record. After resolving J23, recalculate the complete distribution. Until then, distinguish the known cash reconciliation from the incomplete R analysis; neither is a forecast of future performance.
Three exercises with explanations
1. What are J21’s net amount and R?
Price +60 PLN; signed commission −4; financing −1; risk 50 PLN.
Show the answer and explanation
C. Map source signs to the journal’s field convention before calculating.
- A. That turns the charges into gains.
- B. That omits separate charges.
- C. 60−4−1=55 PLN; 55/50=1.1R.
- D. The net amount is not already a risk multiple.
2. What R can be assigned to the third decision?
Net −8 PLN; original planned risk missing.
Show the answer and explanation
D. Preserve the closed cash event and the missing-data flag.
- A. Missing evidence is not zero risk or zero outcome.
- B. A cash value is not an R value.
- C. The desired result is not evidence.
- D. The required denominator is missing.
3. Which statement preserves the supplied coverage?
J21 net 55 PLN; J22−32; third −8 without risk.
Show the answer and explanation
A. Report both scope and units beside a metric.
- A. 55−32−8=15 PLN; the missing risk still blocks a complete R distribution.
- B. The subset excludes a closed decision.
- C. Missing risk does not erase its cash effect.
- D. A label change performs no conversion.