{
  "category": "Financial functions",
  "display_name": "FVSCHEDULE",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.FVSCHEDULE",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Recorded: 6 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 6 recorded answers",
    "workbook_corpus": {
      "cells": 6,
      "matched": 6
    }
  },
  "implementations": [
    {
      "commit": "9e1884369a678158dd82d3d74188daf986995e87",
      "flavour": "excel-compatibility-candidate",
      "language": "Rust",
      "name": "CalcFunc",
      "own_code": [
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/financial.rs#L205-L209",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/financial.rs#L143-L160",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/ported/financial_time_value_family.rs#L1094-L1106"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/financial::tv_out",
        "ported/excel_numeric::backend::sqrt",
        "ported/excel_numeric::binary_with",
        "ported/excel_numeric::excel_pow_positive",
        "ported/excel_numeric::excel_pow_chain",
        "ported/excel_numeric::excel_x87_mul",
        "ported/excel_numeric::excel_x87_recip",
        "ported/excel_numeric/x87::mul",
        "ported/excel_numeric/x87::recip",
        "ported/excel_numeric/x87_chains::pow2_positive",
        "ported/excel_numeric/x87_chains::pow2",
        "ported/excel_numeric/x87_chains::exp_ext",
        "ported/excel_numeric/x87_chains::exp_with",
        "ported/excel_numeric/x87_chains::excel_exp",
        "ported/excel_numeric/x87_chains::log_with",
        "ported/excel_numeric/x87_chains::excel_log",
        "ported/financial_time_value_family::PaymentTiming::factor",
        "ported/financial_time_value_family::validate_finite",
        "ported/financial_time_value_family::growth",
        "ported/financial_time_value_family::annuity_term",
        "ported/financial_time_value_family::balance_equation",
        "ported/financial_time_value_family::values_bracket_root",
        "ported/financial_time_value_family::bisect_rate_bracket",
        "ported/financial_time_value_family::search_rate_bracket_from_zero",
        "ported/financial_time_value_family::rate",
        "ported/financial_time_value_family::polish_root",
        "ported/financial_time_value_family::rate_root",
        "ported/power_fn::exact_integer_magnitude",
        "ported/power_fn::accept_negative_base_odd_root",
        "ported/power_fn::binexp_positive",
        "ported/power_fn::power_kernel"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/financial.rs#L205-L209",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 6 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.FVSCHEDULE.json",
  "name": "FVSCHEDULE",
  "notes": [],
  "schema": "efh.function-reference/v1",
  "section_order": [
    "what-it-does",
    "try-it",
    "quirks",
    "how-to-implement",
    "version-differences",
    "alternatives"
  ],
  "sections": {
    "alternatives": "\n### Relationships\n\n\n- **[FV](FUNC.FV.md)** — the constant-rate, payment-bearing sibling. `FVSCHEDULE(P, {r,r,…,r})` and\n  `−FV(r, n, 0, −P)` compute the same quantity by different routes and are a good cross-check.\n- **`PV`** — there is **no `PVSCHEDULE`**. To discount through a varying rate path you divide, or\n  you build the reciprocal schedule by hand. The asymmetry is a real gap in the function set.\n- **`RRI`** — the equivalent constant rate: `RRI(m, principal, FVSCHEDULE(principal, schedule))`\n  returns the geometric mean growth rate of the schedule. This pair is the cleanest way to express\n  the AM–GM point above.\n- **`PRODUCT`** — what `FVSCHEDULE` does, one step removed. `principal * PRODUCT(1 + schedule)` as an\n  array formula is the hand-built equivalent, and it is worth knowing because it makes the treatment\n  of blanks and text explicit rather than implicit.\n- **`GEOMEAN`** — the geometric mean, on `1 + r` values, which relates directly to the equivalent\n  constant rate.\n- **[EFFECT](FUNC.EFFECT.md)** — a *within-year* compounding conversion at a single rate, not a\n  path of rates. Different question.\n- **Confused with**: applying an average rate. See the AM–GM note; the arithmetic mean always\n  overstates.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\n`FVSCHEDULE` is a product of `m` factors and its error analysis is the classical one for repeated\nmultiplication.\n\n**Error accumulates linearly, and there is no cancellation.** Each multiplication introduces at most\nhalf an ULP of relative error, and the errors compound multiplicatively — so after `m` steps the\nrelative error is bounded by roughly `m·u/(1 − m·u)` with `u` the unit roundoff. For any schedule a\nspreadsheet would realistically hold, that is a handful of ULPs at worst. There is no subtraction\nanywhere in the computation, and therefore no cancellation and no ill-conditioning. Compared with\nalmost everything else in this family, `FVSCHEDULE` is benign.\n\n**Order changes the last bits.** Floating-point multiplication is commutative but not associative,\nso the product of the same factors in a different order can differ by an ULP or two. The reference\nengine multiplies strictly left to right in schedule order. An implementation that sorted the\nfactors, or that used pairwise multiplication for parallelism, would return slightly different bits\nfor the same schedule — which is worth knowing before treating a last-digit disagreement as a bug.\n\n**The `1 + r_i` addition is the accuracy floor.** For a small rate — a daily rate of `1e-5`, say —\nforming `1 + r` discards the low bits of `r` before any multiplication happens, and no amount of\ncare in the product recovers them. A schedule of many small rates therefore loses more precision in\nits additions than in its multiplications. The accurate alternative accumulates\n`Σ log1p(r_i)` and exponentiates once:\n\n    FVSCHEDULE  =  principal × exp( Σ log1p(r_i) )\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturns `Number` — a value in the same units as `principal`.\n\n- **A rate of exactly `−1`** produces zero, and every subsequent rate is irrelevant. The reference\n  engine applies no guard here — no `#NUM!`, no `#DIV/0!` — it simply multiplies by zero.\n- **A rate below `−1`** flips the sign of the result. Two such rates flip it back. This is\n  arithmetic behaving correctly on input that has no financial reading, and no function in Excel\n  will warn you.\n- **Negative `principal`** carries through; the family sign convention is not enforced here, because\n  there is no equation to balance — `FVSCHEDULE` is a product, not a solved equation, and it returns\n  the same sign it was given.\n- **Numeric text in the schedule** is coerced; non-numeric text produces `#VALUE!`.\n- Empty, missing and error arguments follow the shared call model; see\n  [The value universe](../model/01-value-universe.md) and\n  [Coercion and lifting](../model/02-coercion-and-lifting.md).\n\n\n\n### Errors\n\n\n| Error | Condition |\n|---|---|\n| `#VALUE!` | A schedule entry is non-numeric (documented) |\n| `#VALUE!` | `principal` receives non-numeric text or an unsupported value kind |\n| propagated | An error value in the schedule or in `principal` surfaces as that error |\n| `#NUM!` | The product is not representable |\n| `#VALUE!` | The call is made with any number of arguments other than two |\n\n",
    "sources": "- Microsoft, \"FVSCHEDULE function\" —\n  <https://support.microsoft.com/en-us/office/fvschedule-function-bec29522-bd87-4082-bab9-a241f3fb251d>\n  (syntax, the two argument descriptions, the `#VALUE!` condition on non-numeric schedule values,\n  and the remark that empty cells are treated as zero — no interest).\n- Handbook, [FV](FUNC.FV.md) — the constant-rate sibling and the shared family equation.\n- Handbook, [The value universe](../model/01-value-universe.md) and\n  [Coercion and lifting](../model/02-coercion-and-lifting.md).\n- Handbook projections `data/functions/FUNC.FVSCHEDULE.json` and\n  `data/presence/FUNC.FVSCHEDULE.json`.\n\n",
    "version-differences": "No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.",
    "what-it-does": "\n`FVSCHEDULE(principal, schedule)` returns the future value of a `principal` after applying a\n**series of compound interest rates**, one per period:\n\n    FVSCHEDULE  =  principal × Π_{i=1}^{m} (1 + r_i)\n\nwhere `r_1 … r_m` are the entries of `schedule` in order. That is the entire definition: a running\nproduct of growth factors.\n\nIts place in the family is defined by what it is *not*. [FV](FUNC.FV.md) assumes one **constant**\nrate and adds a payment stream; `FVSCHEDULE` allows the rate to **vary** and has no payment stream\nat all. When the rate changes over the life of the investment — a floating-rate note, a forecast\npath of short rates, a scenario ladder — `FV` is structurally the wrong function and `FVSCHEDULE` is\nthe right one.\n\nThe relation to `FV` is exact in the degenerate case: a schedule of `n` identical rates `r` gives\n`principal × (1 + r)^n`, which is `−FV(r, n, 0, −principal)`.\n\nTwo mathematical properties are worth stating because they are easy to assume wrongly:\n\n1. **Order does not matter.** Multiplication is commutative, so shuffling the schedule leaves the\n   answer unchanged in exact arithmetic. (In binary64 it changes the last bits — see *Numerical\n   notes* — but never the value in any meaningful sense.) Contrast `NPV` or `IRR`, where order *is*\n   meaning.\n2. **The average that reproduces the answer is geometric, not arithmetic.** The single equivalent\n   constant rate is `(Π(1 + r_i))^(1/m) − 1`, which is at or below the arithmetic mean of the `r_i`\n   by the AM–GM inequality, with equality only when all rates are equal. Substituting the mean rate\n   into `FV` therefore **overstates** the result, always. That gap is the whole reason volatility\n   drags on compound returns, and `FVSCHEDULE` is the function that shows it.\n\nRange: the product is positive whenever every `1 + r_i > 0`. A rate of exactly `−1` in any period\nannihilates the whole thing to zero; a rate below `−1` flips the sign, which is arithmetically\nconsistent and financially meaningless.\n\n\n\n### Arguments\n\n\n| Argument | Meaning | Default |\n|---|---|---|\n| `principal` | The present value — the amount to compound forward. Required. | — |\n| `schedule` | An array or reference of interest rates to apply, one per period, **in order**. Required. | — |\n\n- **The rates are per period, expressed as decimal fractions**, and the period is implicit: it is\n  however long each schedule entry represents. There is no period-length argument and no unit\n  checking.\n- **The number of periods is the length of the schedule.** There is no separate `nper`, which\n  removes one whole class of mismatch error that the `FV`-family functions are prone to.\n- **`schedule` must be an array or reference of numbers.** Microsoft documents that non-numeric\n  values in the schedule produce `#VALUE!`, and that **empty cells are treated as zero — no\n  interest**.\n\n"
  },
  "signature": {
    "display": "FVSCHEDULE(principal, schedule)",
    "parameters": [
      {
        "description": null,
        "name": "principal",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "schedule",
        "optional": false,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 2,
        "min": 2
      },
      "category": "Financial functions",
      "classification": {
        "arg_preparation_profile": "RefsVisibleInAdapter",
        "coercion_lift_profile": "Custom",
        "determinism_class": "Deterministic",
        "error_collapse_profile": "None",
        "fec_dependency_profile": "None",
        "host_interaction_class": "None",
        "kernel_signature_class": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "RefOnly",
        "thread_safety_class": "SafePure",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "Future value of a principal grown by a series of interest rates",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the future value of an initial principal after applying a series of compound interest rates",
        "microsoft_url": "https://support.microsoft.com/en-us/office/fvschedule-function-bec29522-bd87-4082-bab9-a241f3fb251d"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "bg-BG",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "cs-CZ",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "da-DK",
          "name": "FVTABEL"
        },
        {
          "locale": "de-DE",
          "name": "ZW2"
        },
        {
          "locale": "el-GR",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "en-AU",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "en-GB",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "en-US",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "es-ES",
          "name": "VF.PLAN"
        },
        {
          "locale": "et-EE",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "fi-FI",
          "name": "TULEVA.ARVO.ERIKORKO"
        },
        {
          "locale": "fr-FR",
          "name": "VC.PAIEMENTS"
        },
        {
          "locale": "he-IL",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "hr-HR",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "hu-HU",
          "name": "KJÉ"
        },
        {
          "locale": "id-ID",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "it-IT",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "ja-JP",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "ko-KR",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "lt-LT",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "lv-LV",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "nb-NO",
          "name": "SVPLAN"
        },
        {
          "locale": "nl-NL",
          "name": "TOEK.WAARDE2"
        },
        {
          "locale": "pl-PL",
          "name": "WART.PRZYSZŁ.KAP"
        },
        {
          "locale": "pt-BR",
          "name": "VFPLANO"
        },
        {
          "locale": "pt-PT",
          "name": "VFPLANO"
        },
        {
          "locale": "ro-RO",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "ru-RU",
          "name": "БЗРАСПИС"
        },
        {
          "locale": "sk-SK",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "sl-SI",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "sv-SE",
          "name": "FÖRRÄNTNING"
        },
        {
          "locale": "th-TH",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "tr-TR",
          "name": "GDPROGRAM"
        },
        {
          "locale": "uk-UA",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "vi-VN",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "zh-CN",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "zh-HK",
          "name": "FVSCHEDULE"
        },
        {
          "locale": "zh-TW",
          "name": "FVSCHEDULE"
        }
      ],
      "signature": {
        "display": "FVSCHEDULE(principal, schedule)",
        "parameters": [
          {
            "description": null,
            "name": "principal",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "schedule",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "FVSCHEDULE",
      "version_marker": null,
      "xlcall": {
        "code": "476",
        "symbol": "xlfFvschedule"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/fvschedule-function-bec29522-bd87-4082-bab9-a241f3fb251d"
  },
  "try_it": {
    "formula": "=FVSCHEDULE(1000,{0.05;0.06;0.04})"
  },
  "url": "https://handbook.dnacalc.com/functions/FVSCHEDULE.html",
  "variants": [],
  "versions": []
}