@livefolio/sdk 0.5.0-rc.3 → 0.5.0-rc.5
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.
- package/dist/index.d.ts +275 -10
- package/dist/index.js +317 -102
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -127,6 +127,22 @@ type Series = ReadonlyArray<{
|
|
|
127
127
|
t: Date;
|
|
128
128
|
v: number;
|
|
129
129
|
}>;
|
|
130
|
+
/**
|
|
131
|
+
* A cash distribution (dividend) or interest payment for an asset, carrying
|
|
132
|
+
* what the SDK needs to credit cash and classify the income per-lot.
|
|
133
|
+
*
|
|
134
|
+
* `incomeKind: 'qualified-eligible'` means the distribution CAN be qualified if
|
|
135
|
+
* a holding lot satisfies the 60-of-121-day rule; the runtime resolves the
|
|
136
|
+
* actual qualified-vs-ordinary split per lot. `'ordinary'`/`'interest'` are
|
|
137
|
+
* never qualified.
|
|
138
|
+
*/
|
|
139
|
+
type DividendEvent = {
|
|
140
|
+
asset: Asset;
|
|
141
|
+
exDate: Date;
|
|
142
|
+
payDate: Date;
|
|
143
|
+
amountPerShare: number;
|
|
144
|
+
incomeKind: 'qualified-eligible' | 'ordinary' | 'interest';
|
|
145
|
+
};
|
|
130
146
|
|
|
131
147
|
/**
|
|
132
148
|
* Stable opaque string identifier for a {@link Position}. Generated by the
|
|
@@ -187,7 +203,7 @@ type IncomeKind = 'capital-gain' | 'qualified-dividend' | 'ordinary-dividend' |
|
|
|
187
203
|
* sales reduce `quantity` and pro-rate `basis`.
|
|
188
204
|
*/
|
|
189
205
|
type Lot = {
|
|
190
|
-
/** Opaque id assigned by
|
|
206
|
+
/** Opaque id assigned by `nextLotId` (internal) on creation. */
|
|
191
207
|
id: string;
|
|
192
208
|
asset: Asset;
|
|
193
209
|
/** Shares remaining in this lot after any partial sales. */
|
|
@@ -767,9 +783,13 @@ interface DataFeed {
|
|
|
767
783
|
* @param asset - The instrument to fetch bars for.
|
|
768
784
|
* @param range - Half-open date range; `range.from` inclusive, `range.to` exclusive.
|
|
769
785
|
* @param freq - Bar width. `'1d'` returns one bar per trading day.
|
|
786
|
+
* @param kind - `'adjusted'` (default) applies split/dividend adjustments;
|
|
787
|
+
* `'unadjusted'` returns raw prices. Indicators consume adjusted bars;
|
|
788
|
+
* execution fills and dividend cash-flow use unadjusted bars. Vendors that
|
|
789
|
+
* do not distinguish may ignore this and always return their single series.
|
|
770
790
|
* @returns An async iterable of {@link Bar} objects.
|
|
771
791
|
*/
|
|
772
|
-
bars(asset: Asset, range: DateRange, freq: Frequency): AsyncIterable<Bar>;
|
|
792
|
+
bars(asset: Asset, range: DateRange, freq: Frequency, kind?: 'adjusted' | 'unadjusted'): AsyncIterable<Bar>;
|
|
773
793
|
/**
|
|
774
794
|
* Returns a snapshot of fundamental data for `asset` as of `t`.
|
|
775
795
|
* Optional — not all data providers carry fundamentals.
|
|
@@ -790,6 +810,17 @@ interface DataFeed {
|
|
|
790
810
|
* @returns An async iterable of {@link DataEvent} objects.
|
|
791
811
|
*/
|
|
792
812
|
events?(range: DateRange, kinds: ReadonlyArray<EventKind>): AsyncIterable<DataEvent>;
|
|
813
|
+
/**
|
|
814
|
+
* Returns cash distributions (dividends / interest) for `asset` over `range`.
|
|
815
|
+
* Optional — providers without dividend data omit it. Consumed by
|
|
816
|
+
* `runBacktest`'s per-session dividend hook. Amounts are per-share, on the
|
|
817
|
+
* unadjusted price basis.
|
|
818
|
+
*
|
|
819
|
+
* @param asset - The instrument to query.
|
|
820
|
+
* @param range - Half-open date range.
|
|
821
|
+
* @returns A promise resolving to an array of {@link DividendEvent} objects.
|
|
822
|
+
*/
|
|
823
|
+
dividends?(asset: Asset, range: DateRange): Promise<DividendEvent[]>;
|
|
793
824
|
}
|
|
794
825
|
|
|
795
826
|
/**
|
|
@@ -1620,6 +1651,26 @@ type CashEvent = {
|
|
|
1620
1651
|
*/
|
|
1621
1652
|
reason?: 'deposit' | 'withdrawal' | 'interest' | 'dividend';
|
|
1622
1653
|
};
|
|
1654
|
+
/** How dividends are handled during a backtest. `reinvest: true` enables DRIP (dividend reinvestment). */
|
|
1655
|
+
type DividendsConfig = {
|
|
1656
|
+
reinvest: boolean;
|
|
1657
|
+
};
|
|
1658
|
+
/**
|
|
1659
|
+
* How idle cash earns interest during a backtest.
|
|
1660
|
+
* - `none` — cash earns nothing (default).
|
|
1661
|
+
* - `flat` — a constant annual percentage yield; daily rate is `apy / 365`.
|
|
1662
|
+
* - `tbill` — track a macro yield series (default `DGS3MO`) minus `spread`, as `(yield/100 - spread) / 365`.
|
|
1663
|
+
*/
|
|
1664
|
+
type CashYieldConfig = {
|
|
1665
|
+
kind: 'none';
|
|
1666
|
+
} | {
|
|
1667
|
+
kind: 'flat';
|
|
1668
|
+
apy: number;
|
|
1669
|
+
} | {
|
|
1670
|
+
kind: 'tbill';
|
|
1671
|
+
spread: number;
|
|
1672
|
+
assetId?: AssetId;
|
|
1673
|
+
};
|
|
1623
1674
|
/**
|
|
1624
1675
|
* All inputs required to run a historical backtest.
|
|
1625
1676
|
*
|
|
@@ -1684,6 +1735,32 @@ type RunBacktestOptions<F extends Features = Features, S = unknown> = {
|
|
|
1684
1735
|
* fund withdrawals is deferred to a later release, so this behavior may change.
|
|
1685
1736
|
*/
|
|
1686
1737
|
cashEvents?: ReadonlyArray<CashEvent>;
|
|
1738
|
+
/**
|
|
1739
|
+
* Optional dividend handling. When `dataFeed.dividends` exists, the universe's
|
|
1740
|
+
* day-0 dividends are pre-fetched and dividends are applied to held lots on the
|
|
1741
|
+
* first session on/after their `exDate`: cash mode credits cash, DRIP mode
|
|
1742
|
+
* (`reinvest: true`) reinvests into a new lot at the unadjusted pay-date close.
|
|
1743
|
+
*
|
|
1744
|
+
* @remarks Default = no dividends applied unless `dataFeed.dividends` exists;
|
|
1745
|
+
* `reinvest` defaults to `false` (cash mode).
|
|
1746
|
+
* @remarks Static-universe assumption: dividends are queried once for the day-0
|
|
1747
|
+
* universe (`strategy.universe(sessions[0], initialPortfolio)`). Assets that
|
|
1748
|
+
* enter the universe on later sessions — e.g. a dynamic-universe strategy that
|
|
1749
|
+
* opens a new position mid-run — will NOT have their dividends applied. This is
|
|
1750
|
+
* a non-issue for `fromSpec` strategies, whose universe is statically declared.
|
|
1751
|
+
*/
|
|
1752
|
+
dividends?: DividendsConfig;
|
|
1753
|
+
/**
|
|
1754
|
+
* Optional idle-cash interest accrual. Each session — after dividends, before
|
|
1755
|
+
* the strategy runs — interest is accrued on positive cash at a daily rate
|
|
1756
|
+
* resolved from this config (`flat` → `apy/365`; `tbill` → macro yield series
|
|
1757
|
+
* `(yield/100 - spread)/365`, clamped ≥ 0). The interest is credited to cash,
|
|
1758
|
+
* recorded as an `interest` `RealizedEvent` on the synthetic cash asset, and
|
|
1759
|
+
* reported via `BacktestSnapshot.interestIncome`.
|
|
1760
|
+
*
|
|
1761
|
+
* @remarks Default = `{ kind: 'none' }` (no interest → today's behavior).
|
|
1762
|
+
*/
|
|
1763
|
+
cashYield?: CashYieldConfig;
|
|
1687
1764
|
};
|
|
1688
1765
|
/**
|
|
1689
1766
|
* A point-in-time snapshot of the simulation at the end of a single trading session.
|
|
@@ -1704,6 +1781,13 @@ type BacktestSnapshot = {
|
|
|
1704
1781
|
* Net cash delta applied this session via `cashEvents`. Omitted when zero.
|
|
1705
1782
|
*/
|
|
1706
1783
|
cashFlow?: number;
|
|
1784
|
+
/** Dividend income recognized this session, split by qualified status. Omitted when zero. */
|
|
1785
|
+
dividendIncome?: {
|
|
1786
|
+
qualified: number;
|
|
1787
|
+
ordinary: number;
|
|
1788
|
+
};
|
|
1789
|
+
/** Interest income accrued on cash this session. Omitted when zero. */
|
|
1790
|
+
interestIncome?: number;
|
|
1707
1791
|
};
|
|
1708
1792
|
/**
|
|
1709
1793
|
* The return value of `runBacktest`, containing the full simulation history
|
|
@@ -2202,6 +2286,28 @@ type BacktestExecutorOptions = {
|
|
|
2202
2286
|
* the fill quantity and recorded in `Fill.fees`. Defaults to `0`.
|
|
2203
2287
|
*/
|
|
2204
2288
|
perShareFee?: number;
|
|
2289
|
+
/**
|
|
2290
|
+
* Tax-lot selection method applied to long sells (a `rebalance` reduce or a
|
|
2291
|
+
* `close` of a long position). When set to a non-default method
|
|
2292
|
+
* (`'LIFO'` / `'HIFO'` / `'min-tax'`), such a sell is split into one
|
|
2293
|
+
* {@link Fill} per selected lot — each carrying `Fill.lotId` — so
|
|
2294
|
+
* {@link applyFills} consumes those exact lots.
|
|
2295
|
+
*
|
|
2296
|
+
* Defaults to `'FIFO'` (equivalently, leaving this unset): the executor emits
|
|
2297
|
+
* a single fill per order with no `lotId`, and `applyFills` performs its own
|
|
2298
|
+
* internal FIFO. Buys, short-side closes, and `adjust` orders are never split.
|
|
2299
|
+
*/
|
|
2300
|
+
lotMethod?: 'FIFO' | 'LIFO' | 'HIFO' | 'min-tax';
|
|
2301
|
+
/**
|
|
2302
|
+
* Short- and long-term capital-gains tax rates (as decimals, e.g. `0.37`)
|
|
2303
|
+
* forwarded to the `'min-tax'` selector. **Required** when
|
|
2304
|
+
* `lotMethod === 'min-tax'`; the constructor throws otherwise. Ignored for
|
|
2305
|
+
* all other lot methods.
|
|
2306
|
+
*/
|
|
2307
|
+
taxRates?: {
|
|
2308
|
+
shortTerm: number;
|
|
2309
|
+
longTerm: number;
|
|
2310
|
+
};
|
|
2205
2311
|
};
|
|
2206
2312
|
/**
|
|
2207
2313
|
* Reference {@link Executor} implementation for backtesting. Fills each order
|
|
@@ -2222,6 +2328,12 @@ type BacktestExecutorOptions = {
|
|
|
2222
2328
|
* A flat per-share fee is added to `Fill.fees`. Orders with zero quantity are
|
|
2223
2329
|
* silently skipped.
|
|
2224
2330
|
*
|
|
2331
|
+
* **Lot selection**: by default each order yields exactly one fill. When a
|
|
2332
|
+
* non-default `lotMethod` (`'LIFO'` / `'HIFO'` / `'min-tax'`) is configured,
|
|
2333
|
+
* long sells (a `rebalance` reduce or a `close` of a long position) are split
|
|
2334
|
+
* into one fill per selected lot — each tagged with `Fill.lotId` — so
|
|
2335
|
+
* {@link applyFills} consumes those exact lots. See {@link BacktestExecutorOptions.lotMethod}.
|
|
2336
|
+
*
|
|
2225
2337
|
* @example
|
|
2226
2338
|
* ```ts
|
|
2227
2339
|
* import { BacktestExecutor } from '@livefolio/sdk';
|
|
@@ -2250,7 +2362,8 @@ declare class BacktestExecutor implements Executor {
|
|
|
2250
2362
|
* when the routed feed does not support the requested optional method.
|
|
2251
2363
|
*
|
|
2252
2364
|
* Distinguish the two cases via the message text: "no feed registered" vs
|
|
2253
|
-
* "does not implement fundamentals"
|
|
2365
|
+
* "does not implement `<method>`" (e.g. "does not implement fundamentals()" or
|
|
2366
|
+
* "does not implement dividends()").
|
|
2254
2367
|
*/
|
|
2255
2368
|
declare class RoutingDataFeedError extends Error {
|
|
2256
2369
|
constructor(message: string);
|
|
@@ -2271,9 +2384,11 @@ type RoutingDataFeedRouteMap = Readonly<Partial<Record<Asset['kind'], DataFeed>>
|
|
|
2271
2384
|
* - **Function form:** `new RoutingDataFeed((a) => a.kind === 'macro' ? fred : yahoo)`.
|
|
2272
2385
|
* Use when routing depends on more than `kind` (e.g. allowlists).
|
|
2273
2386
|
*
|
|
2274
|
-
*
|
|
2275
|
-
*
|
|
2276
|
-
*
|
|
2387
|
+
* `dividends()` and `fundamentals()` ARE implemented — each targets a single
|
|
2388
|
+
* asset, so it resolves to that asset's routed feed (or throws if the feed
|
|
2389
|
+
* lacks the method). The router does **not** implement `events()` — the
|
|
2390
|
+
* optional method is genuinely absent (`'events' in router === false`) because
|
|
2391
|
+
* cross-feed event fan-out is a separate, deferred problem.
|
|
2277
2392
|
*
|
|
2278
2393
|
* @example
|
|
2279
2394
|
* ```ts
|
|
@@ -2292,8 +2407,17 @@ type RoutingDataFeedRouteMap = Readonly<Partial<Record<Asset['kind'], DataFeed>>
|
|
|
2292
2407
|
declare class RoutingDataFeed implements DataFeed {
|
|
2293
2408
|
private readonly route;
|
|
2294
2409
|
constructor(routes: RoutingDataFeedRouteMap | RoutingDataFeedRouteFn);
|
|
2295
|
-
bars(asset: Asset, range: DateRange, freq: Frequency): AsyncGenerator<Bar>;
|
|
2410
|
+
bars(asset: Asset, range: DateRange, freq: Frequency, kind?: 'adjusted' | 'unadjusted'): AsyncGenerator<Bar>;
|
|
2296
2411
|
fundamentals(asset: Asset, t: Date): Promise<Fundamentals>;
|
|
2412
|
+
/**
|
|
2413
|
+
* Resolves `asset` to its routed feed and delegates `dividends`. This method
|
|
2414
|
+
* is ALWAYS present on the router (unlike a leaf feed's optional `dividends?`),
|
|
2415
|
+
* so `typeof routingFeed.dividends === 'function'` is always `true` — capability
|
|
2416
|
+
* detection must account for the routed feed possibly lacking it at call time.
|
|
2417
|
+
*
|
|
2418
|
+
* @throws {RoutingDataFeedError} when the routed feed does not implement `dividends`.
|
|
2419
|
+
*/
|
|
2420
|
+
dividends(asset: Asset, range: DateRange): Promise<DividendEvent[]>;
|
|
2297
2421
|
private resolve;
|
|
2298
2422
|
}
|
|
2299
2423
|
|
|
@@ -3194,7 +3318,7 @@ declare function evaluateFeatureSpecs(specs: ReadonlyArray<TacticalFeatureSpec>,
|
|
|
3194
3318
|
* independently scaled); `volume` is passed through from the underlying bar.
|
|
3195
3319
|
*
|
|
3196
3320
|
* Non-synthetic assets are proxied transparently to the original `dataFeed`.
|
|
3197
|
-
* `fundamentals` and `
|
|
3321
|
+
* `fundamentals`, `events`, and `dividends` methods, if present, are forwarded unchanged.
|
|
3198
3322
|
*
|
|
3199
3323
|
* Throws at construction time if `synthetics` contains duplicate `id` values.
|
|
3200
3324
|
*
|
|
@@ -3923,25 +4047,166 @@ declare function computeTaxBill(income: TaxableIncome, rates: TaxRates): {
|
|
|
3923
4047
|
};
|
|
3924
4048
|
};
|
|
3925
4049
|
|
|
4050
|
+
/**
|
|
4051
|
+
* Options for the 60-of-121-day qualified-dividend holding test.
|
|
4052
|
+
*
|
|
4053
|
+
* Both fields default to values for common stock dividends: the investor must
|
|
4054
|
+
* have held the lot throughout the 60-day window ending at the ex-dividend date, within
|
|
4055
|
+
* the 121-day window that begins 60 days before the ex-date.
|
|
4056
|
+
*/
|
|
4057
|
+
type QualificationOpts = {
|
|
4058
|
+
/** Minimum days the lot must be held within the window. Defaults to `60`. */
|
|
4059
|
+
holdingDaysRequired?: number;
|
|
4060
|
+
/** Width of the holding window in calendar days. Defaults to `121`. */
|
|
4061
|
+
windowDays?: number;
|
|
4062
|
+
};
|
|
4063
|
+
/**
|
|
4064
|
+
* Determines whether a single {@link Lot} satisfies the IRS 60-of-121-day
|
|
4065
|
+
* qualified-dividend holding requirement as of a given `exDate`.
|
|
4066
|
+
*
|
|
4067
|
+
* The 121-day window is centred on `exDate` with `half = floor(121 / 2) = 60`,
|
|
4068
|
+
* so it spans the 60 days before `exDate`, the ex-date itself, and the 60 days
|
|
4069
|
+
* after. Only days the lot was held **on or before** `exDate` count — `heldTo`
|
|
4070
|
+
* is capped at `exDate` so future hold time never qualifies a dividend. This
|
|
4071
|
+
* keeps the test lookahead-free and conservative: it never over-grants
|
|
4072
|
+
* qualified status. Because `heldTo` is capped at `exDate`, the most a lot can
|
|
4073
|
+
* accumulate is the 60-day run-up to the ex-date, so the default threshold of
|
|
4074
|
+
* `60` models "held throughout the 60-day window ending at ex-date"
|
|
4075
|
+
* (`60 >= 60`). Returns `true` when the days held within the window are
|
|
4076
|
+
* `>= holdingDaysRequired`.
|
|
4077
|
+
*
|
|
4078
|
+
* @param lot - The tax lot to test.
|
|
4079
|
+
* @param exDate - The dividend ex-dividend date.
|
|
4080
|
+
* @param opts - Optional overrides for `holdingDaysRequired` (default `60` —
|
|
4081
|
+
* "held throughout the 60-day window ending at ex-date") and `windowDays`
|
|
4082
|
+
* (default `121`).
|
|
4083
|
+
* @returns `true` when the lot satisfies the holding-period test.
|
|
4084
|
+
*/
|
|
4085
|
+
declare function isQualifiedForLot(lot: Lot, exDate: Date, opts?: QualificationOpts): boolean;
|
|
4086
|
+
/**
|
|
4087
|
+
* The result of {@link distributeDividend}: per-lot cash amounts with
|
|
4088
|
+
* qualified/ordinary classification, plus rolled-up totals.
|
|
4089
|
+
*/
|
|
4090
|
+
type DividendDistribution = {
|
|
4091
|
+
/** Rolled-up qualified and ordinary dividend totals across all participating lots. */
|
|
4092
|
+
totals: {
|
|
4093
|
+
qualified: number;
|
|
4094
|
+
ordinary: number;
|
|
4095
|
+
};
|
|
4096
|
+
/** One entry per participating lot: the cash received and whether it is qualified. */
|
|
4097
|
+
perLot: {
|
|
4098
|
+
lotId: string;
|
|
4099
|
+
cash: number;
|
|
4100
|
+
qualified: boolean;
|
|
4101
|
+
}[];
|
|
4102
|
+
};
|
|
4103
|
+
/**
|
|
4104
|
+
* Distributes a {@link DividendEvent} across a set of lots held at the
|
|
4105
|
+
* ex-dividend date, classifying each lot's income as qualified or ordinary.
|
|
4106
|
+
*
|
|
4107
|
+
* Only lots that pass all three eligibility tests participate:
|
|
4108
|
+
* - `quantity > 0`
|
|
4109
|
+
* - `openDate <= exDate` (lot was open before or on the ex-date)
|
|
4110
|
+
* - `asset.id === event.asset.id` (same asset)
|
|
4111
|
+
*
|
|
4112
|
+
* For `incomeKind: 'ordinary'` or `'interest'` events every participating lot
|
|
4113
|
+
* is classified as ordinary regardless of how long it was held. For
|
|
4114
|
+
* `'qualified-eligible'` events each lot is tested individually via
|
|
4115
|
+
* {@link isQualifiedForLot} using the default 60-of-121-day rule.
|
|
4116
|
+
*
|
|
4117
|
+
* @param event - The dividend event to distribute.
|
|
4118
|
+
* @param lotsHeldAtExDate - All lots in the portfolio at the ex-dividend date
|
|
4119
|
+
* (the function filters to eligible ones internally).
|
|
4120
|
+
* @returns A {@link DividendDistribution} with per-lot breakdown and rolled-up totals.
|
|
4121
|
+
*/
|
|
4122
|
+
declare function distributeDividend(event: DividendEvent, lotsHeldAtExDate: readonly Lot[]): DividendDistribution;
|
|
4123
|
+
/**
|
|
4124
|
+
* Converts dividend cash into a new whole-share DRIP tax lot at the pay-date price.
|
|
4125
|
+
*
|
|
4126
|
+
* Computes `shares = floor(cashAvailable / pricePayDate)` and opens a fresh
|
|
4127
|
+
* {@link Lot} with `openDate = payDate`, `openPrice = pricePayDate`,
|
|
4128
|
+
* `basis = shares * pricePayDate`, and `dripParent` set to the originating lot
|
|
4129
|
+
* id. Any fractional-share remainder is returned as `residual`.
|
|
4130
|
+
*
|
|
4131
|
+
* When `cashAvailable` is less than one share (`shares === 0`), `newLot.quantity`
|
|
4132
|
+
* will be `0` and `residual` will equal `cashAvailable`. The caller is
|
|
4133
|
+
* responsible for skipping zero-quantity lots.
|
|
4134
|
+
*
|
|
4135
|
+
* @param cashAvailable - Total dividend cash to reinvest.
|
|
4136
|
+
* @param asset - The asset being purchased.
|
|
4137
|
+
* @param pricePayDate - Share price on the dividend pay date.
|
|
4138
|
+
* @param payDate - The dividend pay date; becomes `openDate` on the new lot.
|
|
4139
|
+
* @param dripParent - Id of the originating lot that generated the dividend cash.
|
|
4140
|
+
* @returns An object with `newLot` (the freshly created {@link Lot}) and
|
|
4141
|
+
* `residual` (uninvested cash remainder).
|
|
4142
|
+
*/
|
|
4143
|
+
declare function reinvestDividend(cashAvailable: number, asset: Asset, pricePayDate: number, payDate: Date, dripParent: string): {
|
|
4144
|
+
newLot: Lot;
|
|
4145
|
+
residual: number;
|
|
4146
|
+
};
|
|
4147
|
+
|
|
4148
|
+
/**
|
|
4149
|
+
* Result of a single {@link accrueCashInterest} call: the updated cash balance
|
|
4150
|
+
* and the interest earned in that session.
|
|
4151
|
+
*/
|
|
4152
|
+
type CashInterestResult = {
|
|
4153
|
+
/** Cash balance after interest has been credited: `cash + interest`. */
|
|
4154
|
+
newCash: number;
|
|
4155
|
+
/** Interest earned in this session: `cash * dailyRate`. */
|
|
4156
|
+
interest: number;
|
|
4157
|
+
};
|
|
4158
|
+
/**
|
|
4159
|
+
* Pure per-session interest accrual using the actual/365 day-count convention.
|
|
4160
|
+
*
|
|
4161
|
+
* Computes simple (non-compounding within a single call) interest for one
|
|
4162
|
+
* trading session. To model compounding over multiple sessions, call this
|
|
4163
|
+
* function repeatedly, passing the returned `newCash` as `cash` in each
|
|
4164
|
+
* subsequent call.
|
|
4165
|
+
*
|
|
4166
|
+
* `dailyRate` should be `APY / 365` for an actual/365 day-count (e.g.
|
|
4167
|
+
* `0.05 / 365` for a 5% APY). A daily rate of `0` returns the original cash
|
|
4168
|
+
* balance with zero interest.
|
|
4169
|
+
*
|
|
4170
|
+
* @param cash - The current cash balance before interest is applied.
|
|
4171
|
+
* @param dailyRate - The per-session interest rate expressed as a decimal
|
|
4172
|
+
* fraction (e.g. `0.05 / 365` for 5% APY on an actual/365 basis).
|
|
4173
|
+
* @returns A {@link CashInterestResult} with `newCash` (updated balance) and
|
|
4174
|
+
* `interest` (amount earned this session).
|
|
4175
|
+
*
|
|
4176
|
+
* @example
|
|
4177
|
+
* ```ts
|
|
4178
|
+
* // Single session at 5% APY
|
|
4179
|
+
* const { newCash, interest } = accrueCashInterest(10_000, 0.05 / 365);
|
|
4180
|
+
* ```
|
|
4181
|
+
*/
|
|
4182
|
+
declare function accrueCashInterest(cash: number, dailyRate: number): CashInterestResult;
|
|
4183
|
+
|
|
4184
|
+
type index_CashInterestResult = CashInterestResult;
|
|
4185
|
+
type index_DividendDistribution = DividendDistribution;
|
|
3926
4186
|
type index_LotSlice = LotSlice;
|
|
3927
4187
|
declare const index_ORDINARY_OFFSET_CAP: typeof ORDINARY_OFFSET_CAP;
|
|
4188
|
+
type index_QualificationOpts = QualificationOpts;
|
|
3928
4189
|
type index_RealizeResult = RealizeResult;
|
|
3929
4190
|
type index_TaxRates = TaxRates;
|
|
3930
4191
|
type index_TaxableIncome = TaxableIncome;
|
|
4192
|
+
declare const index_accrueCashInterest: typeof accrueCashInterest;
|
|
3931
4193
|
declare const index_aggregateByYear: typeof aggregateByYear;
|
|
3932
4194
|
declare const index_bucketByTerm: typeof bucketByTerm;
|
|
3933
4195
|
declare const index_computeTaxBill: typeof computeTaxBill;
|
|
3934
4196
|
declare const index_crossOffset: typeof crossOffset;
|
|
4197
|
+
declare const index_distributeDividend: typeof distributeDividend;
|
|
3935
4198
|
declare const index_holdingPeriodDays: typeof holdingPeriodDays;
|
|
3936
4199
|
declare const index_isLongTerm: typeof isLongTerm;
|
|
4200
|
+
declare const index_isQualifiedForLot: typeof isQualifiedForLot;
|
|
3937
4201
|
declare const index_netWithinBucket: typeof netWithinBucket;
|
|
3938
4202
|
declare const index_realize: typeof realize;
|
|
4203
|
+
declare const index_reinvestDividend: typeof reinvestDividend;
|
|
3939
4204
|
declare const index_selectFIFO: typeof selectFIFO;
|
|
3940
4205
|
declare const index_selectHIFO: typeof selectHIFO;
|
|
3941
4206
|
declare const index_selectLIFO: typeof selectLIFO;
|
|
3942
4207
|
declare const index_selectMinTax: typeof selectMinTax;
|
|
3943
4208
|
declare namespace index {
|
|
3944
|
-
export { type index_LotSlice as LotSlice, index_ORDINARY_OFFSET_CAP as ORDINARY_OFFSET_CAP, type index_RealizeResult as RealizeResult, type index_TaxRates as TaxRates, type index_TaxableIncome as TaxableIncome, index_aggregateByYear as aggregateByYear, index_bucketByTerm as bucketByTerm, index_computeTaxBill as computeTaxBill, index_crossOffset as crossOffset, index_holdingPeriodDays as holdingPeriodDays, index_isLongTerm as isLongTerm, index_netWithinBucket as netWithinBucket, index_realize as realize, index_selectFIFO as selectFIFO, index_selectHIFO as selectHIFO, index_selectLIFO as selectLIFO, index_selectMinTax as selectMinTax };
|
|
4209
|
+
export { type index_CashInterestResult as CashInterestResult, type index_DividendDistribution as DividendDistribution, type index_LotSlice as LotSlice, index_ORDINARY_OFFSET_CAP as ORDINARY_OFFSET_CAP, type index_QualificationOpts as QualificationOpts, type index_RealizeResult as RealizeResult, type index_TaxRates as TaxRates, type index_TaxableIncome as TaxableIncome, index_accrueCashInterest as accrueCashInterest, index_aggregateByYear as aggregateByYear, index_bucketByTerm as bucketByTerm, index_computeTaxBill as computeTaxBill, index_crossOffset as crossOffset, index_distributeDividend as distributeDividend, index_holdingPeriodDays as holdingPeriodDays, index_isLongTerm as isLongTerm, index_isQualifiedForLot as isQualifiedForLot, index_netWithinBucket as netWithinBucket, index_realize as realize, index_reinvestDividend as reinvestDividend, index_selectFIFO as selectFIFO, index_selectHIFO as selectHIFO, index_selectLIFO as selectLIFO, index_selectMinTax as selectMinTax };
|
|
3945
4210
|
}
|
|
3946
4211
|
|
|
3947
4212
|
/**
|
|
@@ -4057,4 +4322,4 @@ declare function applyOrders(portfolio: Portfolio, orders: ReadonlyArray<Order>)
|
|
|
4057
4322
|
*/
|
|
4058
4323
|
declare function positionsByAsset(portfolio: Portfolio): Position[];
|
|
4059
4324
|
|
|
4060
|
-
export { type AdhocTimeOverrides, type AdjustOrder, type AllocateNode, type Asset, type AssetId, type AssetRef, BacktestExecutor, type BacktestExecutorOptions, type BacktestResult, type BacktestSnapshot, type Bar, type BarField, type Calendar, type CashEvent, CashEventQueue, type CloseOrder, type Comparison, type ComparisonOp, type ComputeFn, Crypto24x7Calendar, type DataEvent, type DataFeed, type DateRange, type EquityAsset, type EventKind, ExchangeCalendar, type ExchangeName, type Executor, type FeatureCache, type FeatureKey, type FeatureKind, type FeatureRef, FeatureRuntime, type FeatureRuntimeOptions, type FeatureScope, type FeatureSpec, type Features, type Fill, type Frequency, type FromSpecOptions, type Fundamentals, type HolidayRule, type IfNode, type IncomeKind, LSEExchangeCalendar, type LiveEvent, type Lot, type LotSlice, type MacroAsset, MemoryFeatureCache, NYSEExchangeCalendar, type NextOpenFn, ORDINARY_OFFSET_CAP, type OpenOrder, type Order, type PollingSchedule, type PollingStreamOptions, type Portfolio, type Position, type PositionId, type PriceMap, type Quote, type QuoteFeed, type RealizeResult, type RealizedEvent, type RebalanceConfig, type RebalanceFrequency, type RebalanceOrder, type ReturnMode, RoutingDataFeed, RoutingDataFeedError, type RoutingDataFeedRouteFn, type RoutingDataFeedRouteMap, RoutingQuoteFeed, RoutingQuoteFeedError, type RoutingQuoteFeedRouteFn, type RoutingQuoteFeedRouteMap, RoutingStreamingDataFeed, RoutingStreamingDataFeedError, type RoutingStreamingDataFeedRouteFn, type RoutingStreamingDataFeedRouteMap, type RuleNode, type RuleTreeState, type RunBacktestOptions, type RunLiveOptions, type Series, type Session, type SpecialClose, type SpecialOpen, type Strategy, type StreamingBar, type StreamingDataFeed, type SyntheticAsset, type TacticalFeatureKind, type TacticalFeatureSpec, type TacticalFeatures, type TacticalSpec, type TargetWeights, type TaxRates, type TaxableIncome, type TimeOfDay, type Tolerance, type WithStreamingSyntheticsOptions, aggregateByYear, applyFills, applyOrders, barsToSeries, bucketByTerm, collectBars, computeTaxBill, crossOffset, defineFeature, drawdown, ema, evaluateFeatureSpecs, evaluateRuleTree, index$1 as features, fromSpec, getCalendar, getFeatureCompute, holdingPeriodDays, isLongTerm, isRebalanceDay, netWithinBucket, paramsHash, periodKey, pollingStreamFromHistorical, positionsByAsset, realize, reconcile, returnSeries, rsi, runBacktest, runLive, selectFIFO, selectHIFO, selectLIFO, selectMinTax, seriesAt, sma, index$2 as tactical, index as tax, volatility, withStreamingSynthetics, withSynthetics };
|
|
4325
|
+
export { type AdhocTimeOverrides, type AdjustOrder, type AllocateNode, type Asset, type AssetId, type AssetRef, BacktestExecutor, type BacktestExecutorOptions, type BacktestResult, type BacktestSnapshot, type Bar, type BarField, type Calendar, type CashEvent, CashEventQueue, type CashInterestResult, type CashYieldConfig, type CloseOrder, type Comparison, type ComparisonOp, type ComputeFn, Crypto24x7Calendar, type DataEvent, type DataFeed, type DateRange, type DividendDistribution, type DividendEvent, type DividendsConfig, type EquityAsset, type EventKind, ExchangeCalendar, type ExchangeName, type Executor, type FeatureCache, type FeatureKey, type FeatureKind, type FeatureRef, FeatureRuntime, type FeatureRuntimeOptions, type FeatureScope, type FeatureSpec, type Features, type Fill, type Frequency, type FromSpecOptions, type Fundamentals, type HolidayRule, type IfNode, type IncomeKind, LSEExchangeCalendar, type LiveEvent, type Lot, type LotSlice, type MacroAsset, MemoryFeatureCache, NYSEExchangeCalendar, type NextOpenFn, ORDINARY_OFFSET_CAP, type OpenOrder, type Order, type PollingSchedule, type PollingStreamOptions, type Portfolio, type Position, type PositionId, type PriceMap, type QualificationOpts, type Quote, type QuoteFeed, type RealizeResult, type RealizedEvent, type RebalanceConfig, type RebalanceFrequency, type RebalanceOrder, type ReturnMode, RoutingDataFeed, RoutingDataFeedError, type RoutingDataFeedRouteFn, type RoutingDataFeedRouteMap, RoutingQuoteFeed, RoutingQuoteFeedError, type RoutingQuoteFeedRouteFn, type RoutingQuoteFeedRouteMap, RoutingStreamingDataFeed, RoutingStreamingDataFeedError, type RoutingStreamingDataFeedRouteFn, type RoutingStreamingDataFeedRouteMap, type RuleNode, type RuleTreeState, type RunBacktestOptions, type RunLiveOptions, type Series, type Session, type SpecialClose, type SpecialOpen, type Strategy, type StreamingBar, type StreamingDataFeed, type SyntheticAsset, type TacticalFeatureKind, type TacticalFeatureSpec, type TacticalFeatures, type TacticalSpec, type TargetWeights, type TaxRates, type TaxableIncome, type TimeOfDay, type Tolerance, type WithStreamingSyntheticsOptions, accrueCashInterest, aggregateByYear, applyFills, applyOrders, barsToSeries, bucketByTerm, collectBars, computeTaxBill, crossOffset, defineFeature, distributeDividend, drawdown, ema, evaluateFeatureSpecs, evaluateRuleTree, index$1 as features, fromSpec, getCalendar, getFeatureCompute, holdingPeriodDays, isLongTerm, isQualifiedForLot, isRebalanceDay, netWithinBucket, paramsHash, periodKey, pollingStreamFromHistorical, positionsByAsset, realize, reconcile, reinvestDividend, returnSeries, rsi, runBacktest, runLive, selectFIFO, selectHIFO, selectLIFO, selectMinTax, seriesAt, sma, index$2 as tactical, index as tax, volatility, withStreamingSynthetics, withSynthetics };
|