@vantagestack/mcp-server 0.1.56 → 0.1.59
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/package.json +1 -1
- package/dist/client.d.ts +0 -25
- package/dist/client.js +0 -172
- package/dist/client.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -1319
- package/dist/index.js.map +0 -1
- package/dist/tools/account-deletion.d.ts +0 -6
- package/dist/tools/account-deletion.js +0 -92
- package/dist/tools/account-deletion.js.map +0 -1
- package/dist/tools/account-health.d.ts +0 -21
- package/dist/tools/account-health.js +0 -84
- package/dist/tools/account-health.js.map +0 -1
- package/dist/tools/account.d.ts +0 -19
- package/dist/tools/account.js +0 -291
- package/dist/tools/account.js.map +0 -1
- package/dist/tools/account.test.d.ts +0 -1
- package/dist/tools/account.test.js +0 -213
- package/dist/tools/account.test.js.map +0 -1
- package/dist/tools/calendar.d.ts +0 -4
- package/dist/tools/calendar.js +0 -85
- package/dist/tools/calendar.js.map +0 -1
- package/dist/tools/calendar.test.d.ts +0 -1
- package/dist/tools/calendar.test.js +0 -62
- package/dist/tools/calendar.test.js.map +0 -1
- package/dist/tools/canary.d.ts +0 -4
- package/dist/tools/canary.js +0 -25
- package/dist/tools/canary.js.map +0 -1
- package/dist/tools/canary.test.d.ts +0 -1
- package/dist/tools/canary.test.js +0 -46
- package/dist/tools/canary.test.js.map +0 -1
- package/dist/tools/contract-configs.d.ts +0 -9
- package/dist/tools/contract-configs.js +0 -187
- package/dist/tools/contract-configs.js.map +0 -1
- package/dist/tools/contract-configs.test.d.ts +0 -1
- package/dist/tools/contract-configs.test.js +0 -245
- package/dist/tools/contract-configs.test.js.map +0 -1
- package/dist/tools/copier.d.ts +0 -11
- package/dist/tools/copier.js +0 -52
- package/dist/tools/copier.js.map +0 -1
- package/dist/tools/copier.test.d.ts +0 -1
- package/dist/tools/copier.test.js +0 -75
- package/dist/tools/copier.test.js.map +0 -1
- package/dist/tools/groups.d.ts +0 -14
- package/dist/tools/groups.js +0 -44
- package/dist/tools/groups.js.map +0 -1
- package/dist/tools/groups.test.d.ts +0 -1
- package/dist/tools/groups.test.js +0 -72
- package/dist/tools/groups.test.js.map +0 -1
- package/dist/tools/ip-allowlist.d.ts +0 -6
- package/dist/tools/ip-allowlist.js +0 -69
- package/dist/tools/ip-allowlist.js.map +0 -1
- package/dist/tools/journal.d.ts +0 -6
- package/dist/tools/journal.js +0 -110
- package/dist/tools/journal.js.map +0 -1
- package/dist/tools/journal.test.d.ts +0 -1
- package/dist/tools/journal.test.js +0 -100
- package/dist/tools/journal.test.js.map +0 -1
- package/dist/tools/latency.d.ts +0 -3
- package/dist/tools/latency.js +0 -54
- package/dist/tools/latency.js.map +0 -1
- package/dist/tools/market-history.d.ts +0 -4
- package/dist/tools/market-history.js +0 -50
- package/dist/tools/market-history.js.map +0 -1
- package/dist/tools/market-hours.d.ts +0 -3
- package/dist/tools/market-hours.js +0 -19
- package/dist/tools/market-hours.js.map +0 -1
- package/dist/tools/paper-trading.d.ts +0 -10
- package/dist/tools/paper-trading.js +0 -200
- package/dist/tools/paper-trading.js.map +0 -1
- package/dist/tools/ping.d.ts +0 -8
- package/dist/tools/ping.js +0 -22
- package/dist/tools/ping.js.map +0 -1
- package/dist/tools/ping.test.d.ts +0 -1
- package/dist/tools/ping.test.js +0 -25
- package/dist/tools/ping.test.js.map +0 -1
- package/dist/tools/qc.d.ts +0 -18
- package/dist/tools/qc.js +0 -422
- package/dist/tools/qc.js.map +0 -1
- package/dist/tools/qc.test.d.ts +0 -1
- package/dist/tools/qc.test.js +0 -218
- package/dist/tools/qc.test.js.map +0 -1
- package/dist/tools/read.d.ts +0 -7
- package/dist/tools/read.js +0 -154
- package/dist/tools/read.js.map +0 -1
- package/dist/tools/read.test.d.ts +0 -1
- package/dist/tools/read.test.js +0 -102
- package/dist/tools/read.test.js.map +0 -1
- package/dist/tools/risk.d.ts +0 -7
- package/dist/tools/risk.js +0 -108
- package/dist/tools/risk.js.map +0 -1
- package/dist/tools/signal-templates.d.ts +0 -6
- package/dist/tools/signal-templates.js +0 -90
- package/dist/tools/signal-templates.js.map +0 -1
- package/dist/tools/signals.d.ts +0 -8
- package/dist/tools/signals.js +0 -318
- package/dist/tools/signals.js.map +0 -1
- package/dist/tools/signals.test.d.ts +0 -1
- package/dist/tools/signals.test.js +0 -92
- package/dist/tools/signals.test.js.map +0 -1
- package/dist/tools/sync-accounts.d.ts +0 -18
- package/dist/tools/sync-accounts.js +0 -68
- package/dist/tools/sync-accounts.js.map +0 -1
- package/dist/tools/trade.d.ts +0 -3
- package/dist/tools/trade.js +0 -49
- package/dist/tools/trade.js.map +0 -1
- package/dist/user.d.ts +0 -19
- package/dist/user.js +0 -21
- package/dist/user.js.map +0 -1
package/dist/tools/groups.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { VantageClient } from "../client.js";
|
|
2
|
-
import { UserResolver, ToolResult } from "../user.js";
|
|
3
|
-
/**
|
|
4
|
-
* GMODE-07 — partial-PATCH a signal group's settings.
|
|
5
|
-
* Wraps `PATCH /api/account/{userId}/groups/{groupId}` with the GMODE rev-4
|
|
6
|
-
* two-column model: `routingMode` is the top-level toggle
|
|
7
|
-
* (`signal` | `copy_trading`), `copyMode` is the CT sub-mode
|
|
8
|
-
* (`executions` | `orders`) and is only meaningful when
|
|
9
|
-
* `routingMode='copy_trading'`. The server enforces enum + cross-field
|
|
10
|
-
* validity (422 on bad value; 422 on `copyMode` change in signal mode) and
|
|
11
|
-
* auto-demotes every `is_copy_source=true` member when `routingMode` flips
|
|
12
|
-
* to `'signal'`.
|
|
13
|
-
*/
|
|
14
|
-
export declare function updateGroup(client: VantageClient, resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
package/dist/tools/groups.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { makeErrorResult } from "../user.js";
|
|
2
|
-
/**
|
|
3
|
-
* GMODE-07 — partial-PATCH a signal group's settings.
|
|
4
|
-
* Wraps `PATCH /api/account/{userId}/groups/{groupId}` with the GMODE rev-4
|
|
5
|
-
* two-column model: `routingMode` is the top-level toggle
|
|
6
|
-
* (`signal` | `copy_trading`), `copyMode` is the CT sub-mode
|
|
7
|
-
* (`executions` | `orders`) and is only meaningful when
|
|
8
|
-
* `routingMode='copy_trading'`. The server enforces enum + cross-field
|
|
9
|
-
* validity (422 on bad value; 422 on `copyMode` change in signal mode) and
|
|
10
|
-
* auto-demotes every `is_copy_source=true` member when `routingMode` flips
|
|
11
|
-
* to `'signal'`.
|
|
12
|
-
*/
|
|
13
|
-
export async function updateGroup(client, resolver, input) {
|
|
14
|
-
try {
|
|
15
|
-
const groupId = Number(input.groupId);
|
|
16
|
-
if (!Number.isFinite(groupId) || groupId <= 0)
|
|
17
|
-
return makeErrorResult(new Error("groupId is required and must be a positive integer"));
|
|
18
|
-
// Build the partial-PATCH body — only forward fields the caller supplied.
|
|
19
|
-
const body = {};
|
|
20
|
-
for (const key of ["name", "payloadFormat", "routingMode", "copyMode"]) {
|
|
21
|
-
if (key in input)
|
|
22
|
-
body[key] = input[key];
|
|
23
|
-
}
|
|
24
|
-
if (Object.keys(body).length === 0)
|
|
25
|
-
return makeErrorResult(new Error("At least one updatable field (name, payloadFormat, routingMode, copyMode) must be supplied"));
|
|
26
|
-
const userId = await resolver.resolve(client);
|
|
27
|
-
const res = await client.patch(`/api/account/${userId}/groups/${groupId}`, body);
|
|
28
|
-
const summary = [`### Group updated`, `Group #${groupId}\n`];
|
|
29
|
-
for (const k of ["name", "payloadFormat", "routingMode", "copyMode"]) {
|
|
30
|
-
if (res?.[k] !== undefined)
|
|
31
|
-
summary.push(`- **${k}:** ${String(res[k])}`);
|
|
32
|
-
}
|
|
33
|
-
return {
|
|
34
|
-
content: [
|
|
35
|
-
{ type: "text", text: summary.join("\n") },
|
|
36
|
-
{ type: "text", text: JSON.stringify(res, null, 2) },
|
|
37
|
-
],
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
catch (e) {
|
|
41
|
-
return makeErrorResult(e);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=groups.js.map
|
package/dist/tools/groups.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"groups.js","sourceRoot":"","sources":["../../src/tools/groups.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,eAAe,EAAc,MAAM,YAAY,CAAC;AAEvE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAqB,EACrB,QAAsB,EACtB,KAA8B;IAE9B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC;YAC3C,OAAO,eAAe,CAAC,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC,CAAC;QAE1F,0EAA0E;QAC1E,MAAM,IAAI,GAA4B,EAAE,CAAC;QACzC,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,CAAC;YACvE,IAAI,GAAG,IAAI,KAAK;gBAAE,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAChC,OAAO,eAAe,CAAC,IAAI,KAAK,CAAC,4FAA4F,CAAC,CAAC,CAAC;QAElI,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAC5B,gBAAgB,MAAM,WAAW,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;QAEpD,MAAM,OAAO,GAAa,CAAC,mBAAmB,EAAE,UAAU,OAAO,IAAI,CAAC,CAAC;QACvE,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,CAAC;YACrE,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS;gBAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBAC1C,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;aACrD;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { updateGroup } from "./groups.js";
|
|
3
|
-
const makeClient = (patchImpl, capture) => ({
|
|
4
|
-
patch: (path, body) => {
|
|
5
|
-
if (capture) {
|
|
6
|
-
capture.path = path;
|
|
7
|
-
capture.body = body;
|
|
8
|
-
}
|
|
9
|
-
return patchImpl(path, body);
|
|
10
|
-
},
|
|
11
|
-
});
|
|
12
|
-
const makeResolver = (userId = 7) => ({ resolve: async () => userId });
|
|
13
|
-
describe("update_group", () => {
|
|
14
|
-
it("PATCHes the group endpoint with only supplied fields", async () => {
|
|
15
|
-
const capture = { path: "", body: undefined };
|
|
16
|
-
const client = makeClient(() => Promise.resolve({ id: 42, name: "renamed", routingMode: "copy_trading", copyMode: "executions", payloadFormat: "auto" }), capture);
|
|
17
|
-
const result = await updateGroup(client, makeResolver(7), {
|
|
18
|
-
groupId: 42,
|
|
19
|
-
routingMode: "copy_trading",
|
|
20
|
-
});
|
|
21
|
-
expect(result.isError).toBeUndefined();
|
|
22
|
-
expect(capture.path).toBe("/api/account/7/groups/42");
|
|
23
|
-
// body MUST only carry the field the caller supplied — not an empty `name`/`copyMode`.
|
|
24
|
-
expect(capture.body).toEqual({ routingMode: "copy_trading" });
|
|
25
|
-
expect(result.content[0].text).toContain("Group #42");
|
|
26
|
-
expect(result.content[0].text).toContain("routingMode");
|
|
27
|
-
});
|
|
28
|
-
it("forwards multiple fields when supplied", async () => {
|
|
29
|
-
const capture = { path: "", body: undefined };
|
|
30
|
-
const client = makeClient(() => Promise.resolve({ id: 9, name: "x", payloadFormat: "pmt", routingMode: "copy_trading", copyMode: "orders" }), capture);
|
|
31
|
-
const result = await updateGroup(client, makeResolver(7), {
|
|
32
|
-
groupId: 9,
|
|
33
|
-
name: "x",
|
|
34
|
-
payloadFormat: "pmt",
|
|
35
|
-
routingMode: "copy_trading",
|
|
36
|
-
copyMode: "orders",
|
|
37
|
-
});
|
|
38
|
-
expect(result.isError).toBeUndefined();
|
|
39
|
-
expect(capture.body).toEqual({
|
|
40
|
-
name: "x",
|
|
41
|
-
payloadFormat: "pmt",
|
|
42
|
-
routingMode: "copy_trading",
|
|
43
|
-
copyMode: "orders",
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
it("returns isError when groupId is missing or invalid", async () => {
|
|
47
|
-
const client = makeClient(() => Promise.resolve({}));
|
|
48
|
-
const missing = await updateGroup(client, makeResolver(), { routingMode: "signal" });
|
|
49
|
-
expect(missing.isError).toBe(true);
|
|
50
|
-
const negative = await updateGroup(client, makeResolver(), { groupId: -1, routingMode: "signal" });
|
|
51
|
-
expect(negative.isError).toBe(true);
|
|
52
|
-
const zero = await updateGroup(client, makeResolver(), { groupId: 0, routingMode: "signal" });
|
|
53
|
-
expect(zero.isError).toBe(true);
|
|
54
|
-
});
|
|
55
|
-
it("returns isError when no updatable fields are supplied", async () => {
|
|
56
|
-
// Caller passed only groupId — nothing to update. Don't issue an empty PATCH.
|
|
57
|
-
const client = makeClient(() => Promise.reject(new Error("should not be called")));
|
|
58
|
-
const result = await updateGroup(client, makeResolver(), { groupId: 42 });
|
|
59
|
-
expect(result.isError).toBe(true);
|
|
60
|
-
expect(result.content[0].text).toContain("At least one updatable field");
|
|
61
|
-
});
|
|
62
|
-
it("surfaces API errors as isError", async () => {
|
|
63
|
-
const client = makeClient(() => Promise.reject(new Error("422 group_not_in_copy_trading_mode")));
|
|
64
|
-
const result = await updateGroup(client, makeResolver(), {
|
|
65
|
-
groupId: 42,
|
|
66
|
-
copyMode: "orders",
|
|
67
|
-
});
|
|
68
|
-
expect(result.isError).toBe(true);
|
|
69
|
-
expect(result.content[0].text).toContain("422");
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
//# sourceMappingURL=groups.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"groups.test.js","sourceRoot":"","sources":["../../src/tools/groups.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { VantageClient } from "../client.js";
|
|
2
|
-
import { UserResolver, ToolResult } from "../user.js";
|
|
3
|
-
/** IPALLOW-05 — list CIDR allowlist entries for a signal group (admin-only). */
|
|
4
|
-
export declare function getIpAllowlist(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
5
|
-
/** IPALLOW-05 — add or remove a CIDR entry from a group's IP allowlist (admin-only). */
|
|
6
|
-
export declare function manageIpAllowlist(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { makeErrorResult } from "../user.js";
|
|
2
|
-
/** IPALLOW-05 — list CIDR allowlist entries for a signal group (admin-only). */
|
|
3
|
-
export async function getIpAllowlist(client, _resolver, input) {
|
|
4
|
-
try {
|
|
5
|
-
const groupId = Number(input.groupId);
|
|
6
|
-
if (!Number.isFinite(groupId) || groupId <= 0) {
|
|
7
|
-
return makeErrorResult(new Error("groupId is required and must be a positive integer"));
|
|
8
|
-
}
|
|
9
|
-
const entries = await client.get(`/api/admin/ip-allowlist/${groupId}`);
|
|
10
|
-
if (!entries?.length) {
|
|
11
|
-
return {
|
|
12
|
-
content: [{
|
|
13
|
-
type: "text",
|
|
14
|
-
text: `Group ${groupId} has no IP allowlist entries — all webhook sources are permitted.`,
|
|
15
|
-
}],
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
const lines = [`## IP Allowlist — Group ${groupId} (${entries.length} entries)\n`];
|
|
19
|
-
for (const e of entries) {
|
|
20
|
-
lines.push(`- **${e.cidr}**${e.label ? ` — ${e.label}` : ""} (id=${e.id}, added ${e.createdAt}${e.createdByEmail ? ` by ${e.createdByEmail}` : ""})`);
|
|
21
|
-
}
|
|
22
|
-
lines.push(`\n_Webhooks from IPs not covered by any CIDR above will receive 403 ip_not_allowed._`);
|
|
23
|
-
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
24
|
-
}
|
|
25
|
-
catch (e) {
|
|
26
|
-
return makeErrorResult(e);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/** IPALLOW-05 — add or remove a CIDR entry from a group's IP allowlist (admin-only). */
|
|
30
|
-
export async function manageIpAllowlist(client, _resolver, input) {
|
|
31
|
-
try {
|
|
32
|
-
const action = String(input.action ?? "").toLowerCase();
|
|
33
|
-
const groupId = Number(input.groupId);
|
|
34
|
-
if (!Number.isFinite(groupId) || groupId <= 0) {
|
|
35
|
-
return makeErrorResult(new Error("groupId is required and must be a positive integer"));
|
|
36
|
-
}
|
|
37
|
-
if (action === "add") {
|
|
38
|
-
const cidr = String(input.cidr ?? "").trim();
|
|
39
|
-
const label = String(input.label ?? "").trim();
|
|
40
|
-
if (!cidr)
|
|
41
|
-
return makeErrorResult(new Error("cidr is required for action=add"));
|
|
42
|
-
await client.post(`/api/admin/ip-allowlist/${groupId}`, { cidr, label });
|
|
43
|
-
return {
|
|
44
|
-
content: [{
|
|
45
|
-
type: "text",
|
|
46
|
-
text: `Added CIDR ${cidr}${label ? ` (${label})` : ""} to group ${groupId}'s allowlist. Audit row written.`,
|
|
47
|
-
}],
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
if (action === "remove") {
|
|
51
|
-
const entryId = Number(input.entryId);
|
|
52
|
-
if (!Number.isFinite(entryId) || entryId <= 0) {
|
|
53
|
-
return makeErrorResult(new Error("entryId is required for action=remove and must be a positive integer"));
|
|
54
|
-
}
|
|
55
|
-
await client.delete(`/api/admin/ip-allowlist/${groupId}/${entryId}`);
|
|
56
|
-
return {
|
|
57
|
-
content: [{
|
|
58
|
-
type: "text",
|
|
59
|
-
text: `Removed allowlist entry ${entryId} from group ${groupId}. Audit row written.`,
|
|
60
|
-
}],
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
return makeErrorResult(new Error(`Unknown action '${action}'. Use 'add' or 'remove'.`));
|
|
64
|
-
}
|
|
65
|
-
catch (e) {
|
|
66
|
-
return makeErrorResult(e);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
//# sourceMappingURL=ip-allowlist.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ip-allowlist.js","sourceRoot":"","sources":["../../src/tools/ip-allowlist.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/journal.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { VantageClient } from "../client.js";
|
|
2
|
-
import { UserResolver, ToolResult } from "../user.js";
|
|
3
|
-
export declare function getJournalTrades(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
4
|
-
export declare function getJournalDashboard(client: VantageClient, _resolver: UserResolver, _input: Record<string, unknown>): Promise<ToolResult>;
|
|
5
|
-
export declare function getJournalEntries(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
6
|
-
export declare function addJournalEntry(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
package/dist/tools/journal.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { makeErrorResult } from "../user.js";
|
|
2
|
-
export async function getJournalTrades(client, _resolver, input) {
|
|
3
|
-
try {
|
|
4
|
-
const params = new URLSearchParams();
|
|
5
|
-
if (input.startDate)
|
|
6
|
-
params.set("startDate", String(input.startDate));
|
|
7
|
-
if (input.endDate)
|
|
8
|
-
params.set("endDate", String(input.endDate));
|
|
9
|
-
if (input.accountSpec)
|
|
10
|
-
params.set("accountSpec", String(input.accountSpec));
|
|
11
|
-
if (input.limit)
|
|
12
|
-
params.set("limit", String(input.limit));
|
|
13
|
-
if (input.unlinkedFilter === "retained")
|
|
14
|
-
params.set("unlinkedFilter", "retained");
|
|
15
|
-
const qs = params.toString() ? `?${params}` : "";
|
|
16
|
-
const trades = await client.get(`/api/journal/trades${qs}`);
|
|
17
|
-
if (!trades.length) {
|
|
18
|
-
return { content: [{ type: "text", text: "No trades found for the specified filters." }, { type: "text", text: "[]" }] };
|
|
19
|
-
}
|
|
20
|
-
const wins = trades.filter((t) => (t.pnl ?? 0) > 0);
|
|
21
|
-
const losses = trades.filter((t) => (t.pnl ?? 0) <= 0);
|
|
22
|
-
const netPnl = trades.reduce((s, t) => s + (t.pnl ?? 0), 0);
|
|
23
|
-
const summary = `${trades.length} trade(s): ${wins.length}W / ${losses.length}L, net P&L ${netPnl >= 0 ? "+" : ""}${netPnl.toFixed(2)}`;
|
|
24
|
-
const lines = trades.map((t) => `• [${t.entryTime ?? "?"}] ${t.action ?? "?"} ${t.ticker ?? "?"} qty=${t.quantity ?? "?"} ` +
|
|
25
|
-
`entry=${t.entryPrice ?? "?"} exit=${t.exitPrice ?? "?"} pnl=${t.pnl != null ? (t.pnl >= 0 ? "+" : "") + t.pnl.toFixed(2) : "?"}`);
|
|
26
|
-
return {
|
|
27
|
-
content: [
|
|
28
|
-
{ type: "text", text: `${summary}\n${lines.join("\n")}` },
|
|
29
|
-
{ type: "text", text: JSON.stringify(trades, null, 2) },
|
|
30
|
-
],
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
catch (err) {
|
|
34
|
-
return makeErrorResult(err);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
export async function getJournalDashboard(client, _resolver, _input) {
|
|
38
|
-
try {
|
|
39
|
-
const bundle = await client.get("/api/journal/dashboard-bundle");
|
|
40
|
-
const pnlStr = bundle.netPnl != null
|
|
41
|
-
? `${bundle.netPnl >= 0 ? "+" : ""}${bundle.netPnl.toFixed(2)}`
|
|
42
|
-
: "?";
|
|
43
|
-
const winRateStr = bundle.winRate != null ? `${(bundle.winRate * 100).toFixed(1)}%` : "?";
|
|
44
|
-
const pfStr = bundle.profitFactor != null ? bundle.profitFactor.toFixed(2) : "?";
|
|
45
|
-
const summary = [
|
|
46
|
-
`Net P&L: ${pnlStr}`,
|
|
47
|
-
`Trades: ${bundle.tradeCount ?? "?"} (${bundle.winCount ?? "?"}W / ${bundle.lossCount ?? "?"}L)`,
|
|
48
|
-
`Win rate: ${winRateStr}`,
|
|
49
|
-
`Profit factor: ${pfStr}`,
|
|
50
|
-
bundle.avgWin != null ? `Avg win: +${bundle.avgWin.toFixed(2)}` : null,
|
|
51
|
-
bundle.avgLoss != null ? `Avg loss: ${bundle.avgLoss.toFixed(2)}` : null,
|
|
52
|
-
bundle.maxDrawdown != null ? `Max drawdown: ${bundle.maxDrawdown.toFixed(2)}` : null,
|
|
53
|
-
bundle.sharpe != null ? `Sharpe: ${bundle.sharpe.toFixed(2)}` : null,
|
|
54
|
-
]
|
|
55
|
-
.filter(Boolean)
|
|
56
|
-
.join(" | ");
|
|
57
|
-
return {
|
|
58
|
-
content: [
|
|
59
|
-
{ type: "text", text: summary },
|
|
60
|
-
{ type: "text", text: JSON.stringify(bundle, null, 2) },
|
|
61
|
-
],
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
catch (err) {
|
|
65
|
-
return makeErrorResult(err);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
export async function getJournalEntries(client, _resolver, input) {
|
|
69
|
-
try {
|
|
70
|
-
const params = new URLSearchParams();
|
|
71
|
-
if (input.startDate)
|
|
72
|
-
params.set("startDate", String(input.startDate));
|
|
73
|
-
if (input.endDate)
|
|
74
|
-
params.set("endDate", String(input.endDate));
|
|
75
|
-
const qs = params.toString() ? `?${params}` : "";
|
|
76
|
-
const entries = await client.get(`/api/journal/entries${qs}`);
|
|
77
|
-
if (!entries.length) {
|
|
78
|
-
return { content: [{ type: "text", text: "No journal entries found." }, { type: "text", text: "[]" }] };
|
|
79
|
-
}
|
|
80
|
-
const lines = entries.map((e) => `• [${e.date ?? e.createdAt ?? "?"}] ${e.text ?? ""}`);
|
|
81
|
-
return {
|
|
82
|
-
content: [
|
|
83
|
-
{ type: "text", text: `${entries.length} entry(ies):\n${lines.join("\n")}` },
|
|
84
|
-
{ type: "text", text: JSON.stringify(entries, null, 2) },
|
|
85
|
-
],
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
catch (err) {
|
|
89
|
-
return makeErrorResult(err);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
export async function addJournalEntry(client, _resolver, input) {
|
|
93
|
-
const date = String(input.date ?? "");
|
|
94
|
-
const text = String(input.text ?? "");
|
|
95
|
-
if (!date || !text)
|
|
96
|
-
return makeErrorResult(new Error("date and text are required"));
|
|
97
|
-
try {
|
|
98
|
-
const entry = await client.post("/api/journal/entries", { date, text });
|
|
99
|
-
return {
|
|
100
|
-
content: [
|
|
101
|
-
{ type: "text", text: `Journal entry created (id=${entry.id ?? "?"}): [${date}] ${text}` },
|
|
102
|
-
{ type: "text", text: JSON.stringify(entry, null, 2) },
|
|
103
|
-
],
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
catch (err) {
|
|
107
|
-
return makeErrorResult(err);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
//# sourceMappingURL=journal.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"journal.js","sourceRoot":"","sources":["../../src/tools/journal.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { getJournalTrades, getJournalDashboard, getJournalEntries, addJournalEntry } from "./journal.js";
|
|
3
|
-
const makeClient = (getImpl, postImpl) => ({
|
|
4
|
-
get: getImpl ?? (() => Promise.resolve([])),
|
|
5
|
-
post: postImpl ?? (() => Promise.resolve({ id: 99 })),
|
|
6
|
-
});
|
|
7
|
-
const resolver = {};
|
|
8
|
-
const TRADES = [
|
|
9
|
-
{ id: 1, ticker: "MYMM6", action: "buy", quantity: 1, entryPrice: 49500, exitPrice: 49600, entryTime: "2026-04-30T10:00:00Z", pnl: 100 },
|
|
10
|
-
{ id: 2, ticker: "MYMM6", action: "sell", quantity: 1, entryPrice: 49700, exitPrice: 49650, entryTime: "2026-04-30T11:00:00Z", pnl: -50 },
|
|
11
|
-
];
|
|
12
|
-
describe("getJournalTrades", () => {
|
|
13
|
-
it("returns trade summary with win/loss counts and net P&L", async () => {
|
|
14
|
-
const result = await getJournalTrades(makeClient(() => Promise.resolve(TRADES)), resolver, {});
|
|
15
|
-
expect(result.isError).toBeUndefined();
|
|
16
|
-
expect(result.content[0].text).toContain("2 trade(s)");
|
|
17
|
-
expect(result.content[0].text).toContain("1W / 1L");
|
|
18
|
-
expect(result.content[0].text).toContain("+50.00");
|
|
19
|
-
});
|
|
20
|
-
it("returns empty message when no trades", async () => {
|
|
21
|
-
const result = await getJournalTrades(makeClient(() => Promise.resolve([])), resolver, {});
|
|
22
|
-
expect(result.isError).toBeUndefined();
|
|
23
|
-
expect(result.content[0].text).toContain("No trades found");
|
|
24
|
-
});
|
|
25
|
-
it("returns isError on API failure", async () => {
|
|
26
|
-
const result = await getJournalTrades(makeClient(() => Promise.reject(new Error("500"))), resolver, {});
|
|
27
|
-
expect(result.isError).toBe(true);
|
|
28
|
-
});
|
|
29
|
-
it("includes JSON in second content block", async () => {
|
|
30
|
-
const result = await getJournalTrades(makeClient(() => Promise.resolve(TRADES)), resolver, {});
|
|
31
|
-
expect(JSON.parse(result.content[1].text)).toHaveLength(2);
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
describe("getJournalDashboard", () => {
|
|
35
|
-
const BUNDLE = {
|
|
36
|
-
netPnl: 1500.5,
|
|
37
|
-
tradeCount: 42,
|
|
38
|
-
winCount: 28,
|
|
39
|
-
lossCount: 14,
|
|
40
|
-
winRate: 0.667,
|
|
41
|
-
profitFactor: 2.1,
|
|
42
|
-
avgWin: 120.5,
|
|
43
|
-
avgLoss: -60.25,
|
|
44
|
-
maxDrawdown: -850,
|
|
45
|
-
sharpe: 1.8,
|
|
46
|
-
};
|
|
47
|
-
it("returns formatted stats summary", async () => {
|
|
48
|
-
const result = await getJournalDashboard(makeClient(() => Promise.resolve(BUNDLE)), resolver, {});
|
|
49
|
-
expect(result.isError).toBeUndefined();
|
|
50
|
-
expect(result.content[0].text).toContain("+1500.50");
|
|
51
|
-
expect(result.content[0].text).toContain("42");
|
|
52
|
-
expect(result.content[0].text).toContain("66.7%");
|
|
53
|
-
expect(result.content[0].text).toContain("2.10");
|
|
54
|
-
});
|
|
55
|
-
it("returns isError on API failure", async () => {
|
|
56
|
-
const result = await getJournalDashboard(makeClient(() => Promise.reject(new Error("500"))), resolver, {});
|
|
57
|
-
expect(result.isError).toBe(true);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
describe("getJournalEntries", () => {
|
|
61
|
-
const ENTRIES = [
|
|
62
|
-
{ id: 1, date: "2026-04-29", text: "Tight range day, stayed out." },
|
|
63
|
-
{ id: 2, date: "2026-04-30", text: "Good breakout, hit target." },
|
|
64
|
-
];
|
|
65
|
-
it("returns entry list", async () => {
|
|
66
|
-
const result = await getJournalEntries(makeClient(() => Promise.resolve(ENTRIES)), resolver, {});
|
|
67
|
-
expect(result.isError).toBeUndefined();
|
|
68
|
-
expect(result.content[0].text).toContain("2 entry(ies)");
|
|
69
|
-
expect(result.content[0].text).toContain("Tight range day");
|
|
70
|
-
});
|
|
71
|
-
it("returns empty message when no entries", async () => {
|
|
72
|
-
const result = await getJournalEntries(makeClient(() => Promise.resolve([])), resolver, {});
|
|
73
|
-
expect(result.content[0].text).toContain("No journal entries");
|
|
74
|
-
});
|
|
75
|
-
it("returns isError on API failure", async () => {
|
|
76
|
-
const result = await getJournalEntries(makeClient(() => Promise.reject(new Error("404"))), resolver, {});
|
|
77
|
-
expect(result.isError).toBe(true);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
describe("addJournalEntry", () => {
|
|
81
|
-
it("creates entry and returns confirmation", async () => {
|
|
82
|
-
const result = await addJournalEntry(makeClient(undefined, () => Promise.resolve({ id: 42 })), resolver, { date: "2026-04-30", text: "Good session today." });
|
|
83
|
-
expect(result.isError).toBeUndefined();
|
|
84
|
-
expect(result.content[0].text).toContain("id=42");
|
|
85
|
-
expect(result.content[0].text).toContain("Good session today");
|
|
86
|
-
});
|
|
87
|
-
it("returns isError when date missing", async () => {
|
|
88
|
-
const result = await addJournalEntry(makeClient(), resolver, { text: "no date" });
|
|
89
|
-
expect(result.isError).toBe(true);
|
|
90
|
-
});
|
|
91
|
-
it("returns isError when text missing", async () => {
|
|
92
|
-
const result = await addJournalEntry(makeClient(), resolver, { date: "2026-04-30" });
|
|
93
|
-
expect(result.isError).toBe(true);
|
|
94
|
-
});
|
|
95
|
-
it("returns isError on API failure", async () => {
|
|
96
|
-
const result = await addJournalEntry(makeClient(undefined, () => Promise.reject(new Error("500"))), resolver, { date: "2026-04-30", text: "test" });
|
|
97
|
-
expect(result.isError).toBe(true);
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
//# sourceMappingURL=journal.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"journal.test.js","sourceRoot":"","sources":["../../src/tools/journal.test.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/latency.d.ts
DELETED
package/dist/tools/latency.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { makeErrorResult } from "../user.js";
|
|
2
|
-
export async function getLatencySummary(client, _resolver, _input) {
|
|
3
|
-
try {
|
|
4
|
-
const data = await client.get("/api/public/latency-summary");
|
|
5
|
-
const brokers = data.brokers ?? {};
|
|
6
|
-
const brokerKeys = Object.keys(brokers);
|
|
7
|
-
if (!brokerKeys.length) {
|
|
8
|
-
return {
|
|
9
|
-
content: [
|
|
10
|
-
{ type: "text", text: "No latency data available yet (rollup service may still be warming up)." },
|
|
11
|
-
{ type: "text", text: JSON.stringify(data, null, 2) },
|
|
12
|
-
],
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
const lines = [];
|
|
16
|
-
for (const broker of brokerKeys) {
|
|
17
|
-
const windows = brokers[broker] ?? {};
|
|
18
|
-
for (const [window, stages] of Object.entries(windows)) {
|
|
19
|
-
const total = stages["total_ingress_wire_ms"];
|
|
20
|
-
if (total) {
|
|
21
|
-
const p95 = total.isSparse ? "sparse" : `${total.p95Ms}ms`;
|
|
22
|
-
const p50 = total.isSparse ? "sparse" : `${total.p50Ms}ms`;
|
|
23
|
-
const p99 = total.isSparse ? "sparse" : `${total.p99Ms}ms`;
|
|
24
|
-
lines.push(`${broker} [${window}] total: p50=${p50} p95=${p95} p99=${p99} (n=${total.samples})`);
|
|
25
|
-
}
|
|
26
|
-
for (const [stage, s] of Object.entries(stages)) {
|
|
27
|
-
if (stage === "total_ingress_wire_ms")
|
|
28
|
-
continue;
|
|
29
|
-
if (s.isSparse) {
|
|
30
|
-
lines.push(` ${stage}: sparse (<100 samples)`);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
lines.push(` ${stage}: p50=${s.p50Ms}ms p95=${s.p95Ms}ms p99=${s.p99Ms}ms (n=${s.samples})`);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return {
|
|
39
|
-
content: [
|
|
40
|
-
{ type: "text", text: lines.join("\n") },
|
|
41
|
-
{ type: "text", text: JSON.stringify(data, null, 2) },
|
|
42
|
-
],
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
catch (err) {
|
|
46
|
-
if (err && typeof err === "object" && "status" in err && err.status === 404) {
|
|
47
|
-
return {
|
|
48
|
-
content: [{ type: "text", text: "Latency display feature not enabled (feature.latency-display is off)." }],
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
return makeErrorResult(err);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
//# sourceMappingURL=latency.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"latency.js","sourceRoot":"","sources":["../../src/tools/latency.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { VantageClient } from "../client.js";
|
|
2
|
-
import { UserResolver, ToolResult } from "../user.js";
|
|
3
|
-
export declare function getMarketDataFeeds(client: VantageClient, _resolver: UserResolver, _input: Record<string, unknown>): Promise<ToolResult>;
|
|
4
|
-
export declare function getMarketDataHistory(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { makeErrorResult } from "../user.js";
|
|
2
|
-
export async function getMarketDataFeeds(client, _resolver, _input) {
|
|
3
|
-
try {
|
|
4
|
-
const r = await client.get("/api/marketdata/feeds");
|
|
5
|
-
const lines = r.feeds.map(f => `- ${f.kind} [${f.capabilities}]`);
|
|
6
|
-
return {
|
|
7
|
-
content: [
|
|
8
|
-
{ type: "text", text: `Registered market-data feeds:\n${lines.join("\n")}` },
|
|
9
|
-
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
10
|
-
],
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
catch (err) {
|
|
14
|
-
return makeErrorResult(err);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
export async function getMarketDataHistory(client, _resolver, input) {
|
|
18
|
-
const feed = String(input.feed ?? "");
|
|
19
|
-
const symbol = String(input.symbol ?? "");
|
|
20
|
-
const assetClass = String(input.assetClass ?? "Future");
|
|
21
|
-
const fromUtc = String(input.fromUtc ?? "");
|
|
22
|
-
const toUtc = String(input.toUtc ?? "");
|
|
23
|
-
const bar = input.bar ? String(input.bar) : "1min";
|
|
24
|
-
if (!feed || !symbol || !fromUtc || !toUtc) {
|
|
25
|
-
return makeErrorResult(new Error("feed, symbol, fromUtc, toUtc are required (assetClass defaults to Future, bar to 1min)"));
|
|
26
|
-
}
|
|
27
|
-
const qs = new URLSearchParams({
|
|
28
|
-
feed, symbol, assetClass, fromUtc, toUtc, bar,
|
|
29
|
-
}).toString();
|
|
30
|
-
try {
|
|
31
|
-
const bars = await client.get(`/api/marketdata/history?${qs}`);
|
|
32
|
-
const head = bars.slice(0, 5).map(b => ` ${b.t} O=${b.o} H=${b.h} L=${b.l} C=${b.c} V=${b.v}`).join("\n");
|
|
33
|
-
const tail = bars.length > 10
|
|
34
|
-
? "\n …\n" + bars.slice(-5).map(b => ` ${b.t} O=${b.o} H=${b.h} L=${b.l} C=${b.c} V=${b.v}`).join("\n")
|
|
35
|
-
: "";
|
|
36
|
-
const summary = `Feed ${feed}: ${bars.length} ${bar} bar(s) for ${symbol} ` +
|
|
37
|
-
`(${fromUtc} → ${toUtc})` +
|
|
38
|
-
(bars.length ? `\n${head}${tail}` : "");
|
|
39
|
-
return {
|
|
40
|
-
content: [
|
|
41
|
-
{ type: "text", text: summary },
|
|
42
|
-
{ type: "text", text: JSON.stringify(bars, null, 2) },
|
|
43
|
-
],
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
catch (err) {
|
|
47
|
-
return makeErrorResult(err);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
//# sourceMappingURL=market-history.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"market-history.js","sourceRoot":"","sources":["../../src/tools/market-history.ts"],"names":[],"mappings":"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"}
|