TradingView options workflows

Options probability of profit: distribution, break-even and costs

Probability of profit is the probability that a position's net profit is strictly positive under a specified model and exit rule. For an expiry calculation, first find every terminal price interval where option payoffs exceed premiums and trading costs, then add the distribution's probability over those intervals. In the hypothetical example below, a $100 call bought for $3 with $5 total costs needs a settlement price above $103.05 and has a model probability of profit of 30.0146%. That number is conditional on the stated distribution, not a measured trading win rate.

Review available options data

Write net expiry P&L before calculating a probability

For legs sharing one underlying and expiry, define Π(s) = M × Σ nᵢ[hᵢ(s) - pᵢ] - F - L. Here nᵢ is positive for long contracts and negative for shorts; hᵢ(s) is max(s - Kᵢ, 0) for a call or max(Kᵢ - s, 0) for a put. Premium pᵢ is quoted per underlying unit, M is the contract multiplier, and F and L are total position fees and adverse slippage in dollars. The event is Π(Sₜ) > 0. A zero result is break-even, not a profitable trade.

  • The examples use M = 100 as a declared hypothetical contract specification. Verify the actual deliverable and multiplier, especially for adjusted contracts. With one long call, K = 100, premium = 3, F = 2 and L = 3, Π(s) = 100[max(s - 100, 0) - 3] - 5. Setting Π(s) = 0 gives 103.05.
  • Use execution premiums or documented fill assumptions. If a premium already includes the assumed spread crossing, do not subtract the same slippage again. Here slippage is an additional adverse cash cost relative to the listed reference premiums.
  • All cash amounts use nominal trade P&L: premiums are subtracted without financing accrual, and collateral interest, taxes, borrow costs and stock dividends are excluded. Add those cash flows at a consistent valuation date if the question is economic return after financing.
  • Costs here are fixed estimates through expiry. State-dependent exercise, assignment or liquidation costs require a state-dependent P&L function. A single fixed fee cannot represent all broker outcomes.

Declare the terminal-price distribution and its measure

This page assumes Sₜ = S₀ × exp[(b - σ²/2)T + σ√T Z], with Z standard normal. T is years, σ is annualized proportional volatility as a decimal, and b is the instantaneous expected price-return drift. Thus ln(Sₜ) is normal with mean ln(S₀) + (b - σ²/2)T and standard deviation σ√T. For x > 0, F(x) = Φ([ln(x/S₀) - (b - σ²/2)T]/[σ√T]); F(0) = 0 and F(∞) = 1. A profitable interval (a, c) contributes F(c) - F(a). Add disjoint intervals without renormalizing a truncated chart range.

  • One constant σ is one common distribution for the whole position. Assigning a different terminal distribution to each leg and adding its probability of profit does not give a portfolio probability. A volatility smile, jumps and discrete dividends need a different distribution or model.
  • For a continuous distribution, isolated break-even endpoints have zero probability mass. At zero time or zero volatility, the distribution is a point mass, so evaluating the actual P&L and excluding an exact tie is essential.
ChoiceMeaningWhat it does not establish
Risk-neutral modelUse b = r - q for stock with constant continuous dividend yield q and continuously compounded rate r.The actual chance of a future outcome. Pricing probabilities incorporate risk compensation.
Physical scenario modelSupply an estimated or assumed expected price drift b and a justified future volatility. If μ is total expected return, b = μ - q under the same dividend convention.A calibrated forecast merely because historical returns or implied volatility were entered.
Base illustrationS₀ = 100; T = 30/365; σ = 20%; r = 4%; q = 2%; b = 2%.A current quote or recommended drift. All premiums below are hypothetical inputs.

Six positions under the same distribution

Every leg below has one contract, M = 100 and the base 30-day distribution. Single-leg costs are $2 fees plus $3 slippage; two-leg costs are $4 plus $6; the four-leg condor uses $8 plus $12. B and S mean buy and sell. Premiums are per share, while costs and P&L limits are position dollars. The listed intervals include partial profits as well as maximum-profit regions.

  • The call's standardized break-even is ln(103.05/100)/(0.20√(30/365)) = 0.52398073 because b - σ²/2 = 0. Its POP is 1 - Φ(0.52398073) = 0.30014597. A price of 102 is in the money but still loses $105 after premium and costs.
  • The short put receives $300 and keeps $295 after costs before any intrinsic loss. Its lower break-even is 100 - 2.95 = 97.05. A settlement at 98 is in the money for the option, yet the short position earns $95. Its large potential loss as the stock approaches zero remains relevant despite the 69.9246% POP.
  • The bull call spread costs $310 all-in. Above 110 its intrinsic spread value is $1,000, so maximum net profit is $690. The profit interval extends above the short strike because the capped payoff remains positive; stopping the interval at 110 would undercount POP.
  • The condor receives $200 before $20 costs. In its left slope, Π(s) = 180 - 100(95 - s); in its right slope, Π(s) = 180 - 100(s - 105). The roots are 93.20 and 106.80. Between 95 and 105 it earns $180; outside 90 and 110 it loses $320. POP covers the entire interval between the roots, not just the maximum-profit plateau.
  • The straddle costs $610 all-in and pays 100|Sₜ - 100|. Its two profitable tails give F(93.90) + 1 - F(106.10). Using only one break-even would omit half of the relevant price regions.
