{"id":5857,"date":"2026-10-07T20:59:19","date_gmt":"2026-10-07T10:29:19","guid":{"rendered":"https:\/\/www.strawman.com\/blog\/?page_id=5857"},"modified":"2026-10-07T21:38:39","modified_gmt":"2026-10-07T11:08:39","slug":"mcniven-valuation-calculator","status":"publish","type":"page","link":"https:\/\/www.strawman.com\/blog\/mcniven-valuation-calculator\/","title":{"rendered":"McNiven Valuation Calculator"},"content":{"rendered":"<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\" \/>\n  <link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin \/>\n  <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Roboto:wght@300;400;500;700;900&#038;display=swap\" rel=\"stylesheet\" \/>\n  <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/chart.js@4.4.7\/dist\/chart.umd.min.js\"><\/script>\n  <style>\n    :root {\n      --sm-orange: #f06c39;\n      --sm-orange-dark: #d95528;\n      --sm-blue: #465def;\n      --sm-blue-bright: #555EFF;\n      --sm-brand: #018ccd;\n      --sm-ink: #1a1d26;\n      --sm-muted: #6b7280;\n      --sm-line: #e8eaef;\n      --sm-card: #ffffff;\n      --sm-bg: #f6f7fb;\n      --sm-buy: #0d9f6e;\n      --sm-hold: #d97706;\n      --sm-reduce: #e11d48;\n      --radius: 16px;\n      --shadow: 0 10px 40px rgba(26, 29, 38, 0.08);\n      --shadow-sm: 0 4px 14px rgba(26, 29, 38, 0.06);\n    }\n    * { box-sizing: border-box; }\n    html { scroll-behavior: smooth; }\n    body {\n      margin: 0;\n      font-family: Roboto, system-ui, -apple-system, sans-serif;\n      color: var(--sm-ink);\n      background: var(--sm-bg);\n      line-height: 1.55;\n      -webkit-font-smoothing: antialiased;\n    }\n    #mcniven-calc {\n      max-width: 1100px;\n      margin: 0 auto;\n      padding: 28px 18px 48px;\n    }\n    .mc-hero {\n      background: linear-gradient(135deg, #ffffff 0%, #f0f4ff 55%, #fff4ee 100%);\n      border: 1px solid var(--sm-line);\n      border-radius: calc(var(--radius) + 4px);\n      padding: 28px 28px 24px;\n      box-shadow: var(--shadow);\n      position: relative;\n      overflow: hidden;\n      margin-bottom: 22px;\n      animation: mc-fade-up 0.55s ease both;\n    }\n    .mc-hero::before {\n      content: \"\";\n      position: absolute;\n      inset: auto -40px -60px auto;\n      width: 220px; height: 220px;\n      background: radial-gradient(circle, rgba(240,108,57,0.18), transparent 70%);\n      pointer-events: none;\n    }\n    .mc-inspired {\n      margin: 0 0 10px;\n      font-size: 0.95rem;\n      font-weight: 400;\n      color: var(--sm-muted);\n      line-height: 1.45;\n    }\n    .mc-inspired a {\n      color: var(--sm-brand);\n      font-weight: 600;\n      text-decoration: none;\n      border-bottom: 1px solid rgba(1,140,205,0.35);\n      transition: border-color 0.2s, color 0.2s;\n    }\n    .mc-inspired a:hover {\n      color: var(--sm-orange);\n      border-bottom-color: rgba(240,108,57,0.5);\n    }\n    .mc-hero h1 {\n      margin: 0 0 8px;\n      font-size: clamp(1.55rem, 3vw, 2.1rem);\n      font-weight: 900;\n      letter-spacing: -0.02em;\n      color: var(--sm-ink);\n    }\n    .mc-hero p {\n      margin: 0;\n      max-width: 62ch;\n      color: var(--sm-muted);\n      font-size: 1.02rem;\n      font-weight: 400;\n    }\n    .mc-formula {\n      margin-top: 16px;\n      display: inline-block;\n      font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n      font-size: 0.92rem;\n      background: rgba(70,93,239,0.08);\n      color: var(--sm-blue);\n      padding: 8px 12px;\n      border-radius: 10px;\n      border: 1px solid rgba(70,93,239,0.15);\n    }\n    .mc-grid {\n      display: grid;\n      grid-template-columns: 1.05fr 0.95fr;\n      gap: 18px;\n      align-items: start;\n    }\n    @media (max-width: 900px) {\n      .mc-grid { grid-template-columns: 1fr; }\n    }\n    .mc-card {\n      background: var(--sm-card);\n      border: 1px solid var(--sm-line);\n      border-radius: var(--radius);\n      box-shadow: var(--shadow-sm);\n      padding: 20px 20px 18px;\n      animation: mc-fade-up 0.6s ease both;\n    }\n    .mc-card:nth-child(2) { animation-delay: 0.06s; }\n    .mc-card h2 {\n      margin: 0 0 14px;\n      font-size: 0.95rem;\n      font-weight: 700;\n      letter-spacing: 0.04em;\n      text-transform: uppercase;\n      color: var(--sm-blue);\n    }\n    .mc-field {\n      margin-bottom: 14px;\n    }\n    .mc-field label {\n      display: flex; justify-content: space-between; align-items: baseline;\n      font-size: 0.86rem; font-weight: 500; color: var(--sm-ink);\n      margin-bottom: 6px;\n    }\n    .mc-field label small { color: var(--sm-muted); font-weight: 400; }\n    \/* Currency\/percent fields: fixed height + stretch prefix\/suffix so $\/% share\n       the full field box with the digits (theme CSS cannot override via #id). *\/\n    #mcniven-calc .mc-input-wrap {\n      display: flex;\n      align-items: stretch;\n      gap: 6px;\n      height: 44px;\n      border: 1.5px solid var(--sm-line);\n      border-radius: 12px;\n      background: #fbfcfe;\n      padding: 0 12px;\n      transition: border-color 0.2s, box-shadow 0.2s, background 0.2s;\n    }\n    #mcniven-calc .mc-input-wrap .prefix,\n    #mcniven-calc .mc-input-wrap .suffix {\n      position: static;\n      flex-shrink: 0;\n      align-self: stretch;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      height: auto;\n      margin: 0;\n      padding: 0;\n      border: 0;\n      color: var(--sm-muted);\n      font-family: Roboto, system-ui, -apple-system, sans-serif;\n      font-size: 1rem;\n      font-weight: 500;\n      line-height: 1.25;\n      pointer-events: none;\n      \/* Optical nudge: $ glyph sits slightly low in Roboto vs digits *\/\n      transform: translateY(-0.06em);\n    }\n    #mcniven-calc .mc-input-wrap input[type=\"number\"],\n    #mcniven-calc .mc-input-wrap input[type=\"text\"] {\n      flex: 1;\n      min-width: 0;\n      width: auto;\n      height: 100%;\n      border: none;\n      background: transparent;\n      margin: 0;\n      padding: 0;\n      font-family: Roboto, system-ui, -apple-system, sans-serif;\n      font-size: 1rem;\n      font-weight: 500;\n      line-height: 1.25;\n      color: var(--sm-ink);\n      outline: none;\n      box-shadow: none;\n      transition: none;\n      -moz-appearance: textfield;\n      appearance: textfield;\n    }\n    #mcniven-calc .mc-input-wrap input[type=\"number\"]::-webkit-outer-spin-button,\n    #mcniven-calc .mc-input-wrap input[type=\"number\"]::-webkit-inner-spin-button {\n      -webkit-appearance: none;\n      margin: 0;\n    }\n    #mcniven-calc .mc-input-wrap:hover { border-color: #cfd5e4; }\n    #mcniven-calc .mc-input-wrap:focus-within {\n      border-color: var(--sm-blue);\n      box-shadow: 0 0 0 4px rgba(70,93,239,0.15);\n      background: #fff;\n    }\n    #mcniven-calc .mc-input-wrap input:hover,\n    #mcniven-calc .mc-input-wrap input:focus {\n      border: none;\n      box-shadow: none;\n      background: transparent;\n      outline: none;\n    }\n    input[type=\"range\"] {\n      -webkit-appearance: none; appearance: none;\n      width: 100%; height: 6px; border-radius: 999px;\n      background: linear-gradient(90deg, var(--sm-brand), var(--sm-blue));\n      outline: none; margin: 8px 0 2px;\n    }\n    input[type=\"range\"]::-webkit-slider-thumb {\n      -webkit-appearance: none; appearance: none;\n      width: 20px; height: 20px; border-radius: 50%;\n      background: #fff; border: 3px solid var(--sm-orange);\n      box-shadow: 0 2px 8px rgba(240,108,57,0.35);\n      cursor: pointer; transition: transform 0.15s;\n    }\n    input[type=\"range\"]::-webkit-slider-thumb:hover { transform: scale(1.08); }\n    input[type=\"range\"]::-moz-range-thumb {\n      width: 20px; height: 20px; border-radius: 50%;\n      background: #fff; border: 3px solid var(--sm-orange);\n      box-shadow: 0 2px 8px rgba(240,108,57,0.35);\n      cursor: pointer;\n    }\n    .mc-row-2 {\n      display: grid; grid-template-columns: 1fr 1fr; gap: 12px;\n    }\n    @media (max-width: 520px) { .mc-row-2 { grid-template-columns: 1fr; } }\n    .mc-derived {\n      display: grid; grid-template-columns: 1fr 1fr; gap: 10px;\n      margin-top: 4px; margin-bottom: 8px;\n    }\n    .mc-chip {\n      background: #f3f5fb;\n      border: 1px solid var(--sm-line);\n      border-radius: 12px;\n      padding: 10px 12px;\n    }\n    .mc-chip .k { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--sm-muted); font-weight: 700; }\n    .mc-chip .v { font-size: 1.05rem; font-weight: 700; color: var(--sm-ink); margin-top: 2px; }\n    .mc-actions {\n      display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px;\n    }\n    .mc-btn {\n      border: none; cursor: pointer;\n      border-radius: 999px;\n      padding: 10px 16px;\n      font: 700 0.88rem Roboto, sans-serif;\n      transition: transform 0.15s, box-shadow 0.15s, background 0.15s;\n    }\n    .mc-btn:active { transform: scale(0.98); }\n    .mc-btn-primary {\n      background: var(--sm-orange); color: #fff;\n      box-shadow: 0 6px 16px rgba(240,108,57,0.28);\n    }\n    .mc-btn-primary:hover { background: var(--sm-orange-dark); }\n    .mc-btn-ghost {\n      background: #fff; color: var(--sm-blue);\n      border: 1.5px solid rgba(70,93,239,0.25);\n    }\n    .mc-btn-ghost:hover { background: rgba(70,93,239,0.06); }\n    .mc-results {\n      display: grid; gap: 12px;\n    }\n    .mc-metric {\n      position: relative;\n      border-radius: 14px;\n      padding: 14px 16px;\n      background: linear-gradient(180deg, #fff, #fafbff);\n      border: 1px solid var(--sm-line);\n      overflow: hidden;\n      transition: transform 0.2s ease, box-shadow 0.2s ease;\n    }\n    .mc-metric:hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); }\n    .mc-metric .label {\n      font-size: 0.75rem; font-weight: 700; letter-spacing: 0.06em;\n      text-transform: uppercase; color: var(--sm-muted);\n    }\n    .mc-metric .value {\n      font-size: 1.75rem; font-weight: 900; letter-spacing: -0.02em;\n      margin-top: 2px; color: var(--sm-ink);\n      font-variant-numeric: tabular-nums;\n    }\n    .mc-metric .hint { font-size: 0.82rem; color: var(--sm-muted); margin-top: 2px; }\n    .mc-metric.accent .value { color: var(--sm-blue); }\n    .mc-metric.orange .value { color: var(--sm-orange); }\n    .mc-badge {\n      display: inline-flex; align-items: center; gap: 8px;\n      margin-top: 10px;\n      padding: 10px 14px;\n      border-radius: 999px;\n      font-weight: 700; font-size: 0.95rem;\n      transition: background 0.35s, color 0.35s, box-shadow 0.35s;\n    }\n    .mc-badge::before {\n      content: \"\"; width: 10px; height: 10px; border-radius: 50%;\n      background: currentColor; box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 20%, transparent);\n    }\n    .mc-badge.buy { background: rgba(13,159,110,0.12); color: var(--sm-buy); }\n    .mc-badge.hold { background: rgba(240,108,57,0.12); color: var(--sm-orange-dark); }\n    .mc-badge.reduce { background: rgba(225,29,72,0.12); color: var(--sm-reduce); }\n    .mc-badge .sub { font-weight: 500; font-size: 0.82rem; opacity: 0.9; }\n    .mc-charts {\n      margin-top: 18px;\n      display: grid;\n      grid-template-columns: 1.2fr 0.8fr;\n      gap: 18px;\n    }\n    @media (max-width: 900px) { .mc-charts { grid-template-columns: 1fr; } }\n    .mc-chart-wrap {\n      position: relative;\n      height: 320px;\n    }\n    .mc-disclaimer {\n      margin-top: 18px;\n      padding: 14px 16px;\n      border-radius: 12px;\n      background: #fff8f4;\n      border: 1px solid rgba(240,108,57,0.25);\n      color: #7a3d22;\n      font-size: 0.9rem;\n      animation: mc-fade-up 0.7s ease both;\n    }\n    .mc-disclaimer strong { color: var(--sm-orange-dark); }\n    .mc-foot {\n      margin-top: 14px;\n      font-size: 0.82rem;\n      color: var(--sm-muted);\n      text-align: center;\n    }\n    .mc-tabs {\n      display: flex; gap: 6px; margin-bottom: 12px;\n    }\n    .mc-tab {\n      border: none; background: #eef1f8; color: var(--sm-muted);\n      padding: 7px 12px; border-radius: 999px;\n      font: 600 0.8rem Roboto, sans-serif; cursor: pointer;\n      transition: background 0.2s, color 0.2s;\n    }\n    .mc-tab.active { background: var(--sm-blue); color: #fff; }\n    @keyframes mc-fade-up {\n      from { opacity: 0; transform: translateY(10px); }\n      to { opacity: 1; transform: translateY(0); }\n    }\n    @keyframes mc-pulse {\n      0%, 100% { box-shadow: 0 0 0 0 rgba(70,93,239,0.25); }\n      50% { box-shadow: 0 0 0 8px rgba(70,93,239,0); }\n    }\n    .mc-flash { animation: mc-pulse 0.7s ease; }\n  <\/style>\n<\/head>\n<body>\n  <div id=\"mcniven-calc\">\n    <header class=\"mc-hero\">\n      <p class=\"mc-inspired\">Inspired by <a href=\"https:\/\/www.strawman.com\/forums\/topic\/8371#post-45927\">Rick<\/a>\u2019s write-up on McNiven\u2019s Valuation Formula.<\/p>\n      <h1>McNiven Valuation Calculator<\/h1>\n      <p>A practical framework for deciding when to Buy, Hold or Reduce \u2014 based on equity, future ROE, reinvestment, dividends (incl. franking) and your required return.<\/p>\n      <div class=\"mc-formula\">V<sub>share<\/sub> = E<sub>share<\/sub> \u00d7 [((APC \/ RR) \u00d7 RI) + D<sub>g<\/sub>] \/ RR<\/div>\n    <\/header>\n\n    <div class=\"mc-grid\">\n      <section class=\"mc-card\" aria-label=\"Inputs\">\n        <h2>Assumptions<\/h2>\n        <div class=\"mc-row-2\">\n          <div class=\"mc-field\">\n            <label for=\"mc-equity\">Equity \/ share<\/label>\n            <div class=\"mc-input-wrap has-prefix\">\n              <span class=\"prefix\">$<\/span>\n              <input id=\"mc-equity\" type=\"number\" min=\"0.01\" step=\"0.01\" value=\"5.00\" \/>\n            <\/div>\n          <\/div>\n          <div class=\"mc-field\">\n            <label for=\"mc-eps\">Forward EPS<\/label>\n            <div class=\"mc-input-wrap has-prefix\">\n              <span class=\"prefix\">$<\/span>\n              <input id=\"mc-eps\" type=\"number\" step=\"0.01\" value=\"1.00\" \/>\n            <\/div>\n          <\/div>\n        <\/div>\n        <div class=\"mc-field\">\n          <label for=\"mc-rr\">Required return (RR) <small id=\"mc-rr-label\">10.0%<\/small><\/label>\n          <input id=\"mc-rr\" type=\"range\" min=\"6\" max=\"16\" step=\"0.1\" value=\"10\" \/>\n          <div class=\"mc-input-wrap has-suffix\" style=\"margin-top:8px\">\n            <input id=\"mc-rr-num\" type=\"number\" min=\"1\" max=\"30\" step=\"0.1\" value=\"10\" \/>\n            <span class=\"suffix\">%<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"mc-field\">\n          <label for=\"mc-payout\">Payout ratio <small id=\"mc-payout-label\">50%<\/small><\/label>\n          <input id=\"mc-payout\" type=\"range\" min=\"0\" max=\"100\" step=\"0.5\" value=\"50\" \/>\n          <div class=\"mc-input-wrap has-suffix\" style=\"margin-top:8px\">\n            <input id=\"mc-payout-num\" type=\"number\" min=\"0\" max=\"100\" step=\"0.5\" value=\"50\" \/>\n            <span class=\"suffix\">%<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"mc-field\">\n          <label for=\"mc-franking\">Franking of dividend <small id=\"mc-franking-label\">100% franked<\/small><\/label>\n          <input id=\"mc-franking\" type=\"range\" min=\"0\" max=\"100\" step=\"5\" value=\"100\" \/>\n          <div class=\"mc-input-wrap has-suffix\" style=\"margin-top:8px\">\n            <input id=\"mc-franking-num\" type=\"number\" min=\"0\" max=\"100\" step=\"5\" value=\"100\" \/>\n            <span class=\"suffix\">%<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"mc-derived\">\n          <div class=\"mc-chip\"><div class=\"k\">Forward ROE (APC)<\/div><div class=\"v\" id=\"mc-apc\">\u2014<\/div><\/div>\n          <div class=\"mc-chip\"><div class=\"k\">Reinvestment (RI)<\/div><div class=\"v\" id=\"mc-ri\">\u2014<\/div><\/div>\n          <div class=\"mc-chip\"><div class=\"k\">D<sub>g<\/sub> \/ equity<\/div><div class=\"v\" id=\"mc-dg\">\u2014<\/div><\/div>\n          <div class=\"mc-chip\"><div class=\"k\">Grossed-up DPS<\/div><div class=\"v\" id=\"mc-dps\">\u2014<\/div><\/div>\n        <\/div>\n        <div class=\"mc-field\">\n          <label for=\"mc-price\">Current share price<\/label>\n          <div class=\"mc-input-wrap has-prefix\">\n            <span class=\"prefix\">$<\/span>\n            <input id=\"mc-price\" type=\"number\" min=\"0.01\" step=\"0.01\" value=\"20.00\" \/>\n          <\/div>\n        <\/div>\n        <div class=\"mc-actions\">\n          <button type=\"button\" class=\"mc-btn mc-btn-primary\" id=\"mc-reset\">Reset defaults<\/button>\n          <button type=\"button\" class=\"mc-btn mc-btn-ghost\" id=\"mc-rr10\">Set RR = 10%<\/button>\n        <\/div>\n      <\/section>\n\n      <section class=\"mc-card\" aria-label=\"Results\">\n        <h2>Results<\/h2>\n        <div class=\"mc-results\">\n          <div class=\"mc-metric accent\">\n            <div class=\"label\">McNiven value<\/div>\n            <div class=\"value\" id=\"mc-value\">\u2014<\/div>\n            <div class=\"hint\" id=\"mc-value-hint\">At your required return<\/div>\n          <\/div>\n          <div class=\"mc-metric orange\">\n            <div class=\"label\">Implied return @ price<\/div>\n            <div class=\"value\" id=\"mc-implied\">\u2014<\/div>\n            <div class=\"hint\" id=\"mc-implied-hint\">Solve for RR where value = price<\/div>\n          <\/div>\n          <div class=\"mc-metric\">\n            <div class=\"label\">Price vs value<\/div>\n            <div class=\"value\" id=\"mc-premium\">\u2014<\/div>\n            <div class=\"hint\" id=\"mc-premium-hint\">Positive = trading above McNiven<\/div>\n          <\/div>\n        <\/div>\n        <div class=\"mc-badge hold\" id=\"mc-signal\" role=\"status\">\n          Hold <span class=\"sub\">within \u00b115% of value<\/span>\n        <\/div>\n        <p style=\"margin:14px 0 0; font-size:0.86rem; color:var(--sm-muted)\">\n          Illustrative bands: <strong>Buy<\/strong> if price &gt;15% below value,\n          <strong>Hold<\/strong> within \u00b115%,\n          <strong>Reduce<\/strong> if price &gt;15% above value.\n        <\/p>\n      <\/section>\n    <\/div>\n\n    <div class=\"mc-charts\">\n      <section class=\"mc-card\">\n        <h2>Sensitivity vs required return<\/h2>\n        <div class=\"mc-chart-wrap\">\n          <canvas id=\"mc-chart\" aria-label=\"Valuation sensitivity chart\"><\/canvas>\n        <\/div>\n      <\/section>\n      <section class=\"mc-card\">\n        <h2>What drives value<\/h2>\n        <ul style=\"margin:0; padding-left:18px; color:var(--sm-muted); font-size:0.95rem\">\n          <li style=\"margin-bottom:8px\"><strong style=\"color:var(--sm-ink)\">Future ROE<\/strong> \u2014 if above your RR, reinvestment creates value.<\/li>\n          <li style=\"margin-bottom:8px\"><strong style=\"color:var(--sm-ink)\">Reinvestment<\/strong> \u2014 growth isn\u2019t automatically good when ROE &lt; RR.<\/li>\n          <li style=\"margin-bottom:8px\"><strong style=\"color:var(--sm-ink)\">Dividends + franking<\/strong> \u2014 D<sub>g<\/sub> includes the franking benefit (AU 30% tax gross-up).<\/li>\n          <li><strong style=\"color:var(--sm-ink)\">Required return<\/strong> \u2014 raise it when earnings are less predictable.<\/li>\n        <\/ul>\n        <p style=\"margin:16px 0 0; font-size:0.92rem; color:var(--sm-ink); font-weight:500\">\n          North star: <em>What return am I getting for the price I\u2019m paying?<\/em>\n        <\/p>\n      <\/section>\n    <\/div>\n\n    <div class=\"mc-disclaimer\">\n      <strong>Educational framework only \u2014 not financial advice.<\/strong>\n      McNiven\u2019s formula is a decision aid, not a crystal ball. Forecasting equity, ROE and payouts is the hard part. Defaults are round illustrative numbers \u2014 replace them with your own assumptions. Do your own research.\n    <\/div>\n    <p class=\"mc-foot\">Built for <a href=\"https:\/\/www.strawman.com\" style=\"color:var(--sm-brand); text-decoration:none; font-weight:600\">Strawman<\/a><\/p>\n  <\/div>\n\n  <script>\n  (function () {\n    const TAX = 0.30;\n    const DEFAULTS = {\n      equity: 5,\n      eps: 1,\n      rr: 10,\n      payout: 50,\n      franking: 100,\n      price: 20\n    };\n\n    const el = (id) => document.getElementById(id);\n    const equity = el('mc-equity');\n    const eps = el('mc-eps');\n    const rr = el('mc-rr');\n    const rrNum = el('mc-rr-num');\n    const payout = el('mc-payout');\n    const payoutNum = el('mc-payout-num');\n    const franking = el('mc-franking');\n    const frankingNum = el('mc-franking-num');\n    const price = el('mc-price');\n\n    let chart;\n    const animState = { value: 0, implied: 0, premium: 0 };\n\n    function num(input, fallback) {\n      const v = parseFloat(input.value);\n      return Number.isFinite(v) ? v : fallback;\n    }\n\n    function fmtMoney(v, digits) {\n      if (!Number.isFinite(v)) return '\u2014';\n      const d = digits == null ? (Math.abs(v) >= 100 ? 0 : 2) : digits;\n      return '$' + v.toLocaleString('en-AU', { minimumFractionDigits: d, maximumFractionDigits: d });\n    }\n    function fmtPct(v, digits) {\n      if (!Number.isFinite(v)) return '\u2014';\n      return (v * 100).toLocaleString('en-AU', { minimumFractionDigits: digits ?? 1, maximumFractionDigits: digits ?? 1 }) + '%';\n    }\n\n    function compute() {\n      const E = Math.max(num(equity, 0), 0.0001);\n      const F = num(eps, 0);\n      const RR = Math.max(num(rrNum, 10) \/ 100, 0.001);\n      const p = Math.min(Math.max(num(payout, 0) \/ 100, 0), 1);\n      const frank = Math.min(Math.max(num(franking, 0) \/ 100, 0), 1);\n      const P = Math.max(num(price, 0), 0.0001);\n\n      const APC = F \/ E;\n      const RI = APC * (1 - p);\n      const cashDiv = F * p;\n      const grossUp = 1 + frank * (TAX \/ (1 - TAX));\n      const dpsGross = cashDiv * grossUp;\n      const Dg = dpsGross \/ E;\n\n      const value = E * (((APC \/ RR) * RI) + Dg) \/ RR;\n\n      \/\/ Implied return: solve (P\/E) RR^2 - Dg RR - APC*RI = 0\n      let implied = NaN;\n      const a = P \/ E;\n      const b = -Dg;\n      const c = -APC * RI;\n      const disc = b * b - 4 * a * c;\n      if (disc >= 0) {\n        if (a > 0) {\n          implied = (-b + Math.sqrt(disc)) \/ (2 * a);\n          if (implied < 0) implied = NaN;\n        }\n      }\n\n      const premium = (P - value) \/ value;\n      let signal = 'hold';\n      if (P < value * 0.85) signal = 'buy';\n      else if (P > value * 1.15) signal = 'reduce';\n\n      return { E, F, RR, p, frank, P, APC, RI, Dg, dpsGross, value, implied, premium, signal };\n    }\n\n    function sensitivitySeries(base) {\n      const labels = [];\n      const values = [];\n      for (let r = 6; r <= 16.001; r += 0.5) {\n        const RR = r \/ 100;\n        const v = base.E * (((base.APC \/ RR) * base.RI) + base.Dg) \/ RR;\n        labels.push(r.toFixed(1) + '%');\n        values.push(+v.toFixed(2));\n      }\n      return { labels, values };\n    }\n\n    function tween(key, target, elNode, formatter, ms) {\n      const start = animState[key] || 0;\n      const t0 = performance.now();\n      const dur = ms || 380;\n      function frame(t) {\n        const u = Math.min(1, (t - t0) \/ dur);\n        const eased = 1 - Math.pow(1 - u, 3);\n        const cur = start + (target - start) * eased;\n        animState[key] = cur;\n        elNode.textContent = formatter(cur);\n        if (u < 1) requestAnimationFrame(frame);\n      }\n      if (!Number.isFinite(target)) {\n        elNode.textContent = '\u2014';\n        animState[key] = 0;\n        return;\n      }\n      requestAnimationFrame(frame);\n    }\n\n    function updateSignal(signal) {\n      const badge = el('mc-signal');\n      badge.className = 'mc-badge ' + signal;\n      if (signal === 'buy') {\n        badge.innerHTML = 'Buy <span class=\"sub\">price &gt;15% below McNiven value<\/span>';\n      } else if (signal === 'reduce') {\n        badge.innerHTML = 'Reduce <span class=\"sub\">price &gt;15% above McNiven value<\/span>';\n      } else {\n        badge.innerHTML = 'Hold <span class=\"sub\">within \u00b115% of value<\/span>';\n      }\n      badge.classList.remove('mc-flash');\n      void badge.offsetWidth;\n      badge.classList.add('mc-flash');\n    }\n\n    function ensureChart() {\n      const ctx = el('mc-chart').getContext('2d');\n      if (chart) return chart;\n      chart = new Chart(ctx, {\n        type: 'line',\n        data: { labels: [], datasets: [] },\n        options: {\n          responsive: true,\n          maintainAspectRatio: false,\n          animation: { duration: 550, easing: 'easeOutQuart' },\n          interaction: { mode: 'index', intersect: false },\n          plugins: {\n            legend: {\n              position: 'bottom',\n              labels: { usePointStyle: true, pointStyle: 'circle', boxWidth: 8, font: { family: 'Roboto', size: 12 } }\n            },\n            tooltip: {\n              backgroundColor: '#1a1d26',\n              titleFont: { family: 'Roboto', weight: '700' },\n              bodyFont: { family: 'Roboto' },\n              padding: 10,\n              cornerRadius: 8,\n              callbacks: {\n                label: (c) => ' ' + c.dataset.label + ': $' + Number(c.parsed.y).toFixed(2)\n              }\n            }\n          },\n          scales: {\n            x: {\n              grid: { color: 'rgba(70,93,239,0.06)' },\n              ticks: { font: { family: 'Roboto', size: 11 }, color: '#6b7280' }\n            },\n            y: {\n              grid: { color: 'rgba(26,29,38,0.06)' },\n              ticks: {\n                font: { family: 'Roboto', size: 11 }, color: '#6b7280',\n                callback: (v) => '$' + v\n              }\n            }\n          }\n        }\n      });\n      return chart;\n    }\n\n    function renderChart(base) {\n      const c = ensureChart();\n      const { labels, values } = sensitivitySeries(base);\n      const rrLabel = (base.RR * 100).toFixed(1) + '%';\n      const rrIdx = labels.indexOf(rrLabel);\n      let markerIdx = rrIdx;\n      if (markerIdx < 0) {\n        const rrPct = base.RR * 100;\n        markerIdx = Math.round((rrPct - 6) \/ 0.5);\n        markerIdx = Math.max(0, Math.min(labels.length - 1, markerIdx));\n      }\n      const priceLine = labels.map(() => +base.P.toFixed(2));\n      const pointRadii = labels.map((_, i) => i === markerIdx ? 6 : 0);\n      const pointColors = labels.map((_, i) => i === markerIdx ? '#f06c39' : '#465def');\n\n      c.data.labels = labels;\n      c.data.datasets = [\n        {\n          label: 'McNiven value',\n          data: values,\n          borderColor: '#465def',\n          backgroundColor: 'rgba(70,93,239,0.12)',\n          fill: true,\n          tension: 0.35,\n          borderWidth: 2.5,\n          pointRadius: pointRadii,\n          pointHoverRadius: 5,\n          pointBackgroundColor: pointColors,\n          pointBorderColor: '#fff',\n          pointBorderWidth: 2\n        },\n        {\n          label: 'Current price',\n          data: priceLine,\n          borderColor: '#f06c39',\n          borderDash: [6, 5],\n          borderWidth: 2,\n          pointRadius: 0,\n          fill: false,\n          tension: 0\n        }\n      ];\n      c.options.plugins.tooltip.callbacks.afterBody = (items) => {\n        const i = items[0] ? items[0].dataIndex : undefined;\n        if (i === markerIdx) return ['\u2190 your required return'];\n        return [];\n      };\n      c.update();\n    }\n\n    function refresh() {\n      const base = compute();\n      el('mc-rr-label').textContent = (base.RR * 100).toFixed(1) + '%';\n      el('mc-payout-label').textContent = (base.p * 100).toFixed(1) + '%';\n      el('mc-franking-label').textContent = Math.round(base.frank * 100) + '% franked';\n\n      el('mc-apc').textContent = fmtPct(base.APC, 1);\n      el('mc-ri').textContent = fmtPct(base.RI, 1);\n      el('mc-dg').textContent = fmtPct(base.Dg, 1);\n      el('mc-dps').textContent = fmtMoney(base.dpsGross, 2);\n\n      tween('value', base.value, el('mc-value'), (v) => fmtMoney(v, 2));\n      tween('implied', base.implied, el('mc-implied'), (v) => fmtPct(v, 1));\n      tween('premium', base.premium, el('mc-premium'), (v) => {\n        const sign = v > 0 ? '+' : '';\n        return sign + fmtPct(v, 1);\n      });\n\n      el('mc-value-hint').textContent = 'At RR ' + fmtPct(base.RR, 1);\n      el('mc-implied-hint').textContent = Number.isFinite(base.implied)\n        ? (base.implied >= base.RR ? 'Above your hurdle' : 'Below your hurdle')\n        : 'Unable to solve';\n      el('mc-premium-hint').textContent = base.premium > 0\n        ? 'Trading above McNiven value'\n        : 'Trading below McNiven value';\n\n      updateSignal(base.signal);\n      renderChart(base);\n    }\n\n    function syncRr(fromRange) {\n      if (fromRange) rrNum.value = rr.value;\n      else {\n        let v = num(rrNum, 10);\n        v = Math.min(30, Math.max(1, v));\n        rrNum.value = v;\n        if (v >= 6) { if (v <= 16) rr.value = v; }\n      }\n      refresh();\n    }\n\n    function syncPayout(fromRange) {\n      if (fromRange) payoutNum.value = payout.value;\n      else {\n        let v = Math.min(100, Math.max(0, num(payoutNum, 50)));\n        payoutNum.value = v;\n        payout.value = v;\n      }\n      refresh();\n    }\n    function syncFranking(fromRange) {\n      if (fromRange) frankingNum.value = franking.value;\n      else {\n        let v = Math.min(100, Math.max(0, num(frankingNum, 100)));\n        frankingNum.value = v;\n        franking.value = v;\n      }\n      refresh();\n    }\n\n    ['input', 'change'].forEach((evt) => {\n      [equity, eps, price].forEach((node) => {\n        node.addEventListener(evt, refresh);\n      });\n    });\n    rr.addEventListener('input', () => syncRr(true));\n    rrNum.addEventListener('input', () => syncRr(false));\n    rrNum.addEventListener('change', () => syncRr(false));\n    payout.addEventListener('input', () => syncPayout(true));\n    payoutNum.addEventListener('input', () => syncPayout(false));\n    payoutNum.addEventListener('change', () => syncPayout(false));\n    franking.addEventListener('input', () => syncFranking(true));\n    frankingNum.addEventListener('input', () => syncFranking(false));\n    frankingNum.addEventListener('change', () => syncFranking(false));\n\n    el('mc-reset').addEventListener('click', () => {\n      equity.value = DEFAULTS.equity;\n      eps.value = DEFAULTS.eps;\n      rr.value = DEFAULTS.rr;\n      rrNum.value = DEFAULTS.rr;\n      payout.value = DEFAULTS.payout;\n      payoutNum.value = DEFAULTS.payout;\n      franking.value = DEFAULTS.franking;\n      frankingNum.value = DEFAULTS.franking;\n      price.value = DEFAULTS.price;\n      refresh();\n    });\n    el('mc-rr10').addEventListener('click', () => {\n      rr.value = 10;\n      rrNum.value = 10;\n      refresh();\n    });\n\n    refresh();\n  })();\n  <\/script>\n\n\n<p class=\"has-text-align-center has-very-dark-gray-color has-very-light-gray-background-color has-text-color has-background has-normal-font-size wp-block-paragraph\"><em>Strawman is Australia\u2019s premier online investment club. <br>Members share research &amp; recommendations on ASX-listed stocks by managing Virtual Portfolios and building Company Reports. By ranking content according to performance and community endorsement, Strawman provides accountable and peer-reviewed investment insights.<\/em><\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-fe48e5de wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button aligncenter is-style-fill\"><a class=\"wp-block-button__link has-very-light-gray-color has-tertiary-background-color has-text-color has-background has-text-align-center wp-element-button\" href=\"https:\/\/strawman.com\/member\/landing\/signup\"> Create your FREE Strawman account<\/a><\/div>\n<\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color wp-block-paragraph\"><em><strong>Disclaimer\u2013<\/strong> Strawman is not a broker and you cannot purchase shares through the platform. All trades on Strawman use play money and are intended only as a tool to gain experience and have fun. No content on Strawman should be considered an inducement to buy or sell real world financial securities, and you should seek professional advice before making any investment decisions<\/em>.<\/p>\n\n\n\n<p class=\"has-text-align-center has-cyan-bluish-gray-color has-text-color wp-block-paragraph\">\u00a9 2026 Strawman Pty Ltd. All rights reserved.<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">| <a href=\"https:\/\/www.strawman.com\/landing\/privacy\">Privacy Policy<\/a>&nbsp;|&nbsp;<a href=\"https:\/\/www.strawman.com\/landing\/terms\">Terms of Service<\/a> |<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Interactive McNiven valuation framework \u2014 Buy, Hold or Reduce based on equity, ROE, reinvestment, franking and your required return. Educational only, not advice.<\/p>\n","protected":false},"author":97057,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"wpai_generated_summary":"","footnotes":""},"class_list":["post-5857","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>McNiven Valuation Calculator - Strawman Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.strawman.com\/blog\/mcniven-valuation-calculator\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"McNiven Valuation Calculator - Strawman Blog\" \/>\n<meta property=\"og:description\" content=\"Interactive McNiven valuation framework \u2014 Buy, Hold or Reduce based on equity, ROE, reinvestment, franking and your required return. Educational only, not advice.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.strawman.com\/blog\/mcniven-valuation-calculator\/\" \/>\n<meta property=\"og:site_name\" content=\"Strawman Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/strawman.invest\/\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-07T11:08:39+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@strawmaninvest\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/mcniven-valuation-calculator\\\/\",\"url\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/mcniven-valuation-calculator\\\/\",\"name\":\"McNiven Valuation Calculator - Strawman Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-10-07T10:29:19+00:00\",\"dateModified\":\"2026-10-07T11:08:39+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/mcniven-valuation-calculator\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.strawman.com\\\/blog\\\/mcniven-valuation-calculator\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/mcniven-valuation-calculator\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"McNiven Valuation Calculator\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/\",\"name\":\"Strawman Blog\",\"description\":\"Independent sharemarket research and insights from Australia&#039;s best private investors.\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/#organization\",\"name\":\"Strawman\",\"alternateName\":\"Strawman Pty Ltd\",\"url\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/cropped-strawman-favicon.png\",\"contentUrl\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/cropped-strawman-favicon.png\",\"width\":512,\"height\":512,\"caption\":\"Strawman\"},\"image\":{\"@id\":\"https:\\\/\\\/www.strawman.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/strawman.invest\\\/\",\"https:\\\/\\\/x.com\\\/strawmaninvest\",\"https:\\\/\\\/www.strawman.com\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"McNiven Valuation Calculator - Strawman Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.strawman.com\/blog\/mcniven-valuation-calculator\/","og_locale":"en_US","og_type":"article","og_title":"McNiven Valuation Calculator - Strawman Blog","og_description":"Interactive McNiven valuation framework \u2014 Buy, Hold or Reduce based on equity, ROE, reinvestment, franking and your required return. Educational only, not advice.","og_url":"https:\/\/www.strawman.com\/blog\/mcniven-valuation-calculator\/","og_site_name":"Strawman Blog","article_publisher":"https:\/\/www.facebook.com\/strawman.invest\/","article_modified_time":"2026-10-07T11:08:39+00:00","twitter_card":"summary_large_image","twitter_site":"@strawmaninvest","twitter_misc":{"Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.strawman.com\/blog\/mcniven-valuation-calculator\/","url":"https:\/\/www.strawman.com\/blog\/mcniven-valuation-calculator\/","name":"McNiven Valuation Calculator - Strawman Blog","isPartOf":{"@id":"https:\/\/www.strawman.com\/blog\/#website"},"datePublished":"2026-10-07T10:29:19+00:00","dateModified":"2026-10-07T11:08:39+00:00","breadcrumb":{"@id":"https:\/\/www.strawman.com\/blog\/mcniven-valuation-calculator\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.strawman.com\/blog\/mcniven-valuation-calculator\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.strawman.com\/blog\/mcniven-valuation-calculator\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.strawman.com\/blog\/"},{"@type":"ListItem","position":2,"name":"McNiven Valuation Calculator"}]},{"@type":"WebSite","@id":"https:\/\/www.strawman.com\/blog\/#website","url":"https:\/\/www.strawman.com\/blog\/","name":"Strawman Blog","description":"Independent sharemarket research and insights from Australia&#039;s best private investors.","publisher":{"@id":"https:\/\/www.strawman.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.strawman.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.strawman.com\/blog\/#organization","name":"Strawman","alternateName":"Strawman Pty Ltd","url":"https:\/\/www.strawman.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.strawman.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.strawman.com\/blog\/wp-content\/uploads\/2019\/04\/cropped-strawman-favicon.png","contentUrl":"https:\/\/www.strawman.com\/blog\/wp-content\/uploads\/2019\/04\/cropped-strawman-favicon.png","width":512,"height":512,"caption":"Strawman"},"image":{"@id":"https:\/\/www.strawman.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/strawman.invest\/","https:\/\/x.com\/strawmaninvest","https:\/\/www.strawman.com"]}]}},"_links":{"self":[{"href":"https:\/\/www.strawman.com\/blog\/wp-json\/wp\/v2\/pages\/5857","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.strawman.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.strawman.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.strawman.com\/blog\/wp-json\/wp\/v2\/users\/97057"}],"replies":[{"embeddable":true,"href":"https:\/\/www.strawman.com\/blog\/wp-json\/wp\/v2\/comments?post=5857"}],"version-history":[{"count":0,"href":"https:\/\/www.strawman.com\/blog\/wp-json\/wp\/v2\/pages\/5857\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.strawman.com\/blog\/wp-json\/wp\/v2\/media?parent=5857"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}