Financial functions
AMORDEGRC
Matches all 46 recorded answers
Recorded: 46 workbook cells. How we measure this · See the Rust code
Local names in 40 languages
| Language | Name in Excel |
|---|---|
| Arabic | AMORDEGRC |
| Bulgarian | AMORDEGRC |
| Czech | AMORDEGRC |
| Danish | AMORDEGRC |
| German | AMORDEGRC |
| Greek | AMORDEGRC |
| English (Australia) | AMORDEGRC |
| English (United Kingdom) | AMORDEGRC |
| English (United States) | AMORDEGRC |
| Spanish | AMORTIZ.PROGRE |
| Estonian | AMORDEGRC |
| Finnish | AMORDEGRC |
| French | AMORDEGRC |
| Hebrew | AMORDEGRC |
| Croatian | AMORDEGRC |
| Hungarian | ÉRTÉKCSÖKK.TÉNYEZŐVEL |
| Indonesian | AMORDEGRC |
| Italian | AMORDEGRC |
| Japanese | AMORDEGRC |
| Korean | AMORDEGRC |
| Lithuanian | AMORDEGRC |
| Latvian | AMORDEGRC |
| Norwegian | AMORDEGRC |
| Dutch | AMORDEGRC |
| Polish | AMORT.NIELIN |
| Portuguese (Brazil) | AMORDEGRC |
| Portuguese (Portugal) | AMORDEGRC |
| Romanian | AMORDEGRC |
| Russian | АМОРУМ |
| Slovak | AMORDEGRC |
| Slovenian | AMORDEGRC |
| Serbian (Latin) | AMORDEGRC |
| Swedish | AMORDEGRC |
| Thai | AMORDEGRC |
| Turkish | AMORDEGRC işlevi |
| Ukrainian | AMORDEGRC |
| Vietnamese | AMORDEGRC |
| Chinese (Simplified) | AMORDEGRC |
| Chinese (Hong Kong) | AMORDEGRC |
| Chinese (Traditional) | AMORDEGRC |
Names from Microsoft's support site.
What it does
AMORDEGRC(cost, date_purchased, first_period, salvage, period, rate, [basis])
Two ideas define it, and the second is what separates it from its sibling:
- Proration of the first period. If the asset is bought part-way through the first
accounting period, the first charge is scaled by the fraction of that period the asset was
held. That fraction is a day-count computation on the chosen
basis, fromdate_purchasedtofirst_period. - A declining-balance charge with a statutory coefficient. The annual rate is not
ratebutrate × coefficient, where the coefficient is a step function of the asset's life; and in the last two periods the rate is forced up so the book value is fully written off.
Sketching the schedule the way the documentation describes it:
effective rate = rate × coefficient(1 / rate) first charge = cost × effective rate × first-period fraction later charges = book value × effective rate second-to-last = book value × 50 % last = the whole remaining book value
Microsoft states the last two lines directly: "The depreciation rate will grow to 50 percent for the period preceding the last period and will grow to 100 percent for the last period." And it states the stopping rule: "This function will return the depreciation until the last period of the life of the assets or until the cumulated value of depreciation is greater than the cost of the assets minus the salvage value."
period is 0-based here — period 0 is the prorated first period — which is unusual in
Excel's depreciation category and is the single most common source of an off-by-one answer.
Arguments
AMORDEGRC(cost, date_purchased, first_period, salvage, period, rate, [basis])
| Argument | Meaning | Required? |
|---|---|---|
cost | The cost of the asset. | Required |
date_purchased | The date of purchase. | Required |
first_period | The date of the end of the first period. | Required |
salvage | The salvage value at the end of the asset's life. | Required |
period | The period. 0-based: 0 is the prorated first period. | Required |
rate | The rate of depreciation — the un-accelerated annual rate, whose reciprocal is the life. | Required |
basis | The year basis. | Optional, defaults to 0 |
rate carries two jobs at once: it is the base depreciation rate and, through 1/rate, the
asset's life in periods. Changing rate therefore moves the schedule length and the coefficient
band simultaneously, which is why small changes to it can produce large, discontinuous changes
to the answer.
The basis table for this function is not the usual one. Microsoft's Learn page gives:
basis | Date system |
|---|---|
| 0 or omitted | 360 days (NASD method) |
| 1 | Actual |
| 3 | 365 days in a year |
| 4 | 360 days in a year (European method) |
Date arguments are Excel date serials in numeric slots; see Coercion and lifting.
Try it
Quirks
The depreciation coefficient
Microsoft's Learn page publishes this table:
| Life of assets (1/rate) | Depreciation coefficient |
|---|---|
| Between 3 and 4 years | 1.5 |
| Between 5 and 6 years | 2 |
| More than 6 years | 2.5 |
and immediately below it, this sentence:
"If the life of assets is between 0 (zero) and 1, 1 and 2, 2 and 3, or 4 and 5, the #NUM! error value is returned."
Read together, the documentation says the function is defined only for lives in [3, 4], [5, 6] and (6, ∞), and errors everywhere else — including the whole band between 4 and 5 years, which is a hole in the middle of the domain rather than an edge case.
The two disagree on two named bands, and the disagreement is not subtle:
Result and edge cases
Returns a Number: the depreciation charge for the requested period, in the units of cost.
period= 0 is the first period, and it is the only prorated one. Asking for period 1 on an asset bought mid-period returns a full-period charge, not the prorated one.date_purchasedafterfirst_periodis rejected; the proration fraction would be negative.- Empty, missing and error arguments follow the shared call model; see The value universe.
Errors
Documented on Microsoft's Learn page — one condition only, and it is the coefficient-band
sentence quoted above: a life between 0 and 1, 1 and 2, 2 and 3, or 4 and 5 returns #NUM!.
No other error condition is documented there.
How to implement
Numerical notes
- The coefficient is a step function, so the result is discontinuous in
rate. Crossing a band boundary changes the answer by a finite amount, not by an epsilon. Any implementation that compares1/rateagainst 3, 5 or 6 in floating point is deciding those boundaries with a comparison that a rate like0.2(life exactly 5) will exercise — and1.0/0.2is exactly 5 in binary64, while1.0/0.15is not exactly 6.667. Pin the comparison, and state whether the boundary is inclusive. - The stopping rule needs the whole schedule. There is no closed form for period n: the
book value depends on every rounded charge before it, so the implementation must iterate.
That makes the function
O(period)and makes early-period errors permanent. 1/rateis used both as a coefficient selector and, ceilinged, as the schedule length. Those two uses can disagree for aratewhose reciprocal is barely above an integer.
Rust code
Show the CalcFunc source of this function
Quoted from the public repository DnaCalc/DnaCalc, crates calc-func and calc-fml, at commit 9e1884369a67. Comments are the source's own. A kernel shared with other functions appears once, on its module page.
AMORDEGRC · 6 lines · calc-func/src/catalogue/financial.rs on GitHub27 amordegrc_fn "AMORDEGRC" (6, 7) [V "cost", V "date_purchased", V "first_period", V "salvage", V "period", V "rate", V "basis"] |s, a, sv| {
let purchased = date_1900(s, a, 1, sv)?;
let first = date_1900(s, a, 2, sv)?;
let basis = if given(a, 6) { num(s, a, 6)? } else { 0.0 };
amor_out(s, amor::amordegrc_kernel(num(s, a, 0)?, purchased, first, num(s, a, 3)?, num(s, a, 4)?, num(s, a, 5)?, Some(basis)))
}
normalize_amordegrc_period · 6 lines · calc-func/src/ported/amor_depreciation_family.rs on GitHubfn normalize_amordegrc_period(value: f64) -> Result<i64, AmorDepreciationEvalError> {
if !value.is_finite() || value < 0.0 {
return Err(AmorDepreciationEvalError::Domain(WorksheetErrorCode::Num));
}
Ok(value.floor() as i64)
}
round_half_away_from_zero · 4 lines · calc-func/src/ported/amor_depreciation_family.rs on GitHubfn round_half_away_from_zero(value: f64) -> f64 {
let rounded = (value.abs() + 0.5).floor().copysign(value);
if rounded == -0.0 { 0.0 } else { rounded }
}
amordegrc_coefficient · 15 lines · calc-func/src/ported/amor_depreciation_family.rs on GitHubfn amordegrc_coefficient(rate: f64) -> Result<f64, AmorDepreciationEvalError> {
if !rate.is_finite() || rate <= 0.0 || rate >= 0.5 {
return Err(AmorDepreciationEvalError::Domain(WorksheetErrorCode::Num));
}
let life = 1.0 / rate;
if life < 3.0 {
Ok(1.0)
} else if life < 5.0 {
Ok(1.5)
} else if life <= 6.0 {
Ok(2.0)
} else {
Ok(2.5)
}
}
amordegrc_kernel · 53 lines · calc-func/src/ported/amor_depreciation_family.rs on GitHubpub fn amordegrc_kernel(
cost: f64,
date_purchased: f64,
first_period: f64,
salvage: f64,
period: f64,
rate: f64,
basis: Option<f64>,
) -> Result<f64, AmorDepreciationEvalError> {
if !cost.is_finite() || !salvage.is_finite() || !rate.is_finite() {
return Err(AmorDepreciationEvalError::Domain(WorksheetErrorCode::Num));
}
if cost <= 0.0 || salvage < 0.0 || salvage > cost {
return Err(AmorDepreciationEvalError::Domain(WorksheetErrorCode::Num));
}
let purchase = parse_date_serial(date_purchased)?;
let first = parse_date_serial(first_period)?;
let basis = parse_basis(basis.unwrap_or(0.0))?;
let normalized_period = normalize_amordegrc_period(period)?;
if period > 0.0 && period < 1.0 {
return Ok(0.0);
}
let coefficient = amordegrc_coefficient(rate)?;
let depreciation_rate = rate * coefficient;
let initial_fraction = first_period_fraction(purchase, first, basis)?;
let first_depreciation = round_half_away_from_zero(cost * depreciation_rate * initial_fraction);
if normalized_period == 0 {
return Ok(first_depreciation);
}
let total_periods = (1.0 / rate).ceil() as i64;
let mut book_value = cost - first_depreciation;
for current in 1..=normalized_period {
if book_value < salvage || book_value <= 0.0 {
return Ok(0.0);
}
let remaining_periods = total_periods - current;
let depreciation = if remaining_periods > 2 {
round_half_away_from_zero(book_value * depreciation_rate)
} else if remaining_periods == 2 {
round_half_away_from_zero(book_value * 0.5)
} else {
book_value
};
if current == normalized_period {
return Ok(depreciation.max(0.0));
}
book_value = (book_value - depreciation).max(0.0);
}
Ok(0.0)
}
Kernels shared with other functions
date_1900catalogue/financialamor_outcatalogue/financialdays_from_civillocalecivil_from_dayslocaleexcel_serial_from_ymdlocaleymd_from_excel_seriallocalemax_excel_serialported/amor_depreciation_familyparse_basisported/amor_depreciation_familyparse_date_serialported/amor_depreciation_familydays_in_yearported/amor_depreciation_familydays_in_monthported/amor_depreciation_familyactual_daysported/amor_depreciation_familydays360_usported/amor_depreciation_familydays360_euported/amor_depreciation_familyactual_actual_positiveported/amor_depreciation_familyfirst_period_fractionported/amor_depreciation_familymap_amor_depreciation_error_to_wsported/amor_depreciation_family
Argument and result plumbing
No implementation has been published with a Handbook test suite for this function.
Version differences
No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.
Alternatives
Relationships
- AMORLINC — the same function without the acceleration. Microsoft
describes the pair explicitly:
AMORDEGRC"is similar to AmorLinc, except that a depreciation coefficient is applied in the calculation depending on the life of the assets." Same arguments, same proration, same four-row basis table; different charge per period. - DB — the Anglo-American fixed-declining-balance function. It also prorates a
partial first year, but through a
monthargument rather than a pair of dates, and its rate is derived from the salvage ratio rather than supplied.DBis period-1-based;AMORDEGRCis period-0-based. - DDB and
VDB— declining balance with an explicit factor.VDBis the closest in spirit, since it also handles partial periods, but it prorates by period number rather than by calendar date. SLN,SYD— the straight-line and sum-of-years-digits schedules, with no proration at all.- Confused with:
AMORLINC(above), and withDDB— the coefficient here is not thefactorargument ofDDB; it is derived fromrateand cannot be supplied.
Named variants
No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents