The Backtesting Spreadsheet Template for Recording Your Own Test Results
The per-trade columns for logging a manual backtest, the two formulas that compute R-multiple and net R, and the summary tab that rolls it up into a real expectancy number.
Most backtesting spreadsheets fail for the same reason most trading journals do: the columns do not match the job. A trading journal exists to record what you actually did with your own money. A backtest log exists to answer a narrower, earlier question, whether a strategy would have made money across a sample of past setups big enough to trust. Different question, different columns. Below is a two-tab structure built for that question: a per-trade log where you record each historical setup you replay, and a summary tab that rolls those rows up into a win rate and an expectancy number, after cost. Both tabs are copy-paste text further down this page.
Quick Answer
A backtesting spreadsheet needs two tabs. The per-trade log has 12 columns: test date, strategy, ticker, historical trade date, direction, entry, stop, exit, R-multiple, a cost assumption in R, net R after cost, and notes. Only two of those are formulas. The summary tab has one row per strategy and pulls sample size, win rate, gross average R, and net expectancy straight out of the log with COUNTIF, COUNTIFS, and AVERAGEIF. Both are copy-paste text below, so a working sheet is about two minutes away.
What a Backtest Log Records (and a Trading Journal Doesn't)
The two get confused because they look similar on a screen: rows of trades, a direction column, an entry and a stop. The difference is what each row means. A row in a trading journal is a trade you actually took, with real money on it, logged as it happened. A row in a backtest log is a historical setup you are replaying after the fact, to find out whether the rule that would have told you to take it is any good. If you are logging fills from your broker, you want the trading journal template, not this one.
The two also answer different-sized questions. A backtest log is judged in aggregate, across dozens or hundreds of rows, because a single historical trade proves nothing about a strategy. A pre-trade grade is judged on one setup, the one in front of you right now, because the backtest already told you the strategy has an edge and the only open question left is whether this instance of it is clean. The full argument for why you want both rather than either one is in backtesting versus pre-trade AI grading. This post is the spreadsheet, not the argument.
It will not fetch historical price data, replay a strategy across years of charts, or generate results for you. Every row is something you decide by hand, either by reading historical charts yourself or by using your platform's strategy tester and copying the results in. The spreadsheet organizes the verdict. It does not produce one.
The Per-Trade Backtest Log: Every Column
One row per historical setup you replay. Paste the line below into cell A1 of a blank sheet named "Log" and it splits on the tabs into 12 columns. The formulas further down assume this exact order and this exact tab name, since the summary formulas point at Log! directly.
Test Date Strategy Ticker Trade Date Direction Entry Stop Exit R-Multiple Cost (R) Net R Notes
| Column | Type | What goes in it | When |
|---|---|---|---|
| A. Test date | Date | When you ran this backtest session, not the date of the historical setup. | Typed |
| B. Strategy | Dropdown | The name of the strategy under test, pulled from a second tab so it stays consistent. | Typed |
| C. Ticker | Text | The symbol, uppercase, for sorting later. | Typed |
| D. Trade date | Date | The historical date the setup actually occurred on the chart. | Typed |
| E. Direction | Dropdown | Long or Short. Both R-multiple formulas below read this cell. | Typed |
| F. Entry | Number | The price you would have entered at, per your strategy's rules. | Typed |
| G. Stop | Number | The price that invalidates the setup. This is your risk unit for the R-multiple. | Typed |
| H. Exit | Number | What actually happened when you played the setup forward on the historical chart. | Typed |
| I. R-multiple | Formula | The raw result, before cost, in units of the risk you took. | Computed |
| J. Cost (R) | Number | Your slippage and commission assumption for this trade, expressed in R. | Typed |
| K. Net R | Formula | R-multiple minus the cost assumption. This is the number the summary tab should read. | Computed |
| L. Notes | Text | What the setup looked like and any judgment call you made replaying it. | Typed |
Column J, the cost assumption, is the one most homemade backtests skip, and it is the reason this template has it as its own column rather than folding it into the R-multiple. Keeping it separate means you can see both numbers: what the setup would have returned in a frictionless world, and what it actually nets once slippage and commission take their cut.
The Two Formulas: R-Multiple and Net R
Ten columns are typed. Two compute themselves. Paste each formula into row 2 of the matching column and it carries down for every trade you add after that.
I2 (R-Multiple) =IFERROR(IF(E2="Long",(H2-F2)/ABS(F2-G2),(F2-H2)/ABS(F2-G2)),"") K2 (Net R) =IF(I2="","",I2-J2)
| Cell | Formula | What it gives you |
|---|---|---|
| I2 (R-multiple) | =IFERROR(IF(E2="Long",(H2-F2)/ABS(F2-G2),(F2-H2)/ABS(F2-G2)),"") | Distance from entry to exit, divided by distance from entry to stop. Flips the direction of the subtraction for shorts. |
| K2 (Net R) | =IF(I2="","",I2-J2) | Subtracts your cost assumption from the raw result. Stays blank until the R-multiple exists. |
The R-multiple formula measures the exit against the stop distance rather than against a fixed dollar amount, which is what makes rows from different tickers and different position sizes comparable on the summary tab. A setup that returned $40 on a tight stop and one that returned $400 on a wide stop can land at the same R-multiple, and that is the point: the number describes how the trade performed relative to the risk it was structured to take, not how large the account swing was. If reward-to-risk as a concept is new, the underlying math is covered in the reward-to-risk breakdown.
How one row in the per-trade log becomes one line in the strategy summary
The Strategy Summary Tab
Add a second tab named "Summary" with one row per strategy. Every cell on it reads from the Log tab, so it stays current as you add more test rows without you touching it again.
| Column | What goes in it |
|---|---|
| Strategy | One row per strategy you have tested, matched against column B of the per-trade log. |
| Date range tested | Typed by hand: the earliest and latest trade date you pulled from the log. |
| Sample size | How many rows in the log belong to this strategy. Formula, never typed. |
| Win rate | Share of this strategy's rows with a positive net R, after cost. |
| Avg R (gross) | Average of the raw R-multiple column, before your cost assumption is subtracted. |
| Cost assumption | Typed once per strategy: your slippage and commission estimate, in R. |
| Net expectancy | Average of the Net R column. The number that should decide whether you trade this live. |
| Column | Formula | What it gives you |
|---|---|---|
| Sample size | =COUNTIF(Log!B:B,"Bull Flag") | Counts every row in the per-trade log tagged with this strategy name. |
| Win rate | =COUNTIFS(Log!B:B,"Bull Flag",Log!K:K,">0")/C2 | Rows for this strategy with a positive net R, divided by the sample size in the cell to its left. |
| Avg R (gross) | =AVERAGEIF(Log!B:B,"Bull Flag",Log!I:I) | Average raw R-multiple for this strategy, before cost. |
| Net expectancy | =AVERAGEIF(Log!B:B,"Bull Flag",Log!K:K) | Average net R for this strategy, after cost. Compare this to the gross figure to see what cost is actually taking. |
Swap the literal strategy name in each formula for the one you are summarizing, and add a new summary row every time you start testing something new. The win rate formula in particular is worth reading carefully: it counts rows with a positive net R, after cost, not a positive raw R-multiple. A strategy can look like it wins 60% of the time before cost and something noticeably lower after it, and the summary tab is built to surface that gap rather than hide it.
The summary tab tells you the strategy works. It can't tell you this setup is a clean example of it
That is a separate, smaller question, and it has to be answered fresh every time, on the chart in front of you. Upload the screenshot and SnapPChart grades the current setup A+ to F with an entry, a stop, and the bear case, which is the read a backtest cannot give you.
Grade a setupBuilding It in Excel or Google Sheets
Paste the Log header into A1 of a sheet named "Log," select the row, and in Excel hit Ctrl+T to convert it into a real table so the formulas you enter in row 2 extend automatically as you add rows. Microsoft's documentation on calculated columns in a table covers the mechanic. Google Sheets does not need the table conversion step; just select I2:K2 after pasting the formulas and drag the fill handle down as you log more trades, or wrap them in an ARRAYFORMULA if you want them to populate ahead of the data.
Set Direction as a dropdown with Long and Short as the only options, and set Strategy as a dropdown pointed at a short list on a third tab. Google's guide to creating an in-cell dropdown list covers both range-backed and manually typed versions. The dropdown matters more here than on a trading journal, because every summary formula matches on the literal text in that column, and "Bull Flag" and "bull flag" will silently split into two rows on the summary tab if you type it by hand twice.
Add the summary tab last, once the log has a handful of rows to point at, and reference the Log tab by name in every formula exactly as shown above. If a formula returns a blank instead of a number, the tab name is the first thing to check; a renamed tab breaks every COUNTIF and AVERAGEIF pointed at it silently, with no error message.
Why the Cost Row Changes the Verdict
A backtest run entirely on clean historical prices, with no cost column, is measuring a strategy that does not exist. Every real fill loses a little to the spread you cross going in and out, a little more to slippage on a fast move, and a fixed amount to commission on some brokers. None of those show up on a historical chart, which is exactly why column J exists as its own input rather than being baked silently into the exit price.
Pick a conservative cost assumption for the instrument you are testing and apply it uniformly: a wider assumption for a fast-moving low-float stock or a thin altcoin, a narrower one for a liquid major pair or a large-cap index name. Say a strategy's Log rows average 1.4R gross across forty tested trades. A 0.2R cost assumption is not a rounding error against that number, it is roughly a seventh of the entire edge, and the Net Expectancy column on the summary tab is what tells you whether 1.2R survives being traded live or was mostly an artifact of testing on frictionless prices.
If your spreadsheet only has the raw R-multiple column and nothing subtracting from it, the expectancy number it produces is a ceiling, not an estimate. Treat any backtest result you read online the same way: ask what cost assumption it used, and if the answer is none, assume the live number is lower.
How Many Trades Before It Means Anything
A sample size column exists on the summary tab for a reason beyond bookkeeping: it is the number that tells you how much to trust the win rate next to it. Twenty rows is a starting point for a rough read and nothing more, since the range of outcomes consistent with a real edge and consistent with pure noise overlap heavily at that count. Fifty rows narrows that range enough to act on cautiously. A hundred or more, spanning more than one kind of market condition rather than one clean trending month, is closer to where an expectancy number deserves real weight.
Condition matters as much as count. Forty rows tested entirely during a strong trend tells you how the strategy performs in a strong trend, and nothing about how it performs in a choppy range, even though the sample size column reads the same either way. If you can tag which market condition each row belongs to, a third dropdown column on the Log tab pays for itself the first time a strategy that looked great in one regime falls apart in another.
Frequently Asked Questions
What should a backtesting spreadsheet template include?
Two tabs. The first is a per-trade log: one row for every historical setup you replay, with the strategy name, ticker, direction, entry, stop, and what actually happened when you played it forward. Twelve columns, and only two of them are formulas. The second is a summary tab that rolls those rows up by strategy: sample size, win rate, average R before cost, your slippage assumption, and the expectancy that survives after you subtract it. The per-trade tab is where the testing happens. The summary tab is the only part you should trust a verdict from.
Is there a free backtesting spreadsheet template?
Yes, and it is the copy-paste text on this page rather than a file to download. Select the tab-separated header line under the per-trade log, drop it into cell A1 of a blank Google Sheet or Excel workbook, and it splits into 12 columns on its own. Paste the two formulas into row 2 and the sheet computes R-multiple and net R after cost for every row you add. That avoids a real problem with downloaded templates: a stranger's macros, an email gate, or a structure that does not match how you actually want to test.
Can SnapPChart backtest my strategy for me?
No. SnapPChart does not run backtests, does not have access to historical price data, and cannot bulk-simulate a strategy across past charts. It reads one chart screenshot you upload and grades that current setup, nothing more. This spreadsheet is a manual log you fill in yourself after you replay historical setups by hand or in your platform's strategy tester. If you want a tool to auto-populate a backtest for you, this is not that, and neither is anything else that reads a single static image.
How many trades do I need before a backtest result means anything?
Most traders start looking too early. Twenty trades of one setup is a starting point for a rough read, not a verdict, because the confidence interval around a win rate at that sample size is wide enough to hide a coin flip inside a real edge. Fifty gives you something worth acting on cautiously. A hundred or more, spanning more than one type of market condition, is where an expectancy number starts to mean what you think it means. If your test only covers a single strong trend, the strategy has not been tested against chop yet, regardless of the trade count.
Why does my backtest look better than my live results?
Cost is the usual answer, and it is the column most homemade backtests skip entirely. A manual backtest replayed on clean historical charts rarely accounts for slippage on the actual fill, the spread you cross on entry and exit, and commissions per round trip. Each is small per trade and compounds across a sample. Subtract a conservative cost assumption from every row before you trust the expectancy number, which is exactly what the net R column on this template is for. A strategy that only looks profitable before costs was never profitable.
This article is for educational and informational purposes only and does not constitute financial advice. The example figures, strategy names, and formulas here are illustrative teaching aids rather than trade recommendations or records of actual trades, and the spreadsheet formulas are provided as-is for you to verify against your own data before relying on them. A backtest measures past performance and does not guarantee future results. Day trading carries a substantial risk of loss and is not suitable for every investor. AI analysis evaluates chart structure, levels, and visible indicator behavior on a single uploaded screenshot; it does not run backtests, does not access historical price data, and does not guarantee trade outcomes. Always do your own research and never trade with money you cannot afford to lose.
Writes about AI-assisted day trading, technical analysis, and the systems traders actually use to stay disciplined.
The backtest validates the strategy. Something still has to grade the setup in front of you
This spreadsheet tells you whether a strategy has an edge across a hundred past trades. It cannot tell you whether the one setup on your screen right now is a clean example of it. Upload the chart screenshot and SnapPChart grades that current setup A+ to F with an entry, a stop, and the case against the trade.