opentool 0.20.0 → 0.21.0
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/adapters/hyperliquid/browser.d.ts +2 -2
- package/dist/adapters/hyperliquid/browser.js +44 -2
- package/dist/adapters/hyperliquid/browser.js.map +1 -1
- package/dist/adapters/hyperliquid/index.d.ts +3 -3
- package/dist/adapters/hyperliquid/index.js +44 -2
- package/dist/adapters/hyperliquid/index.js.map +1 -1
- package/dist/adapters/polymarket/index.d.ts +1 -1
- package/dist/{browser-lhj5OsZa.d.ts → browser-Bf-eTSwj.d.ts} +21 -4
- package/dist/index.d.ts +5 -2
- package/dist/index.js +1305 -6
- package/dist/index.js.map +1 -1
- package/dist/mpp/index.d.ts +64 -0
- package/dist/mpp/index.js +75 -0
- package/dist/mpp/index.js.map +1 -0
- package/dist/quant/index.d.ts +579 -0
- package/dist/quant/index.js +1103 -0
- package/dist/quant/index.js.map +1 -0
- package/dist/{types-BaTmu0gS.d.ts → types-D8s9zx-U.d.ts} +18 -1
- package/dist/wallet/browser.d.ts +1 -1
- package/dist/wallet/browser.js +27 -1
- package/dist/wallet/browser.js.map +1 -1
- package/dist/wallet/index.d.ts +2 -2
- package/dist/wallet/index.js +96 -4
- package/dist/wallet/index.js.map +1 -1
- package/package.json +11 -2
- package/templates/base/package.json +1 -1
- package/templates/polymarket-simple-trade/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { zeroAddress, createWalletClient, http, createPublicClient, parseUnits, encodeFunctionData, erc20Abi, maxUint256, decodeFunctionData } from 'viem';
|
|
3
3
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
4
|
-
import { arbitrumSepolia, arbitrum, baseSepolia, mainnet, base } from 'viem/chains';
|
|
4
|
+
import { tempo, arbitrumSepolia, arbitrum, baseSepolia, mainnet, base } from 'viem/chains';
|
|
5
|
+
import { Receipt } from 'mppx';
|
|
6
|
+
import { tempo as tempo$1, Mppx } from 'mppx/client';
|
|
5
7
|
import { Turnkey } from '@turnkey/sdk-server';
|
|
6
8
|
import { createAccount } from '@turnkey/viem';
|
|
7
9
|
import { encode } from '@msgpack/msgpack';
|
|
@@ -759,11 +761,79 @@ async function payX402WithWallet(walletClient, chainId, request) {
|
|
|
759
761
|
const client = new X402BrowserClient({ walletClient, chainId });
|
|
760
762
|
return client.pay(request);
|
|
761
763
|
}
|
|
764
|
+
var MPP_TEMPO_MAINNET_CHAIN_ID = 4217;
|
|
765
|
+
var MPP_TEMPO_USDCE_ADDRESS = "0x20C000000000000000000000b9537d11c60E8b50";
|
|
766
|
+
var MPP_TEMPO_PATHUSD_ADDRESS = "0x20c0000000000000000000000000000000000000";
|
|
767
|
+
var MPP_DEFAULT_TEMPO_CURRENCY = MPP_TEMPO_USDCE_ADDRESS;
|
|
768
|
+
function createMppClient(options) {
|
|
769
|
+
assertMppWallet(options.wallet);
|
|
770
|
+
const methods = [
|
|
771
|
+
tempo$1({
|
|
772
|
+
account: options.wallet.account,
|
|
773
|
+
getClient: ({ chainId }) => resolveWalletClient(options.wallet, chainId),
|
|
774
|
+
...options.tempo?.autoSwap !== void 0 ? { autoSwap: options.tempo.autoSwap } : {},
|
|
775
|
+
...options.tempo?.deposit !== void 0 ? { deposit: options.tempo.deposit } : {},
|
|
776
|
+
...options.tempo?.maxDeposit !== void 0 ? { maxDeposit: options.tempo.maxDeposit } : {},
|
|
777
|
+
...options.tempo?.mode !== void 0 ? { mode: options.tempo.mode } : {}
|
|
778
|
+
})
|
|
779
|
+
];
|
|
780
|
+
const client = Mppx.create({
|
|
781
|
+
methods,
|
|
782
|
+
polyfill: options.polyfill ?? false,
|
|
783
|
+
...options.fetch ? { fetch: options.fetch } : {},
|
|
784
|
+
...options.acceptPaymentPolicy ? { acceptPaymentPolicy: options.acceptPaymentPolicy } : {}
|
|
785
|
+
});
|
|
786
|
+
return {
|
|
787
|
+
fetch: client.fetch,
|
|
788
|
+
rawFetch: client.rawFetch,
|
|
789
|
+
createCredential: (response, context) => client.createCredential(response, context)
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
function createMppFetch(options) {
|
|
793
|
+
return createMppClient(options).fetch;
|
|
794
|
+
}
|
|
795
|
+
async function createMppCredential(response, options, context) {
|
|
796
|
+
const client = createMppClient(options);
|
|
797
|
+
const authorization = await client.createCredential(response, context);
|
|
798
|
+
return { authorization };
|
|
799
|
+
}
|
|
800
|
+
async function fetchWithMpp(request, options) {
|
|
801
|
+
const client = createMppClient(options);
|
|
802
|
+
const init = request.context === void 0 ? request.init : {
|
|
803
|
+
...request.init,
|
|
804
|
+
context: request.context
|
|
805
|
+
};
|
|
806
|
+
const response = await client.fetch(request.input, init);
|
|
807
|
+
return {
|
|
808
|
+
response,
|
|
809
|
+
receipt: readMppReceipt(response)
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
function readMppReceipt(response) {
|
|
813
|
+
if (!response.headers.has("Payment-Receipt")) {
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
return Receipt.fromResponse(response);
|
|
817
|
+
}
|
|
818
|
+
function assertMppWallet(wallet2) {
|
|
819
|
+
if (!wallet2.account || !wallet2.walletClient) {
|
|
820
|
+
throw new Error("MPP payments require a signing wallet context");
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
function resolveWalletClient(wallet2, chainId) {
|
|
824
|
+
if (chainId !== void 0 && wallet2.chain.id !== chainId) {
|
|
825
|
+
throw new Error(
|
|
826
|
+
`MPP challenge requires chain ${chainId}, but wallet is configured for chain ${wallet2.chain.id}`
|
|
827
|
+
);
|
|
828
|
+
}
|
|
829
|
+
return wallet2.walletClient;
|
|
830
|
+
}
|
|
762
831
|
var BASE_ALCHEMY_HOST = "https://base-mainnet.g.alchemy.com/v2/";
|
|
763
832
|
var ETHEREUM_ALCHEMY_HOST = "https://eth-mainnet.g.alchemy.com/v2/";
|
|
764
833
|
var BASE_SEPOLIA_ALCHEMY_HOST = "https://base-sepolia.g.alchemy.com/v2/";
|
|
765
834
|
var ARBITRUM_ALCHEMY_HOST = "https://arb-mainnet.g.alchemy.com/v2/";
|
|
766
835
|
var ARBITRUM_SEPOLIA_ALCHEMY_HOST = "https://arb-sepolia.g.alchemy.com/v2/";
|
|
836
|
+
var TEMPO_RPC_URL = "https://rpc.tempo.xyz";
|
|
767
837
|
function buildRpcResolver(host, fallbackUrls) {
|
|
768
838
|
return (options) => {
|
|
769
839
|
if (options?.url) {
|
|
@@ -819,6 +889,14 @@ var chains = {
|
|
|
819
889
|
chain: arbitrumSepolia,
|
|
820
890
|
rpcUrl: buildRpcResolver(ARBITRUM_SEPOLIA_ALCHEMY_HOST, arbitrumSepolia.rpcUrls.default.http),
|
|
821
891
|
publicRpcUrls: arbitrumSepolia.rpcUrls.default.http
|
|
892
|
+
},
|
|
893
|
+
tempo: {
|
|
894
|
+
id: tempo.id,
|
|
895
|
+
slug: "tempo",
|
|
896
|
+
name: "Tempo",
|
|
897
|
+
chain: tempo,
|
|
898
|
+
rpcUrl: buildRpcResolver(TEMPO_RPC_URL, [TEMPO_RPC_URL]),
|
|
899
|
+
publicRpcUrls: [TEMPO_RPC_URL]
|
|
822
900
|
}
|
|
823
901
|
};
|
|
824
902
|
function createNativeToken(chainId, symbol, name) {
|
|
@@ -864,6 +942,23 @@ var tokens = {
|
|
|
864
942
|
"0x1baAbB04529D43a73232B713C0FE471f7c7334d5",
|
|
865
943
|
6
|
|
866
944
|
)
|
|
945
|
+
},
|
|
946
|
+
tempo: {
|
|
947
|
+
...createNativeToken(tempo.id, "USD", "USD"),
|
|
948
|
+
USDC: token(
|
|
949
|
+
tempo.id,
|
|
950
|
+
"USDC",
|
|
951
|
+
"Tempo USDC (USDC.e)",
|
|
952
|
+
"0x20C000000000000000000000b9537d11c60E8b50",
|
|
953
|
+
6
|
|
954
|
+
),
|
|
955
|
+
PathUSD: token(
|
|
956
|
+
tempo.id,
|
|
957
|
+
"PathUSD",
|
|
958
|
+
"PathUSD",
|
|
959
|
+
"0x20c0000000000000000000000000000000000000",
|
|
960
|
+
6
|
|
961
|
+
)
|
|
867
962
|
}
|
|
868
963
|
};
|
|
869
964
|
var DEFAULT_CHAIN = chains.base;
|
|
@@ -945,6 +1040,62 @@ function createPrivateKeyProvider(config) {
|
|
|
945
1040
|
nonceSource: createMonotonicNonceSource()
|
|
946
1041
|
};
|
|
947
1042
|
}
|
|
1043
|
+
function toRecord(value) {
|
|
1044
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
1045
|
+
}
|
|
1046
|
+
function toString(value) {
|
|
1047
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
1048
|
+
}
|
|
1049
|
+
function extractActivity(response) {
|
|
1050
|
+
const record = toRecord(response);
|
|
1051
|
+
return toRecord(record?.activity);
|
|
1052
|
+
}
|
|
1053
|
+
function recordActivityTrace(params) {
|
|
1054
|
+
const activity = extractActivity(params.response);
|
|
1055
|
+
const errorRecord = toRecord(params.error);
|
|
1056
|
+
const activityId = toString(activity?.id) ?? toString(errorRecord?.activityId);
|
|
1057
|
+
if (!activityId) return;
|
|
1058
|
+
const type = toString(activity?.type) ?? toString(errorRecord?.activityType);
|
|
1059
|
+
const status = toString(activity?.status) ?? toString(errorRecord?.activityStatus);
|
|
1060
|
+
params.traces.push({
|
|
1061
|
+
activityId,
|
|
1062
|
+
organizationId: toString(activity?.organizationId) ?? params.organizationId,
|
|
1063
|
+
operation: params.operation,
|
|
1064
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1065
|
+
...type ? { type } : {},
|
|
1066
|
+
...status ? { status } : {}
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
function createActivityCaptureClient(client, traces, organizationId) {
|
|
1070
|
+
return new Proxy(client, {
|
|
1071
|
+
get(target, prop, receiver) {
|
|
1072
|
+
const value = Reflect.get(target, prop, receiver);
|
|
1073
|
+
if (prop !== "signRawPayload" && prop !== "signTransaction") {
|
|
1074
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
1075
|
+
}
|
|
1076
|
+
return async (...args) => {
|
|
1077
|
+
try {
|
|
1078
|
+
const response = await value.apply(target, args);
|
|
1079
|
+
recordActivityTrace({
|
|
1080
|
+
traces,
|
|
1081
|
+
operation: prop,
|
|
1082
|
+
organizationId,
|
|
1083
|
+
response
|
|
1084
|
+
});
|
|
1085
|
+
return response;
|
|
1086
|
+
} catch (error) {
|
|
1087
|
+
recordActivityTrace({
|
|
1088
|
+
traces,
|
|
1089
|
+
operation: prop,
|
|
1090
|
+
organizationId,
|
|
1091
|
+
error
|
|
1092
|
+
});
|
|
1093
|
+
throw error;
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
948
1099
|
async function createTurnkeyProvider(config) {
|
|
949
1100
|
const turnkey = new Turnkey({
|
|
950
1101
|
apiBaseUrl: config.apiBaseUrl ?? "https://api.turnkey.com",
|
|
@@ -953,8 +1104,11 @@ async function createTurnkeyProvider(config) {
|
|
|
953
1104
|
apiPublicKey: config.apiPublicKey,
|
|
954
1105
|
apiPrivateKey: config.apiPrivateKey
|
|
955
1106
|
});
|
|
1107
|
+
const activityTraces = [];
|
|
1108
|
+
const apiClient = turnkey.apiClient();
|
|
1109
|
+
const accountClient = config.captureActivities ? createActivityCaptureClient(apiClient, activityTraces, config.organizationId) : apiClient;
|
|
956
1110
|
const account = await createAccount({
|
|
957
|
-
client:
|
|
1111
|
+
client: accountClient,
|
|
958
1112
|
organizationId: config.organizationId,
|
|
959
1113
|
signWith: config.signWith
|
|
960
1114
|
});
|
|
@@ -1001,7 +1155,13 @@ async function createTurnkeyProvider(config) {
|
|
|
1001
1155
|
sendTransaction,
|
|
1002
1156
|
getNativeBalance,
|
|
1003
1157
|
transfer,
|
|
1004
|
-
nonceSource: createMonotonicNonceSource()
|
|
1158
|
+
nonceSource: createMonotonicNonceSource(),
|
|
1159
|
+
...config.captureActivities ? {
|
|
1160
|
+
getTurnkeyActivities: () => activityTraces.map((trace) => ({ ...trace })),
|
|
1161
|
+
clearTurnkeyActivities: () => {
|
|
1162
|
+
activityTraces.length = 0;
|
|
1163
|
+
}
|
|
1164
|
+
} : {}
|
|
1005
1165
|
};
|
|
1006
1166
|
}
|
|
1007
1167
|
|
|
@@ -1106,7 +1266,8 @@ async function wallet(options = {}) {
|
|
|
1106
1266
|
organizationId: effectiveTurnkey.organizationId,
|
|
1107
1267
|
apiPublicKey: effectiveTurnkey.apiPublicKey,
|
|
1108
1268
|
apiPrivateKey: effectiveTurnkey.apiPrivateKey,
|
|
1109
|
-
signWith: effectiveTurnkey.signWith
|
|
1269
|
+
signWith: effectiveTurnkey.signWith,
|
|
1270
|
+
captureActivities: options.captureTurnkeyActivities ?? effectiveTurnkey.captureActivities
|
|
1110
1271
|
};
|
|
1111
1272
|
if (effectiveTurnkey.apiBaseUrl) {
|
|
1112
1273
|
turnkeyConfig.apiBaseUrl = effectiveTurnkey.apiBaseUrl;
|
|
@@ -1484,6 +1645,22 @@ var normalizeHyperliquidBase = (value) => {
|
|
|
1484
1645
|
if (!normalized || normalized === UNKNOWN_SYMBOL) return null;
|
|
1485
1646
|
return normalized;
|
|
1486
1647
|
};
|
|
1648
|
+
var normalizeText = (value) => {
|
|
1649
|
+
const trimmed = value?.trim();
|
|
1650
|
+
return trimmed ? trimmed : null;
|
|
1651
|
+
};
|
|
1652
|
+
var normalizeSymbolText = (value) => {
|
|
1653
|
+
const trimmed = value?.trim().toUpperCase();
|
|
1654
|
+
return trimmed ? trimmed : null;
|
|
1655
|
+
};
|
|
1656
|
+
var normalizeOutcomeMarketDataCoin = (value) => {
|
|
1657
|
+
const encoding = parseHyperliquidOutcomeEncoding(value);
|
|
1658
|
+
return encoding == null ? null : `#${encoding}`;
|
|
1659
|
+
};
|
|
1660
|
+
var normalizeOutcomeTokenName = (value) => {
|
|
1661
|
+
const encoding = parseHyperliquidOutcomeEncoding(value);
|
|
1662
|
+
return encoding == null ? null : `+${encoding}`;
|
|
1663
|
+
};
|
|
1487
1664
|
var normalizeSpotTokenName = (value) => {
|
|
1488
1665
|
const raw = (value ?? "").trim().toUpperCase();
|
|
1489
1666
|
if (!raw) return "";
|
|
@@ -1538,6 +1715,32 @@ function buildHyperliquidMarketIdentity(input) {
|
|
|
1538
1715
|
canonical_symbol: `perp:hyperliquid:${base2}`
|
|
1539
1716
|
};
|
|
1540
1717
|
}
|
|
1718
|
+
function buildHyperliquidOutcomeMarketIdentity(input) {
|
|
1719
|
+
const rawSymbol = normalizeText(input.rawSymbol);
|
|
1720
|
+
const marketDataCoin = normalizeOutcomeMarketDataCoin(input.marketDataCoin) ?? normalizeOutcomeMarketDataCoin(rawSymbol) ?? normalizeOutcomeMarketDataCoin(input.outcomeTokenName);
|
|
1721
|
+
const outcomeTokenName = normalizeOutcomeTokenName(input.outcomeTokenName) ?? normalizeOutcomeTokenName(rawSymbol) ?? normalizeOutcomeTokenName(input.marketDataCoin);
|
|
1722
|
+
const outcomeId = typeof input.outcomeId === "number" && Number.isSafeInteger(input.outcomeId) ? input.outcomeId : typeof input.outcomeId === "string" && input.outcomeId.trim().length > 0 ? Number.parseInt(input.outcomeId, 10) : null;
|
|
1723
|
+
const outcomeSide = typeof input.outcomeSide === "number" && Number.isSafeInteger(input.outcomeSide) ? input.outcomeSide : typeof input.outcomeSide === "string" && input.outcomeSide.trim().length > 0 ? Number.parseInt(input.outcomeSide, 10) : null;
|
|
1724
|
+
const derivedEncoding = outcomeId != null && outcomeId >= 0 && outcomeSide != null && outcomeSide >= 0 && outcomeSide <= 1 ? outcomeId * 10 + outcomeSide : null;
|
|
1725
|
+
const derivedMarketDataCoin = marketDataCoin ?? (derivedEncoding != null ? `#${derivedEncoding}` : null);
|
|
1726
|
+
const positionId = normalizeText(input.positionId) ?? derivedMarketDataCoin ?? outcomeTokenName ?? null;
|
|
1727
|
+
const protocolMarketId = normalizeText(input.protocolMarketId) ?? normalizeText(input.roundKey) ?? normalizeText(input.seriesKey) ?? (outcomeId != null && outcomeId >= 0 ? `hip4-outcome-${outcomeId}` : null);
|
|
1728
|
+
if (!protocolMarketId || !positionId) return null;
|
|
1729
|
+
const sideName = normalizeSymbolText(input.sideName);
|
|
1730
|
+
const underlying = normalizeSymbolText(input.underlying);
|
|
1731
|
+
const base2 = underlying && sideName ? `${underlying}-${sideName}` : sideName ?? underlying ?? null;
|
|
1732
|
+
return {
|
|
1733
|
+
market_type: "prediction",
|
|
1734
|
+
venue: "hyperliquid",
|
|
1735
|
+
environment: input.environment,
|
|
1736
|
+
base: base2,
|
|
1737
|
+
quote: "USDH",
|
|
1738
|
+
raw_symbol: rawSymbol ?? derivedMarketDataCoin ?? outcomeTokenName,
|
|
1739
|
+
protocol_market_id: protocolMarketId,
|
|
1740
|
+
position_id: positionId,
|
|
1741
|
+
canonical_symbol: `prediction:hyperliquid:${protocolMarketId}:${positionId}`
|
|
1742
|
+
};
|
|
1743
|
+
}
|
|
1541
1744
|
function resolveHyperliquidAbstractionFromMode(mode) {
|
|
1542
1745
|
switch (mode) {
|
|
1543
1746
|
case "standard":
|
|
@@ -3944,7 +4147,7 @@ function formatHyperliquidMarketablePrice(params) {
|
|
|
3944
4147
|
if (!formatted) {
|
|
3945
4148
|
throw new RangeError("Marketable price is too small and was truncated to 0.");
|
|
3946
4149
|
}
|
|
3947
|
-
return formatted;
|
|
4150
|
+
return tick ? roundHyperliquidPriceToTick(formatted, tick, side) : formatted;
|
|
3948
4151
|
}
|
|
3949
4152
|
const midString = normalizeDecimalString(mid.toString());
|
|
3950
4153
|
const baseDecimals = countDecimalPlaces(midString);
|
|
@@ -7980,6 +8183,1102 @@ function buildBacktestDecisionSeriesInput(request) {
|
|
|
7980
8183
|
...accountValueUsd != null ? { accountValueUsd } : {}
|
|
7981
8184
|
};
|
|
7982
8185
|
}
|
|
8186
|
+
var quantStrategyFamilySchema = z.enum([
|
|
8187
|
+
"benchmark",
|
|
8188
|
+
"signal_rule",
|
|
8189
|
+
"trend",
|
|
8190
|
+
"mean_reversion",
|
|
8191
|
+
"stat_arb",
|
|
8192
|
+
"carry",
|
|
8193
|
+
"hedge",
|
|
8194
|
+
"execution",
|
|
8195
|
+
"market_making",
|
|
8196
|
+
"options",
|
|
8197
|
+
"regime_ml",
|
|
8198
|
+
"prediction_market",
|
|
8199
|
+
"defi_lp"
|
|
8200
|
+
]);
|
|
8201
|
+
var quantTestKindSchema = z.enum([
|
|
8202
|
+
"prompt_plan_check",
|
|
8203
|
+
"data_availability",
|
|
8204
|
+
"signal_study",
|
|
8205
|
+
"idea_rule_simulation",
|
|
8206
|
+
"variant_sensitivity",
|
|
8207
|
+
"leakage_check",
|
|
8208
|
+
"cost_stress"
|
|
8209
|
+
]);
|
|
8210
|
+
var quantResolutionSchema = z.enum(["1", "5", "15", "30", "60", "240", "1D", "1W"]);
|
|
8211
|
+
var quantBarSchema = z.object({
|
|
8212
|
+
time: z.number().int().nonnegative(),
|
|
8213
|
+
open: z.number().positive(),
|
|
8214
|
+
high: z.number().positive(),
|
|
8215
|
+
low: z.number().positive(),
|
|
8216
|
+
close: z.number().positive(),
|
|
8217
|
+
volume: z.number().nonnegative().optional(),
|
|
8218
|
+
fundingRate: z.number().optional()
|
|
8219
|
+
}).strict();
|
|
8220
|
+
var quantFeatureSpecSchema = z.object({
|
|
8221
|
+
id: z.string().min(1),
|
|
8222
|
+
kind: z.string().min(1),
|
|
8223
|
+
params: z.record(z.string(), z.unknown()).default({})
|
|
8224
|
+
}).strict();
|
|
8225
|
+
var quantRuleSpecSchema = z.object({
|
|
8226
|
+
kind: z.string().min(1),
|
|
8227
|
+
params: z.record(z.string(), z.unknown()).default({})
|
|
8228
|
+
}).strict();
|
|
8229
|
+
var quantIdeaSpecV1Schema = z.object({
|
|
8230
|
+
version: z.literal("1"),
|
|
8231
|
+
family: quantStrategyFamilySchema,
|
|
8232
|
+
thesis: z.object({
|
|
8233
|
+
title: z.string().min(1),
|
|
8234
|
+
belief: z.string().min(1),
|
|
8235
|
+
expectedDirection: z.enum([
|
|
8236
|
+
"up",
|
|
8237
|
+
"down",
|
|
8238
|
+
"relative",
|
|
8239
|
+
"mean_revert",
|
|
8240
|
+
"volatility",
|
|
8241
|
+
"carry",
|
|
8242
|
+
"hedge",
|
|
8243
|
+
"unknown"
|
|
8244
|
+
]),
|
|
8245
|
+
horizon: z.array(z.string().min(1)).min(1)
|
|
8246
|
+
}).strict(),
|
|
8247
|
+
market: z.object({
|
|
8248
|
+
venue: z.enum(["hyperliquid", "polymarket", "derive", "external_fixture"]),
|
|
8249
|
+
symbol: z.string().min(1).optional(),
|
|
8250
|
+
universe: z.array(z.string().min(1)).optional()
|
|
8251
|
+
}).strict(),
|
|
8252
|
+
requiredSources: z.array(z.string().min(1)).default([]),
|
|
8253
|
+
features: z.array(quantFeatureSpecSchema).default([]),
|
|
8254
|
+
rule: quantRuleSpecSchema.optional(),
|
|
8255
|
+
risk: z.object({
|
|
8256
|
+
maxPositionUsd: z.number().positive().optional(),
|
|
8257
|
+
maxLeverage: z.number().positive().optional(),
|
|
8258
|
+
stopLossPct: z.number().positive().optional(),
|
|
8259
|
+
takeProfitPct: z.number().positive().optional(),
|
|
8260
|
+
maxDrawdownPct: z.number().positive().optional()
|
|
8261
|
+
}).strict().optional()
|
|
8262
|
+
}).strict();
|
|
8263
|
+
var quantTestRequestV1Schema = z.object({
|
|
8264
|
+
version: z.literal("1"),
|
|
8265
|
+
idea: quantIdeaSpecV1Schema,
|
|
8266
|
+
testKinds: z.array(quantTestKindSchema).min(1),
|
|
8267
|
+
window: z.object({
|
|
8268
|
+
resolution: quantResolutionSchema,
|
|
8269
|
+
timeframeStart: z.string().min(1),
|
|
8270
|
+
timeframeEnd: z.string().min(1),
|
|
8271
|
+
warmupBars: z.number().int().nonnegative().optional()
|
|
8272
|
+
}).strict(),
|
|
8273
|
+
assumptions: z.object({
|
|
8274
|
+
initialEquityUsd: z.number().positive().optional(),
|
|
8275
|
+
makerFeeBps: z.number().nonnegative().optional(),
|
|
8276
|
+
takerFeeBps: z.number().nonnegative().optional(),
|
|
8277
|
+
slippageBps: z.number().nonnegative().optional(),
|
|
8278
|
+
fundingModel: z.enum(["ignore", "historical", "estimated"]).optional()
|
|
8279
|
+
}).strict().default({}),
|
|
8280
|
+
variantSpace: z.record(z.string(), z.unknown()).optional()
|
|
8281
|
+
}).strict();
|
|
8282
|
+
var quantDecisionActionSchema = z.enum(["hold", "flat", "long", "short", "exit"]);
|
|
8283
|
+
var quantDecisionSchema = z.object({
|
|
8284
|
+
time: z.number().int().nonnegative(),
|
|
8285
|
+
symbol: z.string().min(1),
|
|
8286
|
+
action: quantDecisionActionSchema,
|
|
8287
|
+
targetPosition: z.number(),
|
|
8288
|
+
reason: z.string().min(1),
|
|
8289
|
+
price: z.number().positive().optional()
|
|
8290
|
+
}).strict();
|
|
8291
|
+
var quantDecisionArtifactV1Schema = z.object({
|
|
8292
|
+
version: z.literal("1"),
|
|
8293
|
+
family: quantStrategyFamilySchema,
|
|
8294
|
+
symbol: z.string().min(1),
|
|
8295
|
+
resolution: quantResolutionSchema,
|
|
8296
|
+
decisions: z.array(quantDecisionSchema),
|
|
8297
|
+
warnings: z.array(z.string()).default([])
|
|
8298
|
+
}).strict();
|
|
8299
|
+
var quantTesterReportV1Schema = z.object({
|
|
8300
|
+
ok: z.boolean(),
|
|
8301
|
+
testRunKind: z.enum([
|
|
8302
|
+
"prompt_plan_check",
|
|
8303
|
+
"data_availability",
|
|
8304
|
+
"signal_study",
|
|
8305
|
+
"idea_rule_simulation",
|
|
8306
|
+
"variant_sensitivity"
|
|
8307
|
+
]),
|
|
8308
|
+
supported: z.boolean(),
|
|
8309
|
+
unsupportedReason: z.string().optional(),
|
|
8310
|
+
summary: z.string(),
|
|
8311
|
+
dataLineage: z.object({
|
|
8312
|
+
venue: z.string(),
|
|
8313
|
+
symbols: z.array(z.string()),
|
|
8314
|
+
resolution: quantResolutionSchema,
|
|
8315
|
+
timeframeStart: z.string(),
|
|
8316
|
+
timeframeEnd: z.string(),
|
|
8317
|
+
sourceIds: z.array(z.string()),
|
|
8318
|
+
warnings: z.array(z.string())
|
|
8319
|
+
}).strict(),
|
|
8320
|
+
signalStudy: z.record(z.string(), z.unknown()).optional(),
|
|
8321
|
+
ideaSimulation: z.record(z.string(), z.unknown()).optional(),
|
|
8322
|
+
decisionArtifact: quantDecisionArtifactV1Schema.optional(),
|
|
8323
|
+
warnings: z.array(z.string()).default([])
|
|
8324
|
+
}).strict();
|
|
8325
|
+
|
|
8326
|
+
// src/quant/bars.ts
|
|
8327
|
+
function normalizeQuantBars(input) {
|
|
8328
|
+
const bars = quantBarSchema.array().parse(input).slice();
|
|
8329
|
+
bars.sort((a, b) => a.time - b.time);
|
|
8330
|
+
for (let index = 0; index < bars.length; index += 1) {
|
|
8331
|
+
const bar = bars[index];
|
|
8332
|
+
if (bar.high < Math.max(bar.open, bar.close) || bar.low > Math.min(bar.open, bar.close)) {
|
|
8333
|
+
throw new Error(`Invalid OHLC relationship at bar ${index}`);
|
|
8334
|
+
}
|
|
8335
|
+
if (index > 0 && bar.time <= bars[index - 1].time) {
|
|
8336
|
+
throw new Error(`Duplicate or non-increasing bar time at index ${index}`);
|
|
8337
|
+
}
|
|
8338
|
+
}
|
|
8339
|
+
return bars;
|
|
8340
|
+
}
|
|
8341
|
+
function closePrices(bars) {
|
|
8342
|
+
return bars.map((bar) => bar.close);
|
|
8343
|
+
}
|
|
8344
|
+
function typicalPrices(bars) {
|
|
8345
|
+
return bars.map((bar) => (bar.high + bar.low + bar.close) / 3);
|
|
8346
|
+
}
|
|
8347
|
+
function sliceBarsToWindow(params) {
|
|
8348
|
+
const startIndex = params.bars.findIndex((bar) => bar.time >= params.startSeconds);
|
|
8349
|
+
const fromIndex = startIndex < 0 ? params.bars.length : Math.max(0, startIndex - (params.warmupBars ?? 0));
|
|
8350
|
+
return params.bars.slice(fromIndex).filter((bar) => bar.time <= params.endSeconds);
|
|
8351
|
+
}
|
|
8352
|
+
|
|
8353
|
+
// src/quant/decision-series.ts
|
|
8354
|
+
function validateDecisionArtifact(value) {
|
|
8355
|
+
const artifact = quantDecisionArtifactV1Schema.parse(value);
|
|
8356
|
+
for (let index = 1; index < artifact.decisions.length; index += 1) {
|
|
8357
|
+
if (artifact.decisions[index].time < artifact.decisions[index - 1].time) {
|
|
8358
|
+
throw new Error(`Decision artifact times must be sorted at index ${index}`);
|
|
8359
|
+
}
|
|
8360
|
+
}
|
|
8361
|
+
return artifact;
|
|
8362
|
+
}
|
|
8363
|
+
function compactDecisionChanges(decisions) {
|
|
8364
|
+
const compact = [];
|
|
8365
|
+
let previousTarget = null;
|
|
8366
|
+
for (const decision of decisions) {
|
|
8367
|
+
if (previousTarget === null || decision.targetPosition !== previousTarget) {
|
|
8368
|
+
compact.push(decision);
|
|
8369
|
+
previousTarget = decision.targetPosition;
|
|
8370
|
+
}
|
|
8371
|
+
}
|
|
8372
|
+
return compact;
|
|
8373
|
+
}
|
|
8374
|
+
|
|
8375
|
+
// src/quant/features/beta.ts
|
|
8376
|
+
function beta(assetReturns, benchmarkReturns) {
|
|
8377
|
+
const length = Math.min(assetReturns.length, benchmarkReturns.length);
|
|
8378
|
+
if (length < 2) return null;
|
|
8379
|
+
const asset = assetReturns.slice(assetReturns.length - length);
|
|
8380
|
+
const benchmark = benchmarkReturns.slice(benchmarkReturns.length - length);
|
|
8381
|
+
const meanAsset = asset.reduce((total, value) => total + value, 0) / length;
|
|
8382
|
+
const meanBenchmark = benchmark.reduce((total, value) => total + value, 0) / length;
|
|
8383
|
+
let covariance = 0;
|
|
8384
|
+
let benchmarkVariance = 0;
|
|
8385
|
+
for (let index = 0; index < length; index += 1) {
|
|
8386
|
+
covariance += (asset[index] - meanAsset) * (benchmark[index] - meanBenchmark);
|
|
8387
|
+
benchmarkVariance += (benchmark[index] - meanBenchmark) ** 2;
|
|
8388
|
+
}
|
|
8389
|
+
return benchmarkVariance === 0 ? null : covariance / benchmarkVariance;
|
|
8390
|
+
}
|
|
8391
|
+
|
|
8392
|
+
// src/quant/features/correlation.ts
|
|
8393
|
+
function correlation(a, b) {
|
|
8394
|
+
const length = Math.min(a.length, b.length);
|
|
8395
|
+
if (length < 2) return null;
|
|
8396
|
+
const left = a.slice(a.length - length);
|
|
8397
|
+
const right = b.slice(b.length - length);
|
|
8398
|
+
const meanA = left.reduce((total, value) => total + value, 0) / length;
|
|
8399
|
+
const meanB = right.reduce((total, value) => total + value, 0) / length;
|
|
8400
|
+
let covariance = 0;
|
|
8401
|
+
let varianceA = 0;
|
|
8402
|
+
let varianceB = 0;
|
|
8403
|
+
for (let index = 0; index < length; index += 1) {
|
|
8404
|
+
const da = left[index] - meanA;
|
|
8405
|
+
const db = right[index] - meanB;
|
|
8406
|
+
covariance += da * db;
|
|
8407
|
+
varianceA += da * da;
|
|
8408
|
+
varianceB += db * db;
|
|
8409
|
+
}
|
|
8410
|
+
if (varianceA === 0 || varianceB === 0) return null;
|
|
8411
|
+
return covariance / Math.sqrt(varianceA * varianceB);
|
|
8412
|
+
}
|
|
8413
|
+
function rollingCorrelation(a, b, period = 20) {
|
|
8414
|
+
return a.map((_, index) => {
|
|
8415
|
+
if (index < period - 1) return null;
|
|
8416
|
+
return correlation(
|
|
8417
|
+
a.slice(index - period + 1, index + 1),
|
|
8418
|
+
b.slice(index - period + 1, index + 1)
|
|
8419
|
+
);
|
|
8420
|
+
});
|
|
8421
|
+
}
|
|
8422
|
+
|
|
8423
|
+
// src/quant/features/funding.ts
|
|
8424
|
+
function fundingRates(bars) {
|
|
8425
|
+
return bars.map((bar) => bar.fundingRate ?? 0);
|
|
8426
|
+
}
|
|
8427
|
+
function cumulativeFunding(bars) {
|
|
8428
|
+
let running = 0;
|
|
8429
|
+
return fundingRates(bars).map((rate) => {
|
|
8430
|
+
running += rate;
|
|
8431
|
+
return running;
|
|
8432
|
+
});
|
|
8433
|
+
}
|
|
8434
|
+
|
|
8435
|
+
// src/quant/features/momentum.ts
|
|
8436
|
+
function momentum(values, lookbackBars) {
|
|
8437
|
+
if (!Number.isInteger(lookbackBars) || lookbackBars <= 0) {
|
|
8438
|
+
throw new Error("Momentum lookback must be a positive integer");
|
|
8439
|
+
}
|
|
8440
|
+
return values.map((value, index) => {
|
|
8441
|
+
const prior = values[index - lookbackBars];
|
|
8442
|
+
return prior == null || prior === 0 ? null : value / prior - 1;
|
|
8443
|
+
});
|
|
8444
|
+
}
|
|
8445
|
+
|
|
8446
|
+
// src/quant/features/relative-strength.ts
|
|
8447
|
+
function relativeStrength(assetPrices, benchmarkPrices, lookbackBars) {
|
|
8448
|
+
const assetMomentum = momentum(assetPrices, lookbackBars);
|
|
8449
|
+
const benchmarkMomentum = momentum(benchmarkPrices, lookbackBars);
|
|
8450
|
+
return assetMomentum.map(
|
|
8451
|
+
(value, index) => value == null || benchmarkMomentum[index] == null ? null : value - benchmarkMomentum[index]
|
|
8452
|
+
);
|
|
8453
|
+
}
|
|
8454
|
+
|
|
8455
|
+
// src/quant/features/returns.ts
|
|
8456
|
+
function simpleReturns(values) {
|
|
8457
|
+
return values.map((value, index) => {
|
|
8458
|
+
if (index === 0) return 0;
|
|
8459
|
+
const previous = values[index - 1];
|
|
8460
|
+
return previous === 0 ? 0 : value / previous - 1;
|
|
8461
|
+
});
|
|
8462
|
+
}
|
|
8463
|
+
function logReturns(values) {
|
|
8464
|
+
return values.map((value, index) => {
|
|
8465
|
+
if (index === 0) return 0;
|
|
8466
|
+
const previous = values[index - 1];
|
|
8467
|
+
return previous <= 0 || value <= 0 ? 0 : Math.log(value / previous);
|
|
8468
|
+
});
|
|
8469
|
+
}
|
|
8470
|
+
function forwardReturns(values, horizonBars2) {
|
|
8471
|
+
if (!Number.isInteger(horizonBars2) || horizonBars2 <= 0) {
|
|
8472
|
+
throw new Error("Forward return horizon must be a positive integer");
|
|
8473
|
+
}
|
|
8474
|
+
return values.map((value, index) => {
|
|
8475
|
+
const future = values[index + horizonBars2];
|
|
8476
|
+
return future == null || value === 0 ? null : future / value - 1;
|
|
8477
|
+
});
|
|
8478
|
+
}
|
|
8479
|
+
|
|
8480
|
+
// src/quant/indicators/sma.ts
|
|
8481
|
+
function sma(values, period) {
|
|
8482
|
+
if (!Number.isInteger(period) || period <= 0) {
|
|
8483
|
+
throw new Error("SMA period must be a positive integer");
|
|
8484
|
+
}
|
|
8485
|
+
const output = [];
|
|
8486
|
+
let sum = 0;
|
|
8487
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
8488
|
+
sum += values[index];
|
|
8489
|
+
if (index >= period) sum -= values[index - period];
|
|
8490
|
+
output.push(index >= period - 1 ? sum / period : null);
|
|
8491
|
+
}
|
|
8492
|
+
return output;
|
|
8493
|
+
}
|
|
8494
|
+
|
|
8495
|
+
// src/quant/features/volume.ts
|
|
8496
|
+
function volumes(bars) {
|
|
8497
|
+
return bars.map((bar) => bar.volume ?? 0);
|
|
8498
|
+
}
|
|
8499
|
+
function relativeVolume(bars, period = 20) {
|
|
8500
|
+
const raw = volumes(bars);
|
|
8501
|
+
const average = sma(raw, period);
|
|
8502
|
+
return raw.map((value, index) => {
|
|
8503
|
+
const baseline = average[index];
|
|
8504
|
+
return baseline == null || baseline === 0 ? null : value / baseline;
|
|
8505
|
+
});
|
|
8506
|
+
}
|
|
8507
|
+
|
|
8508
|
+
// src/quant/indicators/atr.ts
|
|
8509
|
+
function trueRanges(bars) {
|
|
8510
|
+
return bars.map((bar, index) => {
|
|
8511
|
+
const previousClose = index > 0 ? bars[index - 1].close : bar.close;
|
|
8512
|
+
return Math.max(
|
|
8513
|
+
bar.high - bar.low,
|
|
8514
|
+
Math.abs(bar.high - previousClose),
|
|
8515
|
+
Math.abs(bar.low - previousClose)
|
|
8516
|
+
);
|
|
8517
|
+
});
|
|
8518
|
+
}
|
|
8519
|
+
function atr(bars, period = 14) {
|
|
8520
|
+
return sma(trueRanges(bars), period);
|
|
8521
|
+
}
|
|
8522
|
+
|
|
8523
|
+
// src/quant/indicators/bollinger.ts
|
|
8524
|
+
function bollinger(values, period = 20, standardDeviations = 2) {
|
|
8525
|
+
const middle = sma(values, period);
|
|
8526
|
+
return values.map((_, index) => {
|
|
8527
|
+
const average = middle[index];
|
|
8528
|
+
if (average == null || index < period - 1) {
|
|
8529
|
+
return { lower: null, middle: null, upper: null, width: null };
|
|
8530
|
+
}
|
|
8531
|
+
const window = values.slice(index - period + 1, index + 1);
|
|
8532
|
+
const variance = window.reduce((total, value) => total + (value - average) ** 2, 0) / period;
|
|
8533
|
+
const deviation = Math.sqrt(variance);
|
|
8534
|
+
const lower = average - deviation * standardDeviations;
|
|
8535
|
+
const upper = average + deviation * standardDeviations;
|
|
8536
|
+
return {
|
|
8537
|
+
lower,
|
|
8538
|
+
middle: average,
|
|
8539
|
+
upper,
|
|
8540
|
+
width: average === 0 ? null : (upper - lower) / average
|
|
8541
|
+
};
|
|
8542
|
+
});
|
|
8543
|
+
}
|
|
8544
|
+
|
|
8545
|
+
// src/quant/indicators/donchian.ts
|
|
8546
|
+
function donchian(highs, lows, period = 20) {
|
|
8547
|
+
if (highs.length !== lows.length) {
|
|
8548
|
+
throw new Error("Donchian high/low arrays must have the same length");
|
|
8549
|
+
}
|
|
8550
|
+
if (!Number.isInteger(period) || period <= 0) {
|
|
8551
|
+
throw new Error("Donchian period must be a positive integer");
|
|
8552
|
+
}
|
|
8553
|
+
return highs.map((_, index) => {
|
|
8554
|
+
if (index < period - 1) return { lower: null, upper: null };
|
|
8555
|
+
const highWindow = highs.slice(index - period + 1, index + 1);
|
|
8556
|
+
const lowWindow = lows.slice(index - period + 1, index + 1);
|
|
8557
|
+
return {
|
|
8558
|
+
lower: Math.min(...lowWindow),
|
|
8559
|
+
upper: Math.max(...highWindow)
|
|
8560
|
+
};
|
|
8561
|
+
});
|
|
8562
|
+
}
|
|
8563
|
+
|
|
8564
|
+
// src/quant/indicators/ema.ts
|
|
8565
|
+
function ema(values, period) {
|
|
8566
|
+
if (!Number.isInteger(period) || period <= 0) {
|
|
8567
|
+
throw new Error("EMA period must be a positive integer");
|
|
8568
|
+
}
|
|
8569
|
+
const output = [];
|
|
8570
|
+
const multiplier = 2 / (period + 1);
|
|
8571
|
+
let previous = null;
|
|
8572
|
+
let seedSum = 0;
|
|
8573
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
8574
|
+
const value = values[index];
|
|
8575
|
+
if (index < period) {
|
|
8576
|
+
seedSum += value;
|
|
8577
|
+
if (index === period - 1) {
|
|
8578
|
+
previous = seedSum / period;
|
|
8579
|
+
output.push(previous);
|
|
8580
|
+
} else {
|
|
8581
|
+
output.push(null);
|
|
8582
|
+
}
|
|
8583
|
+
continue;
|
|
8584
|
+
}
|
|
8585
|
+
previous = previous == null ? value : (value - previous) * multiplier + previous;
|
|
8586
|
+
output.push(previous);
|
|
8587
|
+
}
|
|
8588
|
+
return output;
|
|
8589
|
+
}
|
|
8590
|
+
|
|
8591
|
+
// src/quant/indicators/macd.ts
|
|
8592
|
+
function macd(values, fastPeriod = 12, slowPeriod = 26, signalPeriod = 9) {
|
|
8593
|
+
if (fastPeriod >= slowPeriod) {
|
|
8594
|
+
throw new Error("MACD fast period must be less than slow period");
|
|
8595
|
+
}
|
|
8596
|
+
const fast = ema(values, fastPeriod);
|
|
8597
|
+
const slow = ema(values, slowPeriod);
|
|
8598
|
+
const macdLine = values.map(
|
|
8599
|
+
(_, index) => fast[index] == null || slow[index] == null ? null : fast[index] - slow[index]
|
|
8600
|
+
);
|
|
8601
|
+
const signalInput = macdLine.map((value) => value ?? 0);
|
|
8602
|
+
const signalLine = ema(signalInput, signalPeriod);
|
|
8603
|
+
return values.map((_, index) => {
|
|
8604
|
+
const macdValue = macdLine[index];
|
|
8605
|
+
const signalValue = macdValue == null ? null : signalLine[index];
|
|
8606
|
+
return {
|
|
8607
|
+
macd: macdValue,
|
|
8608
|
+
signal: signalValue,
|
|
8609
|
+
histogram: macdValue == null || signalValue == null ? null : macdValue - signalValue
|
|
8610
|
+
};
|
|
8611
|
+
});
|
|
8612
|
+
}
|
|
8613
|
+
|
|
8614
|
+
// src/quant/indicators/rsi.ts
|
|
8615
|
+
function rsi(values, period = 14) {
|
|
8616
|
+
if (!Number.isInteger(period) || period <= 0) {
|
|
8617
|
+
throw new Error("RSI period must be a positive integer");
|
|
8618
|
+
}
|
|
8619
|
+
const output = Array.from({ length: values.length }, () => null);
|
|
8620
|
+
if (values.length <= period) return output;
|
|
8621
|
+
let gainSum = 0;
|
|
8622
|
+
let lossSum = 0;
|
|
8623
|
+
for (let index = 1; index <= period; index += 1) {
|
|
8624
|
+
const delta = values[index] - values[index - 1];
|
|
8625
|
+
if (delta >= 0) gainSum += delta;
|
|
8626
|
+
else lossSum += Math.abs(delta);
|
|
8627
|
+
}
|
|
8628
|
+
let averageGain = gainSum / period;
|
|
8629
|
+
let averageLoss = lossSum / period;
|
|
8630
|
+
output[period] = averageLoss === 0 ? 100 : 100 - 100 / (1 + averageGain / averageLoss);
|
|
8631
|
+
for (let index = period + 1; index < values.length; index += 1) {
|
|
8632
|
+
const delta = values[index] - values[index - 1];
|
|
8633
|
+
const gain = delta > 0 ? delta : 0;
|
|
8634
|
+
const loss = delta < 0 ? Math.abs(delta) : 0;
|
|
8635
|
+
averageGain = (averageGain * (period - 1) + gain) / period;
|
|
8636
|
+
averageLoss = (averageLoss * (period - 1) + loss) / period;
|
|
8637
|
+
output[index] = averageLoss === 0 ? 100 : 100 - 100 / (1 + averageGain / averageLoss);
|
|
8638
|
+
}
|
|
8639
|
+
return output;
|
|
8640
|
+
}
|
|
8641
|
+
|
|
8642
|
+
// src/quant/indicators/volatility.ts
|
|
8643
|
+
function rollingVolatility(returns, period = 20, annualization = 365) {
|
|
8644
|
+
if (!Number.isInteger(period) || period <= 1) {
|
|
8645
|
+
throw new Error("Volatility period must be an integer greater than 1");
|
|
8646
|
+
}
|
|
8647
|
+
return returns.map((_, index) => {
|
|
8648
|
+
if (index < period - 1) return null;
|
|
8649
|
+
const window = returns.slice(index - period + 1, index + 1);
|
|
8650
|
+
const mean = window.reduce((total, value) => total + value, 0) / period;
|
|
8651
|
+
const variance = window.reduce((total, value) => total + (value - mean) ** 2, 0) / (period - 1);
|
|
8652
|
+
return Math.sqrt(variance) * Math.sqrt(annualization);
|
|
8653
|
+
});
|
|
8654
|
+
}
|
|
8655
|
+
|
|
8656
|
+
// src/quant/indicators/zscore.ts
|
|
8657
|
+
function rollingZScore(values, period = 20) {
|
|
8658
|
+
if (!Number.isInteger(period) || period <= 1) {
|
|
8659
|
+
throw new Error("Z-score period must be an integer greater than 1");
|
|
8660
|
+
}
|
|
8661
|
+
return values.map((value, index) => {
|
|
8662
|
+
if (index < period - 1) return null;
|
|
8663
|
+
const window = values.slice(index - period + 1, index + 1);
|
|
8664
|
+
const mean = window.reduce((total, current) => total + current, 0) / period;
|
|
8665
|
+
const variance = window.reduce((total, current) => total + (current - mean) ** 2, 0) / period;
|
|
8666
|
+
const deviation = Math.sqrt(variance);
|
|
8667
|
+
return deviation === 0 ? 0 : (value - mean) / deviation;
|
|
8668
|
+
});
|
|
8669
|
+
}
|
|
8670
|
+
|
|
8671
|
+
// src/quant/lineage.ts
|
|
8672
|
+
function buildQuantDataLineage(params) {
|
|
8673
|
+
const symbol = params.request.idea.market.symbol ?? params.request.idea.market.universe?.[0] ?? "UNKNOWN";
|
|
8674
|
+
return {
|
|
8675
|
+
venue: params.request.idea.market.venue,
|
|
8676
|
+
symbols: params.request.idea.market.universe ?? [symbol],
|
|
8677
|
+
resolution: params.request.window.resolution,
|
|
8678
|
+
timeframeStart: params.request.window.timeframeStart,
|
|
8679
|
+
timeframeEnd: params.request.window.timeframeEnd,
|
|
8680
|
+
sourceIds: params.request.idea.requiredSources,
|
|
8681
|
+
warnings: params.warnings ?? []
|
|
8682
|
+
};
|
|
8683
|
+
}
|
|
8684
|
+
|
|
8685
|
+
// src/quant/result.ts
|
|
8686
|
+
function summarizeNumbers(values) {
|
|
8687
|
+
const finite = values.filter((value) => Number.isFinite(value));
|
|
8688
|
+
if (finite.length === 0) {
|
|
8689
|
+
return {
|
|
8690
|
+
count: 0,
|
|
8691
|
+
max: null,
|
|
8692
|
+
mean: null,
|
|
8693
|
+
median: null,
|
|
8694
|
+
min: null,
|
|
8695
|
+
positiveRate: null,
|
|
8696
|
+
standardDeviation: null
|
|
8697
|
+
};
|
|
8698
|
+
}
|
|
8699
|
+
const sorted = finite.slice().sort((a, b) => a - b);
|
|
8700
|
+
const mean = finite.reduce((total, value) => total + value, 0) / finite.length;
|
|
8701
|
+
const variance = finite.reduce((total, value) => total + (value - mean) ** 2, 0) / finite.length;
|
|
8702
|
+
const middle = Math.floor(sorted.length / 2);
|
|
8703
|
+
const median = sorted.length % 2 === 0 ? (sorted[middle - 1] + sorted[middle]) / 2 : sorted[middle];
|
|
8704
|
+
return {
|
|
8705
|
+
count: finite.length,
|
|
8706
|
+
max: sorted[sorted.length - 1],
|
|
8707
|
+
mean,
|
|
8708
|
+
median,
|
|
8709
|
+
min: sorted[0],
|
|
8710
|
+
positiveRate: finite.filter((value) => value > 0).length / Math.max(1, finite.length),
|
|
8711
|
+
standardDeviation: Math.sqrt(variance)
|
|
8712
|
+
};
|
|
8713
|
+
}
|
|
8714
|
+
|
|
8715
|
+
// src/quant/signal-study/adverse-excursion.ts
|
|
8716
|
+
function summarizeExcursions(params) {
|
|
8717
|
+
const adverse = [];
|
|
8718
|
+
const favorable = [];
|
|
8719
|
+
for (let index = 0; index < params.bars.length; index += 1) {
|
|
8720
|
+
if (!params.condition[index]) continue;
|
|
8721
|
+
const entry = params.bars[index].close;
|
|
8722
|
+
const window = params.bars.slice(index + 1, index + params.horizonBars + 1);
|
|
8723
|
+
if (window.length === 0) continue;
|
|
8724
|
+
adverse.push(Math.min(...window.map((bar) => bar.low / entry - 1)));
|
|
8725
|
+
favorable.push(Math.max(...window.map((bar) => bar.high / entry - 1)));
|
|
8726
|
+
}
|
|
8727
|
+
return {
|
|
8728
|
+
averageAdverse: adverse.length === 0 ? null : adverse.reduce((total, value) => total + value, 0) / adverse.length,
|
|
8729
|
+
averageFavorable: favorable.length === 0 ? null : favorable.reduce((total, value) => total + value, 0) / favorable.length,
|
|
8730
|
+
count: adverse.length
|
|
8731
|
+
};
|
|
8732
|
+
}
|
|
8733
|
+
|
|
8734
|
+
// src/quant/signal-study/event-windows.ts
|
|
8735
|
+
function buildEventWindows(params) {
|
|
8736
|
+
const windows = [];
|
|
8737
|
+
for (let index = 0; index < params.bars.length; index += 1) {
|
|
8738
|
+
if (!params.condition[index]) continue;
|
|
8739
|
+
const start = params.bars[Math.max(0, index - params.preBars)];
|
|
8740
|
+
const end = params.bars[Math.min(params.bars.length - 1, index + params.postBars)];
|
|
8741
|
+
windows.push({
|
|
8742
|
+
endTime: end.time,
|
|
8743
|
+
eventTime: params.bars[index].time,
|
|
8744
|
+
startTime: start.time
|
|
8745
|
+
});
|
|
8746
|
+
}
|
|
8747
|
+
return windows;
|
|
8748
|
+
}
|
|
8749
|
+
|
|
8750
|
+
// src/quant/signal-study/forward-returns.ts
|
|
8751
|
+
function studyForwardReturns(params) {
|
|
8752
|
+
const forward = forwardReturns(params.prices, params.horizonBars);
|
|
8753
|
+
const all = forward.filter((value) => value != null);
|
|
8754
|
+
const conditioned = forward.filter(
|
|
8755
|
+
(value, index) => value != null && params.condition[index] === true
|
|
8756
|
+
);
|
|
8757
|
+
return {
|
|
8758
|
+
conditioned: summarizeNumbers(conditioned),
|
|
8759
|
+
horizonBars: params.horizonBars,
|
|
8760
|
+
unconditional: summarizeNumbers(all)
|
|
8761
|
+
};
|
|
8762
|
+
}
|
|
8763
|
+
|
|
8764
|
+
// src/quant/signal-study/hit-rate.ts
|
|
8765
|
+
function hitRate(values) {
|
|
8766
|
+
const finite = values.filter((value) => Number.isFinite(value));
|
|
8767
|
+
if (finite.length === 0) return null;
|
|
8768
|
+
return finite.filter((value) => value > 0).length / finite.length;
|
|
8769
|
+
}
|
|
8770
|
+
|
|
8771
|
+
// src/quant/signal-study/information-coefficient.ts
|
|
8772
|
+
function informationCoefficient(params) {
|
|
8773
|
+
const pairs = [];
|
|
8774
|
+
const length = Math.min(params.signal.length, params.forwardReturns.length);
|
|
8775
|
+
for (let index = 0; index < length; index += 1) {
|
|
8776
|
+
const x = params.signal[index];
|
|
8777
|
+
const y = params.forwardReturns[index];
|
|
8778
|
+
if (x != null && y != null && Number.isFinite(x) && Number.isFinite(y)) {
|
|
8779
|
+
pairs.push({ x, y });
|
|
8780
|
+
}
|
|
8781
|
+
}
|
|
8782
|
+
if (pairs.length < 3) return null;
|
|
8783
|
+
const meanX = pairs.reduce((total, pair) => total + pair.x, 0) / pairs.length;
|
|
8784
|
+
const meanY = pairs.reduce((total, pair) => total + pair.y, 0) / pairs.length;
|
|
8785
|
+
let covariance = 0;
|
|
8786
|
+
let varianceX = 0;
|
|
8787
|
+
let varianceY = 0;
|
|
8788
|
+
for (const pair of pairs) {
|
|
8789
|
+
const dx = pair.x - meanX;
|
|
8790
|
+
const dy = pair.y - meanY;
|
|
8791
|
+
covariance += dx * dy;
|
|
8792
|
+
varianceX += dx * dx;
|
|
8793
|
+
varianceY += dy * dy;
|
|
8794
|
+
}
|
|
8795
|
+
if (varianceX === 0 || varianceY === 0) return null;
|
|
8796
|
+
return covariance / Math.sqrt(varianceX * varianceY);
|
|
8797
|
+
}
|
|
8798
|
+
|
|
8799
|
+
// src/quant/signal-study/summary.ts
|
|
8800
|
+
function signalStudySummary(params) {
|
|
8801
|
+
if (params.conditionedCount === 0) {
|
|
8802
|
+
return "No signal events were available in the supplied window.";
|
|
8803
|
+
}
|
|
8804
|
+
const conditioned = params.conditionedMean == null ? "n/a" : `${(params.conditionedMean * 100).toFixed(2)}%`;
|
|
8805
|
+
const unconditional = params.unconditionalMean == null ? "n/a" : `${(params.unconditionalMean * 100).toFixed(2)}%`;
|
|
8806
|
+
return `Signal events=${params.conditionedCount}; conditioned forward return=${conditioned}; unconditional=${unconditional}.`;
|
|
8807
|
+
}
|
|
8808
|
+
|
|
8809
|
+
// src/quant/strategies/breakout.ts
|
|
8810
|
+
var DONCHIAN_BREAKOUT_RULE_KIND = "donchian_breakout";
|
|
8811
|
+
|
|
8812
|
+
// src/quant/strategies/funding-carry.ts
|
|
8813
|
+
var FUNDING_CARRY_RULE_KIND = "funding_carry";
|
|
8814
|
+
|
|
8815
|
+
// src/quant/strategies/macd-trend.ts
|
|
8816
|
+
var MACD_CROSSOVER_RULE_KIND = "macd_crossover";
|
|
8817
|
+
|
|
8818
|
+
// src/quant/strategies/ma-cross.ts
|
|
8819
|
+
var MA_CROSS_RULE_KIND = "ma_cross";
|
|
8820
|
+
|
|
8821
|
+
// src/quant/strategies/momentum.ts
|
|
8822
|
+
var MOMENTUM_RULE_KIND = "momentum";
|
|
8823
|
+
|
|
8824
|
+
// src/quant/strategies/registry.ts
|
|
8825
|
+
var BASE_TESTS = [
|
|
8826
|
+
"prompt_plan_check",
|
|
8827
|
+
"data_availability",
|
|
8828
|
+
"signal_study",
|
|
8829
|
+
"idea_rule_simulation",
|
|
8830
|
+
"variant_sensitivity",
|
|
8831
|
+
"leakage_check",
|
|
8832
|
+
"cost_stress"
|
|
8833
|
+
];
|
|
8834
|
+
var QUANT_FAMILY_CAPABILITIES = [
|
|
8835
|
+
{
|
|
8836
|
+
aliases: ["benchmark", "buy-and-hold", "buy_and_hold", "hold"],
|
|
8837
|
+
family: "benchmark",
|
|
8838
|
+
supportLevel: "v1_replayable",
|
|
8839
|
+
supportedTestKinds: BASE_TESTS
|
|
8840
|
+
},
|
|
8841
|
+
{
|
|
8842
|
+
aliases: ["signal_rule", "moving_average", "ma_cross", "rsi", "macd", "bollinger", "donchian"],
|
|
8843
|
+
family: "signal_rule",
|
|
8844
|
+
supportLevel: "v1_replayable",
|
|
8845
|
+
supportedTestKinds: BASE_TESTS
|
|
8846
|
+
},
|
|
8847
|
+
{
|
|
8848
|
+
aliases: ["trend", "momentum", "breakout", "time_series_momentum"],
|
|
8849
|
+
family: "trend",
|
|
8850
|
+
supportLevel: "v1_replayable",
|
|
8851
|
+
supportedTestKinds: BASE_TESTS
|
|
8852
|
+
},
|
|
8853
|
+
{
|
|
8854
|
+
aliases: ["mean_reversion", "zscore", "rsi_mean_reversion", "bollinger_mean_reversion"],
|
|
8855
|
+
family: "mean_reversion",
|
|
8856
|
+
supportLevel: "v1_replayable",
|
|
8857
|
+
supportedTestKinds: BASE_TESTS
|
|
8858
|
+
},
|
|
8859
|
+
{
|
|
8860
|
+
aliases: ["stat_arb", "pairs", "pair_spread", "cointegration"],
|
|
8861
|
+
family: "stat_arb",
|
|
8862
|
+
supportLevel: "v1_signal_or_idea_test",
|
|
8863
|
+
supportedTestKinds: ["prompt_plan_check", "data_availability", "signal_study", "leakage_check"]
|
|
8864
|
+
},
|
|
8865
|
+
{
|
|
8866
|
+
aliases: ["carry", "funding", "basis", "funding_carry"],
|
|
8867
|
+
family: "carry",
|
|
8868
|
+
supportLevel: "v1_signal_or_idea_test",
|
|
8869
|
+
supportedTestKinds: BASE_TESTS
|
|
8870
|
+
},
|
|
8871
|
+
{
|
|
8872
|
+
aliases: ["hedge", "overlay", "tail_hedge"],
|
|
8873
|
+
family: "hedge",
|
|
8874
|
+
supportLevel: "v1_signal_or_idea_test",
|
|
8875
|
+
supportedTestKinds: ["prompt_plan_check", "data_availability", "signal_study", "cost_stress"]
|
|
8876
|
+
},
|
|
8877
|
+
{
|
|
8878
|
+
aliases: ["execution", "twap", "vwap", "participation", "iceberg"],
|
|
8879
|
+
family: "execution",
|
|
8880
|
+
supportLevel: "advanced_research",
|
|
8881
|
+
supportedTestKinds: ["prompt_plan_check", "data_availability", "cost_stress"]
|
|
8882
|
+
},
|
|
8883
|
+
{
|
|
8884
|
+
aliases: ["market_making", "maker", "avellaneda", "inventory_skew"],
|
|
8885
|
+
family: "market_making",
|
|
8886
|
+
supportLevel: "advanced_research",
|
|
8887
|
+
supportedTestKinds: ["prompt_plan_check", "data_availability", "cost_stress"]
|
|
8888
|
+
},
|
|
8889
|
+
{
|
|
8890
|
+
aliases: ["options", "vol", "black_scholes", "put_call_parity"],
|
|
8891
|
+
family: "options",
|
|
8892
|
+
supportLevel: "unsupported_until_data",
|
|
8893
|
+
supportedTestKinds: ["prompt_plan_check", "data_availability"]
|
|
8894
|
+
},
|
|
8895
|
+
{
|
|
8896
|
+
aliases: ["regime_ml", "ml", "regime", "markov", "hmm", "rl"],
|
|
8897
|
+
family: "regime_ml",
|
|
8898
|
+
supportLevel: "advanced_research",
|
|
8899
|
+
supportedTestKinds: ["prompt_plan_check", "data_availability", "leakage_check"]
|
|
8900
|
+
},
|
|
8901
|
+
{
|
|
8902
|
+
aliases: ["prediction_market", "outcome", "hip4", "binary"],
|
|
8903
|
+
family: "prediction_market",
|
|
8904
|
+
supportLevel: "v1_signal_or_idea_test",
|
|
8905
|
+
supportedTestKinds: ["prompt_plan_check", "data_availability", "signal_study", "cost_stress"]
|
|
8906
|
+
},
|
|
8907
|
+
{
|
|
8908
|
+
aliases: ["defi_lp", "amm", "lp", "concentrated_liquidity"],
|
|
8909
|
+
family: "defi_lp",
|
|
8910
|
+
supportLevel: "unsupported_until_data",
|
|
8911
|
+
supportedTestKinds: ["prompt_plan_check", "data_availability"]
|
|
8912
|
+
}
|
|
8913
|
+
];
|
|
8914
|
+
function resolveQuantFamilyCapability(value) {
|
|
8915
|
+
const normalized = value.trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
8916
|
+
return QUANT_FAMILY_CAPABILITIES.find(
|
|
8917
|
+
(capability) => capability.family === normalized || capability.aliases.some((alias) => alias === normalized)
|
|
8918
|
+
) ?? null;
|
|
8919
|
+
}
|
|
8920
|
+
|
|
8921
|
+
// src/quant/strategies/rsi-mean-reversion.ts
|
|
8922
|
+
var RSI_MEAN_REVERSION_RULE_KIND = "rsi_mean_reversion";
|
|
8923
|
+
|
|
8924
|
+
// src/quant/strategies/rule-evaluator.ts
|
|
8925
|
+
function numberParam(params, key, fallback) {
|
|
8926
|
+
const value = params[key];
|
|
8927
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
8928
|
+
}
|
|
8929
|
+
function stringParam(params, key, fallback) {
|
|
8930
|
+
const value = params[key];
|
|
8931
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : fallback;
|
|
8932
|
+
}
|
|
8933
|
+
function ma(values, type, period) {
|
|
8934
|
+
return type.toLowerCase() === "sma" ? sma(values, period) : ema(values, period);
|
|
8935
|
+
}
|
|
8936
|
+
function shiftedBreakoutCondition(bars, period) {
|
|
8937
|
+
const channels = donchian(
|
|
8938
|
+
bars.map((bar) => bar.high),
|
|
8939
|
+
bars.map((bar) => bar.low),
|
|
8940
|
+
period
|
|
8941
|
+
);
|
|
8942
|
+
return bars.map((bar, index) => {
|
|
8943
|
+
const prior = channels[index - 1];
|
|
8944
|
+
return prior?.upper != null && bar.close > prior.upper;
|
|
8945
|
+
});
|
|
8946
|
+
}
|
|
8947
|
+
function evaluateQuantRule(params) {
|
|
8948
|
+
const prices = closePrices(params.bars);
|
|
8949
|
+
const rule = params.idea.rule;
|
|
8950
|
+
const kind = rule?.kind ?? (params.idea.family === "benchmark" ? "buy_hold" : "momentum");
|
|
8951
|
+
const ruleParams = rule?.params ?? {};
|
|
8952
|
+
const warnings = [];
|
|
8953
|
+
let condition = [];
|
|
8954
|
+
let positions = [];
|
|
8955
|
+
let signal = [];
|
|
8956
|
+
if (kind === "buy_hold") {
|
|
8957
|
+
condition = prices.map(() => true);
|
|
8958
|
+
positions = prices.map(() => 1);
|
|
8959
|
+
signal = prices.map(() => 1);
|
|
8960
|
+
} else if (kind === "ma_cross" || kind === "moving_average_crossover") {
|
|
8961
|
+
const fastPeriod = Math.max(1, Math.trunc(numberParam(ruleParams, "fastPeriod", 20)));
|
|
8962
|
+
const slowPeriod = Math.max(fastPeriod + 1, Math.trunc(numberParam(ruleParams, "slowPeriod", 100)));
|
|
8963
|
+
const averageType = stringParam(ruleParams, "averageType", "ema");
|
|
8964
|
+
const fast = ma(prices, averageType, fastPeriod);
|
|
8965
|
+
const slow = ma(prices, averageType, slowPeriod);
|
|
8966
|
+
signal = prices.map(
|
|
8967
|
+
(_, index) => fast[index] == null || slow[index] == null ? null : fast[index] - slow[index]
|
|
8968
|
+
);
|
|
8969
|
+
condition = signal.map((value) => value != null && value > 0);
|
|
8970
|
+
positions = condition.map((active) => active ? 1 : 0);
|
|
8971
|
+
} else if (kind === "rsi_mean_reversion") {
|
|
8972
|
+
const period = Math.max(2, Math.trunc(numberParam(ruleParams, "period", 14)));
|
|
8973
|
+
const oversold = numberParam(ruleParams, "oversold", 30);
|
|
8974
|
+
const exit = numberParam(ruleParams, "exit", 50);
|
|
8975
|
+
signal = rsi(prices, period);
|
|
8976
|
+
let active = false;
|
|
8977
|
+
positions = signal.map((value) => {
|
|
8978
|
+
if (value == null) return 0;
|
|
8979
|
+
if (value <= oversold) active = true;
|
|
8980
|
+
if (value >= exit) active = false;
|
|
8981
|
+
return active ? 1 : 0;
|
|
8982
|
+
});
|
|
8983
|
+
condition = signal.map((value) => value != null && value <= oversold);
|
|
8984
|
+
} else if (kind === "macd_crossover") {
|
|
8985
|
+
const points = macd(prices);
|
|
8986
|
+
signal = points.map(
|
|
8987
|
+
(point) => point.macd == null || point.signal == null ? null : point.macd - point.signal
|
|
8988
|
+
);
|
|
8989
|
+
condition = signal.map((value) => value != null && value > 0);
|
|
8990
|
+
positions = condition.map((active) => active ? 1 : 0);
|
|
8991
|
+
} else if (kind === "donchian_breakout") {
|
|
8992
|
+
const period = Math.max(2, Math.trunc(numberParam(ruleParams, "period", 20)));
|
|
8993
|
+
condition = shiftedBreakoutCondition(params.bars, period);
|
|
8994
|
+
signal = condition.map((active) => active ? 1 : 0);
|
|
8995
|
+
positions = condition.map((active) => active ? 1 : 0);
|
|
8996
|
+
} else if (kind === "zscore_mean_reversion") {
|
|
8997
|
+
const period = Math.max(2, Math.trunc(numberParam(ruleParams, "period", 20)));
|
|
8998
|
+
const entry = Math.abs(numberParam(ruleParams, "entry", 2));
|
|
8999
|
+
const exit = Math.abs(numberParam(ruleParams, "exit", 0.25));
|
|
9000
|
+
signal = rollingZScore(prices, period);
|
|
9001
|
+
let active = false;
|
|
9002
|
+
positions = signal.map((value) => {
|
|
9003
|
+
if (value == null) return 0;
|
|
9004
|
+
if (value <= -entry) active = true;
|
|
9005
|
+
if (Math.abs(value) <= exit || value >= entry) active = false;
|
|
9006
|
+
return active ? 1 : 0;
|
|
9007
|
+
});
|
|
9008
|
+
condition = signal.map((value) => value != null && value <= -entry);
|
|
9009
|
+
} else if (kind === "momentum") {
|
|
9010
|
+
const lookbackBars = Math.max(1, Math.trunc(numberParam(ruleParams, "lookbackBars", 30)));
|
|
9011
|
+
const threshold = numberParam(ruleParams, "threshold", 0);
|
|
9012
|
+
signal = momentum(prices, lookbackBars);
|
|
9013
|
+
condition = signal.map((value) => value != null && value > threshold);
|
|
9014
|
+
positions = condition.map((active) => active ? 1 : 0);
|
|
9015
|
+
} else if (kind === "funding_carry") {
|
|
9016
|
+
const threshold = numberParam(ruleParams, "maxFundingRate", 0);
|
|
9017
|
+
signal = fundingRates(params.bars);
|
|
9018
|
+
condition = signal.map((value) => value != null && value <= threshold);
|
|
9019
|
+
positions = condition.map((active) => active ? 1 : 0);
|
|
9020
|
+
} else {
|
|
9021
|
+
warnings.push(`Rule kind ${kind} is not supported by the V1 evaluator; using signal-only flat positions.`);
|
|
9022
|
+
condition = prices.map(() => false);
|
|
9023
|
+
positions = prices.map(() => 0);
|
|
9024
|
+
signal = prices.map(() => null);
|
|
9025
|
+
}
|
|
9026
|
+
return { condition, positions, signal, warnings };
|
|
9027
|
+
}
|
|
9028
|
+
|
|
9029
|
+
// src/quant/strategies/zscore-mean-reversion.ts
|
|
9030
|
+
var ZSCORE_MEAN_REVERSION_RULE_KIND = "zscore_mean_reversion";
|
|
9031
|
+
|
|
9032
|
+
// src/quant/tester/plan.ts
|
|
9033
|
+
function buildQuantTestPlan(idea) {
|
|
9034
|
+
const capability = resolveQuantFamilyCapability(idea.family);
|
|
9035
|
+
if (!capability) {
|
|
9036
|
+
return {
|
|
9037
|
+
supportedTestKinds: ["prompt_plan_check", "data_availability"],
|
|
9038
|
+
supportLevel: "unsupported_until_data",
|
|
9039
|
+
warnings: [`No V1 quant capability found for family ${idea.family}.`]
|
|
9040
|
+
};
|
|
9041
|
+
}
|
|
9042
|
+
return {
|
|
9043
|
+
supportedTestKinds: capability.supportedTestKinds,
|
|
9044
|
+
supportLevel: capability.supportLevel,
|
|
9045
|
+
warnings: capability.supportLevel === "advanced_research" || capability.supportLevel === "unsupported_until_data" ? [`Family ${idea.family} is ${capability.supportLevel}; do not mark it strict-backtest-ready.`] : []
|
|
9046
|
+
};
|
|
9047
|
+
}
|
|
9048
|
+
|
|
9049
|
+
// src/quant/tester/report.ts
|
|
9050
|
+
function finalizeQuantTesterReport(report) {
|
|
9051
|
+
return quantTesterReportV1Schema.parse(report);
|
|
9052
|
+
}
|
|
9053
|
+
|
|
9054
|
+
// src/quant/tester/warnings.ts
|
|
9055
|
+
function quantDataWarnings(params) {
|
|
9056
|
+
const warnings = [];
|
|
9057
|
+
if (params.bars.length < 50) {
|
|
9058
|
+
warnings.push("Sample has fewer than 50 bars; treat metrics as unstable.");
|
|
9059
|
+
}
|
|
9060
|
+
if (params.bars.length > 1) {
|
|
9061
|
+
const gaps = [];
|
|
9062
|
+
for (let index = 1; index < params.bars.length; index += 1) {
|
|
9063
|
+
gaps.push(params.bars[index].time - params.bars[index - 1].time);
|
|
9064
|
+
}
|
|
9065
|
+
const medianGap = gaps.slice().sort((a, b) => a - b)[Math.floor(gaps.length / 2)];
|
|
9066
|
+
if (gaps.some((gap) => gap > medianGap * 2)) {
|
|
9067
|
+
warnings.push("Bars contain time gaps larger than twice the median interval.");
|
|
9068
|
+
}
|
|
9069
|
+
}
|
|
9070
|
+
if (params.request.variantSpace && Object.keys(params.request.variantSpace).length > 20) {
|
|
9071
|
+
warnings.push("Variant space is broad; use multiple-comparison controls before promotion.");
|
|
9072
|
+
}
|
|
9073
|
+
return warnings;
|
|
9074
|
+
}
|
|
9075
|
+
function quantCostBps(request) {
|
|
9076
|
+
return (request.assumptions.takerFeeBps ?? request.assumptions.makerFeeBps ?? 0) + (request.assumptions.slippageBps ?? 0);
|
|
9077
|
+
}
|
|
9078
|
+
|
|
9079
|
+
// src/quant/tester/run-idea-test.ts
|
|
9080
|
+
function symbolForRequest(request) {
|
|
9081
|
+
return request.idea.market.symbol ?? request.idea.market.universe?.[0] ?? "UNKNOWN";
|
|
9082
|
+
}
|
|
9083
|
+
function actionForPosition(target) {
|
|
9084
|
+
if (target > 0) return "long";
|
|
9085
|
+
if (target < 0) return "short";
|
|
9086
|
+
return "flat";
|
|
9087
|
+
}
|
|
9088
|
+
function simulate(params) {
|
|
9089
|
+
const prices = closePrices(params.bars);
|
|
9090
|
+
const initialEquity = params.request.assumptions.initialEquityUsd ?? 1e4;
|
|
9091
|
+
const symbol = symbolForRequest(params.request);
|
|
9092
|
+
let equity = initialEquity;
|
|
9093
|
+
let peak = initialEquity;
|
|
9094
|
+
let maxDrawdown = 0;
|
|
9095
|
+
let previousPosition = 0;
|
|
9096
|
+
let turnover = 0;
|
|
9097
|
+
let trades = 0;
|
|
9098
|
+
const decisions = [];
|
|
9099
|
+
for (let index = 0; index < params.bars.length; index += 1) {
|
|
9100
|
+
const targetPosition = params.positions[index] ?? 0;
|
|
9101
|
+
const deltaPosition = Math.abs(targetPosition - previousPosition);
|
|
9102
|
+
if (deltaPosition > 0) {
|
|
9103
|
+
turnover += deltaPosition;
|
|
9104
|
+
trades += 1;
|
|
9105
|
+
equity -= equity * deltaPosition * (params.costBps / 1e4);
|
|
9106
|
+
}
|
|
9107
|
+
if (index > 0) {
|
|
9108
|
+
const priceReturn = prices[index - 1] === 0 ? 0 : prices[index] / prices[index - 1] - 1;
|
|
9109
|
+
equity *= 1 + previousPosition * priceReturn;
|
|
9110
|
+
}
|
|
9111
|
+
peak = Math.max(peak, equity);
|
|
9112
|
+
maxDrawdown = Math.max(maxDrawdown, peak === 0 ? 0 : (peak - equity) / peak);
|
|
9113
|
+
decisions.push({
|
|
9114
|
+
time: params.bars[index].time,
|
|
9115
|
+
symbol,
|
|
9116
|
+
action: actionForPosition(targetPosition),
|
|
9117
|
+
targetPosition,
|
|
9118
|
+
reason: targetPosition === previousPosition ? "rule maintained target position" : "rule changed target position",
|
|
9119
|
+
price: params.bars[index].close
|
|
9120
|
+
});
|
|
9121
|
+
previousPosition = targetPosition;
|
|
9122
|
+
}
|
|
9123
|
+
return {
|
|
9124
|
+
decisions: compactDecisionChanges(decisions),
|
|
9125
|
+
metrics: {
|
|
9126
|
+
endingEquityUsd: equity,
|
|
9127
|
+
maxDrawdownPct: maxDrawdown * 100,
|
|
9128
|
+
netReturnPct: (equity / initialEquity - 1) * 100,
|
|
9129
|
+
turnover,
|
|
9130
|
+
trades
|
|
9131
|
+
}
|
|
9132
|
+
};
|
|
9133
|
+
}
|
|
9134
|
+
function runQuantIdeaTest(params) {
|
|
9135
|
+
const request = quantTestRequestV1Schema.parse(params.request);
|
|
9136
|
+
const bars = normalizeQuantBars(params.bars);
|
|
9137
|
+
const plan = buildQuantTestPlan(request.idea);
|
|
9138
|
+
const warnings = [...plan.warnings, ...quantDataWarnings({ bars, request })];
|
|
9139
|
+
const supported = plan.supportedTestKinds.includes("idea_rule_simulation");
|
|
9140
|
+
if (!supported) {
|
|
9141
|
+
return finalizeQuantTesterReport({
|
|
9142
|
+
ok: false,
|
|
9143
|
+
testRunKind: "idea_rule_simulation",
|
|
9144
|
+
supported: false,
|
|
9145
|
+
unsupportedReason: `Family ${request.idea.family} does not support deterministic idea simulation in V1.`,
|
|
9146
|
+
summary: "Idea simulation is not supported for this family.",
|
|
9147
|
+
dataLineage: buildQuantDataLineage({ request, warnings }),
|
|
9148
|
+
warnings
|
|
9149
|
+
});
|
|
9150
|
+
}
|
|
9151
|
+
const evaluated = evaluateQuantRule({ bars, idea: request.idea });
|
|
9152
|
+
warnings.push(...evaluated.warnings);
|
|
9153
|
+
const simulation = simulate({
|
|
9154
|
+
bars,
|
|
9155
|
+
costBps: quantCostBps(request),
|
|
9156
|
+
positions: evaluated.positions,
|
|
9157
|
+
request
|
|
9158
|
+
});
|
|
9159
|
+
const decisionArtifact = validateDecisionArtifact({
|
|
9160
|
+
version: "1",
|
|
9161
|
+
family: request.idea.family,
|
|
9162
|
+
symbol: symbolForRequest(request),
|
|
9163
|
+
resolution: request.window.resolution,
|
|
9164
|
+
decisions: simulation.decisions,
|
|
9165
|
+
warnings
|
|
9166
|
+
});
|
|
9167
|
+
return finalizeQuantTesterReport({
|
|
9168
|
+
ok: true,
|
|
9169
|
+
testRunKind: "idea_rule_simulation",
|
|
9170
|
+
supported: true,
|
|
9171
|
+
summary: `Idea simulation completed: net return ${simulation.metrics.netReturnPct.toFixed(2)}%, trades ${simulation.metrics.trades}.`,
|
|
9172
|
+
dataLineage: buildQuantDataLineage({ request, warnings }),
|
|
9173
|
+
ideaSimulation: simulation.metrics,
|
|
9174
|
+
decisionArtifact,
|
|
9175
|
+
warnings
|
|
9176
|
+
});
|
|
9177
|
+
}
|
|
9178
|
+
|
|
9179
|
+
// src/quant/tester/run-signal-study.ts
|
|
9180
|
+
function horizonBars(request) {
|
|
9181
|
+
const value = request.idea.rule?.params.horizonBars;
|
|
9182
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : 1;
|
|
9183
|
+
}
|
|
9184
|
+
function runSignalStudy(params) {
|
|
9185
|
+
const request = quantTestRequestV1Schema.parse(params.request);
|
|
9186
|
+
const bars = normalizeQuantBars(params.bars);
|
|
9187
|
+
const plan = buildQuantTestPlan(request.idea);
|
|
9188
|
+
const warnings = [...plan.warnings, ...quantDataWarnings({ bars, request })];
|
|
9189
|
+
const supported = plan.supportedTestKinds.includes("signal_study");
|
|
9190
|
+
if (!supported) {
|
|
9191
|
+
return finalizeQuantTesterReport({
|
|
9192
|
+
ok: false,
|
|
9193
|
+
testRunKind: "signal_study",
|
|
9194
|
+
supported: false,
|
|
9195
|
+
unsupportedReason: `Family ${request.idea.family} does not support signal studies in V1.`,
|
|
9196
|
+
summary: "Signal study is not supported for this family.",
|
|
9197
|
+
dataLineage: buildQuantDataLineage({ request, warnings }),
|
|
9198
|
+
warnings
|
|
9199
|
+
});
|
|
9200
|
+
}
|
|
9201
|
+
const evaluated = evaluateQuantRule({ bars, idea: request.idea });
|
|
9202
|
+
warnings.push(...evaluated.warnings);
|
|
9203
|
+
const prices = closePrices(bars);
|
|
9204
|
+
const horizon = horizonBars(request);
|
|
9205
|
+
const study = studyForwardReturns({
|
|
9206
|
+
condition: evaluated.condition,
|
|
9207
|
+
horizonBars: horizon,
|
|
9208
|
+
prices
|
|
9209
|
+
});
|
|
9210
|
+
const forward = forwardReturns(prices, horizon);
|
|
9211
|
+
const excursions = summarizeExcursions({
|
|
9212
|
+
bars,
|
|
9213
|
+
condition: evaluated.condition,
|
|
9214
|
+
horizonBars: horizon
|
|
9215
|
+
});
|
|
9216
|
+
const ic = informationCoefficient({
|
|
9217
|
+
forwardReturns: forward,
|
|
9218
|
+
signal: evaluated.signal
|
|
9219
|
+
});
|
|
9220
|
+
const summary = signalStudySummary({
|
|
9221
|
+
conditionedCount: study.conditioned.count,
|
|
9222
|
+
conditionedMean: study.conditioned.mean,
|
|
9223
|
+
unconditionalMean: study.unconditional.mean
|
|
9224
|
+
});
|
|
9225
|
+
return finalizeQuantTesterReport({
|
|
9226
|
+
ok: true,
|
|
9227
|
+
testRunKind: "signal_study",
|
|
9228
|
+
supported: true,
|
|
9229
|
+
summary,
|
|
9230
|
+
dataLineage: buildQuantDataLineage({ request, warnings }),
|
|
9231
|
+
signalStudy: {
|
|
9232
|
+
forwardReturns: study,
|
|
9233
|
+
informationCoefficient: ic,
|
|
9234
|
+
excursions,
|
|
9235
|
+
signalEventCount: evaluated.condition.filter(Boolean).length
|
|
9236
|
+
},
|
|
9237
|
+
warnings
|
|
9238
|
+
});
|
|
9239
|
+
}
|
|
9240
|
+
|
|
9241
|
+
// src/quant/timeframes.ts
|
|
9242
|
+
var QUANT_RESOLUTION_SECONDS = {
|
|
9243
|
+
"1": 60,
|
|
9244
|
+
"5": 300,
|
|
9245
|
+
"15": 900,
|
|
9246
|
+
"30": 1800,
|
|
9247
|
+
"60": 3600,
|
|
9248
|
+
"240": 14400,
|
|
9249
|
+
"1D": 86400,
|
|
9250
|
+
"1W": 604800
|
|
9251
|
+
};
|
|
9252
|
+
function quantResolutionToSeconds(resolution) {
|
|
9253
|
+
return QUANT_RESOLUTION_SECONDS[resolution];
|
|
9254
|
+
}
|
|
9255
|
+
function parseQuantTimeToSeconds(value) {
|
|
9256
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
9257
|
+
return Math.max(0, Math.trunc(value));
|
|
9258
|
+
}
|
|
9259
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
9260
|
+
const trimmed = value.trim();
|
|
9261
|
+
if (/^-?(?:\d+\.?\d*|\.\d+)$/.test(trimmed)) {
|
|
9262
|
+
return Math.max(0, Math.trunc(Number.parseFloat(trimmed)));
|
|
9263
|
+
}
|
|
9264
|
+
const parsed = new Date(trimmed);
|
|
9265
|
+
if (!Number.isNaN(parsed.getTime())) {
|
|
9266
|
+
return Math.max(0, Math.trunc(parsed.getTime() / 1e3));
|
|
9267
|
+
}
|
|
9268
|
+
}
|
|
9269
|
+
return null;
|
|
9270
|
+
}
|
|
9271
|
+
function assertQuantWindow(params) {
|
|
9272
|
+
const startSeconds = parseQuantTimeToSeconds(params.timeframeStart);
|
|
9273
|
+
const endSeconds = parseQuantTimeToSeconds(params.timeframeEnd);
|
|
9274
|
+
if (startSeconds == null || endSeconds == null) {
|
|
9275
|
+
throw new Error("Quant test window must use parseable start and end times");
|
|
9276
|
+
}
|
|
9277
|
+
if (endSeconds <= startSeconds) {
|
|
9278
|
+
throw new Error("Quant test window end must be after start");
|
|
9279
|
+
}
|
|
9280
|
+
return { endSeconds, startSeconds };
|
|
9281
|
+
}
|
|
7983
9282
|
function createMcpAdapter(options) {
|
|
7984
9283
|
const normalizedSchema = ensureSchema(options.schema);
|
|
7985
9284
|
const defaultMethod = resolveDefaultMethod(options);
|
|
@@ -8092,6 +9391,6 @@ async function responseToToolResponse(response) {
|
|
|
8092
9391
|
};
|
|
8093
9392
|
}
|
|
8094
9393
|
|
|
8095
|
-
export { AIAbortError, AIError, AIFetchError, AIResponseError, BACKTEST_DECISION_MODE, DEFAULT_BASE_URL, DEFAULT_CHAIN, DEFAULT_FACILITATOR, DEFAULT_HYPERLIQUID_CADENCE_CRON, DEFAULT_HYPERLIQUID_MARKET_SLIPPAGE_BPS, DEFAULT_HYPERLIQUID_TPSL_MARKET_SLIPPAGE_BPS, DEFAULT_MODEL, DEFAULT_OPENPOND_GATEWAY_URL2 as DEFAULT_OPENPOND_GATEWAY_URL, DEFAULT_TIMEOUT_MS, DEFAULT_TOKENS, HTTP_METHODS, HYPERLIQUID_HIP3_DEXES, HyperliquidApiError, HyperliquidBuilderApprovalError, HyperliquidExchangeClient, HyperliquidGuardError, HyperliquidInfoClient, HyperliquidTermsError, NewsSignalClient, PAYMENT_HEADERS, POLYMARKET_CHAIN_ID, POLYMARKET_CLOB_AUTH_DOMAIN, POLYMARKET_CLOB_DOMAIN, POLYMARKET_ENDPOINTS, POLYMARKET_EXCHANGE_ADDRESSES, PolymarketApiError, PolymarketAuthError, PolymarketExchangeClient, PolymarketInfoClient, SUPPORTED_CURRENCIES, StoreError, WEBSEARCH_TOOL_DEFINITION, WEBSEARCH_TOOL_NAME, X402BrowserClient, X402Client, X402PaymentRequiredError, __hyperliquidInternals, __hyperliquidMarketDataInternals, approveHyperliquidBuilderFee, backtestDecisionRequestSchema, batchModifyHyperliquidOrders, buildBacktestDecisionSeriesInput, buildHmacSignature, buildHyperliquidMarketDescriptor, buildHyperliquidMarketIdentity, buildHyperliquidProfileAssets, buildHyperliquidSpotUsdPriceMap, buildL1Headers, buildL2Headers, buildPolymarketApprovalTransactions, buildPolymarketOrderAmounts, buildPolymarketOutcomeTokenApprovalTransactions, buildPolymarketUsdcApprovalTransaction, buildSignedOrderPayload, cancelAllHyperliquidOrders, cancelAllPolymarketOrders, cancelHyperliquidOrders, cancelHyperliquidOrdersByCloid, cancelHyperliquidTwapOrder, cancelMarketPolymarketOrders, cancelPolymarketOrder, cancelPolymarketOrders, chains, clampHyperliquidAbs, clampHyperliquidFloat, clampHyperliquidInt, computeHyperliquidMarketIocLimitPrice, createAIClient, createHyperliquidSubAccount, createMcpAdapter, createMonotonicNonceFactory, createOrDerivePolymarketApiKey, createPolymarketApiKey, decodePolymarketBootstrapTransaction, defineX402Payment, depositToHyperliquidBridge, derivePolymarketApiKey, ensureTextContent, estimateCountBack, estimateHyperliquidLiquidationPrice, evaluateNewsContinuationGate, executeTool, extractHyperliquidDex, extractHyperliquidOrderIds, fetchHyperliquidActiveAsset, fetchHyperliquidAllMids, fetchHyperliquidAssetCtxs, fetchHyperliquidBars, fetchHyperliquidClearinghouseState, fetchHyperliquidDexMeta, fetchHyperliquidDexMetaAndAssetCtxs, fetchHyperliquidFrontendOpenOrders, fetchHyperliquidFrontendOpenOrdersAcrossDexes, fetchHyperliquidHistoricalOrders, fetchHyperliquidMeta, fetchHyperliquidMetaAndAssetCtxs, fetchHyperliquidOpenOrders, fetchHyperliquidOpenOrdersAcrossDexes, fetchHyperliquidOrderStatus, fetchHyperliquidOutcomeMeta, fetchHyperliquidPerpMarketInfo, fetchHyperliquidPreTransferCheck, fetchHyperliquidResolvedInfoCoin, fetchHyperliquidResolvedMarketDescriptor, fetchHyperliquidSizeDecimals, fetchHyperliquidSpotAccountValue, fetchHyperliquidSpotAssetCtxs, fetchHyperliquidSpotClearinghouseState, fetchHyperliquidSpotMarketInfo, fetchHyperliquidSpotMeta, fetchHyperliquidSpotMetaAndAssetCtxs, fetchHyperliquidSpotTickSize, fetchHyperliquidSpotUsdPriceMap, fetchHyperliquidTickSize, fetchHyperliquidUserFills, fetchHyperliquidUserFillsByTime, fetchHyperliquidUserRateLimit, fetchNewsEventSignal, fetchNewsPropositionSignal, fetchPolymarketActivity, fetchPolymarketApprovalState, fetchPolymarketClosedPositions, fetchPolymarketDepositAddresses, fetchPolymarketMarket, fetchPolymarketMarkets, fetchPolymarketMidpoint, fetchPolymarketOrderbook, fetchPolymarketPositionValue, fetchPolymarketPositions, fetchPolymarketPrice, fetchPolymarketPriceHistory, fetchPolymarketPublicProfile, flattenMessageContent, formatHyperliquidMarketablePrice, formatHyperliquidOrderSize, formatHyperliquidPrice, formatHyperliquidSize, generateText, getHyperliquidMaxBuilderFee, getKnownHyperliquidDexes, getModelConfig, getMyPerformance, getMyTools, getRpcUrl, getX402PaymentContext, isHyperliquidSpotSymbol, isStreamingSupported, isToolCallingSupported, listModels, modifyHyperliquidOrder, normalizeHyperliquidBaseSymbol, normalizeHyperliquidDcaEntries, normalizeHyperliquidIndicatorBars, normalizeHyperliquidMetaSymbol, normalizeModelName, normalizeNumberArrayish, normalizeSpotTokenName2 as normalizeSpotTokenName, normalizeStringArrayish, parseHyperliquidJson, parseHyperliquidOutcomeSymbol, parseHyperliquidSymbol, parseSpotPairSymbol, parseTimeToSeconds, payX402, payX402WithWallet, placeHyperliquidOrder2 as placeHyperliquidOrder, placeHyperliquidOrderWithTpSl, placeHyperliquidPositionTpSl, placeHyperliquidTwapOrder, placePolymarketOrder, planHyperliquidTrade, postAgentDigest, readHyperliquidAccountValue, readHyperliquidNumber, readHyperliquidPerpPosition, readHyperliquidPerpPositionSize, readHyperliquidSpotAccountValue, readHyperliquidSpotBalance, readHyperliquidSpotBalanceSize, recordHyperliquidBuilderApproval, recordHyperliquidTermsAcceptance, registry, requireX402Payment, reserveHyperliquidRequestWeight, resolutionToSeconds, resolveBacktestAccountValueUsd, resolveBacktestMode, resolveBacktestWindow, resolveConfig2 as resolveConfig, resolveExchangeAddress, resolveHyperliquidAbstractionFromMode, resolveHyperliquidBudgetUsd, resolveHyperliquidCadenceCron, resolveHyperliquidCadenceFromResolution, resolveHyperliquidChain, resolveHyperliquidChainConfig, resolveHyperliquidDcaSymbolEntries, resolveHyperliquidErrorDetail, resolveHyperliquidHourlyInterval, resolveHyperliquidIntervalCron, resolveHyperliquidLeverageMode, resolveHyperliquidMarketDataCoin, resolveHyperliquidMaxPerRunUsd, resolveHyperliquidOrderRef, resolveHyperliquidOrderSymbol, resolveHyperliquidPair, resolveHyperliquidPerpSymbol, resolveHyperliquidProfileChain, resolveHyperliquidRpcEnvVar, resolveHyperliquidScheduleEvery, resolveHyperliquidScheduleUnit, resolveHyperliquidSpotSymbol, resolveHyperliquidStoreNetwork, resolveHyperliquidSymbol, resolveHyperliquidTargetSize, resolveNewsGatewayBase, resolvePolymarketBaseUrl, resolvePolymarketBootstrapContracts, resolveSpotMidCandidates, resolveSpotTokenCandidates, resolveToolset, responseToToolResponse, retrieve, roundHyperliquidPriceToTick, scheduleHyperliquidCancel, sendHyperliquidSpot, setHyperliquidAccountAbstractionMode, setHyperliquidPortfolioMargin, store, streamText, supportsHyperliquidBuilderFee, tokens, transferHyperliquidSubAccount, updateHyperliquidIsolatedMargin, updateHyperliquidLeverage, wallet, walletToolkit, withX402Payment, withdrawFromHyperliquid };
|
|
9394
|
+
export { AIAbortError, AIError, AIFetchError, AIResponseError, BACKTEST_DECISION_MODE, DEFAULT_BASE_URL, DEFAULT_CHAIN, DEFAULT_FACILITATOR, DEFAULT_HYPERLIQUID_CADENCE_CRON, DEFAULT_HYPERLIQUID_MARKET_SLIPPAGE_BPS, DEFAULT_HYPERLIQUID_TPSL_MARKET_SLIPPAGE_BPS, DEFAULT_MODEL, DEFAULT_OPENPOND_GATEWAY_URL2 as DEFAULT_OPENPOND_GATEWAY_URL, DEFAULT_TIMEOUT_MS, DEFAULT_TOKENS, DONCHIAN_BREAKOUT_RULE_KIND, FUNDING_CARRY_RULE_KIND, HTTP_METHODS, HYPERLIQUID_HIP3_DEXES, HyperliquidApiError, HyperliquidBuilderApprovalError, HyperliquidExchangeClient, HyperliquidGuardError, HyperliquidInfoClient, HyperliquidTermsError, MACD_CROSSOVER_RULE_KIND, MA_CROSS_RULE_KIND, MOMENTUM_RULE_KIND, MPP_DEFAULT_TEMPO_CURRENCY, MPP_TEMPO_MAINNET_CHAIN_ID, MPP_TEMPO_PATHUSD_ADDRESS, MPP_TEMPO_USDCE_ADDRESS, NewsSignalClient, PAYMENT_HEADERS, POLYMARKET_CHAIN_ID, POLYMARKET_CLOB_AUTH_DOMAIN, POLYMARKET_CLOB_DOMAIN, POLYMARKET_ENDPOINTS, POLYMARKET_EXCHANGE_ADDRESSES, PolymarketApiError, PolymarketAuthError, PolymarketExchangeClient, PolymarketInfoClient, QUANT_FAMILY_CAPABILITIES, QUANT_RESOLUTION_SECONDS, RSI_MEAN_REVERSION_RULE_KIND, SUPPORTED_CURRENCIES, StoreError, WEBSEARCH_TOOL_DEFINITION, WEBSEARCH_TOOL_NAME, X402BrowserClient, X402Client, X402PaymentRequiredError, ZSCORE_MEAN_REVERSION_RULE_KIND, __hyperliquidInternals, __hyperliquidMarketDataInternals, approveHyperliquidBuilderFee, assertQuantWindow, atr, backtestDecisionRequestSchema, batchModifyHyperliquidOrders, beta, bollinger, buildBacktestDecisionSeriesInput, buildEventWindows, buildHmacSignature, buildHyperliquidMarketDescriptor, buildHyperliquidMarketIdentity, buildHyperliquidOutcomeMarketIdentity, buildHyperliquidProfileAssets, buildHyperliquidSpotUsdPriceMap, buildL1Headers, buildL2Headers, buildPolymarketApprovalTransactions, buildPolymarketOrderAmounts, buildPolymarketOutcomeTokenApprovalTransactions, buildPolymarketUsdcApprovalTransaction, buildQuantDataLineage, buildQuantTestPlan, buildSignedOrderPayload, cancelAllHyperliquidOrders, cancelAllPolymarketOrders, cancelHyperliquidOrders, cancelHyperliquidOrdersByCloid, cancelHyperliquidTwapOrder, cancelMarketPolymarketOrders, cancelPolymarketOrder, cancelPolymarketOrders, chains, clampHyperliquidAbs, clampHyperliquidFloat, clampHyperliquidInt, closePrices, compactDecisionChanges, computeHyperliquidMarketIocLimitPrice, correlation, createAIClient, createHyperliquidSubAccount, createMcpAdapter, createMonotonicNonceFactory, createMppClient, createMppCredential, createMppFetch, createOrDerivePolymarketApiKey, createPolymarketApiKey, cumulativeFunding, decodePolymarketBootstrapTransaction, defineX402Payment, depositToHyperliquidBridge, derivePolymarketApiKey, donchian, ema, ensureTextContent, estimateCountBack, estimateHyperliquidLiquidationPrice, evaluateNewsContinuationGate, evaluateQuantRule, executeTool, extractHyperliquidDex, extractHyperliquidOrderIds, fetchHyperliquidActiveAsset, fetchHyperliquidAllMids, fetchHyperliquidAssetCtxs, fetchHyperliquidBars, fetchHyperliquidClearinghouseState, fetchHyperliquidDexMeta, fetchHyperliquidDexMetaAndAssetCtxs, fetchHyperliquidFrontendOpenOrders, fetchHyperliquidFrontendOpenOrdersAcrossDexes, fetchHyperliquidHistoricalOrders, fetchHyperliquidMeta, fetchHyperliquidMetaAndAssetCtxs, fetchHyperliquidOpenOrders, fetchHyperliquidOpenOrdersAcrossDexes, fetchHyperliquidOrderStatus, fetchHyperliquidOutcomeMeta, fetchHyperliquidPerpMarketInfo, fetchHyperliquidPreTransferCheck, fetchHyperliquidResolvedInfoCoin, fetchHyperliquidResolvedMarketDescriptor, fetchHyperliquidSizeDecimals, fetchHyperliquidSpotAccountValue, fetchHyperliquidSpotAssetCtxs, fetchHyperliquidSpotClearinghouseState, fetchHyperliquidSpotMarketInfo, fetchHyperliquidSpotMeta, fetchHyperliquidSpotMetaAndAssetCtxs, fetchHyperliquidSpotTickSize, fetchHyperliquidSpotUsdPriceMap, fetchHyperliquidTickSize, fetchHyperliquidUserFills, fetchHyperliquidUserFillsByTime, fetchHyperliquidUserRateLimit, fetchNewsEventSignal, fetchNewsPropositionSignal, fetchPolymarketActivity, fetchPolymarketApprovalState, fetchPolymarketClosedPositions, fetchPolymarketDepositAddresses, fetchPolymarketMarket, fetchPolymarketMarkets, fetchPolymarketMidpoint, fetchPolymarketOrderbook, fetchPolymarketPositionValue, fetchPolymarketPositions, fetchPolymarketPrice, fetchPolymarketPriceHistory, fetchPolymarketPublicProfile, fetchWithMpp, finalizeQuantTesterReport, flattenMessageContent, formatHyperliquidMarketablePrice, formatHyperliquidOrderSize, formatHyperliquidPrice, formatHyperliquidSize, forwardReturns, fundingRates, generateText, getHyperliquidMaxBuilderFee, getKnownHyperliquidDexes, getModelConfig, getMyPerformance, getMyTools, getRpcUrl, getX402PaymentContext, hitRate, informationCoefficient, isHyperliquidSpotSymbol, isStreamingSupported, isToolCallingSupported, listModels, logReturns, macd, modifyHyperliquidOrder, momentum, normalizeHyperliquidBaseSymbol, normalizeHyperliquidDcaEntries, normalizeHyperliquidIndicatorBars, normalizeHyperliquidMetaSymbol, normalizeModelName, normalizeNumberArrayish, normalizeQuantBars, normalizeSpotTokenName2 as normalizeSpotTokenName, normalizeStringArrayish, parseHyperliquidJson, parseHyperliquidOutcomeSymbol, parseHyperliquidSymbol, parseQuantTimeToSeconds, parseSpotPairSymbol, parseTimeToSeconds, payX402, payX402WithWallet, placeHyperliquidOrder2 as placeHyperliquidOrder, placeHyperliquidOrderWithTpSl, placeHyperliquidPositionTpSl, placeHyperliquidTwapOrder, placePolymarketOrder, planHyperliquidTrade, postAgentDigest, quantBarSchema, quantCostBps, quantDataWarnings, quantDecisionActionSchema, quantDecisionArtifactV1Schema, quantDecisionSchema, quantFeatureSpecSchema, quantIdeaSpecV1Schema, quantResolutionSchema, quantResolutionToSeconds, quantRuleSpecSchema, quantStrategyFamilySchema, quantTestKindSchema, quantTestRequestV1Schema, quantTesterReportV1Schema, readHyperliquidAccountValue, readHyperliquidNumber, readHyperliquidPerpPosition, readHyperliquidPerpPositionSize, readHyperliquidSpotAccountValue, readHyperliquidSpotBalance, readHyperliquidSpotBalanceSize, readMppReceipt, recordHyperliquidBuilderApproval, recordHyperliquidTermsAcceptance, registry, relativeStrength, relativeVolume, requireX402Payment, reserveHyperliquidRequestWeight, resolutionToSeconds, resolveBacktestAccountValueUsd, resolveBacktestMode, resolveBacktestWindow, resolveConfig2 as resolveConfig, resolveExchangeAddress, resolveHyperliquidAbstractionFromMode, resolveHyperliquidBudgetUsd, resolveHyperliquidCadenceCron, resolveHyperliquidCadenceFromResolution, resolveHyperliquidChain, resolveHyperliquidChainConfig, resolveHyperliquidDcaSymbolEntries, resolveHyperliquidErrorDetail, resolveHyperliquidHourlyInterval, resolveHyperliquidIntervalCron, resolveHyperliquidLeverageMode, resolveHyperliquidMarketDataCoin, resolveHyperliquidMaxPerRunUsd, resolveHyperliquidOrderRef, resolveHyperliquidOrderSymbol, resolveHyperliquidPair, resolveHyperliquidPerpSymbol, resolveHyperliquidProfileChain, resolveHyperliquidRpcEnvVar, resolveHyperliquidScheduleEvery, resolveHyperliquidScheduleUnit, resolveHyperliquidSpotSymbol, resolveHyperliquidStoreNetwork, resolveHyperliquidSymbol, resolveHyperliquidTargetSize, resolveNewsGatewayBase, resolvePolymarketBaseUrl, resolvePolymarketBootstrapContracts, resolveQuantFamilyCapability, resolveSpotMidCandidates, resolveSpotTokenCandidates, resolveToolset, responseToToolResponse, retrieve, rollingCorrelation, rollingVolatility, rollingZScore, roundHyperliquidPriceToTick, rsi, runQuantIdeaTest, runSignalStudy, scheduleHyperliquidCancel, sendHyperliquidSpot, setHyperliquidAccountAbstractionMode, setHyperliquidPortfolioMargin, signalStudySummary, simpleReturns, sliceBarsToWindow, sma, store, streamText, studyForwardReturns, summarizeExcursions, summarizeNumbers, supportsHyperliquidBuilderFee, tokens, transferHyperliquidSubAccount, trueRanges, typicalPrices, updateHyperliquidIsolatedMargin, updateHyperliquidLeverage, validateDecisionArtifact, volumes, wallet, walletToolkit, withX402Payment, withdrawFromHyperliquid };
|
|
8096
9395
|
//# sourceMappingURL=index.js.map
|
|
8097
9396
|
//# sourceMappingURL=index.js.map
|