Position and reference premiumsPositive net expiry P&LModel POP
Long call: B 100C @ 3Sₜ > 103.0530.0146%
Long put: B 100P @ 30 < Sₜ < 96.9529.4525%
Short put: S 100P @ 3Sₜ > 97.0569.9246%
Bull call spread: B 100C @ 5; S 110C @ 2Sₜ > 103.1029.7210%
Iron condor: B 90P @ 0.5; S 95P @ 1.5; S 105C @ 1.5; B 110C @ 0.593.20 < Sₜ < 106.8076.4697%
Long straddle: B 100C @ 3; B 100P @ 30 < Sₜ < 93.90 or Sₜ > 106.1028.7047%

Change costs and assumptions without changing the trade

This sensitivity table keeps the long 100 call and its $3 reference premium fixed. It changes one input at a time relative to the base row. These are probability scenarios for an existing entry cost, not a repricing of a new option purchase at each volatility.

  • Higher fixed costs cannot increase POP when the distribution and position are unchanged: they shrink the set of profitable outcomes. Changing volatility has no universal direction across strategies. It increases this long call's POP over these chosen inputs, but can reduce the probability inside a bounded condor interval.
  • The 8% row is a hypothetical physical-drift assumption. It is not inferred from the risk-free rate, the stock chart or the option premium. Implied volatility also need not equal future realized volatility; recording the estimate and testing alternatives is part of interpreting the number.
Scenarioσ; b; total costsBreak-evenModel POP
No fees or slippage20%; 2%; $0103.0030.3096%
Base20%; 2%; $5103.0530.0146%
Worse execution: $2 fees + $23 slippage20%; 2%; $25103.2528.8492%
Lower volatility15%; 2%; $5103.0524.7646%
Higher volatility30%; 2%; $5103.0535.4496%
Assumed physical price drift of 8%20%; 8%; $5103.0533.0703%

Delta, ITM probability, POP and historical win rate answer different questions

Under the stock Black-Scholes assumptions, d₂ = [ln(S₀/K) + (r - q - σ²/2)T]/(σ√T) and d₁ = d₂ + σ√T. A call's risk-neutral ITM probability is Φ(d₂), whereas its spot delta is exp(-qT)Φ(d₁). For the base 100-strike contract, ITM probability is 50.00%, call delta is about 0.5220 and the bought call's cost-adjusted POP is 30.0146%. Delta is a sensitivity and may be used as a rough ITM proxy; it is not the exact profit probability.

  • A high POP does not establish positive expected profit. Expected P&L is the integral of Π(s) over the distribution and depends on loss size and every partial payoff. Multiplying POP by maximum profit and the remaining probability by maximum loss generally misstates a spread's expectation.
  • Do not label the expiry calculation as a TradingView Strategy Tester win rate. A historical strategy result depends on the tested rules and execution assumptions; the calculation here has no historical trade sample.
MeasureEvent or quantityNeeded information
Probability of expiring ITMCall: Sₜ > K; put: Sₜ < KTerminal distribution and strike
Probability of profitΠ(Sₜ) > 0 for the whole positionPremiums, costs, all legs and terminal distribution
Historical win rateProfitable closed trades / eligible closed tradesA specified sample, fill history, costs and entry/exit rules
Probability of touch or early profit targetA barrier or P&L condition is reached before expiryA path model, monitoring rule and, for option exits, valuation and execution assumptions

Run the complete calculation in Python

Save this block as pop.py and run python3 pop.py. It uses only the standard library. Signed leg quantities determine the piecewise-linear expiry P&L; the code solves each interval between strikes and integrates all profitable pieces with the normal CDF. Adjacent pieces may share a strike endpoint, which does not double-count probability in the continuous case. Edit EXAMPLES and the explicit model inputs to inspect another same-expiry position.

  • An independent check integrated the direct net P&L indicator over 400,000 midpoint samples of Z from -9 to 9, without using the interval solver or CDF. Each of the six probabilities agreed within 0.00004 in probability units (0.004 percentage points). This verifies the implementation for these scenarios; it does not validate the assumed market distribution.
  • The interval method integrates the full positive price support. A chart-based approximation that divides the profitable mass by the mass inside a limited plot range instead estimates a conditional probability inside that range. The two can differ when omitted tails matter.
