@general-liquidity/sharpebench 0.0.6 → 0.0.12
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 +17 -1
- package/dist/index.js +63 -0
- package/dist/types.d.ts +54 -0
- package/package.json +1 -1
- package/pkg/package.json +1 -1
- package/pkg/sharpebench.d.ts +4 -0
- package/pkg/sharpebench.js +47 -0
- package/pkg/sharpebench_bg.wasm +0 -0
- package/pkg/sharpebench_bg.wasm.d.ts +2 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentSubmission, AllocationPolicy, AllocationReport, AllocationTrajectory, Briefing, BriefingAudit, BriefingPolicy, Canary, CompositeScore, GreeksParams, GreeksResult, ScoreConfig, SelfAuditReport } from "./types.js";
|
|
1
|
+
import type { AgentSubmission, AllocationPolicy, AllocationReport, AllocationTrajectory, Briefing, BriefingAudit, BriefingPolicy, Canary, CompositeScore, FullVerdict, GreeksParams, GreeksResult, HonestyOpts, HonestyVerdict, ScoreConfig, SelfAuditReport } from "./types.js";
|
|
2
2
|
export * from "./types.js";
|
|
3
3
|
/**
|
|
4
4
|
* Score and rank a field of submissions on the luck-robust composite. Returns the
|
|
@@ -21,3 +21,19 @@ export declare function scoreAllocation(trajectory: AllocationTrajectory, policy
|
|
|
21
21
|
export declare function greeks(params: GreeksParams): GreeksResult;
|
|
22
22
|
/** Derive a deterministic do-not-train contamination tripwire from seed material. */
|
|
23
23
|
export declare function canary(seed: string): Canary;
|
|
24
|
+
/**
|
|
25
|
+
* "Is my Sharpe real, or an artifact of luck and multiple testing?" — the LITE
|
|
26
|
+
* backtest-honesty verdict over one per-period return series. Deflates the observed
|
|
27
|
+
* Sharpe for `nTrials` (the search footprint), then renders Pass / Borderline / Fail
|
|
28
|
+
* with PSR, expected-max-Sharpe, haircut, and MinTRL.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isMySharpeReal(returns: number[], opts: HonestyOpts): HonestyVerdict;
|
|
31
|
+
/**
|
|
32
|
+
* The FULL verdict: the winner's LITE verdict plus the multiple-testing family
|
|
33
|
+
* (White's Reality Check, Hansen's SPA + consistent variant, Romano-Wolf step-down)
|
|
34
|
+
* and the CSCV Probability of Backtest Overfitting over the whole field.
|
|
35
|
+
*
|
|
36
|
+
* `field` is N rows (candidate strategies) × T cols (time); `winnerIdx` is the row
|
|
37
|
+
* whose LITE verdict is reported.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isMySharpeRealFull(field: number[][], winnerIdx: number, opts: HonestyOpts): FullVerdict;
|
package/dist/index.js
CHANGED
|
@@ -43,6 +43,8 @@ exports.auditBriefing = auditBriefing;
|
|
|
43
43
|
exports.scoreAllocation = scoreAllocation;
|
|
44
44
|
exports.greeks = greeks;
|
|
45
45
|
exports.canary = canary;
|
|
46
|
+
exports.isMySharpeReal = isMySharpeReal;
|
|
47
|
+
exports.isMySharpeRealFull = isMySharpeRealFull;
|
|
46
48
|
/**
|
|
47
49
|
* `@general-liquidity/sharpebench` — the luck-robust scoring kernel for AI trading
|
|
48
50
|
* agents, as a typed JS API over the *identical* Rust kernel that powers the
|
|
@@ -103,3 +105,64 @@ function greeks(params) {
|
|
|
103
105
|
function canary(seed) {
|
|
104
106
|
return parse(kernel.canary(seed));
|
|
105
107
|
}
|
|
108
|
+
/** Map camelCase {@link HonestyOpts} → the snake_case `HonestyConfig` JSON the kernel reads. */
|
|
109
|
+
function honestyConfigJson(opts) {
|
|
110
|
+
const cfg = { n_trials: opts.nTrials };
|
|
111
|
+
if (opts.trialsSrStd !== undefined)
|
|
112
|
+
cfg.trials_sr_std = opts.trialsSrStd;
|
|
113
|
+
if (opts.confidence !== undefined)
|
|
114
|
+
cfg.confidence = opts.confidence;
|
|
115
|
+
if (opts.borderline !== undefined)
|
|
116
|
+
cfg.borderline = opts.borderline;
|
|
117
|
+
if (opts.srBenchmark !== undefined)
|
|
118
|
+
cfg.sr_benchmark = opts.srBenchmark;
|
|
119
|
+
return JSON.stringify(cfg);
|
|
120
|
+
}
|
|
121
|
+
/** Map the kernel's snake_case HonestyVerdict JSON → the camelCase {@link HonestyVerdict}. */
|
|
122
|
+
function toHonestyVerdict(raw) {
|
|
123
|
+
return {
|
|
124
|
+
sharpe: raw.sharpe,
|
|
125
|
+
nObs: raw.n_obs,
|
|
126
|
+
skew: raw.skew,
|
|
127
|
+
kurtosis: raw.kurtosis,
|
|
128
|
+
nTrials: raw.n_trials,
|
|
129
|
+
expectedMaxSharpe: raw.expected_max_sharpe,
|
|
130
|
+
deflatedSharpe: raw.deflated_sharpe,
|
|
131
|
+
probabilisticSharpe: raw.probabilistic_sharpe,
|
|
132
|
+
haircut: raw.haircut,
|
|
133
|
+
haircutSharpe: raw.haircut_sharpe,
|
|
134
|
+
minTrackRecordLen: raw.min_track_record_len,
|
|
135
|
+
verdict: raw.verdict,
|
|
136
|
+
explanation: raw.explanation,
|
|
137
|
+
methodologyVersion: raw.methodology_version,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* "Is my Sharpe real, or an artifact of luck and multiple testing?" — the LITE
|
|
142
|
+
* backtest-honesty verdict over one per-period return series. Deflates the observed
|
|
143
|
+
* Sharpe for `nTrials` (the search footprint), then renders Pass / Borderline / Fail
|
|
144
|
+
* with PSR, expected-max-Sharpe, haircut, and MinTRL.
|
|
145
|
+
*/
|
|
146
|
+
function isMySharpeReal(returns, opts) {
|
|
147
|
+
const raw = parse(kernel.is_my_sharpe_real(JSON.stringify(returns), honestyConfigJson(opts)));
|
|
148
|
+
return toHonestyVerdict(raw);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The FULL verdict: the winner's LITE verdict plus the multiple-testing family
|
|
152
|
+
* (White's Reality Check, Hansen's SPA + consistent variant, Romano-Wolf step-down)
|
|
153
|
+
* and the CSCV Probability of Backtest Overfitting over the whole field.
|
|
154
|
+
*
|
|
155
|
+
* `field` is N rows (candidate strategies) × T cols (time); `winnerIdx` is the row
|
|
156
|
+
* whose LITE verdict is reported.
|
|
157
|
+
*/
|
|
158
|
+
function isMySharpeRealFull(field, winnerIdx, opts) {
|
|
159
|
+
const raw = parse(kernel.is_my_sharpe_real_full(JSON.stringify(field), winnerIdx, honestyConfigJson(opts)));
|
|
160
|
+
return {
|
|
161
|
+
honesty: toHonestyVerdict(raw.honesty),
|
|
162
|
+
realityCheckP: raw.reality_check_p,
|
|
163
|
+
spaP: raw.spa_p,
|
|
164
|
+
spaConsistentP: raw.spa_consistent_p,
|
|
165
|
+
stepDown: raw.step_down,
|
|
166
|
+
pbo: raw.pbo,
|
|
167
|
+
};
|
|
168
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -126,3 +126,57 @@ export interface Canary {
|
|
|
126
126
|
id: string;
|
|
127
127
|
token: string;
|
|
128
128
|
}
|
|
129
|
+
/** The headline call: does the edge survive deflation for the search? */
|
|
130
|
+
export type Verdict = "Pass" | "Borderline" | "Fail";
|
|
131
|
+
/**
|
|
132
|
+
* Options for {@link isMySharpeReal}. `nTrials` is the multiple-testing footprint
|
|
133
|
+
* (how many strategies/configs were tried before this one was kept) and is the one
|
|
134
|
+
* the caller must think about — `nTrials = 1` is almost always a lie.
|
|
135
|
+
*/
|
|
136
|
+
export interface HonestyOpts {
|
|
137
|
+
/** Number of strategy trials behind this result. REQUIRED. */
|
|
138
|
+
nTrials: number;
|
|
139
|
+
/** Cross-trial Sharpe dispersion. Omit → estimated at 0.5 and flagged. */
|
|
140
|
+
trialsSrStd?: number;
|
|
141
|
+
/** Deflated-Sharpe threshold for a Pass. Default 0.95. */
|
|
142
|
+
confidence?: number;
|
|
143
|
+
/** Deflated-Sharpe threshold for Borderline. Default 0.90. */
|
|
144
|
+
borderline?: number;
|
|
145
|
+
/** PSR / MinTRL benchmark Sharpe to beat. Default 0.0. */
|
|
146
|
+
srBenchmark?: number;
|
|
147
|
+
}
|
|
148
|
+
/** The LITE verdict: everything derivable from one return series. */
|
|
149
|
+
export interface HonestyVerdict {
|
|
150
|
+
sharpe: number;
|
|
151
|
+
nObs: number;
|
|
152
|
+
skew: number;
|
|
153
|
+
kurtosis: number;
|
|
154
|
+
nTrials: number;
|
|
155
|
+
expectedMaxSharpe: number;
|
|
156
|
+
deflatedSharpe: number;
|
|
157
|
+
probabilisticSharpe: number;
|
|
158
|
+
/** `1 - deflatedSharpe`: probability the edge is a search artifact. */
|
|
159
|
+
haircut: number;
|
|
160
|
+
/** `sharpe * deflatedSharpe`: Sharpe discounted by survival probability. */
|
|
161
|
+
haircutSharpe: number;
|
|
162
|
+
minTrackRecordLen: number;
|
|
163
|
+
verdict: Verdict;
|
|
164
|
+
explanation: string;
|
|
165
|
+
methodologyVersion: string;
|
|
166
|
+
[k: string]: unknown;
|
|
167
|
+
}
|
|
168
|
+
/** The FULL verdict: LITE on the winner plus the multiple-testing family + PBO. */
|
|
169
|
+
export interface FullVerdict {
|
|
170
|
+
honesty: HonestyVerdict;
|
|
171
|
+
/** White's Reality Check p-value over the field. */
|
|
172
|
+
realityCheckP: number;
|
|
173
|
+
/** Hansen's SPA p-value (liberal/lower studentized variant). */
|
|
174
|
+
spaP: number;
|
|
175
|
+
/** Hansen's consistent SPA p-value. */
|
|
176
|
+
spaConsistentP: number;
|
|
177
|
+
/** Romano-Wolf step-down: which field members are significant at α. */
|
|
178
|
+
stepDown: boolean[];
|
|
179
|
+
/** CSCV Probability of Backtest Overfitting over the field. */
|
|
180
|
+
pbo: number;
|
|
181
|
+
[k: string]: unknown;
|
|
182
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@general-liquidity/sharpebench",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "The luck-robust scoring kernel for AI trading agents — deflated Sharpe, pass^k reliability, and process-discipline gates. The identical Rust kernel as the SharpeBench benchmark, compiled to WASM.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"trading",
|
package/pkg/package.json
CHANGED
package/pkg/sharpebench.d.ts
CHANGED
|
@@ -7,6 +7,10 @@ export function canary(seed: string): string;
|
|
|
7
7
|
|
|
8
8
|
export function greeks(params_json: string): string;
|
|
9
9
|
|
|
10
|
+
export function is_my_sharpe_real(returns_json: string, config_json: string): string;
|
|
11
|
+
|
|
12
|
+
export function is_my_sharpe_real_full(field_json: string, winner_idx: number, config_json: string): string;
|
|
13
|
+
|
|
10
14
|
export function score(submissions_json: string, config_json: string): string;
|
|
11
15
|
|
|
12
16
|
export function score_agent(submission_json: string, config_json: string): string;
|
package/pkg/sharpebench.js
CHANGED
|
@@ -63,6 +63,53 @@ function greeks(params_json) {
|
|
|
63
63
|
}
|
|
64
64
|
exports.greeks = greeks;
|
|
65
65
|
|
|
66
|
+
/**
|
|
67
|
+
* @param {string} returns_json
|
|
68
|
+
* @param {string} config_json
|
|
69
|
+
* @returns {string}
|
|
70
|
+
*/
|
|
71
|
+
function is_my_sharpe_real(returns_json, config_json) {
|
|
72
|
+
let deferred3_0;
|
|
73
|
+
let deferred3_1;
|
|
74
|
+
try {
|
|
75
|
+
const ptr0 = passStringToWasm0(returns_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
76
|
+
const len0 = WASM_VECTOR_LEN;
|
|
77
|
+
const ptr1 = passStringToWasm0(config_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
78
|
+
const len1 = WASM_VECTOR_LEN;
|
|
79
|
+
const ret = wasm.is_my_sharpe_real(ptr0, len0, ptr1, len1);
|
|
80
|
+
deferred3_0 = ret[0];
|
|
81
|
+
deferred3_1 = ret[1];
|
|
82
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
83
|
+
} finally {
|
|
84
|
+
wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.is_my_sharpe_real = is_my_sharpe_real;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @param {string} field_json
|
|
91
|
+
* @param {number} winner_idx
|
|
92
|
+
* @param {string} config_json
|
|
93
|
+
* @returns {string}
|
|
94
|
+
*/
|
|
95
|
+
function is_my_sharpe_real_full(field_json, winner_idx, config_json) {
|
|
96
|
+
let deferred3_0;
|
|
97
|
+
let deferred3_1;
|
|
98
|
+
try {
|
|
99
|
+
const ptr0 = passStringToWasm0(field_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
100
|
+
const len0 = WASM_VECTOR_LEN;
|
|
101
|
+
const ptr1 = passStringToWasm0(config_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
102
|
+
const len1 = WASM_VECTOR_LEN;
|
|
103
|
+
const ret = wasm.is_my_sharpe_real_full(ptr0, len0, winner_idx, ptr1, len1);
|
|
104
|
+
deferred3_0 = ret[0];
|
|
105
|
+
deferred3_1 = ret[1];
|
|
106
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
107
|
+
} finally {
|
|
108
|
+
wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
exports.is_my_sharpe_real_full = is_my_sharpe_real_full;
|
|
112
|
+
|
|
66
113
|
/**
|
|
67
114
|
* @param {string} submissions_json
|
|
68
115
|
* @param {string} config_json
|
package/pkg/sharpebench_bg.wasm
CHANGED
|
Binary file
|
|
@@ -4,6 +4,8 @@ export const memory: WebAssembly.Memory;
|
|
|
4
4
|
export const audit_briefing: (a: number, b: number, c: number, d: number) => [number, number];
|
|
5
5
|
export const canary: (a: number, b: number) => [number, number];
|
|
6
6
|
export const greeks: (a: number, b: number) => [number, number];
|
|
7
|
+
export const is_my_sharpe_real: (a: number, b: number, c: number, d: number) => [number, number];
|
|
8
|
+
export const is_my_sharpe_real_full: (a: number, b: number, c: number, d: number, e: number) => [number, number];
|
|
7
9
|
export const score: (a: number, b: number, c: number, d: number) => [number, number];
|
|
8
10
|
export const score_agent: (a: number, b: number, c: number, d: number) => [number, number];
|
|
9
11
|
export const score_allocation: (a: number, b: number, c: number, d: number) => [number, number];
|