@sheetxl/formulas-extended 0.7.28-beta.4 → 0.8.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/browser/cjs/B4ANcw0mAmhe2Aeb.cjs +1 -0
  2. package/browser/cjs/B6IXpae7f0J8Ocq6.cjs +1 -0
  3. package/browser/cjs/Bncc0oXhFMdj_HuR.cjs +1 -0
  4. package/browser/cjs/C4cZxb9nRtzTCA40.cjs +1 -0
  5. package/browser/cjs/{lEQC21-Sk4lwHy2r.cjs → CFxueP0tbpmvY1Ip.cjs} +1 -1
  6. package/browser/cjs/CRcv32tHTbGSGtkh.cjs +1 -0
  7. package/browser/cjs/CaJGoNwTL6pAJ6a4.cjs +1 -0
  8. package/browser/cjs/CfXcRa4RlFmqU0Op.cjs +1 -0
  9. package/browser/cjs/{CnZfa45XxA-9Jhmp.cjs → DRmo6uoGoqtiVff8.cjs} +1 -1
  10. package/browser/cjs/DSXLVieENYN9qXYl.cjs +1 -0
  11. package/browser/cjs/DpFg69dDCPoOK2BY.cjs +1 -0
  12. package/browser/cjs/PmwvZPFhqmL4DO58.cjs +1 -0
  13. package/browser/cjs/SATfdSwNygvlOSKC.cjs +1 -0
  14. package/browser/cjs/XRCcogT-Iqd3Wv6R.cjs +1 -0
  15. package/browser/cjs/iYn00uzmSLl2T0oN.cjs +1 -0
  16. package/browser/cjs/index.cjs +1 -1
  17. package/{node/esm/CsrMSYiKGo3-I_Qk.mjs → browser/esm/B819DNjPdbTwz9F1.mjs} +1 -1
  18. package/{node/esm/ffkoQUSdLhFyILRL.mjs → browser/esm/BPDTXAH_YiFBVS9b.mjs} +1 -1
  19. package/browser/esm/{fhXUc-E6MSehd9Ep.mjs → Bil0YAk5yZiRX2y1.mjs} +27 -29
  20. package/browser/esm/{DxiRpwBhgWoK5Erd.mjs → Bsu4BOOlbAHpAp8R.mjs} +5 -5
  21. package/browser/esm/BtB39tHAccv8ITPI.mjs +119 -0
  22. package/{node/esm/DoS1jziW_TXjkH37.mjs → browser/esm/BxTcfN8h_FE-sbSK.mjs} +5 -5
  23. package/browser/esm/{BybuwnuafVL8RdTx.mjs → C6Qt3r7mhw1LR02X.mjs} +3 -3
  24. package/browser/esm/C7p2YYAK6S2mN92V.mjs +19 -0
  25. package/browser/esm/CBsy5mA5btmVkbzR.mjs +32 -0
  26. package/browser/esm/{BKnXVC21NesUzU9t.mjs → CIHlNxbWDUWI5fd8.mjs} +1 -1
  27. package/browser/esm/{DsJzZKURvUm7apNu.mjs → CntAjIR6qmdYZXg0.mjs} +2 -2
  28. package/browser/esm/CpVnCV52v4qSBk79.mjs +33 -0
  29. package/browser/esm/D62u7Lj1Nd9ZM4Rp.mjs +58 -0
  30. package/browser/esm/{y9VKeU12ARR9HmtI.mjs → Dov9_ZXeOSh41yWn.mjs} +2 -2
  31. package/browser/esm/{DnFUggiR6cNYknMt.mjs → RHxlSf1j-K7Bdtwt.mjs} +1 -1
  32. package/browser/esm/YWvMccjlBVoxmNN_.mjs +47 -0
  33. package/browser/esm/_cE9OKmzmk6MyRKQ.mjs +37 -0
  34. package/browser/esm/index.mjs +3349 -1660
  35. package/browser/esm/r21pRf-kqnnAD611.mjs +32 -0
  36. package/browser/esm/{CN-pAKHIFQkkdFFB.mjs → v2vXc6oQz1MG0L1T.mjs} +1 -1
  37. package/browser/esm/{XATNfSb9mKkYP5Fr.mjs → vMGzN0Xt0WnzZiH5.mjs} +6 -6
  38. package/{browser/esm/CsrMSYiKGo3-I_Qk.mjs → node/esm/B819DNjPdbTwz9F1.mjs} +1 -1
  39. package/{browser/esm/ffkoQUSdLhFyILRL.mjs → node/esm/BPDTXAH_YiFBVS9b.mjs} +1 -1
  40. package/node/esm/{fhXUc-E6MSehd9Ep.mjs → Bil0YAk5yZiRX2y1.mjs} +27 -29
  41. package/node/esm/{DxiRpwBhgWoK5Erd.mjs → Bsu4BOOlbAHpAp8R.mjs} +5 -5
  42. package/node/esm/BtB39tHAccv8ITPI.mjs +119 -0
  43. package/{browser/esm/DoS1jziW_TXjkH37.mjs → node/esm/BxTcfN8h_FE-sbSK.mjs} +5 -5
  44. package/node/esm/CBsy5mA5btmVkbzR.mjs +32 -0
  45. package/node/esm/{BKnXVC21NesUzU9t.mjs → CIHlNxbWDUWI5fd8.mjs} +1 -1
  46. package/node/esm/{DsJzZKURvUm7apNu.mjs → CntAjIR6qmdYZXg0.mjs} +2 -2
  47. package/node/esm/CpVnCV52v4qSBk79.mjs +33 -0
  48. package/node/esm/D62u7Lj1Nd9ZM4Rp.mjs +58 -0
  49. package/node/esm/{y9VKeU12ARR9HmtI.mjs → Dov9_ZXeOSh41yWn.mjs} +2 -2
  50. package/node/esm/{v9tvQuvQYcFQ0zOs.mjs → LF8AasftSZOpXqHe.mjs} +3 -3
  51. package/node/esm/YWvMccjlBVoxmNN_.mjs +47 -0
  52. package/node/esm/YzY_Aik1Q_7Ay4JY.mjs +19 -0
  53. package/node/esm/_cE9OKmzmk6MyRKQ.mjs +37 -0
  54. package/node/esm/index.mjs +3640 -1947
  55. package/node/esm/r21pRf-kqnnAD611.mjs +32 -0
  56. package/node/esm/{C21UeAwlG4Qkfu1Z.mjs → sXWR_bAqmw8b4bT6.mjs} +1 -1
  57. package/node/esm/{CN-pAKHIFQkkdFFB.mjs → v2vXc6oQz1MG0L1T.mjs} +1 -1
  58. package/node/esm/{XATNfSb9mKkYP5Fr.mjs → vMGzN0Xt0WnzZiH5.mjs} +6 -6
  59. package/package.json +3 -3
  60. package/types/src/.generated/decl/financial/Annuity.decl.d.ts +5 -0
  61. package/types/src/.generated/decl/financial/{Financial.decl.d.ts → Cashflow.decl.d.ts} +1 -1
  62. package/types/src/.generated/decl/financial/Convert.decl.d.ts +4 -0
  63. package/types/src/.generated/decl/financial/Coupon.decl.d.ts +4 -0
  64. package/types/src/.generated/decl/financial/{Financial2.decl.d.ts → Depreciation.decl.d.ts} +1 -1
  65. package/types/src/.generated/decl/financial/Growth.decl.d.ts +4 -0
  66. package/types/src/.generated/decl/financial/{ODD.decl.d.ts → Odd.decl.d.ts} +1 -1
  67. package/types/src/.generated/decl/financial/{Financial3.decl.d.ts → STOCKHISTORY.decl.d.ts} +1 -1
  68. package/types/src/.generated/decl/financial/Security.decl.d.ts +4 -0
  69. package/types/src/.generated/decl/financial/{Financial4.decl.d.ts → SecurityMaturity.decl.d.ts} +1 -1
  70. package/types/src/.generated/decl/{statistical/TTEST.decl.d.ts → financial/TBill.decl.d.ts} +1 -1
  71. package/types/src/.generated/decl/statistical/{ETS.decl.d.ts → Ets.decl.d.ts} +1 -1
  72. package/types/src/.generated/decl/statistical/TTest.decl.d.ts +4 -0
  73. package/types/src/.generated/desc/financial/Annuity.desc.d.ts +5 -0
  74. package/types/src/.generated/desc/financial/{Financial.desc.d.ts → Cashflow.desc.d.ts} +1 -1
  75. package/types/src/.generated/desc/financial/Convert.desc.d.ts +4 -0
  76. package/types/src/.generated/desc/financial/Coupon.desc.d.ts +4 -0
  77. package/types/src/.generated/desc/financial/{Financial2.desc.d.ts → Depreciation.desc.d.ts} +1 -1
  78. package/types/src/.generated/desc/financial/Growth.desc.d.ts +4 -0
  79. package/types/src/.generated/desc/financial/{ODD.desc.d.ts → Odd.desc.d.ts} +1 -1
  80. package/types/src/.generated/desc/financial/{Financial3.desc.d.ts → STOCKHISTORY.desc.d.ts} +1 -1
  81. package/types/src/.generated/desc/financial/Security.desc.d.ts +4 -0
  82. package/types/src/.generated/desc/financial/{Financial4.desc.d.ts → SecurityMaturity.desc.d.ts} +1 -1
  83. package/types/src/.generated/desc/{statistical/TTEST.desc.d.ts → financial/TBill.desc.d.ts} +1 -1
  84. package/types/src/.generated/desc/statistical/{ETS.desc.d.ts → Ets.desc.d.ts} +1 -1
  85. package/types/src/.generated/desc/statistical/TTest.desc.d.ts +4 -0
  86. package/types/src/_utils/AnyArgs.d.ts +17 -3
  87. package/types/src/_utils/Consts.d.ts +2 -2
  88. package/types/src/_utils/FinanaceSolver.d.ts +39 -2
  89. package/types/src/_utils/FinanceAmor.d.ts +23 -0
  90. package/types/src/_utils/FinanceCashflow.d.ts +42 -0
  91. package/types/src/_utils/FinanceCoupon.d.ts +92 -82
  92. package/types/src/_utils/FinanceDate.d.ts +24 -0
  93. package/types/src/_utils/FinanceDayCount.d.ts +46 -0
  94. package/types/src/_utils/FinanceOdd.d.ts +93 -0
  95. package/types/src/_utils/FinanceSecurity.d.ts +84 -0
  96. package/types/src/_utils/FinanceUtils.d.ts +34 -0
  97. package/types/src/_utils/LeastSquares.d.ts +20 -22
  98. package/types/src/_utils/RegexCompile.d.ts +33 -0
  99. package/types/src/cube/Cube.d.ts +7 -7
  100. package/types/src/financial/ACCRINT.d.ts +33 -6
  101. package/types/src/financial/AMORDEGRC.d.ts +22 -40
  102. package/types/src/financial/Annuity.d.ts +118 -0
  103. package/types/src/financial/Cashflow.d.ts +84 -0
  104. package/types/src/financial/Convert.d.ts +26 -0
  105. package/types/src/financial/Coupon.d.ts +72 -0
  106. package/types/src/financial/Date.d.ts +34 -5
  107. package/types/src/financial/Depreciation.d.ts +58 -0
  108. package/types/src/financial/Growth.d.ts +22 -0
  109. package/types/src/financial/Odd.d.ts +82 -0
  110. package/types/src/financial/STOCKHISTORY.d.ts +17 -0
  111. package/types/src/financial/Security.d.ts +68 -0
  112. package/types/src/financial/SecurityMaturity.d.ts +107 -0
  113. package/types/src/financial/TBill.d.ts +40 -0
  114. package/types/src/financial/VDB.d.ts +15 -13
  115. package/types/src/statistical/{ETS.d.ts → Ets.d.ts} +14 -14
  116. package/types/src/statistical/Regression.d.ts +13 -18
  117. package/types/src/statistical/{TTEST.d.ts → TTest.d.ts} +5 -5
  118. package/types/src/text/RegEx.d.ts +34 -11
  119. package/browser/cjs/B4JJfKSI4ppwU855.cjs +0 -1
  120. package/browser/cjs/BwLx9ix5Sq7suAYP.cjs +0 -1
  121. package/browser/cjs/Clu7XiAsCB48GDXN.cjs +0 -1
  122. package/browser/cjs/DsFZgtSQpC75d1M0.cjs +0 -1
  123. package/browser/cjs/fqTQ_p3ehzUvc1tF.cjs +0 -1
  124. package/browser/cjs/h3dw1jAp2J5Pu4p3.cjs +0 -1
  125. package/browser/cjs/jev6VGWTdgEgm4Yk.cjs +0 -1
  126. package/browser/esm/C2TyRseZg5dWtMq1.mjs +0 -304
  127. package/browser/esm/CShl-IMQIPnBMVpb.mjs +0 -20
  128. package/node/esm/C2TyRseZg5dWtMq1.mjs +0 -304
  129. package/node/esm/CShl-IMQIPnBMVpb.mjs +0 -20
  130. package/types/src/financial/Financial.d.ts +0 -283
  131. package/types/src/financial/Financial2.d.ts +0 -99
  132. package/types/src/financial/Financial3.d.ts +0 -95
  133. package/types/src/financial/Financial4.d.ts +0 -82
  134. package/types/src/financial/ODD.d.ts +0 -106
