@vantagestack/mcp-server 0.1.2 → 0.1.4
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/client.d.ts +4 -0
- package/dist/client.js +52 -0
- package/dist/client.js.map +1 -1
- package/dist/index.js +336 -3
- package/dist/index.js.map +1 -1
- package/dist/tools/account.d.ts +9 -0
- package/dist/tools/account.js +198 -0
- package/dist/tools/account.js.map +1 -0
- package/dist/tools/account.test.d.ts +1 -0
- package/dist/tools/account.test.js +163 -0
- package/dist/tools/account.test.js.map +1 -0
- package/dist/tools/calendar.d.ts +4 -0
- package/dist/tools/calendar.js +85 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/calendar.test.d.ts +1 -0
- package/dist/tools/calendar.test.js +62 -0
- package/dist/tools/calendar.test.js.map +1 -0
- package/dist/tools/journal 2.d.ts +6 -0
- package/dist/tools/journal 2.js +108 -0
- package/dist/tools/journal 2.js.map +1 -0
- package/dist/tools/journal.d.ts +6 -0
- package/dist/tools/journal.js +108 -0
- package/dist/tools/journal.js.map +1 -0
- package/dist/tools/journal.test.d.ts +1 -0
- package/dist/tools/journal.test.js +100 -0
- package/dist/tools/journal.test.js.map +1 -0
- package/dist/tools/qc.d.ts +14 -0
- package/dist/tools/qc.js +287 -0
- package/dist/tools/qc.js.map +1 -0
- package/dist/tools/qc.test.d.ts +1 -0
- package/dist/tools/qc.test.js +218 -0
- package/dist/tools/qc.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,108 @@
|
|
|
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
|
+
const qs = params.toString() ? `?${params}` : "";
|
|
14
|
+
const trades = await client.get(`/api/journal/trades${qs}`);
|
|
15
|
+
if (!trades.length) {
|
|
16
|
+
return { content: [{ type: "text", text: "No trades found for the specified filters." }, { type: "text", text: "[]" }] };
|
|
17
|
+
}
|
|
18
|
+
const wins = trades.filter((t) => (t.pnl ?? 0) > 0);
|
|
19
|
+
const losses = trades.filter((t) => (t.pnl ?? 0) <= 0);
|
|
20
|
+
const netPnl = trades.reduce((s, t) => s + (t.pnl ?? 0), 0);
|
|
21
|
+
const summary = `${trades.length} trade(s): ${wins.length}W / ${losses.length}L, net P&L ${netPnl >= 0 ? "+" : ""}${netPnl.toFixed(2)}`;
|
|
22
|
+
const lines = trades.map((t) => `• [${t.entryTime ?? "?"}] ${t.action ?? "?"} ${t.ticker ?? "?"} qty=${t.quantity ?? "?"} ` +
|
|
23
|
+
`entry=${t.entryPrice ?? "?"} exit=${t.exitPrice ?? "?"} pnl=${t.pnl != null ? (t.pnl >= 0 ? "+" : "") + t.pnl.toFixed(2) : "?"}`);
|
|
24
|
+
return {
|
|
25
|
+
content: [
|
|
26
|
+
{ type: "text", text: `${summary}\n${lines.join("\n")}` },
|
|
27
|
+
{ type: "text", text: JSON.stringify(trades, null, 2) },
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
return makeErrorResult(err);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export async function getJournalDashboard(client, _resolver, _input) {
|
|
36
|
+
try {
|
|
37
|
+
const bundle = await client.get("/api/journal/dashboard-bundle");
|
|
38
|
+
const pnlStr = bundle.netPnl != null
|
|
39
|
+
? `${bundle.netPnl >= 0 ? "+" : ""}${bundle.netPnl.toFixed(2)}`
|
|
40
|
+
: "?";
|
|
41
|
+
const winRateStr = bundle.winRate != null ? `${(bundle.winRate * 100).toFixed(1)}%` : "?";
|
|
42
|
+
const pfStr = bundle.profitFactor != null ? bundle.profitFactor.toFixed(2) : "?";
|
|
43
|
+
const summary = [
|
|
44
|
+
`Net P&L: ${pnlStr}`,
|
|
45
|
+
`Trades: ${bundle.tradeCount ?? "?"} (${bundle.winCount ?? "?"}W / ${bundle.lossCount ?? "?"}L)`,
|
|
46
|
+
`Win rate: ${winRateStr}`,
|
|
47
|
+
`Profit factor: ${pfStr}`,
|
|
48
|
+
bundle.avgWin != null ? `Avg win: +${bundle.avgWin.toFixed(2)}` : null,
|
|
49
|
+
bundle.avgLoss != null ? `Avg loss: ${bundle.avgLoss.toFixed(2)}` : null,
|
|
50
|
+
bundle.maxDrawdown != null ? `Max drawdown: ${bundle.maxDrawdown.toFixed(2)}` : null,
|
|
51
|
+
bundle.sharpe != null ? `Sharpe: ${bundle.sharpe.toFixed(2)}` : null,
|
|
52
|
+
]
|
|
53
|
+
.filter(Boolean)
|
|
54
|
+
.join(" | ");
|
|
55
|
+
return {
|
|
56
|
+
content: [
|
|
57
|
+
{ type: "text", text: summary },
|
|
58
|
+
{ type: "text", text: JSON.stringify(bundle, null, 2) },
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
return makeErrorResult(err);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export async function getJournalEntries(client, _resolver, input) {
|
|
67
|
+
try {
|
|
68
|
+
const params = new URLSearchParams();
|
|
69
|
+
if (input.startDate)
|
|
70
|
+
params.set("startDate", String(input.startDate));
|
|
71
|
+
if (input.endDate)
|
|
72
|
+
params.set("endDate", String(input.endDate));
|
|
73
|
+
const qs = params.toString() ? `?${params}` : "";
|
|
74
|
+
const entries = await client.get(`/api/journal/entries${qs}`);
|
|
75
|
+
if (!entries.length) {
|
|
76
|
+
return { content: [{ type: "text", text: "No journal entries found." }, { type: "text", text: "[]" }] };
|
|
77
|
+
}
|
|
78
|
+
const lines = entries.map((e) => `• [${e.date ?? e.createdAt ?? "?"}] ${e.text ?? ""}`);
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{ type: "text", text: `${entries.length} entry(ies):\n${lines.join("\n")}` },
|
|
82
|
+
{ type: "text", text: JSON.stringify(entries, null, 2) },
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
return makeErrorResult(err);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export async function addJournalEntry(client, _resolver, input) {
|
|
91
|
+
const date = String(input.date ?? "");
|
|
92
|
+
const text = String(input.text ?? "");
|
|
93
|
+
if (!date || !text)
|
|
94
|
+
return makeErrorResult(new Error("date and text are required"));
|
|
95
|
+
try {
|
|
96
|
+
const entry = await client.post("/api/journal/entries", { date, text });
|
|
97
|
+
return {
|
|
98
|
+
content: [
|
|
99
|
+
{ type: "text", text: `Journal entry created (id=${entry.id ?? "?"}): [${date}] ${text}` },
|
|
100
|
+
{ type: "text", text: JSON.stringify(entry, null, 2) },
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
return makeErrorResult(err);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=journal%202.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal 2.js","sourceRoot":"","sources":["../../src/tools/journal 2.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
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>;
|
|
@@ -0,0 +1,108 @@
|
|
|
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
|
+
const qs = params.toString() ? `?${params}` : "";
|
|
14
|
+
const trades = await client.get(`/api/journal/trades${qs}`);
|
|
15
|
+
if (!trades.length) {
|
|
16
|
+
return { content: [{ type: "text", text: "No trades found for the specified filters." }, { type: "text", text: "[]" }] };
|
|
17
|
+
}
|
|
18
|
+
const wins = trades.filter((t) => (t.pnl ?? 0) > 0);
|
|
19
|
+
const losses = trades.filter((t) => (t.pnl ?? 0) <= 0);
|
|
20
|
+
const netPnl = trades.reduce((s, t) => s + (t.pnl ?? 0), 0);
|
|
21
|
+
const summary = `${trades.length} trade(s): ${wins.length}W / ${losses.length}L, net P&L ${netPnl >= 0 ? "+" : ""}${netPnl.toFixed(2)}`;
|
|
22
|
+
const lines = trades.map((t) => `• [${t.entryTime ?? "?"}] ${t.action ?? "?"} ${t.ticker ?? "?"} qty=${t.quantity ?? "?"} ` +
|
|
23
|
+
`entry=${t.entryPrice ?? "?"} exit=${t.exitPrice ?? "?"} pnl=${t.pnl != null ? (t.pnl >= 0 ? "+" : "") + t.pnl.toFixed(2) : "?"}`);
|
|
24
|
+
return {
|
|
25
|
+
content: [
|
|
26
|
+
{ type: "text", text: `${summary}\n${lines.join("\n")}` },
|
|
27
|
+
{ type: "text", text: JSON.stringify(trades, null, 2) },
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
return makeErrorResult(err);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export async function getJournalDashboard(client, _resolver, _input) {
|
|
36
|
+
try {
|
|
37
|
+
const bundle = await client.get("/api/journal/dashboard-bundle");
|
|
38
|
+
const pnlStr = bundle.netPnl != null
|
|
39
|
+
? `${bundle.netPnl >= 0 ? "+" : ""}${bundle.netPnl.toFixed(2)}`
|
|
40
|
+
: "?";
|
|
41
|
+
const winRateStr = bundle.winRate != null ? `${(bundle.winRate * 100).toFixed(1)}%` : "?";
|
|
42
|
+
const pfStr = bundle.profitFactor != null ? bundle.profitFactor.toFixed(2) : "?";
|
|
43
|
+
const summary = [
|
|
44
|
+
`Net P&L: ${pnlStr}`,
|
|
45
|
+
`Trades: ${bundle.tradeCount ?? "?"} (${bundle.winCount ?? "?"}W / ${bundle.lossCount ?? "?"}L)`,
|
|
46
|
+
`Win rate: ${winRateStr}`,
|
|
47
|
+
`Profit factor: ${pfStr}`,
|
|
48
|
+
bundle.avgWin != null ? `Avg win: +${bundle.avgWin.toFixed(2)}` : null,
|
|
49
|
+
bundle.avgLoss != null ? `Avg loss: ${bundle.avgLoss.toFixed(2)}` : null,
|
|
50
|
+
bundle.maxDrawdown != null ? `Max drawdown: ${bundle.maxDrawdown.toFixed(2)}` : null,
|
|
51
|
+
bundle.sharpe != null ? `Sharpe: ${bundle.sharpe.toFixed(2)}` : null,
|
|
52
|
+
]
|
|
53
|
+
.filter(Boolean)
|
|
54
|
+
.join(" | ");
|
|
55
|
+
return {
|
|
56
|
+
content: [
|
|
57
|
+
{ type: "text", text: summary },
|
|
58
|
+
{ type: "text", text: JSON.stringify(bundle, null, 2) },
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
return makeErrorResult(err);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export async function getJournalEntries(client, _resolver, input) {
|
|
67
|
+
try {
|
|
68
|
+
const params = new URLSearchParams();
|
|
69
|
+
if (input.startDate)
|
|
70
|
+
params.set("startDate", String(input.startDate));
|
|
71
|
+
if (input.endDate)
|
|
72
|
+
params.set("endDate", String(input.endDate));
|
|
73
|
+
const qs = params.toString() ? `?${params}` : "";
|
|
74
|
+
const entries = await client.get(`/api/journal/entries${qs}`);
|
|
75
|
+
if (!entries.length) {
|
|
76
|
+
return { content: [{ type: "text", text: "No journal entries found." }, { type: "text", text: "[]" }] };
|
|
77
|
+
}
|
|
78
|
+
const lines = entries.map((e) => `• [${e.date ?? e.createdAt ?? "?"}] ${e.text ?? ""}`);
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{ type: "text", text: `${entries.length} entry(ies):\n${lines.join("\n")}` },
|
|
82
|
+
{ type: "text", text: JSON.stringify(entries, null, 2) },
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
return makeErrorResult(err);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export async function addJournalEntry(client, _resolver, input) {
|
|
91
|
+
const date = String(input.date ?? "");
|
|
92
|
+
const text = String(input.text ?? "");
|
|
93
|
+
if (!date || !text)
|
|
94
|
+
return makeErrorResult(new Error("date and text are required"));
|
|
95
|
+
try {
|
|
96
|
+
const entry = await client.post("/api/journal/entries", { date, text });
|
|
97
|
+
return {
|
|
98
|
+
content: [
|
|
99
|
+
{ type: "text", text: `Journal entry created (id=${entry.id ?? "?"}): [${date}] ${text}` },
|
|
100
|
+
{ type: "text", text: JSON.stringify(entry, null, 2) },
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
return makeErrorResult(err);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.js","sourceRoot":"","sources":["../../src/tools/journal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.test.js","sourceRoot":"","sources":["../../src/tools/journal.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { VantageClient } from "../client.js";
|
|
2
|
+
import { UserResolver, ToolResult } from "../user.js";
|
|
3
|
+
export declare function listQcAlgorithms(client: VantageClient, _resolver: UserResolver, _input: Record<string, unknown>): Promise<ToolResult>;
|
|
4
|
+
export declare function getQcAlgorithm(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
5
|
+
export declare function getAlgorithmFile(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
6
|
+
export declare function createQcAlgorithm(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
7
|
+
export declare function updateQcAlgorithm(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
8
|
+
export declare function listStrategyInstances(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
9
|
+
export declare function getStrategyInstance(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
10
|
+
export declare function launchStrategy(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
11
|
+
export declare function stopStrategy(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
12
|
+
export declare function getStrategyLogs(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
13
|
+
export declare function getStrategyStats(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|
|
14
|
+
export declare function getStrategyOrders(client: VantageClient, _resolver: UserResolver, input: Record<string, unknown>): Promise<ToolResult>;
|