@adaptic/utils 0.0.1031 → 0.0.1033
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.cjs +631 -208
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +627 -209
- package/dist/index.mjs.map +1 -1
- package/dist/types/__tests__/indicator-parity/generate.d.ts +64 -0
- package/dist/types/__tests__/indicator-parity/generate.d.ts.map +1 -0
- package/dist/types/__tests__/indicator-parity/record.d.ts +144 -0
- package/dist/types/__tests__/indicator-parity/record.d.ts.map +1 -0
- package/dist/types/__tests__/indicator-parity/reference.d.ts +92 -0
- package/dist/types/__tests__/indicator-parity/reference.d.ts.map +1 -0
- package/dist/types/__tests__/indicator-parity/series.d.ts +64 -0
- package/dist/types/__tests__/indicator-parity/series.d.ts.map +1 -0
- package/dist/types/__tests__/indicator-parity/subjects.d.ts +55 -0
- package/dist/types/__tests__/indicator-parity/subjects.d.ts.map +1 -0
- package/dist/types/__tests__/support/statistic.d.ts +18 -0
- package/dist/types/__tests__/support/statistic.d.ts.map +1 -0
- package/dist/types/alpaca/trading/order-utils.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/llm/circuit-breaker.d.ts +18 -1
- package/dist/types/llm/circuit-breaker.d.ts.map +1 -1
- package/dist/types/llm/fallback-chain.d.ts.map +1 -1
- package/dist/types/llm/index.d.ts +3 -1
- package/dist/types/llm/index.d.ts.map +1 -1
- package/dist/types/llm/rate-guard.d.ts +82 -9
- package/dist/types/llm/rate-guard.d.ts.map +1 -1
- package/dist/types/llm/structured-content.d.ts +73 -0
- package/dist/types/llm/structured-content.d.ts.map +1 -0
- package/dist/types/llm/transports/gateway.d.ts.map +1 -1
- package/dist/types/metrics-calcs.d.ts +25 -0
- package/dist/types/metrics-calcs.d.ts.map +1 -1
- package/dist/types/performance-metrics.d.ts +16 -4
- package/dist/types/performance-metrics.d.ts.map +1 -1
- package/dist/types/sample-statistic.d.ts +123 -0
- package/dist/types/sample-statistic.d.ts.map +1 -0
- package/dist/types/schemas/alpaca-schemas.d.ts.map +1 -1
- package/dist/types/strategy-metrics.d.ts +38 -16
- package/dist/types/strategy-metrics.d.ts.map +1 -1
- package/dist/types/trading-policy/schemas/effective-policy.schema.d.ts +18 -18
- package/dist/types/trading-policy/schemas/model-prefs.schema.d.ts +24 -24
- package/dist/types/trading-policy/schemas/policy-mutation.schema.d.ts +36 -36
- package/dist/types/types/alpaca-types.d.ts +36 -5
- package/dist/types/types/alpaca-types.d.ts.map +1 -1
- package/package.json +3 -1
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
* provider's circuit breaker, fail over to a more expensive leg, and keep doing
|
|
9
9
|
* so — converting a self-inflicted pacing problem into a permanent routing
|
|
10
10
|
* change nobody chose. Pacing at the client is what keeps the breaker measuring
|
|
11
|
-
* the provider rather than measuring us.
|
|
11
|
+
* the provider rather than measuring us. The same reasoning bounds the guard
|
|
12
|
+
* from the other side: a client held far BELOW the provider's ceiling refuses
|
|
13
|
+
* calls the provider would have served, and the chain answers those refusals by
|
|
14
|
+
* failing over — the same unchosen routing change, arrived at by under-driving.
|
|
12
15
|
*
|
|
13
16
|
* Two distinct bounds are applied because they fail differently. The rate bound
|
|
14
17
|
* (requests per minute) protects the provider's published ceiling. The
|
|
@@ -17,16 +20,51 @@
|
|
|
17
20
|
* every one of them blows its latency budget and the fan-out produces a hundred
|
|
18
21
|
* timeouts instead of a queue.
|
|
19
22
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
23
|
+
* Each guard is keyed by the unit its provider enforces limits in. A provider
|
|
24
|
+
* that publishes its ceilings per model gets one independent guard per model.
|
|
25
|
+
* Sharing one guard across its models would enforce a ceiling the provider does
|
|
26
|
+
* not impose, and — when a chain's primary and secondary are served by the same
|
|
27
|
+
* provider — would refuse the secondary at exactly the moment the primary's
|
|
28
|
+
* queue is full, so the fallback that exists for that moment is never reached.
|
|
29
|
+
*
|
|
30
|
+
* Limits live in `provider-limits.json` rather than in code, each beside the
|
|
31
|
+
* source it was transcribed from, so a published ceiling and a conservative
|
|
32
|
+
* guess can never be mistaken for one another in review. The file is bundled
|
|
33
|
+
* at build time: changing a limit is a release of this package, not a runtime
|
|
34
|
+
* switch.
|
|
22
35
|
*
|
|
23
36
|
* @module llm/rate-guard
|
|
24
37
|
*/
|
|
38
|
+
/** Where a limit came from: a provider's documented ceiling, or a deliberate under-estimate of an unknown one. */
|
|
39
|
+
export type ProviderLimitBasis = "published" | "conservative-default";
|
|
40
|
+
/**
|
|
41
|
+
* The unit a provider enforces its limits in.
|
|
42
|
+
*
|
|
43
|
+
* `model` means each of the provider's models has its own ceilings, so the
|
|
44
|
+
* client keeps one guard per model; `provider` means one guard covers every
|
|
45
|
+
* model the provider serves.
|
|
46
|
+
*/
|
|
47
|
+
export type ProviderLimitScope = "provider" | "model";
|
|
25
48
|
/** Limits for one provider. */
|
|
26
49
|
export interface ProviderLimits {
|
|
27
50
|
/** Whether these numbers were transcribed from a provider doc or chosen conservatively. */
|
|
28
|
-
readonly basis:
|
|
51
|
+
readonly basis: ProviderLimitBasis;
|
|
52
|
+
/** The unit the provider enforces its limits in. Absent means `provider`. */
|
|
53
|
+
readonly scope?: ProviderLimitScope;
|
|
54
|
+
/**
|
|
55
|
+
* Where a per-model scope was read from, when the entry's numbers are not
|
|
56
|
+
* themselves published. The unit is a claim about the provider and carries
|
|
57
|
+
* the same burden of proof as a number.
|
|
58
|
+
*/
|
|
59
|
+
readonly scope_source?: string | null;
|
|
29
60
|
readonly requests_per_minute: number;
|
|
61
|
+
/**
|
|
62
|
+
* Provenance of `requests_per_minute` when it differs from `basis`. A provider
|
|
63
|
+
* can publish a concurrency ceiling and no per-minute ceiling at all; the
|
|
64
|
+
* per-minute number is then the client's own choice and must not borrow the
|
|
65
|
+
* published label of the bound that was transcribed.
|
|
66
|
+
*/
|
|
67
|
+
readonly requests_per_minute_basis?: ProviderLimitBasis;
|
|
30
68
|
readonly max_concurrent: number;
|
|
31
69
|
readonly acquire_timeout_ms: number;
|
|
32
70
|
/** Where a published limit was read from. Null while the basis is a conservative default. */
|
|
@@ -50,6 +88,28 @@ export declare function limitsInventory(): {
|
|
|
50
88
|
provider: string;
|
|
51
89
|
limits: ProviderLimits;
|
|
52
90
|
}[];
|
|
91
|
+
/** Which guard a call is held by, and how its caller can stop waiting. */
|
|
92
|
+
export interface GuardCallScope {
|
|
93
|
+
/**
|
|
94
|
+
* The model the call is addressed to. Selects the guard for a provider whose
|
|
95
|
+
* limits apply per model; ignored for a provider whose limits apply per
|
|
96
|
+
* provider.
|
|
97
|
+
*/
|
|
98
|
+
readonly modelId?: string;
|
|
99
|
+
/**
|
|
100
|
+
* The caller's cancellation. A caller that stops waiting leaves the queue at
|
|
101
|
+
* once rather than holding its place until its wait budget runs out, and a
|
|
102
|
+
* permit freed after it has gone goes to a caller that is still waiting.
|
|
103
|
+
*/
|
|
104
|
+
readonly signal?: AbortSignal;
|
|
105
|
+
}
|
|
106
|
+
/** What a refusal says about the call it refused. */
|
|
107
|
+
interface RefusalDetail {
|
|
108
|
+
/** The model whose guard refused the call, for a provider whose limits apply per model. */
|
|
109
|
+
readonly modelId?: string;
|
|
110
|
+
/** Whether the caller stopped waiting before the guard's own budget ran out. */
|
|
111
|
+
readonly abandoned?: boolean;
|
|
112
|
+
}
|
|
53
113
|
/**
|
|
54
114
|
* Thrown when a caller could not acquire a slot within its budget.
|
|
55
115
|
*
|
|
@@ -61,12 +121,17 @@ export declare class RateGuardTimeoutError extends Error {
|
|
|
61
121
|
readonly provider: string;
|
|
62
122
|
/** Which of the two bounds the caller waited on. */
|
|
63
123
|
readonly bound: "rate" | "concurrency";
|
|
124
|
+
/** The model whose guard refused the call, when the provider's limits apply per model. */
|
|
125
|
+
readonly modelId: string | undefined;
|
|
126
|
+
/** Whether the caller stopped waiting before the guard's own wait budget ran out. */
|
|
127
|
+
readonly abandoned: boolean;
|
|
64
128
|
/**
|
|
65
129
|
* @param provider The provider.
|
|
66
130
|
* @param bound Which bound was binding.
|
|
67
|
-
* @param waitedMs How long the caller
|
|
131
|
+
* @param waitedMs How long the caller was prepared to wait.
|
|
132
|
+
* @param detail The model, and whether the caller left before the budget ran out.
|
|
68
133
|
*/
|
|
69
|
-
constructor(provider: string, bound: "rate" | "concurrency", waitedMs: number);
|
|
134
|
+
constructor(provider: string, bound: "rate" | "concurrency", waitedMs: number, detail?: RefusalDetail);
|
|
70
135
|
}
|
|
71
136
|
/**
|
|
72
137
|
* Run a call under a provider's rate and concurrency guards.
|
|
@@ -86,13 +151,20 @@ export declare class RateGuardTimeoutError extends Error {
|
|
|
86
151
|
* @param provider The provider key.
|
|
87
152
|
* @param call The work to run once admitted.
|
|
88
153
|
* @param maxWaitMs Ceiling on queue time; the configured guard timeout applies when lower.
|
|
154
|
+
* @param scope The model the call addresses, and the caller's cancellation.
|
|
89
155
|
* @returns The call's result.
|
|
90
|
-
* @throws {RateGuardTimeoutError} When neither bound admitted the call in time
|
|
156
|
+
* @throws {RateGuardTimeoutError} When neither bound admitted the call in time,
|
|
157
|
+
* or the caller stopped waiting first.
|
|
91
158
|
*/
|
|
92
|
-
export declare function withProviderGuards<T>(provider: string, call: () => Promise<T>, maxWaitMs?: number): Promise<T>;
|
|
159
|
+
export declare function withProviderGuards<T>(provider: string, call: () => Promise<T>, maxWaitMs?: number, scope?: GuardCallScope): Promise<T>;
|
|
93
160
|
/** Observable guard state, for dashboards and tests. */
|
|
94
161
|
export interface GuardSnapshot {
|
|
162
|
+
/** The guard's identity: the provider, or `provider/model` for a per-model guard. */
|
|
163
|
+
readonly key: string;
|
|
95
164
|
readonly provider: string;
|
|
165
|
+
/** The model this guard covers, for a provider whose limits apply per model. */
|
|
166
|
+
readonly modelId: string | undefined;
|
|
167
|
+
readonly scope: ProviderLimitScope;
|
|
96
168
|
readonly basis: ProviderLimits["basis"];
|
|
97
169
|
readonly requestsPerMinute: number;
|
|
98
170
|
readonly maxConcurrent: number;
|
|
@@ -104,7 +176,7 @@ export interface GuardSnapshot {
|
|
|
104
176
|
/**
|
|
105
177
|
* Inspect the guards currently in use.
|
|
106
178
|
*
|
|
107
|
-
* @returns A snapshot per
|
|
179
|
+
* @returns A snapshot per guard that has been used, sorted by guard key.
|
|
108
180
|
*/
|
|
109
181
|
export declare function guardSnapshots(): GuardSnapshot[];
|
|
110
182
|
/**
|
|
@@ -116,4 +188,5 @@ export declare function guardSnapshots(): GuardSnapshot[];
|
|
|
116
188
|
* @returns void
|
|
117
189
|
*/
|
|
118
190
|
export declare function resetProviderGuards(): void;
|
|
191
|
+
export {};
|
|
119
192
|
//# sourceMappingURL=rate-guard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-guard.d.ts","sourceRoot":"","sources":["../../../src/llm/rate-guard.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"rate-guard.d.ts","sourceRoot":"","sources":["../../../src/llm/rate-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interpretation of a model's answer to a structured (JSON) request.
|
|
3
|
+
*
|
|
4
|
+
* A JSON request is a promise about the answer's SHAPE, and providers keep it
|
|
5
|
+
* in different ways. An OpenAI-compatible host given `json_object` constrains
|
|
6
|
+
* its decoder, so its answer is bare JSON. A provider with no schema-less JSON
|
|
7
|
+
* mode — Anthropic, reached through the gateway, supports structured output
|
|
8
|
+
* only against a caller-supplied schema — receives nothing but the prompt's
|
|
9
|
+
* instructions for a `json` request, and a model following them commonly
|
|
10
|
+
* returns the object inside one markdown code fence. The fence is presentation,
|
|
11
|
+
* not content: the object inside it is the answer the model gave.
|
|
12
|
+
*
|
|
13
|
+
* So exactly ONE enclosing fence is removed before parsing, and nothing else is
|
|
14
|
+
* forgiven. Prose before or after the fence, two fenced blocks, a fence that
|
|
15
|
+
* never closes (a truncated answer), and a fence declaring another language all
|
|
16
|
+
* still fail. Each of those is an answer whose meaning a parser would have to
|
|
17
|
+
* guess, and a guessed object is a decision made on data no model produced.
|
|
18
|
+
*
|
|
19
|
+
* Content that is not fenced is parsed exactly as it always was: JSON cannot
|
|
20
|
+
* begin with a backtick, so every answer that parsed before this unwrapping
|
|
21
|
+
* existed takes the same path and yields the same value.
|
|
22
|
+
*
|
|
23
|
+
* @module llm/structured-content
|
|
24
|
+
*/
|
|
25
|
+
import type { LlmResponseFormat, LlmUsageRecord } from "./types";
|
|
26
|
+
/** A response format that promises structured content. */
|
|
27
|
+
export type StructuredResponseFormat = Exclude<LlmResponseFormat, "text">;
|
|
28
|
+
/**
|
|
29
|
+
* Thrown when a provider answered a structured request with content that does
|
|
30
|
+
* not parse.
|
|
31
|
+
*
|
|
32
|
+
* Carries the usage the provider billed for that answer. The tokens were spent
|
|
33
|
+
* whether or not the content parsed, and a chain that dropped them would report
|
|
34
|
+
* a failed attempt as free — understating spend by exactly the calls that went
|
|
35
|
+
* wrong.
|
|
36
|
+
*/
|
|
37
|
+
export declare class LlmResponseFormatError extends Error {
|
|
38
|
+
/** The format the caller asked for. */
|
|
39
|
+
readonly responseFormat: "json" | "json_schema";
|
|
40
|
+
/** What the provider billed for the answer that did not parse. */
|
|
41
|
+
readonly usage: LlmUsageRecord;
|
|
42
|
+
/** Whether the answer sat inside one enclosing fence that was removed before parsing. */
|
|
43
|
+
readonly fenced: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* @param responseFormat The format the caller asked for.
|
|
46
|
+
* @param usage What the provider billed for the answer.
|
|
47
|
+
* @param fenced Whether one enclosing fence was removed before parsing.
|
|
48
|
+
* @param cause The parser's own complaint.
|
|
49
|
+
*/
|
|
50
|
+
constructor(responseFormat: "json" | "json_schema", usage: LlmUsageRecord, fenced: boolean, cause: unknown);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The body of the one markdown fence that encloses an answer, if exactly one does.
|
|
54
|
+
*
|
|
55
|
+
* @param text The model's answer.
|
|
56
|
+
* @returns The fenced body, or null when the answer is not wholly one fenced block.
|
|
57
|
+
*/
|
|
58
|
+
export declare function unwrapSingleJsonFence(text: string): string | null;
|
|
59
|
+
/**
|
|
60
|
+
* Parse a model's answer to a structured request.
|
|
61
|
+
*
|
|
62
|
+
* A JSON format that does not parse is an error, not an empty object. Returning
|
|
63
|
+
* a default here would hand the caller a well-typed value that means nothing,
|
|
64
|
+
* and the failure would surface much later as a decision made on absent data.
|
|
65
|
+
*
|
|
66
|
+
* @param content The raw content of the model's message.
|
|
67
|
+
* @param responseFormat The structured format the caller asked for.
|
|
68
|
+
* @param usage What the provider billed for this answer, carried on failure.
|
|
69
|
+
* @returns The parsed value.
|
|
70
|
+
* @throws {LlmResponseFormatError} When the content is not JSON, fenced or not.
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseStructuredContent<T>(content: unknown, responseFormat: StructuredResponseFormat, usage: LlmUsageRecord): T;
|
|
73
|
+
//# sourceMappingURL=structured-content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structured-content.d.ts","sourceRoot":"","sources":["../../../src/llm/structured-content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEjE,0DAA0D;AAC1D,MAAM,MAAM,wBAAwB,GAAG,OAAO,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;AAW1E;;;;;;;;GAQG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,uCAAuC;IACvC,SAAgB,cAAc,EAAE,MAAM,GAAG,aAAa,CAAC;IAEvD,kEAAkE;IAClE,SAAgB,KAAK,EAAE,cAAc,CAAC;IAEtC,yFAAyF;IACzF,SAAgB,MAAM,EAAE,OAAO,CAAC;IAEhC;;;;;OAKG;gBAED,cAAc,EAAE,MAAM,GAAG,aAAa,EACtC,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,OAAO;CAYjB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,wBAAwB,EACxC,KAAK,EAAE,cAAc,GACpB,CAAC,CAaH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../../../src/llm/transports/gateway.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../../../src/llm/transports/gateway.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EAGpB,MAAM,UAAU,CAAC;AAQlB,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,MAAM,CAAC;CACjE;AAED;;;;;;;;GAQG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD;;;OAGG;gBACgB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAMnD;AAED,4DAA4D;AAC5D,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,uBAAuB;IACvB,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B,8DAA8D;IAC9D,SAAgB,SAAS,EAAE,OAAO,CAAC;IAEnC;;;OAGG;gBACgB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAMhD;AAwDD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,sBAAsB,GAC7B,YAAY,CA8Dd"}
|
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
import { Bar, BenchmarkBar } from "./types/alpaca-types";
|
|
2
2
|
import { types } from "@adaptic/backend";
|
|
3
3
|
import { CalculateBetaResult, TradeMetrics } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* Beta of a portfolio against a benchmark, from paired period returns.
|
|
6
|
+
*
|
|
7
|
+
* Non-finite rows are dropped pairwise — a return that is `NaN` on either leg
|
|
8
|
+
* cannot contribute to a covariance — and the count that survives is reported
|
|
9
|
+
* as the cohort rather than discarded. That reporting is the point: silently
|
|
10
|
+
* computing a beta on the 12 rows that happened to be clean, and returning it
|
|
11
|
+
* with the same shape as a beta over all 900, is how a statistic measured on
|
|
12
|
+
* one population gets applied to another.
|
|
13
|
+
*
|
|
14
|
+
* When beta cannot be computed the result is the unavailable branch, never a
|
|
15
|
+
* numeric stand-in. A beta of `0` asserts that the portfolio does not move with
|
|
16
|
+
* the market, which is a strong and consequential claim; emitting it to mean
|
|
17
|
+
* "we could not tell" makes every alpha derived from it wrong by the whole
|
|
18
|
+
* benchmark term.
|
|
19
|
+
*
|
|
20
|
+
* @param portfolioReturns - Portfolio period returns.
|
|
21
|
+
* @param benchmarkReturns - Benchmark period returns, index-aligned to the portfolio.
|
|
22
|
+
* @returns The beta components with their cohort, or a typed unavailable result.
|
|
23
|
+
* @example
|
|
24
|
+
* const result = calculateBetaFromReturns([0.05, -0.02, 0.03], [0.03, -0.01, 0.02]);
|
|
25
|
+
* if (result.available) {
|
|
26
|
+
* // result.value.beta, alongside result.sampleCount and result.coverage
|
|
27
|
+
* }
|
|
28
|
+
*/
|
|
4
29
|
export declare function calculateBetaFromReturns(portfolioReturns: number[], benchmarkReturns: number[]): CalculateBetaResult;
|
|
5
30
|
/**
|
|
6
31
|
* Calculate max drawdown taking position type into account
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics-calcs.d.ts","sourceRoot":"","sources":["../../src/metrics-calcs.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"metrics-calcs.d.ts","sourceRoot":"","sources":["../../src/metrics-calcs.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA0I5D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,wBAAwB,CACtC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,gBAAgB,EAAE,MAAM,EAAE,GACzB,mBAAmB,CA6FrB;AA6QD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,GAAG,EAAE,EAChB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,CAmCjB;AA8CD,wBAA8B,iBAAiB,CAC7C,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,SAAS,EAAE,GAAG,EAAE,EAChB,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,YAAY,CAAC,CA0DvB"}
|
|
@@ -78,10 +78,22 @@ export declare function alignReturnsByDate(portfolioHistory: PortfolioHistory, b
|
|
|
78
78
|
alignedBenchmarkReturns: number[];
|
|
79
79
|
};
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
81
|
+
* Beta of a portfolio against a benchmark, from paired period returns.
|
|
82
|
+
*
|
|
83
|
+
* The two series are index-aligned pairs by contract: every mean, covariance
|
|
84
|
+
* and variance below is taken over the SAME row set. A length mismatch is
|
|
85
|
+
* therefore reported as invalid input rather than absorbed, because dividing
|
|
86
|
+
* one series' sum by the other series' length produces a mean of a population
|
|
87
|
+
* that does not exist — a number with no cohort, which is the failure this
|
|
88
|
+
* return type exists to make impossible.
|
|
89
|
+
*
|
|
90
|
+
* An uncomputable beta is returned as the unavailable branch, never as `0`.
|
|
91
|
+
* Zero beta is a claim of no market exposure, and downstream alpha attributes
|
|
92
|
+
* the entire benchmark move to the strategy when it believes that claim.
|
|
93
|
+
*
|
|
94
|
+
* @param portfolioReturns - Portfolio period returns.
|
|
95
|
+
* @param benchmarkReturns - Benchmark period returns, index-aligned to the portfolio.
|
|
96
|
+
* @returns The beta components with their cohort, or a typed unavailable result.
|
|
85
97
|
*/
|
|
86
98
|
export declare function calculateBetaFromReturns(portfolioReturns: number[], benchmarkReturns: number[]): CalculateBetaResult;
|
|
87
99
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performance-metrics.d.ts","sourceRoot":"","sources":["../../src/performance-metrics.ts"],"names":[],"mappings":"AASA,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,wBAAwB,EACxB,YAAY,EACZ,mBAAmB,EAEnB,uBAAuB,EACvB,UAAU,EAEX,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EACL,kBAAkB,EAClB,4BAA4B,EAC7B,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"performance-metrics.d.ts","sourceRoot":"","sources":["../../src/performance-metrics.ts"],"names":[],"mappings":"AASA,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,wBAAwB,EACxB,YAAY,EACZ,mBAAmB,EAEnB,uBAAuB,EACvB,UAAU,EAEX,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EACL,kBAAkB,EAClB,4BAA4B,EAC7B,MAAM,uBAAuB,CAAC;AAqD/B;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAAC,EAC1C,SAAS,EACT,MAAM,EACN,aAAa,GACd,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiF3C;AAwBD;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAqMD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,gBAAgB,EAAE,wBAAwB,EAC1C,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CA+OD;AAkCD,UAAU,cAAc;IACtB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yBAAyB,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CACrB,GACL,cAAc,CAuHhB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,GAAE,MAAU,GACnB,MAAM,CAGR;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAchE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,gBAAgB,EAAE,gBAAgB,EAClC,aAAa,EAAE,YAAY,EAAE,GAC5B;IAAE,uBAAuB,EAAE,MAAM,EAAE,CAAC;IAAC,uBAAuB,EAAE,MAAM,EAAE,CAAA;CAAE,CAiF1E;AAkFD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CACtC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,gBAAgB,EAAE,MAAM,EAAE,GACzB,mBAAmB,CA2ErB;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,gBAAgB,EAAE,wBAAwB,EAC1C,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,MAAM,CAAC,CAmHjB;AA+BD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,sBAAsB,CAAC,WAAW,CAAC,CAAC;CAChD,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAsB1B;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAAC,EAC5C,MAAM,EACN,MAAM,EACN,SAAS,EACT,aAAa,GACd,EAAE,4BAA4B,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0J5D"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A measured statistic and the cohort it was measured on, carried as one
|
|
3
|
+
* inseparable value.
|
|
4
|
+
*
|
|
5
|
+
* A ratio is meaningless without the population it was taken over: the same
|
|
6
|
+
* `0.42` is a strong result on 2,000 trades and noise on five, and a `0.0`
|
|
7
|
+
* returned because nothing could be computed is indistinguishable from a `0.0`
|
|
8
|
+
* that was genuinely measured. Both confusions are the same error — a number
|
|
9
|
+
* read apart from its unit and its cohort — and both have produced wrong
|
|
10
|
+
* conclusions from correct arithmetic.
|
|
11
|
+
*
|
|
12
|
+
* This type removes the option. Every statistic shaped by a population carries
|
|
13
|
+
* `sampleCount` (how many observations actually entered the computation) and
|
|
14
|
+
* `coverage` (what fraction of the observations the caller offered were usable),
|
|
15
|
+
* on BOTH branches: an unavailable statistic still reports how much data it
|
|
16
|
+
* saw, because "we had nothing" and "we had 900 rows and still could not
|
|
17
|
+
* compute it" are different facts with different responses.
|
|
18
|
+
*
|
|
19
|
+
* Absence is a branch of the union rather than a sentinel value. There is no
|
|
20
|
+
* number a caller can read without first proving the statistic exists, which is
|
|
21
|
+
* what keeps an unknown from silently becoming a zero on its way to a decision.
|
|
22
|
+
*
|
|
23
|
+
* @module sample-statistic
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Why a statistic could not be computed from the observations offered.
|
|
27
|
+
*
|
|
28
|
+
* The distinctions are the point: a caller that cannot tell "too few rows" from
|
|
29
|
+
* "the rows were unusable" from "the population is degenerate" cannot tell a
|
|
30
|
+
* warm-up from a data outage from a genuinely constant series, and will treat
|
|
31
|
+
* all three the same way.
|
|
32
|
+
*/
|
|
33
|
+
export type StatisticUnavailableReason =
|
|
34
|
+
/** Fewer usable observations than the computation requires. */
|
|
35
|
+
"insufficient_samples"
|
|
36
|
+
/** Observations were offered but none survived validation (non-finite, unpaired). */
|
|
37
|
+
| "no_usable_samples"
|
|
38
|
+
/** Enough usable observations, but the population cannot support the statistic
|
|
39
|
+
* (a zero-variance denominator, an undefined ratio). */
|
|
40
|
+
| "degenerate_population"
|
|
41
|
+
/** The request itself is malformed — mismatched series lengths, a non-positive window. */
|
|
42
|
+
| "invalid_input";
|
|
43
|
+
/**
|
|
44
|
+
* How many observations a statistic was actually computed from, against how
|
|
45
|
+
* many the caller offered.
|
|
46
|
+
*
|
|
47
|
+
* `coverage` is the ratio that makes silent row-dropping visible: a function
|
|
48
|
+
* that filters non-finite rows and reports only the surviving statistic hides
|
|
49
|
+
* the size of what it discarded, and a statistic computed on 12% of the
|
|
50
|
+
* requested window is a different claim from the same number computed on all
|
|
51
|
+
* of it.
|
|
52
|
+
*/
|
|
53
|
+
export interface SampleCohort {
|
|
54
|
+
/** Observations that entered the computation. Never negative. */
|
|
55
|
+
readonly sampleCount: number;
|
|
56
|
+
/** Observations the caller offered, or the window width the caller asked for. */
|
|
57
|
+
readonly requestedCount: number;
|
|
58
|
+
/** `sampleCount / requestedCount`, clamped to [0, 1]; `0` when nothing was requested. */
|
|
59
|
+
readonly coverage: number;
|
|
60
|
+
}
|
|
61
|
+
/** A statistic that was computed, carrying the cohort it was computed on. */
|
|
62
|
+
export interface AvailableStatistic<T> extends SampleCohort {
|
|
63
|
+
readonly available: true;
|
|
64
|
+
/** The measured value. */
|
|
65
|
+
readonly value: T;
|
|
66
|
+
}
|
|
67
|
+
/** A statistic that could not be computed, still carrying what data was seen. */
|
|
68
|
+
export interface UnavailableStatistic extends SampleCohort {
|
|
69
|
+
readonly available: false;
|
|
70
|
+
/** Which class of failure prevented the computation. */
|
|
71
|
+
readonly reason: StatisticUnavailableReason;
|
|
72
|
+
/** Human-readable specifics, for logs and error messages. Never parsed. */
|
|
73
|
+
readonly detail: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A statistic that either exists with its cohort, or does not exist and says
|
|
77
|
+
* why — never a number standing in for an unknown.
|
|
78
|
+
*/
|
|
79
|
+
export type SampleStatistic<T> = AvailableStatistic<T> | UnavailableStatistic;
|
|
80
|
+
/**
|
|
81
|
+
* Build the cohort descriptor for a computation.
|
|
82
|
+
*
|
|
83
|
+
* `coverage` is derived here rather than supplied, so it cannot drift from the
|
|
84
|
+
* counts it claims to summarise. A zero request yields zero coverage: no
|
|
85
|
+
* observations were asked for, so none were covered, and the alternative (`1`)
|
|
86
|
+
* would report a vacuous computation as fully covered.
|
|
87
|
+
*
|
|
88
|
+
* @param requestedCount - Observations offered, or the window width requested.
|
|
89
|
+
* @param sampleCount - Observations that entered the computation.
|
|
90
|
+
* @returns The cohort descriptor with `coverage` derived from the two counts.
|
|
91
|
+
* @throws When either count is negative or non-finite, which is a programming
|
|
92
|
+
* error rather than a data condition.
|
|
93
|
+
*/
|
|
94
|
+
export declare function sampleCohort(requestedCount: number, sampleCount: number): SampleCohort;
|
|
95
|
+
/**
|
|
96
|
+
* Wrap a computed value with its cohort.
|
|
97
|
+
*
|
|
98
|
+
* @param value - The measured statistic.
|
|
99
|
+
* @param cohort - The cohort it was measured on.
|
|
100
|
+
* @returns The available branch of {@link SampleStatistic}.
|
|
101
|
+
*/
|
|
102
|
+
export declare function availableStatistic<T>(value: T, cohort: SampleCohort): AvailableStatistic<T>;
|
|
103
|
+
/**
|
|
104
|
+
* Record that a statistic could not be computed, and what was seen instead.
|
|
105
|
+
*
|
|
106
|
+
* @param reason - Which class of failure prevented the computation.
|
|
107
|
+
* @param detail - Specifics for logs; never machine-parsed.
|
|
108
|
+
* @param cohort - What data was available when the attempt was abandoned.
|
|
109
|
+
* @returns The unavailable branch of {@link SampleStatistic}.
|
|
110
|
+
*/
|
|
111
|
+
export declare function unavailableStatistic(reason: StatisticUnavailableReason, detail: string, cohort: SampleCohort): UnavailableStatistic;
|
|
112
|
+
/**
|
|
113
|
+
* Narrow a statistic to its available branch.
|
|
114
|
+
*
|
|
115
|
+
* Exists so consumers in other packages can discriminate without restating the
|
|
116
|
+
* predicate, and so the discriminant stays a single named concept if the shape
|
|
117
|
+
* ever grows a third branch.
|
|
118
|
+
*
|
|
119
|
+
* @param statistic - The statistic to test.
|
|
120
|
+
* @returns Whether the statistic carries a value.
|
|
121
|
+
*/
|
|
122
|
+
export declare function isAvailable<T>(statistic: SampleStatistic<T>): statistic is AvailableStatistic<T>;
|
|
123
|
+
//# sourceMappingURL=sample-statistic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sample-statistic.d.ts","sourceRoot":"","sources":["../../src/sample-statistic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,0BAA0B;AACpC,+DAA+D;AAC7D,sBAAsB;AACxB,qFAAqF;GACnF,mBAAmB;AACrB;yDACyD;GACvD,uBAAuB;AACzB,0FAA0F;GACxF,eAAe,CAAC;AAEpB;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,yFAAyF;IACzF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB,CAAC,CAAC,CAAE,SAAQ,YAAY;IACzD,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;CACnB;AAED,iFAAiF;AACjF,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAC;IAC5C,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC;AAE9E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAC1B,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,GAClB,YAAY,CAkBd;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,KAAK,EAAE,CAAC,EACR,MAAM,EAAE,YAAY,GACnB,kBAAkB,CAAC,CAAC,CAAC,CAEvB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,0BAA0B,EAClC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,GACnB,oBAAoB,CAEtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC,GAC5B,SAAS,IAAI,kBAAkB,CAAC,CAAC,CAAC,CAEpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alpaca-schemas.d.ts","sourceRoot":"","sources":["../../../src/schemas/alpaca-schemas.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAexB,iDAAiD;AACjD,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+CrC,CAAC;AAIH,0CAA0C;AAC1C,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB/B,CAAC;AAEH,8CAA8C;AAC9C,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"alpaca-schemas.d.ts","sourceRoot":"","sources":["../../../src/schemas/alpaca-schemas.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAexB,iDAAiD;AACjD,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+CrC,CAAC;AAIH,0CAA0C;AAC1C,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB/B,CAAC;AAEH,8CAA8C;AAC9C,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAAgC,CAAC;AAsDxE,uCAAuC;AACvC,eAAO,MAAM,iBAAiB,EAAE,CAAC,CAAC,OAiChC,CAAC;AAEH,2CAA2C;AAC3C,eAAO,MAAM,uBAAuB,uDAA6B,CAAC;AAIlE,4CAA4C;AAC5C,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS1B,CAAC;AAEH,0CAA0C;AAC1C,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAI7C,CAAC;AAEH,sCAAsC;AACtC,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGzC,CAAC;AAIH,gCAAgC;AAChC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU5B,CAAC;AAEH,wCAAwC;AACxC,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG3C,CAAC;AAIH,gCAAgC;AAChC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;EAQ5B,CAAC;AAEH,wCAAwC;AACxC,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG3C,CAAC;AAUH,gCAAgC;AAChC,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYlC,CAAC;AAEH,+BAA+B;AAC/B,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGnC,CAAC;AAIH,4CAA4C;AAC5C,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;EAO/C,CAAC;AAIH,sCAAsC;AACtC,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBzC,CAAC"}
|
|
@@ -4,62 +4,84 @@
|
|
|
4
4
|
* Conventions:
|
|
5
5
|
* - tradePnls / tradeReturns is an array of per-trade realised P&L or return
|
|
6
6
|
* (positive = win, negative = loss, zero = breakeven).
|
|
7
|
-
* -
|
|
7
|
+
* - Every statistic here is a ratio or a mean over a WINDOW, so every one is
|
|
8
|
+
* returned as a {@link SampleStatistic}: the value cannot be read without the
|
|
9
|
+
* `sampleCount` it was taken over and the `coverage` of the window that was
|
|
10
|
+
* asked for. A hit-rate is a different claim on 5 trades than on 500, and a
|
|
11
|
+
* window that could only be half-filled is a different cohort from a full
|
|
12
|
+
* one — a caller holding a bare number can tell neither apart.
|
|
13
|
+
* - A window that cannot support the statistic returns the unavailable branch
|
|
14
|
+
* with a reason, never a numeric stand-in. Zero is a measurement.
|
|
8
15
|
* - All public functions reject non-finite inputs (NaN, Infinity) by throwing.
|
|
9
16
|
* Callers must pre-validate or filter their inputs.
|
|
10
17
|
*/
|
|
18
|
+
import { type SampleStatistic } from "./sample-statistic";
|
|
11
19
|
/**
|
|
12
20
|
* Rolling expectancy: mean P&L over the most-recent `windowSize` trades.
|
|
13
21
|
*
|
|
14
22
|
* @param tradePnls - Array of per-trade realised P&L values.
|
|
15
23
|
* @param windowSize - Number of most-recent trades to include. Must be a positive integer.
|
|
16
|
-
* @returns Mean P&L of the last `windowSize` trades
|
|
24
|
+
* @returns Mean P&L of the last `windowSize` trades with its cohort, or a typed
|
|
25
|
+
* unavailable result when fewer than `windowSize` trades exist.
|
|
17
26
|
* @throws When `windowSize` is not a positive integer or any input is non-finite.
|
|
18
27
|
*/
|
|
19
|
-
export declare function calculateRollingExpectancy(tradePnls: number[], windowSize: number): number
|
|
28
|
+
export declare function calculateRollingExpectancy(tradePnls: number[], windowSize: number): SampleStatistic<number>;
|
|
20
29
|
/**
|
|
21
30
|
* Rolling hit-rate: fraction of strictly-positive P&L trades in the most-recent
|
|
22
31
|
* `windowSize` trades. Zero P&L counts as non-win.
|
|
23
32
|
*
|
|
24
33
|
* @param tradePnls - Array of per-trade realised P&L values.
|
|
25
34
|
* @param windowSize - Number of most-recent trades to include. Must be a positive integer.
|
|
26
|
-
* @returns Fraction of winning trades in the window
|
|
35
|
+
* @returns Fraction of winning trades in the window with its cohort, or a typed
|
|
36
|
+
* unavailable result when fewer than `windowSize` trades exist.
|
|
27
37
|
* @throws When `windowSize` is not a positive integer or any input is non-finite.
|
|
28
38
|
*/
|
|
29
|
-
export declare function calculateRollingHitRate(tradePnls: number[], windowSize: number): number
|
|
39
|
+
export declare function calculateRollingHitRate(tradePnls: number[], windowSize: number): SampleStatistic<number>;
|
|
30
40
|
/**
|
|
31
41
|
* Rolling profit factor: sum(wins) / |sum(losses)| over the most-recent `windowSize` trades.
|
|
32
42
|
*
|
|
33
43
|
* Edge cases:
|
|
34
|
-
* - no losses and at least one win → +Infinity
|
|
35
|
-
* - no wins and no losses (all zeros) → 0
|
|
36
|
-
*
|
|
44
|
+
* - no losses and at least one win → +Infinity (an unbounded but real ratio)
|
|
45
|
+
* - no wins and no losses (all zeros) → unavailable: `0 / 0` is undefined, and a
|
|
46
|
+
* window of breakeven trades has no profit factor rather than a profit factor
|
|
47
|
+
* of zero
|
|
48
|
+
* - fewer than windowSize trades → unavailable
|
|
37
49
|
*
|
|
38
50
|
* @param tradePnls - Array of per-trade realised P&L values.
|
|
39
51
|
* @param windowSize - Number of most-recent trades to include. Must be a positive integer.
|
|
40
|
-
* @returns Profit factor for the rolling window
|
|
52
|
+
* @returns Profit factor for the rolling window with its cohort, or a typed
|
|
53
|
+
* unavailable result.
|
|
41
54
|
* @throws When `windowSize` is not a positive integer or any input is non-finite.
|
|
42
55
|
*/
|
|
43
|
-
export declare function calculateRollingProfitFactor(tradePnls: number[], windowSize: number): number
|
|
56
|
+
export declare function calculateRollingProfitFactor(tradePnls: number[], windowSize: number): SampleStatistic<number>;
|
|
44
57
|
/**
|
|
45
58
|
* Rolling Sortino: delegate to `calculateSortino` over the most-recent `windowSize` returns.
|
|
46
59
|
*
|
|
47
60
|
* @param tradeReturns - Array of per-trade return values.
|
|
48
61
|
* @param windowSize - Number of most-recent trades to include. Must be a positive integer.
|
|
49
62
|
* @param riskFreeRate - Risk-free rate to subtract from returns (default 0).
|
|
50
|
-
* @returns Sortino ratio for the rolling window
|
|
63
|
+
* @returns Sortino ratio for the rolling window with its cohort, or a typed
|
|
64
|
+
* unavailable result.
|
|
51
65
|
* @throws When `windowSize` is not a positive integer or any input is non-finite.
|
|
52
66
|
*/
|
|
53
|
-
export declare function calculateRollingSortino(tradeReturns: number[], windowSize: number, riskFreeRate?: number): number
|
|
67
|
+
export declare function calculateRollingSortino(tradeReturns: number[], windowSize: number, riskFreeRate?: number): SampleStatistic<number>;
|
|
54
68
|
/**
|
|
55
69
|
* Z-score of live-expectancy vs backtest-expectancy, scaled by the backtest stddev.
|
|
56
70
|
* Positive Z = live outperforming; negative Z = live underperforming.
|
|
57
71
|
*
|
|
58
|
-
*
|
|
72
|
+
* The live expectancy is taken as a {@link SampleStatistic} rather than a bare
|
|
73
|
+
* number so the z-score inherits the cohort it was actually derived from. A
|
|
74
|
+
* z-score is a statement about how surprising a sample mean is, and how
|
|
75
|
+
* surprising it is depends entirely on how many trades produced it — quoting
|
|
76
|
+
* the z alone is the exact substitution this type exists to block. An
|
|
77
|
+
* unavailable live expectancy yields an unavailable z, because there is no
|
|
78
|
+
* mean to compare.
|
|
79
|
+
*
|
|
80
|
+
* @param liveExpectancy - Mean P&L per trade in the live window, with its cohort.
|
|
59
81
|
* @param backtestExpectancy - Mean P&L per trade from the calibration backtest.
|
|
60
82
|
* @param backtestStddev - Stddev of per-trade P&L in the backtest. Must be > 0.
|
|
61
|
-
* @returns Z-score measuring divergence
|
|
62
|
-
* @throws When
|
|
83
|
+
* @returns Z-score measuring live-vs-backtest divergence, carrying the live cohort.
|
|
84
|
+
* @throws When the backtest inputs are non-finite or `backtestStddev` is not positive.
|
|
63
85
|
*/
|
|
64
|
-
export declare function calculateBacktestDivergenceZ(liveExpectancy: number
|
|
86
|
+
export declare function calculateBacktestDivergenceZ(liveExpectancy: SampleStatistic<number>, backtestExpectancy: number, backtestStddev: number): SampleStatistic<number>;
|
|
65
87
|
//# sourceMappingURL=strategy-metrics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strategy-metrics.d.ts","sourceRoot":"","sources":["../../src/strategy-metrics.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"strategy-metrics.d.ts","sourceRoot":"","sources":["../../src/strategy-metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAC;AAwC5B;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,EAAE,MAAM,GACjB,eAAe,CAAC,MAAM,CAAC,CAezB;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,EAAE,MAAM,GACjB,eAAe,CAAC,MAAM,CAAC,CAgBzB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,EAAE,MAAM,GACjB,eAAe,CAAC,MAAM,CAAC,CAyBzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,EAAE,EACtB,UAAU,EAAE,MAAM,EAClB,YAAY,SAAI,GACf,eAAe,CAAC,MAAM,CAAC,CAuBzB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,4BAA4B,CAC1C,cAAc,EAAE,eAAe,CAAC,MAAM,CAAC,EACvC,kBAAkB,EAAE,MAAM,EAC1B,cAAc,EAAE,MAAM,GACrB,eAAe,CAAC,MAAM,CAAC,CAqBzB"}
|