Standalone expiry calculation. The six example outputs and sensitivity rows reproduce the tables above; no network data or hidden defaults for missing contract fields.python
from math import erfc, exp, inf, isfinite, log, sqrt

# Leg: ("call" or "put", signed contract quantity, strike, premium per share).
# All legs have one underlying, one expiry and the same verified multiplier.
def validate(legs, multiplier, fees, slippage):
    if not legs or not all(isfinite(x) for x in (multiplier, fees, slippage)):
        raise ValueError("Supply legs and finite costs/multiplier")
    if multiplier <= 0 or fees < 0 or slippage < 0:
        raise ValueError("Multiplier must be positive; costs nonnegative")
    for kind, quantity, strike, premium in legs:
        if kind not in ("call", "put") or not all(
            isfinite(x) for x in (quantity, strike, premium)
        ):
            raise ValueError("Invalid leg")
        if quantity == 0 or quantity != int(quantity) or strike <= 0 or premium < 0:
            raise ValueError("Use nonzero integer quantity, positive strike, nonnegative premium")


def pnl(price, legs, multiplier, fees, slippage):
    result = sum(
        q * multiplier * (max(price - k if kind == "call" else k - price, 0) - p)
        for kind, q, k, p in legs
    ) - fees - slippage
    if not isfinite(result):
        raise ValueError("P&L exceeds numeric range")
    return result


def profit_intervals(legs, multiplier=100, fees=0, slippage=0):
    validate(legs, multiplier, fees, slippage)
    knots = [0.0] + sorted({leg[2] for leg in legs}) + [inf]
    intervals = []
    # Payoff is affine between strikes; solve a*S + b > 0 on every segment.
    for lo, hi in zip(knots, knots[1:]):
        a, b = 0.0, -fees - slippage
        for kind, q, k, premium in legs:
            scale = q * multiplier
            b -= scale * premium
            if kind == "call" and k <= lo:
                a += scale
                b -= scale * k
            elif kind == "put" and k >= hi:
                a -= scale
                b += scale * k
        if not isfinite(a) or not isfinite(b):
            raise ValueError("Payoff coefficients exceed numeric range")
        if a > 0:
            lo = max(lo, -b / a)
        elif a < 0:
            hi = min(hi, -b / a)
        elif b <= 0:
            continue
        if lo < hi:
            intervals.append((lo, hi))
    return intervals


def probability(legs, spot=100, years=30/365, sigma=0.20, drift=0.02,
                multiplier=100, fees=0, slippage=0, cash_tolerance=1e-8):
    validate(legs, multiplier, fees, slippage)
    if not isfinite(cash_tolerance) or cash_tolerance < 0:
        raise ValueError("Cash tolerance must be finite and nonnegative")
    if not all(isfinite(x) for x in (spot, years, sigma, drift)):
        raise ValueError("Model inputs must be finite")
    if spot <= 0 or years < 0 or sigma < 0:
        raise ValueError("Spot must be positive; time and volatility nonnegative")
    if years == 0 or sigma == 0:
        try:
            terminal = spot if years == 0 else spot * exp(drift * years)
        except OverflowError as error:
            raise ValueError("Terminal price exceeds numeric range") from error
        if not isfinite(terminal) or terminal <= 0:
            raise ValueError("Terminal price exceeds numeric range")
        return float(pnl(terminal, legs, multiplier, fees, slippage) > cash_tolerance)
    center = log(spot) + (drift - sigma*sigma/2) * years
    scale = sigma * sqrt(years)
    if not isfinite(center) or not isfinite(scale) or scale <= 0:
        raise ValueError("Distribution exceeds numeric range")
    def z(price):
        return -inf if price == 0 else (log(price) - center) / scale
    def mass(lo, hi):
        a, b = z(lo), z(hi)
        # Survival probabilities preserve precision in the right tail.
        if a >= 0:
            return 0.5 * (erfc(a/sqrt(2)) - erfc(b/sqrt(2)))
        return 0.5 * (erfc(-b/sqrt(2)) - erfc(-a/sqrt(2)))
    return sum(mass(lo, hi) for lo, hi in profit_intervals(
        legs, multiplier, fees, slippage))