@@ -1,26 +1,4 @@
1
- /**
2
- * Shared pure-math helpers for bond pricing and coupon date functions.
3
- *
4
- * All formulas follow the Excel spec:
5
- * https://support.microsoft.com/en-us/office/financial-functions-reference
6
- *
7
- * Date arithmetic delegates to SheetXL's existing date utilities
8
- * (dateAddMonths, getDaysInMonth, isLastDayOfMonth, getDayCount), and serial
9
- * <-> Date conversion to FormulaContext's `dateOnly` flavors — same interface
10
- * SheetXL uses throughout the financial module.
11
- *
12
- * Basis codes (used throughout):
13
- * 0 US 30/360 (NASD)
14
- * 1 Actual/actual
15
- * 2 Actual/360
16
- * 3 Actual/365
17
- * 4 European 30/360
18
- *
19
- * These are plain number-in / number-out helpers that the formula wrappers
20
- * call after doing all parameter validation and coercion — they touch
21
- * FormulaContext only for serial<->Date conversion, never IRange or
22
- * FormulaError.
23
- */
1
+ import { Omittable, Scalar } from '@sheetxl/primitives';
24
2
  /**
25
3
  * Returns the signed day count between two Excel serial dates using the given
26
4
  * day-count basis. The result is always positive (or zero) — we clamp
@@ -33,70 +11,117 @@
33
11
  export declare function daysBetween(startSerial: number, endSerial: number, basis: number): number;
34
12
  /**
35
13
  * Previous coupon date (COUPPCD):
36
- * Returns the Excel serial number of the last coupon date before or on the
37
- * settlement date.
38
- *
39
- * Used by: COUPPCD, COUPDAYBS, COUPDAYS (basis=1), PRICE, YIELD, DURATION…
14
+ * Returns the Excel serial number of the last coupon date before or on the settlement date.
15
+ * A coupon date below the calendar answers 0 — Excel's clamp, measured.
40
16
  */
