Notion's formula language is based on JavaScript with its own set of functions. It is expressive enough to calculate every standard trading metric, but the syntax is non-obvious and trading-specific implementations do not appear in Notion's documentation. This guide documents the exact formulas used in the TSB Notion template — ready to copy, paste, and adapt.

All formulas assume a Trade Log database as the primary source. The Performance Summary section is a separate database linked to the Trade Log via a Relation property, with Rollup properties pulling aggregated values.


1. Database setup — required properties

These formulas depend on specific properties in your Trade Log. The names must match exactly, or you will need to update the prop("name") references in each formula.

Number numeric input
Select dropdown choice
Formula calculated automatically
Rollup aggregated from related DB
Relation linked to another database
Trade Log — required properties
P&L ($)dollar profit/loss, negative for losses
Number
Risk ($)dollar amount risked on the trade
Number
Stop Pipsdistance to stop loss in pips
Number
Target Pipsdistance to take profit in pips
Number
OutcomeWin / Loss / Breakeven
Select
ComplianceIn Plan / Out of Plan / Revenge
Select
P&L (R)calculated — see formula below
Formula
Planned R:Rcalculated — see formula below
Formula
Is Wincalculated — used by rollups
Formula
Notion formula properties reference other properties with prop("Property Name"). Property names are case-sensitive. If your properties use different names (e.g. "PnL" instead of "P&L ($)"), update every reference in the formulas below.

2. Per-trade formulas

These go directly in the Trade Log database as Formula properties. Each trade row calculates these automatically when you fill in the required input fields.

P&L in R-multiples
P&L (R)
Formula property
if( prop("Risk ($)") != 0, round(prop("P&L ($)") / prop("Risk ($)") * 100) / 100, 0 )

Converts dollar P&L into R-multiples (how many times your risk you made or lost). A trade where you risked $100 and made $230 shows as +2.3R. A trade where you risked $100 and lost $80 (stopped out before full stop) shows as -0.8R.

The if(... != 0, ..., 0) guard prevents a division-by-zero error on rows where Risk ($) has not been filled in yet.

Needs: P&L ($) Risk ($)
Planned R:R
Formula property
if( prop("Stop Pips") != 0, round(prop("Target Pips") / prop("Stop Pips") * 100) / 100, 0 )

Calculates your planned reward-to-risk ratio from the distances to your target and stop. A trade with a 30-pip stop and 60-pip target shows as 2.0. Compare this to your actual P&L (R) column to see whether you reached your target, exited early, or overran your stop.

Needs: Stop Pips Target Pips
Win/Loss flags (used by rollups)
Is Win
Formula property → Number (0 or 1)
if(prop("Outcome") == "Win", 1, 0)

Outputs 1 for winning trades and 0 for everything else. This is a helper property — you will use it in Rollup properties on your Performance Summary database to count wins. Rollups can Sum a number column, so Sum of Is Win gives you total winning trades.

Needs: Outcome (select)
Is In Plan
Formula property → Number (0 or 1)
if(prop("Compliance") == "In Plan", 1, 0)

Flags whether the trade was part of your trading plan. Use this in a Rollup to calculate what percentage of your trades are in-plan over any period. If this number drops below 80%, your execution discipline is slipping — a clear signal before the loss shows up in P&L.

Needs: Compliance (select)
Gross Win ($)
Formula property → Number
if(prop("P&L ($)") > 0, prop("P&L ($)"), 0)

Returns the trade's dollar profit if it is a winner, 0 otherwise. Used in a Rollup (Sum) to calculate total gross profit — one of the two inputs to Profit Factor.

Needs: P&L ($)
Gross Loss ($)
Formula property → Number
if(prop("P&L ($)") < 0, abs(prop("P&L ($)")), 0)

Returns the absolute dollar loss for losing trades, 0 for winners. Used in a Rollup (Sum) to get total gross losses. Note the abs() function — this ensures the value is positive, so your Profit Factor formula does not divide by a negative number.

Needs: P&L ($)

3. Performance summary formulas

These go in a separate Performance Summary database that is linked to your Trade Log via a Relation property. Each row in the Performance Summary represents a time period (a month, a challenge, a strategy) and pulls data from the related Trade Log rows via Rollup properties.

Create these Rollup properties first, then use them in Formula properties:

Performance Summary — Rollup properties needed
Total TradesCount all of Trade Log relation
Rollup
Winning TradesSum of "Is Win" from Trade Log
Rollup
Total P&LSum of "P&L ($)" from Trade Log
Rollup
Total Gross WinSum of "Gross Win ($)" from Trade Log
Rollup
Total Gross LossSum of "Gross Loss ($)" from Trade Log
Rollup
Total P&L (R)Sum of "P&L (R)" from Trade Log
Rollup
In Plan TradesSum of "Is In Plan" from Trade Log
Rollup
Core performance metrics
Win Rate (%)
Formula property → format as %
if( toNumber(prop("Total Trades")) > 0, round(toNumber(prop("Winning Trades")) / toNumber(prop("Total Trades")) * 10000) / 100, 0 )

Calculates win rate as a percentage. The round(... * 10000) / 100 pattern gives you two decimal places (e.g. 57.14%). The guard checks that you have at least one trade before dividing. Format this property as a Number with % suffix in Notion's property settings.

Needs rollups: Total Trades Winning Trades
Profit Factor
Formula property → Number
if( toNumber(prop("Total Gross Loss")) > 0, round(toNumber(prop("Total Gross Win")) / toNumber(prop("Total Gross Loss")) * 100) / 100, 0 )

Profit Factor = Total Gross Profit ÷ Total Gross Loss. A value of 1.5 means for every $1 lost you made $1.50. Values below 1.0 mean you are losing money overall. Strong strategies typically show 1.5–2.5. Above 3.0 can indicate insufficient sample size or cherry-picked data.

Needs rollups: Total Gross Win Total Gross Loss
Average R:R (Actual)
Formula property → Number
if( toNumber(prop("Total Trades")) > 0, round(toNumber(prop("Total P&L (R)")) / toNumber(prop("Total Trades")) * 100) / 100, 0 )

Average actual R-multiple per trade across the period. This tells you your true expectancy in R-terms — more useful than win rate alone because it accounts for how large your wins are relative to your losses. A positive value here with any win rate above the breakeven threshold means your edge is real.

Needs rollups: Total P&L (R) Total Trades
Expectancy (per trade, $)
Formula property → Number
if( toNumber(prop("Total Trades")) > 0, round(toNumber(prop("Total P&L")) / toNumber(prop("Total Trades")) * 100) / 100, 0 )

Average dollar profit per trade. This is the single most important number in your journal — it tells you how much you make (or lose) on average every time you click the mouse. Multiply by your daily trade count to estimate your expected daily P&L. A positive expectancy does not mean every trade wins, but it means the edge is statistically present.

Needs rollups: Total P&L Total Trades
Plan Adherence (%)
Formula property → format as %
if( toNumber(prop("Total Trades")) > 0, round(toNumber(prop("In Plan Trades")) / toNumber(prop("Total Trades")) * 10000) / 100, 0 )

Percentage of trades taken that were part of your pre-defined setup criteria. This is arguably the most important process metric in your journal — it tells you whether you are trading your strategy or reacting to market noise. Most successful traders maintain 85–95% plan adherence. A drop below 80% in a given week is a warning sign, regardless of P&L that week.

Needs rollups: In Plan Trades Total Trades

4. Prop firm compliance formulas

These formulas go in your Prop Firm Challenge Tracker database. Each row represents one challenge account. You will need number properties for Account Size, Daily Limit %, Max Drawdown %, Starting Balance, and a number property for Today's P&L that you update manually each day.

Daily Loss Limit ($)
Formula property → Number
round(prop("Current Balance") * (prop("Daily Limit %") / 100) * 100) / 100

Calculates your dollar daily loss limit from your current balance and the firm's percentage limit. On FTMO with a $102,000 balance and 5% limit, this shows $5,100. Update the "Current Balance" property each morning before trading. This is the number to write on paper and keep visible during the session.

Needs: Current Balance Daily Limit %
Max Drawdown Floor ($)
Formula property → Number
round(prop("Starting Balance") * (1 - prop("Max DD %") / 100) * 100) / 100

Calculates the absolute equity floor — the level your account must never go below. Uses Starting Balance (not current balance) because FTMO and FundedNext use static drawdown. On a $100k FTMO account with 10% max drawdown, this shows $90,000 regardless of how much the account has grown.

Needs: Starting Balance Max DD %
Drawdown Remaining ($)
Formula property → Number
round((prop("Current Balance") - prop("Max Drawdown Floor ($)")) * 100) / 100

How much further your account can fall before the challenge ends. If this number is positive, you are above the floor. If it drops near zero, stop trading until the next session. This is the most important live number for prop firm traders — it tells you exactly how much you can lose today (or ever) on this account.

Needs: Current Balance Max Drawdown Floor ($)
Profit Progress (%)
Formula property → format as %
if( prop("Profit Target ($)") > 0, round( (prop("Current Balance") - prop("Starting Balance")) / prop("Profit Target ($)") * 10000 ) / 100, 0 )

Percentage of the profit target achieved so far. At 100%, you have hit your target. Negative means you are currently in drawdown from your starting balance. Helps you pace your challenge — if you are at 30% of target with 20 of 30 days remaining, you are behind pace and should not take extra risk to catch up.