EXAMPLES = {
    "Long call": ([("call", 1, 100, 3)], 2, 3),
    "Long put": ([("put", 1, 100, 3)], 2, 3),
    "Short put": ([("put", -1, 100, 3)], 2, 3),
    "Bull call spread": ([("call", 1, 100, 5), ("call", -1, 110, 2)], 4, 6),
    "Iron condor": ([("put", 1, 90, .5), ("put", -1, 95, 1.5),
                     ("call", -1, 105, 1.5), ("call", 1, 110, .5)], 8, 12),
    "Long straddle": ([("call", 1, 100, 3), ("put", 1, 100, 3)], 4, 6),
}

if __name__ == "__main__":
    for name, (legs, fees, slippage) in EXAMPLES.items():
        result = probability(legs, fees=fees, slippage=slippage)
        print(f"{name}: {100*result:.4f}%")
    call = EXAMPLES["Long call"][0]
    for sigma, drift, fees, slippage in [
        (.20, .02, 0, 0), (.20, .02, 2, 3), (.20, .02, 2, 23),
        (.15, .02, 2, 3), (.30, .02, 2, 3), (.20, .08, 2, 3),
    ]:
        result = probability(call, sigma=sigma, drift=drift, fees=fees, slippage=slippage)
        print(f"sigma={sigma}, drift={drift}, costs={fees+slippage}: {100*result:.4f}%")

Handle expiry, degenerate and invalid cases explicitly

At T = 0, use the known settlement reference and return 1 only when its net P&L is positive, otherwise 0. At σ = 0 with T > 0, this model has deterministic Sₜ = S₀exp(bT); use that price directly. Never divide by σ√T in these cases. The probability of an exact break-even is not ignored for a point mass. In the floating-point implementation, deterministic net P&L of at most $0.00000001 is treated as nonprofitable, so rounding residue at a root is not counted as a win. This declared dollar tolerance is adjustable; it does not shift the continuous-distribution break-even roots.

  • Reject negative time or volatility, nonpositive spot or multiplier, nonfinite inputs, invalid option types, negative premiums, negative costs and missing legs. The supplied code also requires nonzero integer contract quantities. Inputs outside floating-point representability raise an error rather than a probability estimate.
  • A long put with premium plus per-unit costs at least its strike cannot make a positive expiry profit on a nonnegative underlying. A debit spread whose all-in debit is at least its width cannot profit either. Return zero rather than treating a nonexistent break-even as an ordinary threshold.
  • Calendar spreads do not share a single terminal intrinsic-payoff function: the later option still has time value at the first expiry. American early assignment, exercise instructions, pin risk and physical delivery can change the actual path and cash flows. The same-expiry terminal model does not estimate these events.
  • For 0DTE positions, use the fraction of a day to the actual settlement time and the correct settlement reference. Constant volatility and a smooth lognormal distribution can miss event jumps; a precise-looking percentage does not resolve that model risk.

Cross-check the contract inputs in TradingView and Pineify

TradingView's options chain exposes strike, expiration, bid, ask, implied volatility and theoretical Greeks where available. Record the contract identifier, quote timestamp, underlying price, settlement convention and each leg's intended premium. A theoretical price or stale last trade is not an executable fill. Keep missing fields unknown until a source supplies them.

  • Pineify AI Stocks & Options Picker includes an Options Chain tab with expiration selection and available contract fields, including bid, ask and IV. Use it to compare the same supported contract and timestamp before copying inputs into a model. It does not certify the physical drift or the probability in this page.
  • The existing Option Probability Analyzer provides leg-based scenario charts, but its current implementation uses a finite price grid normalized over that range, zero commission, a fixed rate and a 100-unit multiplier. Its displayed POP is not an independent exact reproduction of this cost-adjusted calculation. Use the Python block for the declared costs, distribution and boundary handling above.
  • Check the settlement P&L at both roots and inside each profitable interval before accepting a probability. For the condor, test 93.20, 100 and 106.80: the results are approximately $0, $180 and $0. Then save the assumptions alongside the result so another reader can reproduce it.
Where Pineify fits

AI Stocks & Options Picker

Compare available contract fields by expiration, then bring verified premiums, IV and contract terms into the explicit expiry calculation. Missing data and physical return assumptions remain your inputs.

Review available options data

Frequently asked questions

Educational model calculations, not investment advice. All numerical examples use hypothetical inputs. Model probabilities are not forecasts, historical win rates or guarantees of profitable execution.

Sources and verification

Published by Pineify. Pineify is an independent product and is not affiliated with TradingView. Sources support the technical explanations; examples do not establish trading performance.