41
17
  export declare function calculateCouppcd(settlementSerial: number, maturitySerial: number, frequency: number): number;
42
18
  /**
43
19
  * Next coupon date (COUPNCD):
44
20
  * Returns the Excel serial number of the first coupon date after settlement.
45
- *
46
- * Used by: COUPNCD, COUPDAYSNC, ODDLPRICE (basis 2 / 3 branch).
47
21
  */
48
22
  export declare function calculateCoupncd(settlementSerial: number, maturitySerial: number, frequency: number): number;
49
23
  /**
50
- * Days from previous coupon to settlement (COUPDAYBS):
51
- * The "accrued days" — how many days of the current coupon period have elapsed
52
- * by the settlement date.
53
- *
54
- * Used by: COUPDAYBS, PRICE, YIELD, DURATION, MDURATION.
24
+ * Number of remaining coupons from settlement to maturity (COUPNUM). `NaN` (the caller's
25
+ * #NUM!) when the previous coupon date is at or below serial 0 — `COUPNUM(DATE(1900,1,1),
26
+ * DATE(1900,12,31),4)` is #NUM! while its COUPPCD is 0 (measured).
27
+ */
28
+ export declare function calculateCoupnum(settlementSerial: number, maturitySerial: number, frequency: number): number;
29
+ /**
30
+ * Days from previous coupon to settlement (COUPDAYBS): the day count of the basis from the
31
+ * (clamped) previous coupon date to the settlement — the NASD rules `getDayCount` keeps for
32
+ * basis 0, actual days for 1–3, the European 30/360 for 4.
55
33
  */
56
34
  export declare function calculateCoupdaybs(settlementSerial: number, maturitySerial: number, frequency: number, basis: number): number;
57
35
  /**
58
- * Days in the coupon period that contains settlement (COUPDAYS):
59
- * Basis 1 (actual/actual) counts actual calendar days from PCD to NCD.
60
- * Basis 3 is always 365/frequency.
61
- * All 30/360 bases divide 360 by frequency.
62
- *
63
- * Used by: COUPDAYS, PRICE, YIELD, DURATION, MDURATION, ODDLPRICE, ODDLYIELD.
36
+ * Days from settlement to the next coupon date (COUPDAYSNC). Actual days for bases 1–3. The
37
+ * 30/360 bases are NOT `getDayCount`'s (measured, 556 of 556 rows): the count runs from the
38
+ * settlement's own day — a 31 is 30, and a February month end is NOT 30 unless the
39
+ * settlement IS the previous coupon date, in which case the coupon date's unclamped day is
40
+ * read instead (`COUPDAYSNC(DATE(2011,2,28),DATE(2011,5,31),2,0)` is 92, from day 28;
41
+ * `COUPDAYSNC(DATE(2011,2,28),DATE(2011,8,29),2,0)` is 179, from the chain's `Feb 29`) — to
42
+ * the next coupon date carrying the maturity's day unclamped: at basis 0 a February day at or
43
+ * past the month's end is 30 and a 31 is 30 with no advance into the next month; basis 4
44
+ * caps both ends at 30.
45
+ */
46
+ export declare function calculateCoupdaysnc(settlementSerial: number, maturitySerial: number, frequency: number, basis: number): number;
47
+ /**
48
+ * Days in the coupon period that contains settlement (COUPDAYS). Basis 3 is `365/frequency`
49
+ * and the 30/360 bases `360/frequency`. Basis 1 is Excel's own construction, measured on
50
+ * 2,302 rows (fn-battery financial/COUPDAYS + adhoc-coupdays-b1 + adhoc-coupdays-sweep) and
51
+ * NOT the next coupon minus the previous one (LibreOffice's reading; wrong on 30 of the
52
+ * battery's 225 rows). Excel walks TWO chains back from maturity: one whose day of month
53
+ * decays as it is clamped (`Aug 30 → Feb 29 → Aug 29 → Feb 28 → Aug 28`) and one that stays
54
+ * on the month's last day once a clamp lands there (`Aug 30 → Feb 29 → Aug 31 → Feb 28 →
55
+ * Aug 31`). The decaying chain is walked to the first date on or before the settlement; if
56
+ * the coupon after that date is not the same date in both chains, the period is the decaying
57
+ * chain's, otherwise it is the month-end chain's period around the settlement. So for a Nov 30
58
+ * maturity paid twice a year a settlement of Dec 15 sits in `Nov 30 → May 30` (181) while a
59
+ * settlement of May 30 sits in `Nov 30 → May 31` (182) and one of May 31 in `May 31 → Nov 30`
60
+ * (183). A period that begins below serial 1 is counted in real days (`_periodDays`).
61
+ *
62
+ * Used by: COUPDAYS and {@link couponPeriod}.
64
63
  */
65
64
  export declare function calculateCoupdays(settlementSerial: number, maturitySerial: number, frequency: number, basis: number): number;
66
65
  /**
67
- * Number of remaining coupons from settlement to maturity (COUPNUM):
68
- * Counts how many (12/frequency)-month backward steps from maturity are needed
69
- * to pass settlement.
70
- *
71
- * Used by: COUPNUM, PRICE, YIELD, DURATION, MDURATION, ODDFPRICE, ODDFYIELD.
66
+ * The four arguments of the six coupon functions, read in Excel's order — every one is
67
+ * Excel-declared `any` (a boolean is #VALUE!, an empty argument #N/A, a blank cell 0, a
68
+ * multi-cell reference does not broadcast: `NoLift<>` on every slot): the two dates
69
+ * are coerced and validated (#NUM! for a serial outside the calendar or a settlement not
70
+ * strictly before the maturity once both are truncated), then the frequency is read and
71
+ * validated (1, 2 or 4 after truncation), then the basis — so
72
+ * `COUPDAYS(DATE(2020,1,1),DATE(2019,1,1),"x",0)` is #NUM! and so is the same with a text
73
+ * basis, while a text frequency against a bad basis is #VALUE!. Basis truncates; a negative
74
+ * one is #NUM! before truncation.
72
75
  */