Needs: Current Balance Starting Balance Profit Target ($)
Challenge Status
Formula property → Text label
if( prop("Current Balance") <= prop("Max Drawdown Floor ($)"), "🔴 FAILED — Max DD", if( prop("Today P&L") <= -prop("Daily Loss Limit ($)"), "🟠 STOP — Daily limit hit", if( prop("Current Balance") - prop("Max Drawdown Floor ($)") < prop("Daily Loss Limit ($)") * 0.5, "🟡 CAUTION — Near floor", if( prop("Profit Progress (%)") >= 100, "🟢 TARGET HIT", "🔵 Active" ) ) ) )

A single status field that summarises your challenge state at a glance. Shows a red warning if max drawdown is breached, orange if today's daily limit is hit, yellow if you are within 50% of the daily limit from the drawdown floor (danger zone), green if target is hit, and blue otherwise. Put this in your Notion dashboard view so you see it before every session.

Needs: Current Balance Max Drawdown Floor ($) Today P&L Daily Loss Limit ($) Profit Progress (%)
Consistency Rule Check (FundedNext / The5%ers)
Formula property → Text label
if( prop("Consistency %") > 0 and prop("Best Day P&L") > 0 and prop("Total P&L") > 0, if( prop("Best Day P&L") / prop("Total P&L") * 100 > prop("Consistency %"), "⚠️ Consistency risk — best day too large", "✅ Consistent" ), "—" )

Checks whether your best single trading day exceeds the consistency rule limit. Set "Consistency %" to 40 for FundedNext or 50 for The5%ers. Set "Best Day P&L" manually to your highest single-day profit. Update it each time a day beats the previous best. FTMO does not have this rule — leave Consistency % blank and this formula shows "—".

Needs: Consistency % Best Day P&L Total P&L

5. Advanced formulas

Breakeven Win Rate Required
Formula property → format as %
if( prop("Avg Win ($)") + prop("Avg Loss ($)") != 0, round( prop("Avg Loss ($)") / (prop("Avg Win ($)") + prop("Avg Loss ($)")) * 10000 ) / 100, 0 )

Calculates the minimum win rate needed to break even given your average win and loss sizes. Use absolute values for both inputs (Avg Loss should be positive). A 1:2 R:R trader needs 33.3% to break even. A 1:1 R:R trader needs 50.0%. If your actual win rate is above this number, your strategy is profitable over time. Below it, you are losing money even if it feels like you win often.

Needs: Avg Win ($) Avg Loss ($)
Session tag → session label
Formula property → Text (Trade Log)
if( prop("Session") == "London", "🇬🇧 London", if( prop("Session") == "New York", "🇺🇸 New York", if( prop("Session") == "Asian", "🌏 Asian", if( prop("Session") == "London/NY Overlap", "⚡ Overlap", prop("Session") ) ) ) )

Adds emoji flags to session names for faster visual scanning in database views. Not essential — useful when you want to group or filter by session in gallery view and the emoji makes the grouping immediately clear without reading. Adapt the session names to match whatever values you use in your Session select property.

Needs: Session (select)

6. What Notion formulas cannot do

Notion's formula engine is evaluated per-row. It cannot reference values from other rows in the same database (no "previous row" access), and it cannot perform iterative or time-series calculations. This creates specific gaps for trading analytics:

Running equity curve

To draw an equity curve you need cumulative P&L at each row. Notion has no way to sum P&L from all previous rows in sequence. You can approximate this by adding a manual "Balance" property to each row and updating it yourself — but it breaks the moment you re-order rows or insert an old trade. True equity curves require an external analytics tool.

Trailing drawdown

TopStep's trailing drawdown requires knowing your equity peak at end-of-day for every day since the challenge started. Notion cannot iterate backward through rows to find the maximum value. This specific calculation requires code (e.g. a spreadsheet with proper formulas, or TSB Pro which calculates it from your broker data automatically).

Max drawdown (rolling)

Peak-to-trough drawdown requires knowing both your equity peak and the lowest subsequent point — a two-pass calculation across time-ordered rows. Not possible in Notion natively. The static drawdown floor (current balance vs. fixed starting balance) is achievable, as shown above.

Session-level statistics

Win rate per session requires filtering rows by session and dividing counts. Notion can show grouped views by session, but the win rate within each group requires a separate filtered database or rollup from a linked session-level database. TSB Pro calculates this automatically from your imported trades.


Yes. In your Trade Log, create a Formula property called "Is Win" that returns 1 when Outcome = "Win" and 0 otherwise. Then in a linked Performance Summary database, create a Rollup property (Sum of "Is Win") to count total wins, and a Rollup to count all trades. A Formula property divides wins by total trades: round(prop("Winning Trades") / prop("Total Trades") * 10000) / 100. This updates automatically every time you add a trade.