Repository navigation
Category Finance
Home › All Categories › Finance
#import "std/money"
using moneyA module is imported whole. Its files, in pkg/std/money/, are currency.tiko and
decimal.tiko for the money types, and finerror.tiko, fincore.tiko, finsolve.tiko,
fintvm.tiko, finloan.tiko, fincash.tiko, findeprec.tiko, finport.tiko for the
finance functions.
This category is in two halves. The money types come first, because everything else is built on them. The finance functions follow -- interest and rate conventions, the time value of money, loans and amortization schedules, cash-flow appraisal, depreciation, and portfolio returns and risk.
An amount held in a DOUBLE is one rounding away from a penny that does not reconcile, because 0.1 + 0.2 <> 0.3 in binary floating point. These two types are the answer, and which one you want is a single question: is four decimal places enough?
Currency |
Decimal |
|
|---|---|---|
| representation |
LONGINT scaled by 10,000 |
96-bit mantissa + scale + sign |
| range | ±922,337,203,685,477.5807 | ±79,228,162,514,264,337,593,543,950,335 |
| decimal places | 4, always | 0..28, per value |
| significant digits | 19 | 28-29 |
| size | 8 bytes | 16 bytes |
| add | one instruction | software multi-precision |
| the type it already is | VB6/VBA Currency, COM CY, SQL Server money
|
.NET System.Decimal, COM DECIMAL, SQL Server decimal(28,s)
|
Use Currency when four places is enough. It is the cheaper type by a wide margin and this category does not deprecate it. Use Decimal when four places is the thing standing in the way -- FX rates quoted to six or eight, per-unit costs, per-mille rates, interest accrual, tax tables. DecimalFromCurrency( c ) and d.ToCurrency( ) convert between them.
Neither is a new representation. Both are shapes that Windows, COM and SQL Server have used for decades: win\wtypes.bi declares tagCY at line 326 and tagDEC at line 329. Each type here has the matching layout, so the interop boundary is a reinterpret rather than a conversion.
No arithmetic is delegated to OleAut32. This compiler ships and gates on linux-x86_64 and macos-arm64, so the arithmetic is implemented in tiko and VarCy*, VarDec* and .NET itself are test oracles rather than dependencies. Both types behave identically on every target.
One set of rules, not two. The two types deliberately agree on everything they can:
-
Construction is by free function, not constructor. A one-argument constructor taking
LONGINTwould also accept aDOUBLEthrough implicit conversion, soCurrency( 19.99 )would have compiled and stored 19. Naming every conversion means the inexact one cannot be reached by accident. -
Half-to-even is the default, because half-up biases every tie the same way and across a million lines that is real money. The mode names match:
CUR_HALF_EVEN/DEC_HALF_EVENand their six siblings. -
Overflow is
Invalid, it is infectious, andInvalid = Invalidis FALSE -- the same rulestd/chronouses forDateTime. Test withIsValid( ). A default-constructed value is zero and valid. -
Text is exact both ways, with no
DOUBLEanywhere in the path, and parsing is strict: the whole string must be consumed, and more than the type's decimal places is an error rather than a truncation. -
Apportionsplits a total so the parts sum exactly to it. Largest-remainder, in both types.
Defined in currency.tiko.
dim as Currency price = CurrencyParse( "19.99" ).Value( )
dim as Currency line_ = price * 3 ' EXACT
print line_.ToString( ) ' 59.9700A LONGINT scaled by 10,000. Fifteen digits left of the point, four to the right, every value in range exactly representable.
range -922,337,203,685,477.5808 .. +922,337,203,685,477.5807
resolution 0.0001 exactly, everywhere
size 8 bytes
This is the VB6/VBA Currency type, the COM CY / VT_CY type, and SQL Server's money. CY is already declared in win\wtypes.bi, line 326, as a union whose int64 member is exactly this field, so the interop boundary is a reinterpret.
The cost, up front: four decimal places, fixed. FX rates are quoted to 6 or 8, per-unit costs and per-mille rates often need more, and a Currency cannot hold them. CurrencyAccum covers the case that actually loses money; it does not cover storage. If you need to store more than four places, this is the wrong type.
CurrencyFromInt( n ) CurrencyFromRaw( scaled )
CurrencyFromParts( w, tt ) CurrencyFromDouble( d )
CurrencyParse( s ) -> Optional( of Currency )
A one-argument constructor taking LONGINT would also accept a DOUBLE through implicit conversion, so Currency( 19.99 ) would have compiled and stored 19. Naming every conversion means the inexact one cannot be reached by accident.
a + b, a - b EXACT, overflow-checked
a * n (integer) EXACT, overflow-checked
a * x (float64) rounded half-to-even
a / n (integer) rounded HALF-TO-EVEN, not truncated
a / b (Currency) DOUBLE -- a ratio is not an amount
a MOD b, -a, comparisons
Currency * Currency does not exist: money times money is not money.
Division rounds; it does not truncate:
Currency(1) / 3 ' 0.3333
Currency(2) / 3 ' 0.6667 -- truncation would give 0.6666Truncation biases every result downward, systematically, across a ledger.
Overflow is Invalid, it is infectious, and Invalid = Invalid is FALSE -- the same rule as DateTime. Test with IsValid( ). A default-constructed Currency is zero and valid: zero is the meaningful default for money.
c.Round( digits ) half-to-even, digits 0..4
c.RoundMode( digits, mode ) CUR_HALF_EVEN CUR_HALF_UP
CUR_HALF_DOWN CUR_UP CUR_DOWN
CUR_CEILING CUR_FLOOR
c.Floor( ) c.Ceiling( ) c.Truncate( ) c.AbsValue( ) c.Sign( )
Apportion( total, weights( ), result( ) )
Apportion is the most useful function here. Splitting 100.00 three ways gives 33.3333 each, whose sum is 99.9999. Every accounting system has to decide where the missing unit goes, and doing it ad hoc is how a reconciliation fails. Largest-remainder: the parts always sum to the total, exactly.
33.3334 + 33.3333 + 33.3333 = 100.0000
dim acc as CurrencyAccum
acc.Reset( )
for each line_ in invoice
acc.AddProduct( line_.amount, taxRate )
next
dim as Currency tax = acc.Total( ) ' quantised ONCEversus the version that loses money, which rounds at every line. The accumulator carries eight extra decimal places in a 128-bit value. AddScaled( c, num, den ) is the exact form; Add( c ) is exact addition.
Text is exact both ways -- no DOUBLE anywhere in the path. ToString always prints four decimals, invariant separator, no grouping. More than four decimal places on input is an error, not a truncation:
CurrencyParse( "1.23456" ) ' empty -- not silently 1.2345Defined in decimal.tiko.
dim as Decimal price = DecimalParse( "19.99" ).Value( )
dim as Decimal line_ = price * 3 ' 59.97 EXACT
dim as Decimal rate = DecimalParse( "0.0825" ).Value( )
print ( line_ * rate ).ToString( ) ' 4.947525 EXACT, six placesA 96-bit integer, a scale, and a sign. The value is ( -1 ^ sign ) * mantissa / 10 ^ scale, with mantissa in 0 .. 2^96-1 and scale in 0 .. 28.
range -79,228,162,514,264,337,593,543,950,335
.. +79,228,162,514,264,337,593,543,950,335
precision 28-29 significant decimal digits
smallest 0.0000000000000000000000000001 (1e-28)
size 16 bytes
This is the .NET System.Decimal of C# and VB.NET, the COM DECIMAL / VT_DECIMAL type, and SQL Server's decimal(28,s). win\wtypes.bi declares tagDEC at line 329, and money.Decimal has the same sixteen bytes in the same order, so the interop boundary is a reinterpret rather than a conversion.
Why, given Currency already exists? Currency is four decimal places, fixed, in eight bytes, and its own source says up front that this is its central limitation. FX rates quoted to six or eight places, per-unit costs, per-mille rates and interest accrual all need more.
Currency +-922,337,203,685,477.5807 4 places, always 8 bytes
Decimal +-7.9228162514264337e28 0..28, per value 16 bytes
The cost is size and speed: Currency's add is one instruction, Decimal's is software multi-precision. If four places is enough, use Currency -- Decimal does not deprecate it, and DecimalFromCurrency( c ) / d.ToCurrency( ) convert between them.
The scale is part of the value, not part of the formatting. 1.10 and 1.1 are equal, print differently, and report different scales -- exactly as in .NET. That is what lets a price read back from a file print the way it was written.
DecimalParse( "1.10" ).Value( ).ToString( ) ' 1.10
DecimalParse( "1.1" ).Value( ).ToString( ) ' 1.1
DecimalParse( "1.10" ).Value( ) = _
DecimalParse( "1.1" ).Value( ) ' TRUEDecimalZero( ) DecimalOne( ) DecimalMinusOne( )
DecimalMinValue( ) DecimalMaxValue( ) DecimalInvalid( )
DecimalFromInt( n ) DecimalFromUInt( u )
DecimalFromScaled( mantissa, scale ) DecimalFromParts( lo, mid, hi, neg, scale )
DecimalFromDouble( d ) DecimalFromCurrency( c )
DecimalParse( s ) -> Optional( of Decimal )
A one-argument constructor taking LONGINT would also accept a DOUBLE through implicit conversion, so Decimal( 19.99 ) would have compiled and stored 19. Naming every conversion means the inexact one cannot be reached by accident.
a + b, a - b EXACT. Scale = max( scale a, scale b ).
-a EXACT
a * b EXACT at scale a + scale b
a / b the terminating quotient when there is one, 28 digits
when there is not, rounded HALF-TO-EVEN
a MOD b EXACT. Sign follows the DIVIDEND.
a <op> n n as LONGINT, on either side, for + - * /
Unlike Currency, Decimal * Decimal and Decimal / Decimal exist. Currency is an amount and money times money has the wrong units; Decimal is a number that happens to be decimal -- which is what .NET's type is -- and rates, factors and ratios are its ordinary business. There is deliberately no Decimal-and-DOUBLE operator: a DOUBLE is inexact, and DecimalFromDouble has to be written out so that it can be seen.
Division rounds; it does not truncate:
1 / 3 0.3333333333333333333333333333
2 / 3 0.6666666666666666666666666667 ' truncation gives ...6666
1 / 4 0.25 ' the expansion terminates, so it stops there
100.00 / 4 25.00 ' and the scale the operands implied is kept
1 / 0 Invalid ' not a trap and not a wrong number
Overflow is Invalid, it is infectious, and Invalid = Invalid is FALSE -- the same rule as Currency and DateTime. Test with IsValid( ). Every ordering comparison against an Invalid is FALSE, and DecimalCompare returns -2, which is no ordering at all. A default-constructed Decimal is zero and valid.
IsValid( ) IsZero( ) IsNegative( ) Sign( ) Scale( )
Lo( ) Mid( ) Hi( ) ' the three mantissa limbs
ToString( ) ' exact, EXACTLY 'scale' decimals
ToStringFixed( digits ) ' Rescale then ToString
ToDouble( ) ' BOUNDED, named
ToLongInt( ) -> Optional( of int64 ) ' truncates; None if it will not fit
ToCurrency( ) ' half-to-even to four places
Round( digits ) ' half-to-even, 0..28
RoundMode( digits, mode ) ' DEC_HALF_EVEN DEC_HALF_UP
' DEC_HALF_DOWN DEC_UP DEC_DOWN
' DEC_CEILING DEC_FLOOR
Rescale( digits ) ' forces the scale, up or down
Normalize( ) ' strips trailing zeros
Floor( ) Ceiling( ) Truncate( ) AbsValue( )
DecimalCompare( a, b ) ' -1 0 +1, and -2 for Invalid
DecimalApportion( total, scale, weights( ), result( ) )
Round never increases the scale, exactly as .NET's decimal.Round does; Rescale is the one that grows it.
Apportion is the most useful function here. Splitting 100.00 three ways gives 33.33 each, whose sum is 99.99. Every accounting system has to decide where the missing cent goes, and doing it ad hoc is how a reconciliation fails. Largest-remainder: the parts always sum to the total, exactly -- 33.34 + 33.33 + 33.33 = 100.00.
There is no DecimalAccum. Currency needed one because rounding at every line loses money at four places; Decimal has twenty-eight and its addition is exact, so the accumulator is just +.
Text is exact both ways -- no DOUBLE anywhere in the parse or the print. Parsing is strict: the whole string must be consumed, and more than 28 decimal places is an error rather than a truncation.
DecimalParse( "12abc" ) ' empty -- not a prefix parse
DecimalParse( "1e3" ) ' empty -- there is no exponent grammar
DecimalParse( "0.000000000000000000000000000001" )
' empty -- 29 places, not a silent 28The point of naming an existing type is that an oracle already exists. 24,000 random operand pairs across +, -, *, / and MOD: 23,283 identical to .NET, value and scale. The 717 that differ are two deliberate classes -- 657 MOD cases where .NET pre-rounds or throws and this returns the exact remainder (checked against arbitrary precision: this is exact in all 657, and .NET in 2), and 60 multiplications that underflow to zero, where both answers are zero and only the reported scale differs. 3,000 unary cases -- Round at every digit count, Floor, Ceiling, Truncate, Compare, Abs, Negate, ToString -- are identical, with zero divergences.
Without this module, every program that needs a payment, a present value, a rate
conversion, an internal rate of return, a depreciation or an amortization schedule writes
it, in DOUBLE, once per call site.
Here is what that costs. A $400,000 mortgage at 5.95% over thirty years, amortized the way everyone amortizes it -- compute the payment, round it to cents, round each period's interest to cents, subtract:
' COMPILES TODAY, AND THE LAST ROW IS WRONG
dim as float64 pmt = p * i / ( 1.0 - ( 1.0 + i ) ^ ( -n ) )
pmt = int( pmt * 100.0 + 0.5 ) / 100.0
for k as int32 = 1 to 360
dim as float64 interest = int( bal * i * 100.0 + 0.5 ) / 100.0
bal = bal - ( pmt - interest )
next
print bal ' -0.9699999996669249The borrower overpaid 97 cents, and the closing balance is not zero -- and not even a clean -0.97 to apologise for. Three separate defects sit in those six lines and only one is floating point: the payment is rounded once but the residual is never absorbed, the interest is rounded independently of the principal so the row does not add up, and the last period is treated like every other.
#import "std/money"
using money
var t = LoanTermsCanadianMortgage( principal, rate, 25 )
var sched = LoanSchedule( t )
for each row in sched.Value( )
print row.Period_, row.Interest_.ToStringFixed( 2 ), _
row.ClosingBalance_.ToStringFixed( 2 )
next ' the final ClosingBalance_ is EXACTLY zeroThis is the decision the rest of the module follows from. A loan has two frequencies: how often interest compounds, which is a property of how the rate is quoted, and how often a payment is made, which is a property of the contract.
In the United States a mortgage compounds monthly and pays monthly, so the two collapse and the distinction is invisible -- which is why almost every finance library elides it. In Canada the Interest Act requires the rate to be quoted semi-annually, not in advance, while payments are monthly, biweekly or weekly. The two differ, and a library that assumed one number is wrong by dollars a month and thousands over the term.
So there is no CanadianMortgagePayment beside an American one. There is one code path,
and the two markets differ in one enum:
dim as Decimal p = DecimalParse( "400000" ).Value( )
dim as Decimal r = DecimalParse( "0.0595" ).Value( )
print LoanPayment( LoanTermsUsMortgage( p, r, 25 ) ).Value( ).ToStringFixed( 2 ) ' 2564.99
print LoanPayment( LoanTermsCanadianMortgage( p, r, 25 ) ).Value( ).ToStringFixed( 2 ) ' 2547.35$17.64 a month, about $5,292 over the term.
Decimal has no Pow, Exp, Log or Sqrt, so anything needing a power is
either built from multiplication or is not exact. The boundary is drawn once and every
function states which side it is on, in its own doc comment:
| Exact | growth and discount over an integer number of periods; every sum, product and quotient of money; day-count fractions |
float64 |
fractional exponents -- nominal-from-effective, the Canadian sixth root, dated discounting; continuous compounding; every solver; all of finport.tiko
|
A rate that crosses into float64 crosses back at a fixed scale, and everything
downstream of it is exact again. A Canadian mortgage crosses once, at the rate
conversion; the 300-row schedule that follows is exact Decimal arithmetic.
Every fallible call returns Result( of T, FinanceError ). Optional is used only where
absence is the answer -- PaybackPeriod on a project that never pays back -- and plain
values only where the function is total.
The distinction worth knowing: FIN_NO_SIGN_CHANGE means no root can exist, so
retrying with a better guess cannot help. FIN_NO_CONVERGENCE means the range was right
and the tolerance was not reached. Two different remedies, so two codes -- and a solver
failure carries how many iterations it ran and how close it got.
The amortization rounding order is normative, not a matter of taste, because this is
where real implementations go wrong. The load-bearing rule is that principal is the
residual -- payment minus interest, never computed independently -- which makes
Payment = Interest + Principal an identity rather than a coincidence that fails on a few
rows out of 360. The final payment absorbs the remainder by assignment, so the closing
balance lands on exactly zero rather than on 0.0000000001.
Depreciation follows the same discipline: the salvage floor is absolute, and the book value lands on exactly salvage.
The suites are fbcunit suites, vendored in tiko-lang at tests/vendor/fbc-tests/finance/ and
run against the module from tests/std/finance/: deprec, flows, loan, loanextra, portfolio,
rates, solve and tvm.
Where an oracle exists it is named: the IRS MACRS 200%-declining-balance five-year schedule is reproduced exactly; ISDA's 30/360 and 30E/360 rules are applied including the case that separates them. Where one does not, the tests assert properties instead -- the time-value identity balancing, an IRR verified by substituting it back, a rate that must compound back to the one it came from, and the five amortization invariants on every row of every scenario.
Not verified: the published MACRS percentage tables carry display rounding that is deliberately not reproduced -- only the arithmetic beneath them.
Every entry, grouped by task. Money and finance lists them beside the rest of the area.
| Function | What it does | From |
|---|---|---|
| Currency | Holds an exact amount with four decimal places, for money that needs no more. | std/money |
| Decimal | Holds an exact decimal number with up to 28 places, for rates, prices and results. | std/money |
| DecimalParse | Parses text into a Decimal exactly; returns empty on bad input or over 28 places. | std/money |
| CurrencyParse | Parses text into a Currency exactly; returns empty on bad input or over four places. | std/money |
| CurrencyFromInt | Returns a Currency of a whole number of units, exactly. | std/money |
| CurrencyFromParts | Returns a Currency from whole units and a ten-thousandths part, exactly. | std/money |
| CurrencyFromRaw | Returns a Currency from its stored integer, which is the amount times 10000. | std/money |
| CurrencyFromDouble | Converts a double to a Currency, rounded to four decimal places. | std/money |
| DecimalFromInt | Returns a 64-bit integer as a Decimal, exactly. | std/money |
| DecimalFromUInt | Returns an unsigned 64-bit integer as a Decimal, exactly. | std/money |
| DecimalFromScaled | Returns a whole number over a power of ten as a Decimal: 1999 at scale 2 is 19.99. | std/money |
| DecimalFromParts | Builds a Decimal from three 32-bit mantissa words, a sign flag and a scale. | std/money |
| DecimalFromDouble | Converts a double to a Decimal of 15 significant digits; NaN or infinity gives Invalid. | std/money |
| DecimalFromCurrency | Converts a Currency to a Decimal, exactly. | std/money |
| Function | What it does | From |
|---|---|---|
| Currency.IsValid | Returns false if the Currency is Invalid; the only reliable test for a bad value. | std/money |
| Currency.Raw | Returns the stored integer, the amount times 10000, for saving to a file or database. | std/money |
| Currency.ToDouble | Returns the amount as a double, which loses precision above about 900 billion. | std/money |
| DecimalCompare | Returns -1, 0 or 1 comparing two Decimals by value, or -2 if either is Invalid. | std/money |
| Function | What it does | From |
|---|---|---|
| DecimalZero | Returns zero, the same value a new Decimal starts with. | std/money |
| DecimalOne | Returns one as a Decimal. | std/money |
| DecimalMinusOne | Returns minus one as a Decimal. | std/money |
| DecimalMinValue | Returns the most negative value a Decimal can hold. | std/money |
| DecimalMaxValue | Returns the largest value a Decimal can hold. | std/money |
| DecimalInvalid | Returns the Invalid Decimal, which overflow and division by zero also produce. | std/money |
| CurrencyInvalid | Returns the Invalid Currency, which overflow also produces; it never equals anything. | std/money |
| Function | What it does | From |
|---|---|---|
| Currency.Ceiling | Returns the amount rounded up to a whole unit, towards positive infinity. | std/money |
| Currency.RoundMode | Returns the amount rounded to 0 to 4 places by a rounding rule you name. | std/money |
| Apportion | Splits a Currency total by weights into parts that add up to it exactly. | std/money |
| DecimalApportion | Splits a Decimal total by weights, at a scale you choose, into parts that add up exactly. | std/money |
| Function | What it does | From |
|---|---|---|
| CurrencyAccum.AddProduct | Adds an amount times a rate to a running total, rounding only once at the end. | std/money |
| CurrencyAccum.AddScaled | Adds an amount times a fraction, such as one third, to a running total exactly. | std/money |
| CurrencyAccum.Total | Returns the running total as a Currency, rounded once; reading it does not reset it. | std/money |
| Function | What it does | From |
|---|---|---|
| MoneyRounding | Holds a rounding policy: decimal places, rounding mode, and whether to round each amount. | std/money |
| MoneyRoundingMake | Returns a rounding policy with the places, mode and round-each flag you choose. | std/money |
| MoneyRoundingCents | Returns the default policy: two places, half-to-even, every posted amount rounded. | std/money |
| MoneyRoundingBankersFour | Returns a policy of four places, half-to-even, to match a Currency ledger. | std/money |
| MoneyRoundingExact | Returns a policy that never rounds, to keep full precision or see what rounding costs. | std/money |
| MoneyRound | Rounds a Decimal by a policy, or returns it unchanged if the policy does not round. | std/money |
| Function | What it does | From |
|---|---|---|
| FinanceError | Holds why a finance call failed: a code, a message and, for solvers, how close it got. | std/money |
| FinanceErrorCode | Lists the failure codes, such as FIN_INVALID_RATE and FIN_NO_SIGN_CHANGE. | std/money |
| FinanceErrorMessage | Returns a short, fixed English description of a failure code. | std/money |
| Function | What it does | From |
|---|---|---|
| Compounding | Lists how often interest compounds, as periods per year, plus simple and continuous. | std/money |
| RatePerPeriod | Returns a quoted annual rate divided by its compounding periods, exactly. | std/money |
| RateEffectiveFromNominal | Returns what a quoted annual rate really earns in a year once it compounds. | std/money |
| RateNominalFromEffective | Returns the quoted annual rate that earns a given effective yearly return. | std/money |
| RateConvertCompounding | Restates a quoted annual rate for a different compounding frequency. | std/money |
| RateContinuousFromEffective | Returns the continuously compounded rate that gives an effective yearly return. | std/money |
| RateEffectiveFromContinuous | Returns the effective yearly return of a continuously compounded rate. | std/money |
| RatePerPaymentFromNominal | Returns the rate per payment when compounding and payment frequency differ. | std/money |
| Function | What it does | From |
|---|---|---|
| SimpleInterest | Returns principal times rate times a fraction of a year, exactly. | std/money |
| SimpleInterestBetween | Returns simple interest between two dates on a day-count basis you choose. | std/money |
| DayCount | Lists the six day-count bases, such as actual/365 fixed and 30/360 US. | std/money |
| DayCountDays | Counts the days between two dates on a day-count basis. | std/money |
| DayCountFraction | Returns the fraction of a year between two dates on a basis, as an exact Decimal. | std/money |
| DayCountFractionDouble | Returns the fraction of a year between two dates on a basis, as a double. | std/money |
| Function | What it does | From |
|---|---|---|
| GrowthFactor | Returns what one unit grows to over a whole number of periods at a rate, exactly. | std/money |
| DiscountFactor | Returns what one unit due after a whole number of periods is worth today. | std/money |
| GrowthFactorFractional | Returns what one unit grows to over a fractional number of periods. | std/money |
| GrowthFactorContinuous | Returns what one unit grows to over a number of years with continuous compounding. | std/money |
| Function | What it does | From |
|---|---|---|
| AnnuityTerms | Holds rate, periods, payment, present value, future value and timing for annuity sums. | std/money |
| AnnuityTermsMake | Returns annuity terms from the six values; the one being solved for is ignored. | std/money |
| PaymentTiming | Lists whether payments fall at the end or at the start of each period. | std/money |
| PresentValue | Returns what a stream of payments plus a final amount is worth today. | std/money |
| FutureValue | Returns what a stream of payments will be worth at the end of the term. | std/money |
| PaymentAmount | Returns the level payment per period, negative when the present value is positive. | std/money |
| PresentValueOfLump | Returns a single future amount discounted back a number of periods. | std/money |
| FutureValueOfLump | Returns a single amount compounded forward a number of periods. | std/money |
| PeriodsRequired | Returns how many periods a payment takes to clear a balance, as a fractional double. | std/money |
| PeriodsRequiredWhole | Returns how many payments clear a balance, rounded up to a whole number. | std/money |
| SolveRatePerPeriod | Returns the rate per period implied by a known payment, value and term. | std/money |
| AnnuityPresentValueFactor | Returns what one unit paid each period is worth today. | std/money |
| AnnuityFutureValueFactor | Returns what one unit paid each period grows to by the end of the term. | std/money |
| Function | What it does | From |
|---|---|---|
| LoanTerms | Holds a loan's principal, rate, term, frequencies, rounding and first payment date. | std/money |
| LoanTermsMake | Returns loan terms with the payment frequency and compounding you choose. | std/money |
| LoanTermsUsMortgage | Returns loan terms for a US mortgage: monthly compounding and monthly payments. | std/money |
| LoanTermsCanadianMortgage | Returns loan terms for a Canadian mortgage: semi-annual compounding, monthly payments. | std/money |
| PaymentFrequency | Lists how often payments are made, including weekly and accelerated biweekly. | std/money |
| LoanPayment | Returns a loan's level payment, rounded once; the last payment absorbs the remainder. | std/money |
| LoanImpliedRate | Returns the annual rate implied by a known principal, payment and term. | std/money |
| LoanAnnualPercentageRate | Returns the annual rate once financed fees are counted as a cost of borrowing. | std/money |
| Function | What it does | From |
|---|---|---|
| LoanSchedule | Returns a loan's amortization schedule, built lazily, to walk with for each. | std/money |
| AmortizationSchedule | Holds a loan schedule's terms and gives its scheduled payment count and payment. | std/money |
| AmortizationIterator | Walks a loan schedule row by row, for stopping early or reading a window. | std/money |
| AmortizationRow | Holds one period: due date, balances, payment, interest, principal and running totals. | std/money |
| ScheduleToArray | Returns every row of a loan schedule as an Array, for random access. | std/money |
| LoanRowAt | Returns one row of a loan schedule, rounded exactly as it would be posted. | std/money |
| LoanBalanceAt | Returns the balance after a period from a formula, without walking the schedule. | std/money |
| Function | What it does | From |
|---|---|---|
| LoanInterestBetween | Returns the interest posted across a range of periods, such as one tax year. | std/money |
| LoanPrincipalBetween | Returns the principal repaid across a range of periods, extra payments included. | std/money |
| LoanPayoffAmount | Returns what settles a loan on a date: the balance plus interest accrued since. | std/money |
| LoanSummarize | Returns a loan's totals, payment count and payoff date, and what extra payments save. | std/money |
| LoanSummary | Holds what LoanSummarize returns: payments, totals, effective rate and savings. | std/money |
| ExtraPayment | Holds extra principal paid over a range of periods; overlapping ranges add up. | std/money |
| ExtraPaymentOnce | Returns a single extra principal payment made in one period. | std/money |
| ExtraPaymentRecurring | Returns the same extra principal payment in every period of a range. | std/money |
| Function | What it does | From |
|---|---|---|
| CashFlow | Holds an amount and the date it happens, for the dated value and return functions. | std/money |
| CashFlowMake | Returns a cash flow on a date; the dates in a series must ascend. | std/money |
| CashFlowAt | Returns a cash flow with no date, placed by its period number. | std/money |
| NetPresentValue | Returns the net present value of flows at a rate; the first flow is not discounted. | std/money |
| NetFutureValue | Returns the net present value carried forward to the end of the series. | std/money |
| NetPresentValueOnDates | Returns the net present value of dated flows at an annual rate on a day-count basis. | std/money |
| InternalRateOfReturn | Returns the rate at which the net present value of a series of flows is zero. | std/money |
| InternalRateOfReturnOnDates | Returns the internal rate of return of flows on irregular dates. | std/money |
| ModifiedInternalRateOfReturn | Returns a rate of return with one answer, from separate finance and reinvestment rates. | std/money |
| PaybackPeriod | Returns when the running total of flows turns positive, or empty if it never does. | std/money |
| DiscountedPaybackPeriod | Returns when the running total of discounted flows turns positive, or empty if never. | std/money |
| ProfitabilityIndex | Returns the present value of the later flows divided by the initial outlay. | std/money |
| Function | What it does | From |
|---|---|---|
| DepreciationTerms | Holds an asset's cost, salvage value, life in periods and declining-balance factor. | std/money |
| DepreciationTermsMake | Returns depreciation terms from cost, salvage and life, with a factor of 2 and cents. | std/money |
| DepreciationMethod | Lists the six methods, from straight line to units of production. | std/money |
| DepreciationStraightLine | Returns one period's expense, with cost less salvage spread evenly over the life. | std/money |
| DepreciationDecliningBalance | Returns one period's expense as a fixed fraction of the remaining book value. | std/money |
| DepreciationDoubleDeclining | Returns one period's expense at twice the straight-line rate, never below salvage. | std/money |
| DepreciationSumOfYearsDigits | Returns one period's expense, weighted by how many periods of the life are left. | std/money |
| DepreciationUnitsOfProduction | Returns one period's expense from the units it produced out of the lifetime total. | std/money |
| DepreciationScheduleOf | Returns the full schedule for a method, including declining balance with a switch. | std/money |
| DepreciationSchedule | Holds every period of a write-off, to walk with for each. | std/money |
| DepreciationScheduleIterator | Walks a depreciation schedule row by row, for stopping early. | std/money |
| DepreciationRow | Holds one period: opening and closing book value, expense and depreciation so far. | std/money |
| DepreciationScheduleToArray | Returns every row of a depreciation schedule as an Array. | std/money |
| Function | What it does | From |
|---|---|---|
| ReturnFrequency | Lists how many observations make a year: annual, quarterly, monthly, weekly or daily. | std/money |
| HoldingPeriodReturn | Returns the gain plus income over a holding period, as a fraction of the start value. | std/money |
| CompoundAnnualGrowthRate | Returns the steady yearly rate that grows a starting value to an ending value. | std/money |
| AnnualizeReturn | Converts a return per period to a yearly return by compounding, not multiplying. | std/money |
| AnnualizeReturnOverPeriods | Converts a total return over a number of observations to a yearly return. | std/money |
| TimeWeightedReturn | Returns sub-period returns linked by compounding, ignoring when money moved in or out. | std/money |
| ModifiedDietzReturn | Returns an approximate time-weighted return, weighting each flow by days invested. | std/money |
| MoneyWeightedReturn | Returns the dated internal rate of return of contributions and the closing value. | std/money |
| CumulativeReturnSeries | Returns the compounded return after each observation, as a growth chart plots. | std/money |
| Function | What it does | From |
|---|---|---|
| Volatility | Returns the sample standard deviation of returns, annualized. | std/money |
| DownsideDeviation | Returns the annualized shortfall of returns below a target, ignoring gains. | std/money |
| MaxDrawdown | Returns the worst fall from a peak to a later low, as a positive fraction. | std/money |
| MaxDrawdownPeak | Returns the index of the peak the worst drawdown fell from, or empty if none. | std/money |
| MaxDrawdownTrough | Returns the index of the low point of the worst drawdown, or empty if none. | std/money |
| DrawdownSeries | Returns the fall from the running peak at each observation, zero or negative. | std/money |
| SharpeRatio | Returns the annualized return above the risk-free rate per unit of volatility. | std/money |
| SortinoRatio | Returns the annualized return above a target per unit of downside deviation. | std/money |
| SummarizeReturns | Returns total and yearly return, volatility, Sharpe, Sortino and drawdown in one call. | std/money |
| ReturnSummary | Holds the figures SummarizeReturns computes, one field each. | std/money |
| Function | What it does | From |
|---|---|---|
| Beta | Returns how much an asset moves when its benchmark moves by one. | std/money |
| Alpha | Returns the annualized return beyond what the asset's beta to its benchmark explains. | std/money |
| TrackingError | Returns the annualized standard deviation of the asset's return less the benchmark's. | std/money |
| InformationRatio | Returns the return above the benchmark per unit of tracking error. | std/money |
| CorrelationToBenchmark | Returns how closely an asset moves with its benchmark, from -1 to 1. | std/money |
| Function | What it does | From |
|---|---|---|
| FinSolveRoot | Finds where your function is zero between two bounds, and reports how close it got. | std/money |
| FinObjective | Holds a pointer to the function the root finder calls with a value and a context. | std/money |
| FinSolverOptions | Holds the root finder's bounds, starting guess, tolerances and iteration limits. | std/money |
| FinSolverOptionsDefault | Returns the standard solver settings: rate bounds, 128 iterations and no guess. | std/money |
| FinSolverOptionsWithGuess | Returns the standard solver settings with a starting guess. | std/money |
| FinSolveResult | Holds the root found, its residual, the iteration count and whether it converged. | std/money |
tiko-lang · Home · Feature Index · Keyword Index · License
FreeBASIC manual pages reproduced under the GNU FDL 1.3.
- Home
- What Is tiko-lang
- Quick Start
- Installing on macOS
- Debugging
- Feature Index
- Compatibility
- FAQ
- AI Cheatsheet
- Generics
- Interfaces
- For Each
- Iterators
- Tuples
- Array Results
- Defer
- Lambdas
- Block Strings
- Partial Types
- String Slices
- Embed
- Typed Variadics
- C Header Import
- Foreign Library Linking
- UString
- Fixed-Width Types
- Nullptr
- String Library
- Format
- Array
- Map
- Set
- LinkedList
- OrderedMap
- OrderedSet
- Sorting
- Optional
- Result
- Smart Pointers
- Date and Time (Chrono)
- Time Zones
- Filesystem
- File Streams
- Config (INI and TOML)
- Codec
- Hash
- UUID
- OS
- Process
- Net
- HTTP and TLS
- Math Library
- Finance
- Logging
- Terminal TUI Library
- PsControls
- tkControls
- sys/win
- Goroutines and Channels
- LLVM Backend
- tiko build
- TIKO_COMPILER
- Variable Declarations
- Standard Data Types
- User Defined Types
- Procedures
- Operators
- Control Flow Statements
- Converting Data Types
- Array Functions
- String Functions
- Mathematical Functions
- Bit Manipulation
- Date and Time Functions
- File I/O Functions
- Console Functions
- User Input (Runtime Library)
- User Input Functions (Graphics Library)
- Screen Functions
- 2D Drawing Functions
- Graphics Library Reference
- Graphics Keyword List
- Memory Functions
- Threading Support Functions
- Error Handling Functions
- Operating System Functions
- Preprocessor
- Intrinsic Defines
- Miscellaneous Keywords
- Modularizing