73
- export declare function calculateCoupnum(settlementSerial: number, maturitySerial: number, frequency: number): number;
76
+ export declare function readCouponArgs(settlement: Omittable<Scalar>, maturity: Omittable<Scalar>, frequency: Omittable<Scalar>, basis: Omittable<Scalar>): {
77
+ settlement: number;
78
+ maturity: number;
79
+ frequency: number;
80
+ basis: number;
81
+ };
74
82
  /**
75
- * ODDFPRICE core:
76
- * Prices a bond with an irregular (short or long) first coupon period.
77
- *
78
- * Dispatches to the short-coupon or long-coupon sub-function depending on
79
- * whether DFC < E (short first period) or DFC >= E (long first period).
80
- *
81
- * All arguments are already validated scalars. Returns NaN on degenerate
82
- * inputs (the formula wrapper turns NaN → #NUM!).
83
- *
84
- * Reference:
85
- * https://support.microsoft.com/en-us/office/oddfprice-function-d7d664a8-34df-4233-8d2b-922bcf6a69e1
83
+ * The coupon-period numbers PRICE, YIELD, DURATION and MDURATION are built on, as Excel
84
+ * composes them (measured against Excel's own COUPNUM/COUPDAYBS/COUPDAYS/COUPDAYSNC answers on
85
+ * 572 shapes, fn-battery financial/PRICE + /DURATION, 2026-08-28): `N` is COUPNUM (NaN, the
86
+ * caller's #NUM!, when the previous coupon is below the calendar), `A` is COUPDAYBS, and the
87
+ * period length `E` is COUPDAYS — EXCEPT at basis 1, where it is the real span from the
88
+ * previous coupon to the next (`COUPDAYBS + COUPDAYSNC`), not COUPDAYS' two-chain value; the
89
+ * two differ on the month-end and February maturities (22 of the 225 basis-1 shapes). `DSC` is
90
+ * `E − A`, never COUPDAYSNC.
86
91
  */
87
- export declare function calculateOddFPrice(settlementSerial: number, maturitySerial: number, issueSerial: number, firstCouponSerial: number, rate: number, yld: number, redemption: number, frequency: number, basis: number): number;
92
+ export declare function couponPeriod(settlementSerial: number, maturitySerial: number, frequency: number, basis: number): {
93
+ N: number;
94
+ A: number;
95
+ E: number;
96
+ DSC: number;
97
+ };
88
98
  /**
89
- * Standard coupon bond price.
90
- *
91
- * The closed-form formula per $100 face value from the Excel spec:
92
- * https://support.microsoft.com/en-us/office/price-function-3ea9deac-8dfa-436f-a7c8-17ea02c21b0a
93
- *
94
- * Special-cased for N=1 (single remaining coupon period) where the standard
95
- * summation degenerates and the spec provides a simpler formula.
96
- *
97
- * Used by: PRICE, YIELD (via Newton inversion).
99
+ * Standard coupon bond price per $100 face value — the doc's closed form over
100
+ * {@link couponPeriod}'s numbers: with one coupon left `(coupon + redemption) / (1 + DSC/E ·
101
+ * yld/f) − coupon · A/E` (linear, not the power form), otherwise the redemption and each coupon
102
+ * discounted by `(1 + yld/f)^(k − 1 + DSC/E)` less the accrued coupon. Measured bit-for-bit on
103
+ * PRICE's battery (fn-battery financial/PRICE, 2026-08-28).
104
+ *
105
+ * The grouping is measured too, as ODDFPRICE's is: the coupon sum is accumulated on its own,
106
+ * forward, then the redemption term is added to it and the accrued coupon subtracted. Starting
107
+ * the accumulator at the redemption instead costs 146 of PRICE's 779 census rows and 74 of
108
+ * YIELD's 785 (SXL_CENSUS over the financial suite, 2026-09-09) — the terms and the divisions
109
+ * are identical either way, only the order the additions round in differs. It is visible in
110
+ * YIELD because that answer is a PARTIAL iterate.
111
+ *
112
+ * Used by: PRICE, YIELD.
98
113
  */
99
114
  export declare function calculatePrice(settlementSerial: number, maturitySerial: number, rate: number, yld: number, redemption: number, frequency: number, basis: number): number;
115
+ /**
116
+ * `d/dy` of {@link calculatePrice}, term by term — the slope YIELD's Newton divides by. Analytic,
117
+ * not a difference quotient: a finite difference of any step reproduces neither the hundred-step
118
+ * answers of a redemption that dwarfs the price nor the partially-converged ones (fn-battery
119
+ * financial/adhoc-yield-fingerprint, 2026-09-09). A term that overflows makes the slope infinite,
120
+ * which the caller answers as #NUM!.
121
+ *
122
+ * Used by: YIELD.
123
+ */
124
+ export declare function calculatePriceSlope(settlementSerial: number, maturitySerial: number, rate: number, yld: number, redemption: number, frequency: number, basis: number): number;
100
125
  /**
101
126
  * Macaulay duration of a coupon bond.
102
127
  *
@@ -123,19 +148,4 @@ export declare function calculateDuration(settlementSerial: number, maturitySeri
123
148
  */
124
149
  export declare function calculateDDB(cost: number, salvage: number, life: number, period: number, // 1-based period number
125
150
  factor: number): number;
126
- /**
127
- * Returns true if the settlement and maturity dates are aligned to coupon
128
- * dates — i.e., the day-of-month matches and the month difference is an exact
129
- * multiple of (12/frequency).
130
- *
131
- * Used by ODDFPRICE / ODDFYIELD / ODDLPRICE / ODDLYIELD validators.
132
- */
133
- export declare function isDatesAreAlignedToCoupon(date1Serial: number, date2Serial: number, frequency: number): boolean;
134
- /**
135
- * Returns true if calculateCouppcd(d1, d2, frequency) >= 0.
136
- *
137
- * Used by ODDFPRICE / ODDFYIELD validators.
138
- */
139
- export declare function isCouppcdIsNonNegative(date1Serial: number, date2Serial: number, frequency: number): boolean;
140
- export declare function isValidFrequency(frequency: number): boolean;
141
151
  //# sourceMappingURL=FinanceCoupon.d.ts.map
