@tradejs/core 3.1.29-beta.290 → 3.1.29-beta.291
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/aiFeatures.d.mts +14 -0
- package/dist/aiFeatures.d.ts +14 -0
- package/dist/aiFeatures.js +179 -0
- package/dist/aiFeatures.mjs +150 -0
- package/dist/backtest.mjs +3 -3
- package/dist/indicators.mjs +2 -2
- package/dist/portfolio.d.mts +23 -0
- package/dist/portfolio.d.ts +23 -0
- package/dist/portfolio.js +314 -0
- package/dist/portfolio.mjs +280 -0
- package/dist/strategies.mjs +2 -2
- package/dist/tickerProfiles.d.mts +17 -0
- package/dist/tickerProfiles.d.ts +17 -0
- package/dist/tickerProfiles.js +211 -0
- package/dist/tickerProfiles.mjs +182 -0
- package/package.json +17 -2
- package/dist/{chunk-OZVRWW2K.mjs → chunk-6XY6Z2DB.mjs} +3 -3
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AiFeatureDefinition, AiFeatureSnapshot } from '@tradejs/types';
|
|
2
|
+
|
|
3
|
+
declare const validateAiFeatureDefinitions: (definitions: readonly AiFeatureDefinition[]) => void;
|
|
4
|
+
/** The same pure projection is used before export and when reconstructing a gate. */
|
|
5
|
+
declare const projectAiFeatures: (definitions: readonly AiFeatureDefinition[], sources: {
|
|
6
|
+
signal: unknown;
|
|
7
|
+
payload: unknown;
|
|
8
|
+
}) => AiFeatureSnapshot;
|
|
9
|
+
declare const TICKER_PROFILE_AI_FEATURES: readonly AiFeatureDefinition[];
|
|
10
|
+
declare const validateAiFeatureSnapshot: (snapshot: AiFeatureSnapshot) => void;
|
|
11
|
+
/** Frozen pre-admission state, never the result of the candidate's own decision. */
|
|
12
|
+
declare const PORTFOLIO_AI_FEATURES: readonly AiFeatureDefinition[];
|
|
13
|
+
|
|
14
|
+
export { PORTFOLIO_AI_FEATURES, TICKER_PROFILE_AI_FEATURES, projectAiFeatures, validateAiFeatureDefinitions, validateAiFeatureSnapshot };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AiFeatureDefinition, AiFeatureSnapshot } from '@tradejs/types';
|
|
2
|
+
|
|
3
|
+
declare const validateAiFeatureDefinitions: (definitions: readonly AiFeatureDefinition[]) => void;
|
|
4
|
+
/** The same pure projection is used before export and when reconstructing a gate. */
|
|
5
|
+
declare const projectAiFeatures: (definitions: readonly AiFeatureDefinition[], sources: {
|
|
6
|
+
signal: unknown;
|
|
7
|
+
payload: unknown;
|
|
8
|
+
}) => AiFeatureSnapshot;
|
|
9
|
+
declare const TICKER_PROFILE_AI_FEATURES: readonly AiFeatureDefinition[];
|
|
10
|
+
declare const validateAiFeatureSnapshot: (snapshot: AiFeatureSnapshot) => void;
|
|
11
|
+
/** Frozen pre-admission state, never the result of the candidate's own decision. */
|
|
12
|
+
declare const PORTFOLIO_AI_FEATURES: readonly AiFeatureDefinition[];
|
|
13
|
+
|
|
14
|
+
export { PORTFOLIO_AI_FEATURES, TICKER_PROFILE_AI_FEATURES, projectAiFeatures, validateAiFeatureDefinitions, validateAiFeatureSnapshot };
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/aiFeatures.ts
|
|
21
|
+
var aiFeatures_exports = {};
|
|
22
|
+
__export(aiFeatures_exports, {
|
|
23
|
+
PORTFOLIO_AI_FEATURES: () => PORTFOLIO_AI_FEATURES,
|
|
24
|
+
TICKER_PROFILE_AI_FEATURES: () => TICKER_PROFILE_AI_FEATURES,
|
|
25
|
+
projectAiFeatures: () => projectAiFeatures,
|
|
26
|
+
validateAiFeatureDefinitions: () => validateAiFeatureDefinitions,
|
|
27
|
+
validateAiFeatureSnapshot: () => validateAiFeatureSnapshot
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(aiFeatures_exports);
|
|
30
|
+
var forbidden = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
31
|
+
var outcome = /^(tradeResult|backtestExecution|outcome|label|future|pnl|profit|exitPrice|exitTimestamp|aiApproved|deterministicQuality|approvalAllowedNow)$/i;
|
|
32
|
+
var readPath = (source, path) => {
|
|
33
|
+
let value = source;
|
|
34
|
+
for (const part of path.split(".")) {
|
|
35
|
+
if (forbidden.has(part) || !value || typeof value !== "object" || !Object.prototype.hasOwnProperty.call(value, part))
|
|
36
|
+
return void 0;
|
|
37
|
+
value = value[part];
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
};
|
|
41
|
+
var primitive = (value) => {
|
|
42
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
43
|
+
if (typeof value === "boolean" || typeof value === "string") return value;
|
|
44
|
+
return null;
|
|
45
|
+
};
|
|
46
|
+
var validateAiFeatureDefinitions = (definitions) => {
|
|
47
|
+
if (!Array.isArray(definitions))
|
|
48
|
+
throw new Error("Invalid AI feature definitions");
|
|
49
|
+
const ids = /* @__PURE__ */ new Set();
|
|
50
|
+
for (const d of definitions) {
|
|
51
|
+
if (!d || typeof d !== "object" || typeof d.id !== "string" || typeof d.path !== "string" || typeof d.description !== "string" || typeof d.unit !== "string" || !["input", "data-quality", "metadata", "outcome", "policy"].includes(
|
|
52
|
+
d.role
|
|
53
|
+
) || !["target", "benchmark", "global", "setup"].includes(d.scope) || d.source !== void 0 && !["signal", "payload"].includes(d.source) || d.reduction !== void 0 && !["last", "mean", "min", "max", "count"].includes(d.reduction) || d.divideBy !== void 0 && typeof d.divideBy !== "string")
|
|
54
|
+
throw new Error("Invalid AI feature definition");
|
|
55
|
+
if (!/^[a-zA-Z][\w.-]*$/.test(d.id) || ids.has(d.id) || !Number.isSafeInteger(d.version) || d.version < 1 || !d.description.trim() || !d.unit.trim())
|
|
56
|
+
throw new Error(`Invalid or duplicate AI feature: ${d.id}`);
|
|
57
|
+
for (const path of [d.path, ...d.divideBy ? [d.divideBy] : []]) {
|
|
58
|
+
if (!path || path.split(".").some((p) => !p || forbidden.has(p)))
|
|
59
|
+
throw new Error(`Invalid AI feature path: ${d.id}`);
|
|
60
|
+
if (d.role === "input" && path.split(".").some((p) => outcome.test(p)))
|
|
61
|
+
throw new Error(`Outcome/policy cannot be an input: ${d.id}`);
|
|
62
|
+
}
|
|
63
|
+
ids.add(d.id);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var projectAiFeatures = (definitions, sources) => {
|
|
67
|
+
validateAiFeatureDefinitions(definitions);
|
|
68
|
+
const values = {};
|
|
69
|
+
for (const d of definitions) {
|
|
70
|
+
const source = sources[d.source ?? "payload"];
|
|
71
|
+
let raw = readPath(source, d.path);
|
|
72
|
+
if (d.reduction) {
|
|
73
|
+
if (!Array.isArray(raw)) raw = null;
|
|
74
|
+
else if (d.reduction === "count") raw = raw.length;
|
|
75
|
+
else if (d.reduction === "last") raw = raw.at(-1);
|
|
76
|
+
else {
|
|
77
|
+
const numbers = raw.filter(
|
|
78
|
+
(v) => typeof v === "number" && Number.isFinite(v)
|
|
79
|
+
);
|
|
80
|
+
raw = numbers.length !== raw.length || !numbers.length ? null : d.reduction === "mean" ? numbers.reduce((s, v) => s + v, 0) / numbers.length : d.reduction === "min" ? numbers.reduce((a, b) => Math.min(a, b), Infinity) : numbers.reduce((a, b) => Math.max(a, b), -Infinity);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
let value = primitive(raw);
|
|
84
|
+
if (d.divideBy) {
|
|
85
|
+
const denominator = primitive(readPath(source, d.divideBy));
|
|
86
|
+
value = typeof value === "number" && typeof denominator === "number" && denominator !== 0 ? primitive(value / denominator) : null;
|
|
87
|
+
}
|
|
88
|
+
values[d.id] = value;
|
|
89
|
+
}
|
|
90
|
+
return { schema: "tradejs-ai-features/v1", definitions, values };
|
|
91
|
+
};
|
|
92
|
+
var profile = (id, field, unit, role = "input", stationary = true) => ({
|
|
93
|
+
id: `ticker.${id}`,
|
|
94
|
+
version: 1,
|
|
95
|
+
path: `additionalIndicators.tickerProfile.${field}`,
|
|
96
|
+
source: "signal",
|
|
97
|
+
role,
|
|
98
|
+
stationary,
|
|
99
|
+
scope: "target",
|
|
100
|
+
unit,
|
|
101
|
+
description: `Monthly causal ticker profile: ${field}`
|
|
102
|
+
});
|
|
103
|
+
var TICKER_PROFILE_AI_FEATURES = [
|
|
104
|
+
profile("turnover", "dailyTurnoverUSDT", "USDT/day", "input", false),
|
|
105
|
+
profile("volatility", "dailyVolatilityPct", "%/day"),
|
|
106
|
+
profile("btcCorrelation", "correlationBTC", "correlation"),
|
|
107
|
+
profile("ethCorrelation", "correlationETH", "correlation"),
|
|
108
|
+
profile("moneyGroup", "moneyGroup", "category"),
|
|
109
|
+
profile("volatilityGroup", "volatilityGroup", "category"),
|
|
110
|
+
profile("btcGroup", "btcCorrelationGroup", "category"),
|
|
111
|
+
profile("ethGroup", "ethCorrelationGroup", "category"),
|
|
112
|
+
profile("hours", "hours", "hours", "data-quality"),
|
|
113
|
+
profile("returnHours", "returnHours", "hours", "data-quality"),
|
|
114
|
+
profile("btcPairs", "btcAlignedHours", "hours", "data-quality"),
|
|
115
|
+
profile("ethPairs", "ethAlignedHours", "hours", "data-quality"),
|
|
116
|
+
profile("asOf", "asOf", "UTC ms", "metadata"),
|
|
117
|
+
profile("snapshotId", "snapshotId", "sha256", "metadata"),
|
|
118
|
+
profile("validUntil", "validUntil", "UTC ms", "metadata"),
|
|
119
|
+
profile("windowStart", "windowStart", "UTC ms", "metadata"),
|
|
120
|
+
profile("symbol", "symbol", "symbol", "metadata"),
|
|
121
|
+
profile("provider", "provider", "provider", "metadata"),
|
|
122
|
+
profile("universeId", "universeId", "identity", "metadata"),
|
|
123
|
+
profile("definition", "definition", "version", "metadata"),
|
|
124
|
+
profile("turnoverSource", "turnoverSource", "source", "data-quality")
|
|
125
|
+
];
|
|
126
|
+
var validateAiFeatureSnapshot = (snapshot) => {
|
|
127
|
+
if (!snapshot || snapshot.schema !== "tradejs-ai-features/v1" || !snapshot.values || typeof snapshot.values !== "object" || Array.isArray(snapshot.values))
|
|
128
|
+
throw new Error("Invalid AI feature snapshot");
|
|
129
|
+
validateAiFeatureDefinitions(snapshot.definitions);
|
|
130
|
+
if (Object.keys(snapshot.values).length !== snapshot.definitions.length)
|
|
131
|
+
throw new Error("AI feature snapshot does not match definitions");
|
|
132
|
+
for (const d of snapshot.definitions) {
|
|
133
|
+
const v = snapshot.values[d.id];
|
|
134
|
+
if (!Object.prototype.hasOwnProperty.call(snapshot.values, d.id) || v !== null && typeof v !== "string" && typeof v !== "boolean" && !(typeof v === "number" && Number.isFinite(v)))
|
|
135
|
+
throw new Error(`Invalid feature value: ${d.id}`);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
var PORTFOLIO_AI_FEATURES = [
|
|
139
|
+
...[
|
|
140
|
+
"positionCount",
|
|
141
|
+
"pendingEntryCount",
|
|
142
|
+
"longCount",
|
|
143
|
+
"shortCount",
|
|
144
|
+
"grossUnrealizedPnlR",
|
|
145
|
+
"openStopRiskR",
|
|
146
|
+
"largestPositionShare"
|
|
147
|
+
].map((field) => ({
|
|
148
|
+
id: `portfolio.${field}`,
|
|
149
|
+
version: 1,
|
|
150
|
+
source: "signal",
|
|
151
|
+
path: `additionalIndicators.portfolioContext.${field}`,
|
|
152
|
+
role: "input",
|
|
153
|
+
scope: "global",
|
|
154
|
+
stationary: true,
|
|
155
|
+
unit: field.endsWith("R") ? "R" : field.endsWith("Share") ? "fraction" : "count",
|
|
156
|
+
description: `Pre-entry portfolio ${field}`
|
|
157
|
+
})),
|
|
158
|
+
...["asOf", "policyId", "pricesComplete", "unknownOwnershipCount"].map(
|
|
159
|
+
(field) => ({
|
|
160
|
+
id: `portfolio.${field}`,
|
|
161
|
+
version: 1,
|
|
162
|
+
source: "signal",
|
|
163
|
+
path: `additionalIndicators.portfolioContext.${field}`,
|
|
164
|
+
role: field === "asOf" || field === "policyId" ? "metadata" : "data-quality",
|
|
165
|
+
scope: "global",
|
|
166
|
+
stationary: false,
|
|
167
|
+
unit: field === "asOf" ? "ms" : "category",
|
|
168
|
+
description: `Portfolio observation ${field}`
|
|
169
|
+
})
|
|
170
|
+
)
|
|
171
|
+
];
|
|
172
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
173
|
+
0 && (module.exports = {
|
|
174
|
+
PORTFOLIO_AI_FEATURES,
|
|
175
|
+
TICKER_PROFILE_AI_FEATURES,
|
|
176
|
+
projectAiFeatures,
|
|
177
|
+
validateAiFeatureDefinitions,
|
|
178
|
+
validateAiFeatureSnapshot
|
|
179
|
+
});
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// src/aiFeatures.ts
|
|
2
|
+
var forbidden = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
3
|
+
var outcome = /^(tradeResult|backtestExecution|outcome|label|future|pnl|profit|exitPrice|exitTimestamp|aiApproved|deterministicQuality|approvalAllowedNow)$/i;
|
|
4
|
+
var readPath = (source, path) => {
|
|
5
|
+
let value = source;
|
|
6
|
+
for (const part of path.split(".")) {
|
|
7
|
+
if (forbidden.has(part) || !value || typeof value !== "object" || !Object.prototype.hasOwnProperty.call(value, part))
|
|
8
|
+
return void 0;
|
|
9
|
+
value = value[part];
|
|
10
|
+
}
|
|
11
|
+
return value;
|
|
12
|
+
};
|
|
13
|
+
var primitive = (value) => {
|
|
14
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
15
|
+
if (typeof value === "boolean" || typeof value === "string") return value;
|
|
16
|
+
return null;
|
|
17
|
+
};
|
|
18
|
+
var validateAiFeatureDefinitions = (definitions) => {
|
|
19
|
+
if (!Array.isArray(definitions))
|
|
20
|
+
throw new Error("Invalid AI feature definitions");
|
|
21
|
+
const ids = /* @__PURE__ */ new Set();
|
|
22
|
+
for (const d of definitions) {
|
|
23
|
+
if (!d || typeof d !== "object" || typeof d.id !== "string" || typeof d.path !== "string" || typeof d.description !== "string" || typeof d.unit !== "string" || !["input", "data-quality", "metadata", "outcome", "policy"].includes(
|
|
24
|
+
d.role
|
|
25
|
+
) || !["target", "benchmark", "global", "setup"].includes(d.scope) || d.source !== void 0 && !["signal", "payload"].includes(d.source) || d.reduction !== void 0 && !["last", "mean", "min", "max", "count"].includes(d.reduction) || d.divideBy !== void 0 && typeof d.divideBy !== "string")
|
|
26
|
+
throw new Error("Invalid AI feature definition");
|
|
27
|
+
if (!/^[a-zA-Z][\w.-]*$/.test(d.id) || ids.has(d.id) || !Number.isSafeInteger(d.version) || d.version < 1 || !d.description.trim() || !d.unit.trim())
|
|
28
|
+
throw new Error(`Invalid or duplicate AI feature: ${d.id}`);
|
|
29
|
+
for (const path of [d.path, ...d.divideBy ? [d.divideBy] : []]) {
|
|
30
|
+
if (!path || path.split(".").some((p) => !p || forbidden.has(p)))
|
|
31
|
+
throw new Error(`Invalid AI feature path: ${d.id}`);
|
|
32
|
+
if (d.role === "input" && path.split(".").some((p) => outcome.test(p)))
|
|
33
|
+
throw new Error(`Outcome/policy cannot be an input: ${d.id}`);
|
|
34
|
+
}
|
|
35
|
+
ids.add(d.id);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var projectAiFeatures = (definitions, sources) => {
|
|
39
|
+
validateAiFeatureDefinitions(definitions);
|
|
40
|
+
const values = {};
|
|
41
|
+
for (const d of definitions) {
|
|
42
|
+
const source = sources[d.source ?? "payload"];
|
|
43
|
+
let raw = readPath(source, d.path);
|
|
44
|
+
if (d.reduction) {
|
|
45
|
+
if (!Array.isArray(raw)) raw = null;
|
|
46
|
+
else if (d.reduction === "count") raw = raw.length;
|
|
47
|
+
else if (d.reduction === "last") raw = raw.at(-1);
|
|
48
|
+
else {
|
|
49
|
+
const numbers = raw.filter(
|
|
50
|
+
(v) => typeof v === "number" && Number.isFinite(v)
|
|
51
|
+
);
|
|
52
|
+
raw = numbers.length !== raw.length || !numbers.length ? null : d.reduction === "mean" ? numbers.reduce((s, v) => s + v, 0) / numbers.length : d.reduction === "min" ? numbers.reduce((a, b) => Math.min(a, b), Infinity) : numbers.reduce((a, b) => Math.max(a, b), -Infinity);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
let value = primitive(raw);
|
|
56
|
+
if (d.divideBy) {
|
|
57
|
+
const denominator = primitive(readPath(source, d.divideBy));
|
|
58
|
+
value = typeof value === "number" && typeof denominator === "number" && denominator !== 0 ? primitive(value / denominator) : null;
|
|
59
|
+
}
|
|
60
|
+
values[d.id] = value;
|
|
61
|
+
}
|
|
62
|
+
return { schema: "tradejs-ai-features/v1", definitions, values };
|
|
63
|
+
};
|
|
64
|
+
var profile = (id, field, unit, role = "input", stationary = true) => ({
|
|
65
|
+
id: `ticker.${id}`,
|
|
66
|
+
version: 1,
|
|
67
|
+
path: `additionalIndicators.tickerProfile.${field}`,
|
|
68
|
+
source: "signal",
|
|
69
|
+
role,
|
|
70
|
+
stationary,
|
|
71
|
+
scope: "target",
|
|
72
|
+
unit,
|
|
73
|
+
description: `Monthly causal ticker profile: ${field}`
|
|
74
|
+
});
|
|
75
|
+
var TICKER_PROFILE_AI_FEATURES = [
|
|
76
|
+
profile("turnover", "dailyTurnoverUSDT", "USDT/day", "input", false),
|
|
77
|
+
profile("volatility", "dailyVolatilityPct", "%/day"),
|
|
78
|
+
profile("btcCorrelation", "correlationBTC", "correlation"),
|
|
79
|
+
profile("ethCorrelation", "correlationETH", "correlation"),
|
|
80
|
+
profile("moneyGroup", "moneyGroup", "category"),
|
|
81
|
+
profile("volatilityGroup", "volatilityGroup", "category"),
|
|
82
|
+
profile("btcGroup", "btcCorrelationGroup", "category"),
|
|
83
|
+
profile("ethGroup", "ethCorrelationGroup", "category"),
|
|
84
|
+
profile("hours", "hours", "hours", "data-quality"),
|
|
85
|
+
profile("returnHours", "returnHours", "hours", "data-quality"),
|
|
86
|
+
profile("btcPairs", "btcAlignedHours", "hours", "data-quality"),
|
|
87
|
+
profile("ethPairs", "ethAlignedHours", "hours", "data-quality"),
|
|
88
|
+
profile("asOf", "asOf", "UTC ms", "metadata"),
|
|
89
|
+
profile("snapshotId", "snapshotId", "sha256", "metadata"),
|
|
90
|
+
profile("validUntil", "validUntil", "UTC ms", "metadata"),
|
|
91
|
+
profile("windowStart", "windowStart", "UTC ms", "metadata"),
|
|
92
|
+
profile("symbol", "symbol", "symbol", "metadata"),
|
|
93
|
+
profile("provider", "provider", "provider", "metadata"),
|
|
94
|
+
profile("universeId", "universeId", "identity", "metadata"),
|
|
95
|
+
profile("definition", "definition", "version", "metadata"),
|
|
96
|
+
profile("turnoverSource", "turnoverSource", "source", "data-quality")
|
|
97
|
+
];
|
|
98
|
+
var validateAiFeatureSnapshot = (snapshot) => {
|
|
99
|
+
if (!snapshot || snapshot.schema !== "tradejs-ai-features/v1" || !snapshot.values || typeof snapshot.values !== "object" || Array.isArray(snapshot.values))
|
|
100
|
+
throw new Error("Invalid AI feature snapshot");
|
|
101
|
+
validateAiFeatureDefinitions(snapshot.definitions);
|
|
102
|
+
if (Object.keys(snapshot.values).length !== snapshot.definitions.length)
|
|
103
|
+
throw new Error("AI feature snapshot does not match definitions");
|
|
104
|
+
for (const d of snapshot.definitions) {
|
|
105
|
+
const v = snapshot.values[d.id];
|
|
106
|
+
if (!Object.prototype.hasOwnProperty.call(snapshot.values, d.id) || v !== null && typeof v !== "string" && typeof v !== "boolean" && !(typeof v === "number" && Number.isFinite(v)))
|
|
107
|
+
throw new Error(`Invalid feature value: ${d.id}`);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
var PORTFOLIO_AI_FEATURES = [
|
|
111
|
+
...[
|
|
112
|
+
"positionCount",
|
|
113
|
+
"pendingEntryCount",
|
|
114
|
+
"longCount",
|
|
115
|
+
"shortCount",
|
|
116
|
+
"grossUnrealizedPnlR",
|
|
117
|
+
"openStopRiskR",
|
|
118
|
+
"largestPositionShare"
|
|
119
|
+
].map((field) => ({
|
|
120
|
+
id: `portfolio.${field}`,
|
|
121
|
+
version: 1,
|
|
122
|
+
source: "signal",
|
|
123
|
+
path: `additionalIndicators.portfolioContext.${field}`,
|
|
124
|
+
role: "input",
|
|
125
|
+
scope: "global",
|
|
126
|
+
stationary: true,
|
|
127
|
+
unit: field.endsWith("R") ? "R" : field.endsWith("Share") ? "fraction" : "count",
|
|
128
|
+
description: `Pre-entry portfolio ${field}`
|
|
129
|
+
})),
|
|
130
|
+
...["asOf", "policyId", "pricesComplete", "unknownOwnershipCount"].map(
|
|
131
|
+
(field) => ({
|
|
132
|
+
id: `portfolio.${field}`,
|
|
133
|
+
version: 1,
|
|
134
|
+
source: "signal",
|
|
135
|
+
path: `additionalIndicators.portfolioContext.${field}`,
|
|
136
|
+
role: field === "asOf" || field === "policyId" ? "metadata" : "data-quality",
|
|
137
|
+
scope: "global",
|
|
138
|
+
stationary: false,
|
|
139
|
+
unit: field === "asOf" ? "ms" : "category",
|
|
140
|
+
description: `Portfolio observation ${field}`
|
|
141
|
+
})
|
|
142
|
+
)
|
|
143
|
+
];
|
|
144
|
+
export {
|
|
145
|
+
PORTFOLIO_AI_FEATURES,
|
|
146
|
+
TICKER_PROFILE_AI_FEATURES,
|
|
147
|
+
projectAiFeatures,
|
|
148
|
+
validateAiFeatureDefinitions,
|
|
149
|
+
validateAiFeatureSnapshot
|
|
150
|
+
};
|
package/dist/backtest.mjs
CHANGED
|
@@ -2,6 +2,9 @@ import {
|
|
|
2
2
|
compactOrderLog,
|
|
3
3
|
getTimeline
|
|
4
4
|
} from "./chunk-S4KHOAXM.mjs";
|
|
5
|
+
import {
|
|
6
|
+
TestThresholdsConfig
|
|
7
|
+
} from "./chunk-MKCQSB4H.mjs";
|
|
5
8
|
import {
|
|
6
9
|
absReturns,
|
|
7
10
|
equityPoints,
|
|
@@ -10,9 +13,6 @@ import {
|
|
|
10
13
|
round,
|
|
11
14
|
sum
|
|
12
15
|
} from "./chunk-LI6FPPKB.mjs";
|
|
13
|
-
import {
|
|
14
|
-
TestThresholdsConfig
|
|
15
|
-
} from "./chunk-MKCQSB4H.mjs";
|
|
16
16
|
|
|
17
17
|
// src/utils/tests.ts
|
|
18
18
|
var parseTestName = (testName) => {
|
package/dist/indicators.mjs
CHANGED
|
@@ -39,11 +39,11 @@ import {
|
|
|
39
39
|
toArrayData,
|
|
40
40
|
toCoinalyzeTimestampMs,
|
|
41
41
|
toFiniteNumber
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-6XY6Z2DB.mjs";
|
|
43
43
|
import "./chunk-WJQRRGUY.mjs";
|
|
44
44
|
import "./chunk-S4KHOAXM.mjs";
|
|
45
|
-
import "./chunk-LI6FPPKB.mjs";
|
|
46
45
|
import "./chunk-MKCQSB4H.mjs";
|
|
46
|
+
import "./chunk-LI6FPPKB.mjs";
|
|
47
47
|
export {
|
|
48
48
|
COINALYZE_MIN_INTRADAY_RETENTION_POINTS,
|
|
49
49
|
COMPACT_INDICATORS_SNAPSHOT_KEY,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as _tradejs_types from '@tradejs/types';
|
|
2
|
+
import { PortfolioState, PortfolioPolicyConfig, PortfolioObservation, PortfolioContext, PortfolioPosition, PortfolioReservation } from '@tradejs/types';
|
|
3
|
+
|
|
4
|
+
declare function parsePortfolioPolicy(value: unknown): PortfolioPolicyConfig | undefined;
|
|
5
|
+
declare function portfolioFingerprint(policy: PortfolioPolicyConfig, strategy: string): string;
|
|
6
|
+
declare function createPortfolioState(fingerprint: string): PortfolioState;
|
|
7
|
+
declare function portfolioOwns(policy: PortfolioPolicyConfig, strategy: string, owner: string | null): boolean;
|
|
8
|
+
declare function validatePortfolioObservation(o: unknown): asserts o is PortfolioObservation;
|
|
9
|
+
declare function buildPortfolioContext(policy: PortfolioPolicyConfig, strategy: string, state: PortfolioState, o: PortfolioObservation): PortfolioContext;
|
|
10
|
+
/** Reconcile exchange facts before making decisions. Acknowledgement alone is never a fill. */
|
|
11
|
+
declare function reconcilePortfolio(policy: PortfolioPolicyConfig, strategy: string, previous: PortfolioState, o: PortfolioObservation): PortfolioState;
|
|
12
|
+
declare function reservePortfolioEntry(policy: PortfolioPolicyConfig, strategy: string, state: PortfolioState, o: PortfolioObservation, entry: PortfolioReservation): {
|
|
13
|
+
state: PortfolioState;
|
|
14
|
+
reason?: string;
|
|
15
|
+
};
|
|
16
|
+
declare function portfolioCloseCommands(policy: PortfolioPolicyConfig, state: PortfolioState, o: PortfolioObservation): {
|
|
17
|
+
intent: _tradejs_types.PortfolioCloseIntent;
|
|
18
|
+
position: PortfolioPosition;
|
|
19
|
+
}[];
|
|
20
|
+
/** Persisted state is an IO boundary, not a trusted TypeScript object. */
|
|
21
|
+
declare function assertPortfolioState(value: unknown): asserts value is PortfolioState;
|
|
22
|
+
|
|
23
|
+
export { assertPortfolioState, buildPortfolioContext, createPortfolioState, parsePortfolioPolicy, portfolioCloseCommands, portfolioFingerprint, portfolioOwns, reconcilePortfolio, reservePortfolioEntry, validatePortfolioObservation };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as _tradejs_types from '@tradejs/types';
|
|
2
|
+
import { PortfolioState, PortfolioPolicyConfig, PortfolioObservation, PortfolioContext, PortfolioPosition, PortfolioReservation } from '@tradejs/types';
|
|
3
|
+
|
|
4
|
+
declare function parsePortfolioPolicy(value: unknown): PortfolioPolicyConfig | undefined;
|
|
5
|
+
declare function portfolioFingerprint(policy: PortfolioPolicyConfig, strategy: string): string;
|
|
6
|
+
declare function createPortfolioState(fingerprint: string): PortfolioState;
|
|
7
|
+
declare function portfolioOwns(policy: PortfolioPolicyConfig, strategy: string, owner: string | null): boolean;
|
|
8
|
+
declare function validatePortfolioObservation(o: unknown): asserts o is PortfolioObservation;
|
|
9
|
+
declare function buildPortfolioContext(policy: PortfolioPolicyConfig, strategy: string, state: PortfolioState, o: PortfolioObservation): PortfolioContext;
|
|
10
|
+
/** Reconcile exchange facts before making decisions. Acknowledgement alone is never a fill. */
|
|
11
|
+
declare function reconcilePortfolio(policy: PortfolioPolicyConfig, strategy: string, previous: PortfolioState, o: PortfolioObservation): PortfolioState;
|
|
12
|
+
declare function reservePortfolioEntry(policy: PortfolioPolicyConfig, strategy: string, state: PortfolioState, o: PortfolioObservation, entry: PortfolioReservation): {
|
|
13
|
+
state: PortfolioState;
|
|
14
|
+
reason?: string;
|
|
15
|
+
};
|
|
16
|
+
declare function portfolioCloseCommands(policy: PortfolioPolicyConfig, state: PortfolioState, o: PortfolioObservation): {
|
|
17
|
+
intent: _tradejs_types.PortfolioCloseIntent;
|
|
18
|
+
position: PortfolioPosition;
|
|
19
|
+
}[];
|
|
20
|
+
/** Persisted state is an IO boundary, not a trusted TypeScript object. */
|
|
21
|
+
declare function assertPortfolioState(value: unknown): asserts value is PortfolioState;
|
|
22
|
+
|
|
23
|
+
export { assertPortfolioState, buildPortfolioContext, createPortfolioState, parsePortfolioPolicy, portfolioCloseCommands, portfolioFingerprint, portfolioOwns, reconcilePortfolio, reservePortfolioEntry, validatePortfolioObservation };
|