@@ -23,4 +23,28 @@ export declare function isMoreThanOneYearAfter(startSerial: number, endSerial: n
23
23
  * `setMonth` which truncates automatically.
24
24
  */
25
25
  export declare function dateAddMonths(date: Date, months: number): Date;
26
+ /**
27
+ * Calendar fields of a serial date. `m` is 1-based.
28
+ */
29
+ export interface DateFields {
30
+ y: number;
31
+ m: number;
32
+ d: number;
33
+ }
34
+ /** Days in month `m` (1-based), on the real Gregorian calendar. */
35
+ export declare const daysInMonth: (y: number, m: number) => number;
36
+ /** True when `x` is the last day of its month. */
37
+ export declare const isMonthEnd: (x: DateFields) => boolean;
38
+ /** The workbook calendar's fields for a serial. */
39
+ export declare function getDateFields(serial: number): DateFields;
40
+ /**
41
+ * The serial of calendar fields, extended linearly BELOW the calendar (1899-12-31 is 0, and on
42
+ * down) and with a day past the month's end OVERFLOWING into the next month — a "Feb 30" is
43
+ * Mar 1. The coupon chains that walk off either end of the calendar are measured against Excel
44
+ * on those extended values, so they need an arithmetic that keeps producing them
45
+ * (fn-battery financial/ACCRINT and /ODDLPRICE).
46
+ */
47
+ export declare function getSerialOfFields(y: number, m: number, d: number): number;
48
+ /** The fields `months` months on from `x`, the day clamped to the destination month. */
49
+ export declare function addMonthsClamped(x: DateFields, months: number): DateFields;
26
50
  //# sourceMappingURL=FinanceDate.d.ts.map
@@ -77,4 +77,50 @@ export declare function getDayCount(startSerial: number, endSerial: number, basi
77
77
  *
78
78
  */
79
79
  export declare function getDays360US(startSerial: number, endSerial: number): number;
80
+ /** The last serial of the 1900 calendar (9999-12-31). */
81
+ export declare const MAX_SERIAL_DATE = 2958465;
82
+ /**
83
+ * Excel's date-slot domain for the day-count family, measured on DAYS360, YEARFRAC, DATEDIF
84
+ * and the six coupon functions (fn-battery financial/*, 2026-08-28): the RAW value must not be
85
+ * negative (`-1E-9` is #NUM!) and the truncated serial must not pass 9999-12-31 (`2958465.9` is
86
+ * a legal 9999-12-31). The fraction is otherwise discarded by every function in the family.
87
+ */
88
+ export declare function isSerialDateInRange(serial: number): boolean;
89
+ /**
90
+ * `YEARFRAC` — measured against Excel 16.0 (fn-battery financial/YEARFRAC, 2026-08-28). Both
91
+ * serials are truncated first, the earlier date becomes the start, and basis 0 is then the
92
+ * SIGNED NASD count: Excel orders the dates but never takes a magnitude, so
93
+ * `YEARFRAC(59,60,0)` — 1900-02-28, a real month end, against the phantom 1900-02-29 that is
94
+ * not — is `-1/360`. The other bases cannot go negative once ordered. The caller has validated
95
+ * the serials and the basis.
96
+ */
97
+ export declare function getYearFrac(startSerial: number, endSerial: number, basis: number): number;
98
+ /**
99
+ * The years to maturity a bond-yield ITERATION starts from — not `YEARFRAC`, and not the coupon
100
+ * count over the frequency. Whole years are stepped off the settlement (the day clamped to each
101
+ * destination month) and the remainder is the basis's own day count over the basis's year: the
102
+ * 30/360 counts over 360 at bases 0 and 4, real days over 360 at basis 2 and over 365 at basis 3,
103
+ * and real days over the MATURITY'S OWN year at basis 1 — 366 out of a leap year, whatever the
104
+ * remainder itself covers. Basis 0's February here is the LEGACY calendar's: a Feb 29 start is a
105
+ * month end and a Feb 28 is not, which is neither `getDayCount`'s rule (the real calendar's month
106
+ * end, so Feb 28 counts too) nor `getDays360US`'s (which also lets the conversion steer the end).
107
+ *
108
+ * Measured on 1,154 rows where the answer depends on nothing else (fn-battery
109
+ * financial/adhoc-yield-n, -n2, -n3), 2026-09-09.
110
+ *
111
+ * Used by: YIELD, ODDFYIELD.
112
+ */
113
+ export declare function getYearsToMaturity(settlement: number, maturity: number, basis: number): number;
114
+ /**
115
+ * The stub-period day count of AMORLINC/AMORDEGRC (the year fraction is `days / yearDays`, and
116
+ * the caller groups that as Excel does) — measured against Excel 16.0 (fn-battery
117
+ * financial/AMORLINC, /AMORDEGRC, 2026-08-28), and NOT YEARFRAC's: serials are truncated, the
118
+ * 30/360 bases count days as `getDayCount` does over 360, basis 3 is actual days over 365, and
119
+ * basis 1 is actual days over the length of the PURCHASE year (366 only when that year is a
120
+ * Gregorian leap year — 1900 is not — whatever the span crosses; 2007-12-31 → 2008-12-31 is
121
+ * 366/365), and in both actual bases a real Feb 29 counts as the 28th (`_feb29AsFeb28`). A zero-day stub is a whole period (`purchase = first period`, or Dec 30 → Dec 31
122
+ * at basis 0), and a stub longer than a year is not capped. Basis 2 is not accepted by either
123
+ * function; the caller has refused it before this is called.
124
+ */
125
+ export declare function getAmorDayCount(purchased: number, firstPeriod: number, basis: number): DayCount;
80
126
  //# sourceMappingURL=FinanceDayCount.d.ts.map
@@ -0,0 +1,93 @@
1
+ import { Omittable, Scalar } from '@sheetxl/primitives';
2
+ /**
3
+ * The odd-coupon securities' shared machinery — the quasi-coupon chain of an irregular period
4
+ * and the day-count sums the price and yield forms are built from, measured against Excel 16.0
5
+ * (fn-battery financial/ODDLPRICE + /ODDLYIELD + /ODDFPRICE and the `adhoc-oddl-*` /
6
+ * `adhoc-oddf-*` probes, 2026-08-28/29).
7
+ */
8
+ /**
9
+ * `(settlement, maturity, …dates, …numbers, frequency, [basis])` as the four ODD functions read
10
+ * it: every slot is Excel-declared `any` (a boolean is #VALUE!, an empty argument #N/A, a blank
11
+ * cell 0, a multi-cell reference does not broadcast — `NoLift<>` on every slot), and the order is
12
+ * coupon six's, not PRICE's. Each DATE is coerced and range-checked as it is read, so a negative
13
+ * `last_interest` is #NUM! over a text frequency; then the numbers are coerced; then the
14
+ * frequency is validated (1, 2 or 4 after truncation); then the BASIS, last. Only after all of
15
+ * that do the date ORDER and the signs decide — a text frequency beats a settlement that is
16
+ * after its maturity. Serials come back truncated.
17
+ */
18
+ export declare function readOddArgs(dates: Omittable<Scalar>[], numbers: Omittable<Scalar>[], frequency: Omittable<Scalar>, basis: Omittable<Scalar>): {
19
+ dates: number[];
20
+ numbers: number[];
21
+ frequency: number;
22
+ basis: number;
23
+ };
24
+ /**
25
+ * The three day-count sums of the odd LAST period `[lastInterest, maturity]`, in coupon-period
26
+ * units — the numbers ODDLPRICE and ODDLYIELD are built from. Measured on 1,780
27
+ * (shape, frequency, basis) triples, each sum exact (`fn-battery/financial/fit-oddl.mjs`).
28
+ *
29
+ * It takes TWO chains, as COUPDAYS' basis 1 did (batch 3): the DECAYING chain anchored at
30
+ * `lastInterest` gives the period ends and their lengths, while the STICKY chain decides only
31
+ * which period the maturity lands in — so an Aug 31 maturity against a decayed Aug 28 boundary
32
+ * is still inside the period that ENDS there and overhangs it by three days.
33
+ *
34
+ * Over the periods `[B₀ = lastInterest, B₁] … [B_{J−1}, B_J]`:
35
+ *
36
+ * - `A` and `DSC` walk their span (`lastInterest → settlement`, `settlement → maturity`) period
37
+ * by period, no period contributing more than itself — a 31st period end counted raw runs one
38
+ * day past its own length.
39
+ * - `DC` counts every period 1 except the last, which is measured BACKWARD from its end,
40
+ * `(NL − count(maturity, B_J)) / NL`. That is what makes `DC ≠ A + DSC` at basis 0.
41
+ *
42
+ * A chain that leaves the calendar is #NUM!: past its end going forward, and — stepping BACK
43
+ * from the MATURITY to the first date at or below `lastInterest` — below serial 1 going back
44
+ * (measured: a ladder landing on serial 1 computes, one landing on serial 0 is #NUM!).
45
+ */
46
+ export declare function oddLastSums(settlement: number, maturity: number, lastInterest: number, frequency: number, basis: number): {
47
+ A: number;
48
+ DC: number;
49
+ DSC: number;
50
+ };
51
+ /**
52
+ * The numbers ODDFPRICE's form is built from — `N` regular coupons after `firstCoupon`, the
53
+ * accrued sum `A` and the first coupon's sum `DC` (both in coupon-period units), and `u`, the
54
+ * fractional exponent every cash flow after the settlement is discounted by. Measured on 1,125
55
+ * (shape, frequency, basis) triples, the four sums solved out of Excel by linearity
56
+ * (`fn-battery/financial/oddf-model.mjs`, `verify-oddf.mjs`, `adhoc-oddf-*`, 2026-08-29).
57
+ *
58
+ * The maturity must sit on `firstCoupon`'s grid — `COUPPCD(firstCoupon, maturity) = firstCoupon`
59
+ * — and the doc's two branches are real, on DIFFERENT date machinery. `E` is the regular period
60
+ * around the settlement on that grid, PRICE's {@link couponPeriod} (`COUPDAYBS + COUPDAYSNC` at
61
+ * basis 1); `DFC` the basis's count issue → firstCoupon:
62
+ *
63
+ * - `DFC = E` is #NUM! — an odd period that is exactly a regular one.
64
+ * - SHORT (`DFC < E`): one period, every count over `E` — `A = issue→settlement`, `DC = DFC`,
65
+ * `u = settlement→firstCoupon`, the last straight from the settlement (the NASD advance
66
+ * included). `N` is `COUPNUM(settlement, maturity) − 1`, which counts a grid date between the
67
+ * settlement and the first coupon when there is one (a settlement in the gap between a
68
+ * decayed boundary and its sticky twin).
69
+ * - LONG (`DFC > E`): `COUPNUM(issue, firstCoupon)` quasi periods on the STICKY grid, their
70
+ * boundaries walked DECAYED back from `firstCoupon` (each step subtracts `12/f` months from
71
+ * the previous date and clamps: an Aug 31 anchor semiannual is Feb 28, then Aug 28) — so the
72
+ * earliest period can end at or before the issue and count nothing. `NL` is each period's
73
+ * own actual span at basis 1, `360/f` or `365/f` elsewhere; `A` walks issue → settlement as
74
+ * days over `NL`; `DC` is the issue's period as days over `NL` and every later period exactly
75
+ * 1 (the doc's DCᵢ — visible at bases 2 and 3). The exponent `u = Nq + DSC/E` is on the
76
+ * sticky grid instead: `DSC = E − COUPDAYBS` at bases 0/1/4 and the actual days to the next
77
+ * grid date at 2/3, and `Nq` is `COUPNUM(settlement, firstCoupon) − 1` PLUS ONE on a
78
+ * month-end first coupon — Excel discounts every cash flow one period too far — unless the
79
+ * settlement is itself a month end or its month holds an earlier quasi-coupon date
80
+ * (`adhoc-oddf-nq`, 957 settlements swept day by day).
81
+ *
82
+ * A chain that walks below the calendar is #NUM! in either branch (a settlement in the first
83
+ * days of 1900 has quasi dates in 1899).
84
+ */
85
+ export declare function oddFirstSums(settlement: number, maturity: number, issue: number, firstCoupon: number, frequency: number, basis: number): {
86
+ N: number;
87
+ A: number;
88
+ DC: number;
89
+ u: number;
90
+ };
91
+ /** The ATP arithmetic of the family: a product that overflowed is 0 (batch 4's `overflowIsZero`). */
92
+ export declare const zeroIfOverflow: (value: number) => number;
93
+ //# sourceMappingURL=FinanceOdd.d.ts.map
@@ -0,0 +1,84 @@
1
+ import { Omittable, Scalar } from '@sheetxl/primitives';
2
+ /**
3
+ * Argument readers for the securities functions — every slot Excel-declared `any`, read in the
4
+ * order Excel reads them (measured against Excel 16.0, fn-battery financial/*, 2026-08-28).
5
+ *
6
+ * Two orders exist in the family. The discount securities (DISC PRICEDISC YIELDDISC INTRATE
7
+ * RECEIVED) CONVERT from the last slot to the first and only then look for errors in slot
8
+ * order; ACCRINTM, ACCRINT and the coupon functions convert and validate each slot from the
9
+ * first. Each function names its own.
10
+ */
11
+ /** The basis slot: omitted or blank is 0, text parses, a boolean is #VALUE!, out of 0–4 after truncation is #NUM!. */
12
+ export declare function readBasis(basis: Omittable<Scalar>): number;
13
+ /** The two dates of a security, truncated, both in the calendar and the settlement strictly first — else #NUM!. */
14
+ export declare function checkDateOrder(settlement: number, maturity: number): {
15
+ settlement: number;
16
+ maturity: number;
17
+ };
18
+ /**
19
+ * `(settlement, maturity, x, y, [basis])` as DISC, PRICEDISC, YIELDDISC, INTRATE and RECEIVED
20
+ * read it: the basis FIRST — coerced and range-checked, so a text basis is #VALUE!, a basis of 5
21
+ * is #NUM! and an error there is the answer whatever an earlier slot holds — then the four
22
+ * slots from the first, each coerced (its error or a text answered) before the next is read;
23
+ * then the domain: serials in the calendar, `settlement < maturity` once truncated, `x > 0`,
24
+ * `y > 0`. An omitted required slot is #N/A, a blank cell 0.
25
+ */
26
+ export declare function readDiscountArgs(settlement: Omittable<Scalar>, maturity: Omittable<Scalar>, x: Omittable<Scalar>, y: Omittable<Scalar>, basis: Omittable<Scalar>): {
27
+ settlement: number;
28
+ maturity: number;
29
+ x: number;
30
+ y: number;
31
+ basis: number;
32
+ };
33
+ /**
34
+ * `(settlement, maturity, x)` as TBILLEQ, TBILLPRICE and TBILLYIELD read it: each slot coerced
35
+ * from the first (an error or a text is answered before the next slot is read, so a text `x`
36
+ * beats swapped dates), then the domain: both serials in the calendar, `settlement < maturity`
37
+ * once truncated, the maturity at most one calendar year out ({@link _anniversary}), `x > 0`.
38
+ * `days` is the actual span of the truncated serials.
39
+ */
40
+ export declare function readTbillArgs(settlement: Omittable<Scalar>, maturity: Omittable<Scalar>, x: Omittable<Scalar>): {
41
+ settlement: number;
42
+ maturity: number;
43
+ x: number;
44
+ days: number;
45
+ };
46
+ /**
47
+ * `(settlement, maturity, issue, rate, x, [basis])` as PRICEMAT and YIELDMAT read it: the basis
48
+ * first (coerced and range-checked, so a text basis is #VALUE! and a basis of 5 #NUM! whatever
49
+ * the other slots hold, and an error there wins), then the five slots from the first, each
50
+ * coerced before the next is read; then the domain — every serial in the calendar,
51
+ * `issue < settlement < maturity` once truncated, and the signs the caller checks. The three
52
+ * day counts come back with `DSM` as `DIM − A`, which is how Excel has it: at basis 0 a Feb 28
53
+ * settlement against a Mar 31 maturity counts 32 days inside a Jan 31 issue (60 − 28), where
54
+ * the NASD count of the pair alone is 31. `B` is the year length of the issue→settlement pair.
55
+ */
56
+ export declare function readMatArgs(settlement: Omittable<Scalar>, maturity: Omittable<Scalar>, issue: Omittable<Scalar>, rate: Omittable<Scalar>, x: Omittable<Scalar>, basis: Omittable<Scalar>): {
57
+ rate: number;
58
+ x: number;
59
+ DIM: number;
60
+ DSM: number;
61
+ A: number;
62
+ B: number;
63
+ };
64
+ /**
65
+ * `(settlement, maturity, …numbers, frequency, [basis])` as PRICE, YIELD, DURATION and
66
+ * MDURATION read it (measured on all four, fn-battery 2026-08-28). PRICE and YIELD read the
67
+ * basis FIRST — coerced and range-checked, so a text basis is #VALUE! and a 5 is #NUM! whatever
68
+ * else is wrong, and an error there wins over an error in the settlement; DURATION and
69
+ * MDURATION read it LAST (`basisLast`), the coupon functions' way. In between, the settlement
70
+ * and the maturity are each coerced and checked against the calendar before the next slot is
71
+ * read (a negative settlement is #NUM! over a text frequency), then the numeric slots are
72
+ * coerced, then the frequency is coerced and validated (1, 2 or 4 after truncation); the date
73
+ * order (`settlement < maturity` once truncated) and the signs of the numbers come last.
74
+ */
75
+ export declare function readBondArgs(settlement: Omittable<Scalar>, maturity: Omittable<Scalar>, numbers: Omittable<Scalar>[], frequency: Omittable<Scalar>, basis: Omittable<Scalar>, basisLast?: boolean): {
76
+ settlement: number;
77
+ maturity: number;
78
+ numbers: number[];
79
+ frequency: number;
80
+ basis: number;
81
+ };
82
+ /** Excel's Analysis-ToolPak arithmetic answers 0 for a product that overflowed (measured on ACCRINTM, TBILLEQ, TBILLPRICE, PRICEMAT). */
83
+ export declare const overflowIsZero: (value: number) => number;
84
+ //# sourceMappingURL=FinanceSecurity.d.ts.map
@@ -1,4 +1,25 @@
1
1
  import { IRuntime } from '@sheetxl/primitives';
2
+ /**
3
+ * The secant step cap shared by RATE and IRR — Excel gives up after 200, not the documented 20
4
+ * (measured on one 24-period loan: a path of 200 steps converges, one of 203 is #NUM!). IRR runs
5
+ * the same iteration on the discount factor rather than the rate, so the cap is one fact.
6
+ */
7
+ export declare const RATE_MAX_ITERATIONS = 200;
8
+ /**
9
+ * The currency format Excel gives a financial result cell, in the runtime's locale.
10
+ *
11
+ * @remarks
12
+ * Which functions auto-format is a per-function fact and was MEASURED across the category
13
+ * (2026-08-29, `Range.NumberFormat` read after a `Formula2` entry into a General cell): the
14
+ * legacy core formats by result kind — money through this helper (NPV PMT IPMT PPMT FV PV SLN
15
+ * SYD DB DDB VDB) and a rate as `0%` (IRR MIRR RATE) — while everything ATP-era or added later
16
+ * sets nothing at all (XIRR XNPV NPER ISPMT RRI PDURATION EFFECT NOMINAL FVSCHEDULE CUMIPMT
17
+ * CUMPRINC and every security, COUPNCD and COUPPCD included).
18
+ *
19
+ * Excel applies it at ENTRY, before it knows the answer, so a `#NUM!`, `#VALUE!` or `#DIV/0!`
20
+ * cell carries the format too. That is why every `formatResults` call in this category LEADS its
21
+ * body instead of following the domain guards.
22
+ */
2
23
  export declare const defaultCurrencyFormat: (runtime: IRuntime) => string;
3
24
  /**
4
25
  * `base ^ exponent` as Excel evaluates it (the `^` operator, POWER, and the powers inside the
@@ -17,4 +38,17 @@ export declare const defaultCurrencyFormat: (runtime: IRuntime) => string;
17
38
  * A zero base follows the `^` operator: `0^0` is #NUM! and `0^negative` is #DIV/0!.
18
39
  */
19
40
  export declare const excelPow: (base: number, exponent: number) => number;
41
+ /**
42
+ * Excel's C `(int)` cast of an argument: truncation toward zero, and INT_MIN for anything out of
43
+ * the 32-bit range (the x64 `cvttsd2si` convention), NaN included. Measured on DB (fn-battery,
44
+ * 2026-08-28): `DB(…,3E9,2E9)` is #NUM! because only `life` overflows to INT_MIN while
45
+ * `DB(…,1E10,5E9)` is 0 because both do.
46
+ */
47
+ export declare const excelInt32: (value: number) => number;
48
+ /**
49
+ * Round to `digits` decimals as Excel's ROUND does: ties away from zero, decided on the value's
50
+ * 15-significant-digit decimal form rather than its binary one — `550 · 0.45` is
51
+ * 247.49999999999997 in double and Excel rounds it to 248 (AMORDEGRC, measured 2026-08-28).
52
+ */
53
+ export declare const excelRound: (value: number, digits?: number) => number;
20
54
  //# sourceMappingURL=FinanceUtils.d.ts.map
@@ -1,4 +1,4 @@
1
- import { FormulaError, IRange } from '@sheetxl/primitives';
1
+ import { FormulaError, IRange, IReferenceRange, Scalar } from '@sheetxl/primitives';
2
2
  /**
3
3
  * How Excel reads `known_y` / `known_x` into (observations x predictors).
4
4
  *
@@ -33,15 +33,22 @@ export interface RegressionData {
33
33
  /**
34
34
  * Reads `known_y` / `known_x` the way the whole LINEST family does.
35
35
  *
36
- * STRICT membership: any non-numeric member of either range — text, boolean, or BLANK — is
37
- * `#VALUE!`. There is no skipping and no coercion here (`LINEST({2;TRUE;5;4}, …)` and
38
- * `LINEST({2;"3";5;4}, …)` are both `#VALUE!`), which is the opposite of the paired statistics
39
- * (CORREL/SLOPE/…) where a non-numeric member drops its pair. Dropping a member here would shift
40
- * every later observation against its x and silently return a different fit.
36
+ * The SHAPES are judged first — a mismatch is #REF! whatever the members hold — and then the
37
+ * members, in order. Membership is STRICT: any non-numeric member of either range — text,
38
+ * boolean, or BLANK — is `#VALUE!`. There is no skipping and no coercion here
39
+ * (`LINEST({2;TRUE;5;4}, …)` and `LINEST({2;"3";5;4}, …)` are both `#VALUE!`), which is the
40
+ * opposite of the paired statistics (CORREL/SLOPE/…) where a non-numeric member drops its pair.
41
+ * Dropping a member here would shift every later observation against its x and silently return a
42
+ * different fit.
41
43
  *
42
- * @throws #VALUE! on a non-numeric member, #REF! on a dimension mismatch.
44
+ * `log` is the LOGEST/GROWTH read: each y is checked as it is met, so a y at or below zero is
45
+ * #NUM! even when a text member sits later in the range, and the ys come back as their logarithms.
46
+ *
47
+ * @throws #VALUE! on a non-numeric member, #REF! on a dimension mismatch, #NUM! on a y without a
48
+ * logarithm.
43
49
  */
44
- export declare const readRegressionData: (knownYs: IRange, knownXs: IRange | undefined) => RegressionData;
50
+ export declare const readRegressionData: (knownYs: IRange, knownXs: IRange | undefined, log?: boolean) => RegressionData;
51
+ export declare const overLogical: (value: boolean | IReferenceRange | IReferenceRange[] | null | undefined, absent: boolean, compute: (value: boolean) => Scalar[][]) => Scalar[][];
45
52
  /**
46
53
  * Reads a `new_x` range into (observations x k), and reports the shape its predictions spill into.
47
54
  *
@@ -57,15 +64,6 @@ export declare const readNewX: (newXs: IRange, data: RegressionData) => {
57
64
  rows: number;
58
65
  cols: number;
59
66
  };
60
- /**
61
- * `ln(y)` for the log-space members of the family (LOGEST / GROWTH).
62
- *
63
- * A y at or below zero has no logarithm, and Excel reports that as #NUM! — a distinct outcome from
64
- * the #VALUE! a non-numeric member gets, so the two checks stay separate.
65
- *
66
- * @throws #NUM! when any y is <= 0.
67
- */
68
- export declare const toLogYs: (ys: number[]) => number[];
69
67
  /**
70
68
  * Evaluates a fit over `new_x`, in the shape Excel spills.
71
69
  *
@@ -73,7 +71,7 @@ export declare const toLogYs: (ys: number[]) => number[];
73
71
  * the fitted values, so a 6x2 `known_y` spills 6x2. Otherwise the shape comes from `new_x`
74
72
  * ({@link readNewX} decides whether that is element-wise or one row/column per observation).
75
73
  */
76
- export declare const predictInShape: (data: RegressionData, newXs: IRange | undefined, predict: (x: number[]) => number) => number[][];
74
+ export declare const predictInShape: (data: RegressionData, newXs: IRange | undefined, predict: (x: number[]) => Scalar) => Scalar[][];
77
75
  /** A fitted model — coefficients in Excel's slot order plus everything the stats grid needs. */
78
76
  export interface RegressionFit {
79
77
  /**
@@ -81,11 +79,11 @@ export interface RegressionFit {
81
79
  * belongs to the LAST column of `known_x`.
82
80
  */
83
81
  coefficients: number[];
84
- /** Standard errors in the same slot order. `se[k]` is meaningless when `!useConst` (Excel: #N/A). */
82
+ /** Standard errors in the same slot order. `se[k]` is meaningless when `!constant` (Excel: #N/A). */
85
83
  standardErrors: number[];
86
84
  /** Number of predictors actually used — a column dropped for rank deficiency does not count. */
87
85
  kEffective: number;
88
- /** `n - kEffective - (useConst ? 1 : 0)`. */
86
+ /** `n - kEffective - (constant ? 1 : 0)`. */
89
87
  df: number;
90
88
  /** Standard error of the y estimate. 0 when `df <= 0`, which is what Excel returns. */
91
89
  sey: number;
@@ -111,7 +109,7 @@ export interface RegressionFit {
111
109
  * The same path covers "not enough observations": with n = 2 and 2 predictors the second column
112
110
  * has no residual left and is dropped, which is exactly what Excel returns.
113
111
  */
114
- export declare const fitLeastSquares: (ys: number[], xs: number[][], useConst: boolean) => RegressionFit;
112
+ export declare const fitLeastSquares: (ys: number[], xs: number[][], constant: boolean) => RegressionFit;
115
113
  /**
116
114
  * The `stats = TRUE` grid: 5 rows x (k + 1) columns.
117
115
  *
@@ -127,5 +125,5 @@ export declare const fitLeastSquares: (ys: number[], xs: number[][], useConst: b
127
125
  * `se(b)` when the intercept was not fitted — the b slot itself still carries a value (0 for
128
126
  * LINEST, 1 for LOGEST), it is only its error that is #N/A.
129
127
  */
130
- export declare const buildStatsGrid: (fit: RegressionFit, coefficients: number[], useConst: boolean) => (number | FormulaError.Known)[][];
128
+ export declare const buildStatsGrid: (fit: RegressionFit, coefficients: (number | FormulaError.Known)[], constant: boolean) => (number | FormulaError.Known)[][];
131
129
  //# sourceMappingURL=LeastSquares.d.ts.map
@@ -0,0 +1,33 @@
1
+ import { FormulaError } from '@sheetxl/primitives';
2
+ /** A compiled Excel pattern: the regex, and how many capture groups it has. */
3
+ export interface CompiledPattern {
4
+ regex: RegExp;
5
+ groups: number;
6
+ }
7
+ /**
8
+ * Compiles one of Excel's patterns, or `#VALUE!` when neither reading of it will compile.
9
+ *
10
+ * The translated form is tried first, under `u`. A pattern that will not compile that way is
11
+ * retried EXACTLY AS WRITTEN and without `u` — that is the pre-translation reading, and it keeps
12
+ * the patterns that only `u`'s stricter escaping would have broken (`\-` outside a class) working.
13
+ */
14
+ export declare const compilePattern: (pattern: string, caseInsensitive: boolean, extraFlags?: string) => CompiledPattern | FormulaError.Known;
15
+ /**
16
+ * Excel's replacement text, as JavaScript's.
17
+ *
18
+ * The two languages nearly agree — `$1`, `$&`, `` $` `` and `$'` mean the same in both — and
19
+ * differ in three places: Excel's `$0` is the whole match (JavaScript spells that `$&`), its
20
+ * `${1}` and `${name}` are references where JavaScript reads them literally, and a reference to a
21
+ * group that does not exist is `#VALUE!` rather than literal text. That last one is why this
22
+ * returns an error instead of a string: `REGEXREPLACE("ab","(a)(b)","$3")` is refused by Excel,
23
+ * and so is a lone `$`.
24
+ */
25
+ export declare const translateReplacement: (replacement: string, groups: number) => string | FormulaError.Known;
26
+ /**
27
+ * Excel's 0-or-1 enum slots (`caseSensitivity`, and `returnMode`'s three values).
28
+ *
29
+ * Truncated first — 1.5 is 1 — and anything outside the list is `#VALUE!`, including a huge value
30
+ * and non-numeric text.
31
+ */
32
+ export declare const readMode: (value: number, max: number) => number | FormulaError.Known;
33
+ //# sourceMappingURL=RegexCompile.d.ts.map