@trading-boy/cli 1.11.0 → 2.0.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/README.md +50 -22
- package/dist/api-client.d.ts +4 -7
- package/dist/api-client.js +8 -13
- package/dist/cli.bundle.js +1977 -33976
- package/dist/credentials.js +1 -1
- package/dist/index.d.ts +0 -28
- package/dist/index.js +0 -24
- package/dist/logger.d.ts +8 -0
- package/dist/logger.js +12 -0
- package/dist/utils.js +3 -3
- package/package.json +20 -5
- package/dist/cli.d.ts +0 -5
- package/dist/cli.js +0 -157
- package/dist/commands/agent-cmd.d.ts +0 -9
- package/dist/commands/agent-cmd.js +0 -572
- package/dist/commands/audit.d.ts +0 -18
- package/dist/commands/audit.js +0 -73
- package/dist/commands/behavioral.d.ts +0 -73
- package/dist/commands/behavioral.js +0 -349
- package/dist/commands/benchmark-cmd.d.ts +0 -3
- package/dist/commands/benchmark-cmd.js +0 -191
- package/dist/commands/billing.d.ts +0 -12
- package/dist/commands/billing.js +0 -142
- package/dist/commands/catalysts.d.ts +0 -17
- package/dist/commands/catalysts.js +0 -151
- package/dist/commands/coaching-cmd.d.ts +0 -16
- package/dist/commands/coaching-cmd.js +0 -222
- package/dist/commands/config-cmd.d.ts +0 -30
- package/dist/commands/config-cmd.js +0 -515
- package/dist/commands/connect-chatgpt.d.ts +0 -5
- package/dist/commands/connect-chatgpt.js +0 -293
- package/dist/commands/connect-claude.d.ts +0 -5
- package/dist/commands/connect-claude.js +0 -280
- package/dist/commands/context.d.ts +0 -41
- package/dist/commands/context.js +0 -405
- package/dist/commands/cron-cmd.d.ts +0 -3
- package/dist/commands/cron-cmd.js +0 -305
- package/dist/commands/decisions.d.ts +0 -57
- package/dist/commands/decisions.js +0 -364
- package/dist/commands/edge-cmd.d.ts +0 -78
- package/dist/commands/edge-cmd.js +0 -183
- package/dist/commands/edge-guard-cmd.d.ts +0 -36
- package/dist/commands/edge-guard-cmd.js +0 -169
- package/dist/commands/events.d.ts +0 -3
- package/dist/commands/events.js +0 -117
- package/dist/commands/infra.d.ts +0 -24
- package/dist/commands/infra.js +0 -137
- package/dist/commands/journal.d.ts +0 -3
- package/dist/commands/journal.js +0 -302
- package/dist/commands/login.d.ts +0 -18
- package/dist/commands/login.js +0 -127
- package/dist/commands/logout.d.ts +0 -8
- package/dist/commands/logout.js +0 -108
- package/dist/commands/narratives.d.ts +0 -3
- package/dist/commands/narratives.js +0 -259
- package/dist/commands/onboarding.d.ts +0 -7
- package/dist/commands/onboarding.js +0 -298
- package/dist/commands/query.d.ts +0 -32
- package/dist/commands/query.js +0 -135
- package/dist/commands/replay-cmd.d.ts +0 -43
- package/dist/commands/replay-cmd.js +0 -184
- package/dist/commands/review.d.ts +0 -3
- package/dist/commands/review.js +0 -443
- package/dist/commands/risk.d.ts +0 -47
- package/dist/commands/risk.js +0 -158
- package/dist/commands/social.d.ts +0 -43
- package/dist/commands/social.js +0 -318
- package/dist/commands/soul-wizard.d.ts +0 -29
- package/dist/commands/soul-wizard.js +0 -155
- package/dist/commands/strategy-cmd.d.ts +0 -44
- package/dist/commands/strategy-cmd.js +0 -340
- package/dist/commands/subscribe.d.ts +0 -78
- package/dist/commands/subscribe.js +0 -552
- package/dist/commands/suggestions-cmd.d.ts +0 -24
- package/dist/commands/suggestions-cmd.js +0 -148
- package/dist/commands/thesis-cmd.d.ts +0 -3
- package/dist/commands/thesis-cmd.js +0 -129
- package/dist/commands/trader.d.ts +0 -30
- package/dist/commands/trader.js +0 -971
- package/dist/commands/watch.d.ts +0 -16
- package/dist/commands/watch.js +0 -104
- package/dist/commands/whoami.d.ts +0 -14
- package/dist/commands/whoami.js +0 -105
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
// ─── Cron CLI Commands ───
|
|
2
|
-
//
|
|
3
|
-
// tb cron create — Create a new cron job
|
|
4
|
-
// tb cron list — List cron jobs
|
|
5
|
-
// tb cron show — Show a single job
|
|
6
|
-
// tb cron pause — Pause a job
|
|
7
|
-
// tb cron resume — Resume a paused job
|
|
8
|
-
// tb cron delete — Delete a job
|
|
9
|
-
// tb cron run — Trigger immediate execution
|
|
10
|
-
// tb cron history — View execution history
|
|
11
|
-
import { Option } from 'commander';
|
|
12
|
-
import chalk from 'chalk';
|
|
13
|
-
import { createLogger } from '@trading-boy/core';
|
|
14
|
-
import { apiRequest } from '../api-client.js';
|
|
15
|
-
import { padRight, handleApiError, ensureRemote } from '../utils.js';
|
|
16
|
-
const logger = createLogger('cli-cron');
|
|
17
|
-
// ─── Formatters ───
|
|
18
|
-
function formatShortDate(isoString) {
|
|
19
|
-
if (!isoString)
|
|
20
|
-
return chalk.dim('—');
|
|
21
|
-
try {
|
|
22
|
-
return new Date(isoString).toISOString().slice(0, 19).replace('T', ' ');
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return isoString;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
function formatStatus(status) {
|
|
29
|
-
switch (status) {
|
|
30
|
-
case 'active': return chalk.green('active');
|
|
31
|
-
case 'paused': return chalk.yellow('paused');
|
|
32
|
-
case 'deleted': return chalk.red('deleted');
|
|
33
|
-
case 'completed': return chalk.green('completed');
|
|
34
|
-
case 'failed': return chalk.red('failed');
|
|
35
|
-
case 'running': return chalk.cyan('running');
|
|
36
|
-
default: return status;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
// ─── Command Registration ───
|
|
40
|
-
export function registerCronCommand(program) {
|
|
41
|
-
const cron = program
|
|
42
|
-
.command('cron')
|
|
43
|
-
.description('Manage scheduled cron jobs');
|
|
44
|
-
// ── create ──────────────────────────────────────────────────────────────────
|
|
45
|
-
cron
|
|
46
|
-
.command('create')
|
|
47
|
-
.description('Create a new cron job')
|
|
48
|
-
.requiredOption('--schedule <schedule>', 'Schedule: "every 15m", "daily at 9am EST", or cron expression')
|
|
49
|
-
.requiredOption('--type <type>', 'Job type: price_alert, custom_prompt, market_scan, portfolio_check, context_refresh')
|
|
50
|
-
.option('--name <name>', 'Job name (auto-generated if omitted)')
|
|
51
|
-
.option('--tokens <symbols>', 'Comma-separated token symbols (for market_scan)')
|
|
52
|
-
.option('--condition <condition>', 'Price condition, e.g. "BTC > 100000" (for price_alert)')
|
|
53
|
-
.option('--prompt <prompt>', 'Prompt text (for custom_prompt)')
|
|
54
|
-
.option('--delivery <channel>', 'Delivery channel: telegram, email, stream, silent', 'silent')
|
|
55
|
-
.option('--delivery-target <target>', 'Delivery target (chat ID, email address)')
|
|
56
|
-
.option('--timezone <tz>', 'Timezone (IANA name or abbreviation)')
|
|
57
|
-
.addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
|
|
58
|
-
.action(async (options) => {
|
|
59
|
-
if (!(await ensureRemote()))
|
|
60
|
-
return;
|
|
61
|
-
// Build config from options
|
|
62
|
-
const config = {};
|
|
63
|
-
if (options.tokens)
|
|
64
|
-
config.tokens = options.tokens.split(',').map((t) => t.trim().toUpperCase());
|
|
65
|
-
if (options.condition) {
|
|
66
|
-
// Extract token symbol from condition for price_alert
|
|
67
|
-
const match = options.condition.match(/^(\w+)\s/);
|
|
68
|
-
if (match)
|
|
69
|
-
config.tokenSymbol = match[1].toUpperCase();
|
|
70
|
-
config.condition = options.condition;
|
|
71
|
-
}
|
|
72
|
-
if (options.prompt)
|
|
73
|
-
config.prompt = options.prompt;
|
|
74
|
-
const name = options.name ?? `${options.type}: ${options.schedule}`;
|
|
75
|
-
try {
|
|
76
|
-
const result = await apiRequest('/api/v1/cron', {
|
|
77
|
-
method: 'POST',
|
|
78
|
-
body: {
|
|
79
|
-
name,
|
|
80
|
-
schedule: options.schedule,
|
|
81
|
-
type: options.type,
|
|
82
|
-
config,
|
|
83
|
-
delivery: options.delivery,
|
|
84
|
-
deliveryTarget: options.deliveryTarget,
|
|
85
|
-
timezone: options.timezone,
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
if (options.format === 'json') {
|
|
89
|
-
console.log(JSON.stringify(result, null, 2));
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
console.log('');
|
|
93
|
-
console.log(chalk.green(' Cron job created'));
|
|
94
|
-
console.log(` ${chalk.gray('ID:')} ${result.id}`);
|
|
95
|
-
console.log(` ${chalk.gray('Name:')} ${result.name}`);
|
|
96
|
-
console.log(` ${chalk.gray('Schedule:')} ${result.schedule} → ${chalk.dim(result.cronExpression)}`);
|
|
97
|
-
console.log(` ${chalk.gray('Timezone:')} ${result.timezone}`);
|
|
98
|
-
console.log(` ${chalk.gray('Type:')} ${result.type}`);
|
|
99
|
-
console.log(` ${chalk.gray('Next run:')} ${formatShortDate(result.nextRunAt)}`);
|
|
100
|
-
console.log('');
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
catch (error) {
|
|
104
|
-
handleApiError(error, 'Cron create failed', logger);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
// ── list ────────────────────────────────────────────────────────────────────
|
|
108
|
-
cron
|
|
109
|
-
.command('list')
|
|
110
|
-
.description('List cron jobs')
|
|
111
|
-
.option('--status <status>', 'Filter by status: active, paused')
|
|
112
|
-
.addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
|
|
113
|
-
.action(async (options) => {
|
|
114
|
-
if (!(await ensureRemote()))
|
|
115
|
-
return;
|
|
116
|
-
try {
|
|
117
|
-
const query = options.status ? `?status=${options.status}` : '';
|
|
118
|
-
const result = await apiRequest(`/api/v1/cron${query}`);
|
|
119
|
-
if (options.format === 'json') {
|
|
120
|
-
console.log(JSON.stringify(result, null, 2));
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
if (result.jobs.length === 0) {
|
|
124
|
-
console.log(chalk.dim(' No cron jobs found'));
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
console.log('');
|
|
128
|
-
console.log(' ' +
|
|
129
|
-
padRight('Name', 30) +
|
|
130
|
-
padRight('Type', 16) +
|
|
131
|
-
padRight('Schedule', 20) +
|
|
132
|
-
padRight('Status', 10) +
|
|
133
|
-
padRight('Runs', 6) +
|
|
134
|
-
'Next Run');
|
|
135
|
-
console.log(chalk.gray(' ' + '─'.repeat(100)));
|
|
136
|
-
for (const job of result.jobs) {
|
|
137
|
-
console.log(' ' +
|
|
138
|
-
padRight(job.name.slice(0, 28), 30) +
|
|
139
|
-
padRight(job.type, 16) +
|
|
140
|
-
padRight(job.schedule.slice(0, 18), 20) +
|
|
141
|
-
padRight(formatStatus(job.status), 10) +
|
|
142
|
-
padRight(String(job.runCount), 6) +
|
|
143
|
-
formatShortDate(job.nextRunAt));
|
|
144
|
-
}
|
|
145
|
-
console.log('');
|
|
146
|
-
console.log(chalk.dim(` ${result.count} job(s)`));
|
|
147
|
-
console.log('');
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
handleApiError(error, 'Cron list failed', logger);
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
// ── show ────────────────────────────────────────────────────────────────────
|
|
154
|
-
cron
|
|
155
|
-
.command('show <jobId>')
|
|
156
|
-
.description('Show details of a cron job')
|
|
157
|
-
.addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
|
|
158
|
-
.action(async (jobId, options) => {
|
|
159
|
-
if (!(await ensureRemote()))
|
|
160
|
-
return;
|
|
161
|
-
try {
|
|
162
|
-
const result = await apiRequest(`/api/v1/cron/${encodeURIComponent(jobId)}`);
|
|
163
|
-
if (options.format === 'json') {
|
|
164
|
-
console.log(JSON.stringify(result.job, null, 2));
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
const job = result.job;
|
|
168
|
-
console.log('');
|
|
169
|
-
console.log(chalk.bold.cyan(` Cron Job — ${job.name}`));
|
|
170
|
-
console.log(chalk.gray(' ' + '─'.repeat(50)));
|
|
171
|
-
console.log(` ${chalk.gray('ID:')} ${job.id}`);
|
|
172
|
-
console.log(` ${chalk.gray('Status:')} ${formatStatus(job.status)}`);
|
|
173
|
-
console.log(` ${chalk.gray('Type:')} ${job.type}`);
|
|
174
|
-
console.log(` ${chalk.gray('Schedule:')} ${job.schedule} → ${chalk.dim(job.cronExpression)}`);
|
|
175
|
-
console.log(` ${chalk.gray('Timezone:')} ${job.timezone}`);
|
|
176
|
-
console.log(` ${chalk.gray('Delivery:')} ${job.delivery}${job.deliveryTarget ? ` → ${job.deliveryTarget}` : ''}`);
|
|
177
|
-
console.log(` ${chalk.gray('Run count:')} ${job.runCount}`);
|
|
178
|
-
console.log(` ${chalk.gray('Last run:')} ${formatShortDate(job.lastRunAt)}`);
|
|
179
|
-
console.log(` ${chalk.gray('Next run:')} ${formatShortDate(job.nextRunAt)}`);
|
|
180
|
-
console.log(` ${chalk.gray('Created:')} ${formatShortDate(job.createdAt)}`);
|
|
181
|
-
console.log('');
|
|
182
|
-
}
|
|
183
|
-
catch (error) {
|
|
184
|
-
handleApiError(error, 'Cron show failed', logger);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
// ── pause ───────────────────────────────────────────────────────────────────
|
|
188
|
-
cron
|
|
189
|
-
.command('pause <jobId>')
|
|
190
|
-
.description('Pause a cron job')
|
|
191
|
-
.action(async (jobId) => {
|
|
192
|
-
if (!(await ensureRemote()))
|
|
193
|
-
return;
|
|
194
|
-
try {
|
|
195
|
-
await apiRequest(`/api/v1/cron/${encodeURIComponent(jobId)}`, {
|
|
196
|
-
method: 'PATCH',
|
|
197
|
-
body: { status: 'paused' },
|
|
198
|
-
});
|
|
199
|
-
console.log(chalk.green(` Job ${jobId} paused`));
|
|
200
|
-
}
|
|
201
|
-
catch (error) {
|
|
202
|
-
handleApiError(error, 'Cron pause failed', logger);
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
// ── resume ──────────────────────────────────────────────────────────────────
|
|
206
|
-
cron
|
|
207
|
-
.command('resume <jobId>')
|
|
208
|
-
.description('Resume a paused cron job')
|
|
209
|
-
.action(async (jobId) => {
|
|
210
|
-
if (!(await ensureRemote()))
|
|
211
|
-
return;
|
|
212
|
-
try {
|
|
213
|
-
await apiRequest(`/api/v1/cron/${encodeURIComponent(jobId)}`, {
|
|
214
|
-
method: 'PATCH',
|
|
215
|
-
body: { status: 'active' },
|
|
216
|
-
});
|
|
217
|
-
console.log(chalk.green(` Job ${jobId} resumed`));
|
|
218
|
-
}
|
|
219
|
-
catch (error) {
|
|
220
|
-
handleApiError(error, 'Cron resume failed', logger);
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
// ── delete ──────────────────────────────────────────────────────────────────
|
|
224
|
-
cron
|
|
225
|
-
.command('delete <jobId>')
|
|
226
|
-
.description('Delete a cron job')
|
|
227
|
-
.action(async (jobId) => {
|
|
228
|
-
if (!(await ensureRemote()))
|
|
229
|
-
return;
|
|
230
|
-
try {
|
|
231
|
-
await apiRequest(`/api/v1/cron/${encodeURIComponent(jobId)}`, {
|
|
232
|
-
method: 'DELETE',
|
|
233
|
-
});
|
|
234
|
-
console.log(chalk.green(` Job ${jobId} deleted`));
|
|
235
|
-
}
|
|
236
|
-
catch (error) {
|
|
237
|
-
handleApiError(error, 'Cron delete failed', logger);
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
// ── run ─────────────────────────────────────────────────────────────────────
|
|
241
|
-
cron
|
|
242
|
-
.command('run <jobId>')
|
|
243
|
-
.description('Trigger immediate execution of a cron job')
|
|
244
|
-
.action(async (jobId) => {
|
|
245
|
-
if (!(await ensureRemote()))
|
|
246
|
-
return;
|
|
247
|
-
try {
|
|
248
|
-
await apiRequest(`/api/v1/cron/${encodeURIComponent(jobId)}/run`, {
|
|
249
|
-
method: 'POST',
|
|
250
|
-
});
|
|
251
|
-
console.log(chalk.green(` Job ${jobId} execution triggered`));
|
|
252
|
-
}
|
|
253
|
-
catch (error) {
|
|
254
|
-
handleApiError(error, 'Cron run failed', logger);
|
|
255
|
-
}
|
|
256
|
-
});
|
|
257
|
-
// ── history ─────────────────────────────────────────────────────────────────
|
|
258
|
-
cron
|
|
259
|
-
.command('history <jobId>')
|
|
260
|
-
.description('View execution history for a cron job')
|
|
261
|
-
.option('--limit <n>', 'Number of runs to show', '20')
|
|
262
|
-
.addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
|
|
263
|
-
.action(async (jobId, options) => {
|
|
264
|
-
if (!(await ensureRemote()))
|
|
265
|
-
return;
|
|
266
|
-
try {
|
|
267
|
-
const limit = parseInt(options.limit, 10) || 20;
|
|
268
|
-
const result = await apiRequest(`/api/v1/cron/${encodeURIComponent(jobId)}/history?limit=${limit}`);
|
|
269
|
-
if (options.format === 'json') {
|
|
270
|
-
console.log(JSON.stringify(result, null, 2));
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
if (result.runs.length === 0) {
|
|
274
|
-
console.log(chalk.dim(' No execution history'));
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
console.log('');
|
|
278
|
-
console.log(' ' +
|
|
279
|
-
padRight('Time', 22) +
|
|
280
|
-
padRight('Status', 12) +
|
|
281
|
-
padRight('Tokens', 8) +
|
|
282
|
-
padRight('Delivered', 10) +
|
|
283
|
-
'Result');
|
|
284
|
-
console.log(chalk.gray(' ' + '─'.repeat(90)));
|
|
285
|
-
for (const run of result.runs) {
|
|
286
|
-
const summary = run.error
|
|
287
|
-
? chalk.red(run.error.slice(0, 40))
|
|
288
|
-
: (run.resultSummary?.slice(0, 40) ?? chalk.dim('—'));
|
|
289
|
-
console.log(' ' +
|
|
290
|
-
padRight(formatShortDate(run.time), 22) +
|
|
291
|
-
padRight(formatStatus(run.status), 12) +
|
|
292
|
-
padRight(String(run.tokensUsed), 8) +
|
|
293
|
-
padRight(run.delivered ? chalk.green('yes') : chalk.dim('no'), 10) +
|
|
294
|
-
summary);
|
|
295
|
-
}
|
|
296
|
-
console.log('');
|
|
297
|
-
console.log(chalk.dim(` ${result.count} run(s)`));
|
|
298
|
-
console.log('');
|
|
299
|
-
}
|
|
300
|
-
catch (error) {
|
|
301
|
-
handleApiError(error, 'Cron history failed', logger);
|
|
302
|
-
}
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
//# sourceMappingURL=cron-cmd.js.map
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
interface DecisionEventRecord {
|
|
3
|
-
id: string;
|
|
4
|
-
type: string;
|
|
5
|
-
decisionType: string;
|
|
6
|
-
tokenSymbol: string;
|
|
7
|
-
direction: string | null;
|
|
8
|
-
setupType: string | null;
|
|
9
|
-
entryPrice: number | null;
|
|
10
|
-
exitPrice: number | null;
|
|
11
|
-
price?: number;
|
|
12
|
-
sizeTokens?: number;
|
|
13
|
-
sizeUsd?: number;
|
|
14
|
-
thesis?: string;
|
|
15
|
-
confidence: number | null;
|
|
16
|
-
emotionalTag: string | null;
|
|
17
|
-
pnlUsd: number | null;
|
|
18
|
-
pnlPercent: number | null;
|
|
19
|
-
pnlAbsolute: number | null;
|
|
20
|
-
holdDurationMs: number | null;
|
|
21
|
-
eventTime: string;
|
|
22
|
-
timestamp: string;
|
|
23
|
-
traderId: string;
|
|
24
|
-
linkedEntryId?: string;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Format the decisions list output.
|
|
28
|
-
*/
|
|
29
|
-
export declare function formatDecisionsOutput(decisions: DecisionEventRecord[]): string;
|
|
30
|
-
/**
|
|
31
|
-
* Format the stats output.
|
|
32
|
-
*/
|
|
33
|
-
export declare function formatStatsOutput(stats: DecisionStats, label?: string): string;
|
|
34
|
-
/**
|
|
35
|
-
* Format stats grouped by setup type as a summary table.
|
|
36
|
-
*/
|
|
37
|
-
export declare function formatSetupTypeStats(statsBySetup: Map<string, DecisionStats>): string;
|
|
38
|
-
export declare function registerDecisionsCommand(program: Command): void;
|
|
39
|
-
interface DecisionStats {
|
|
40
|
-
totalTrades: number;
|
|
41
|
-
wins: number;
|
|
42
|
-
losses: number;
|
|
43
|
-
breakeven: number;
|
|
44
|
-
winRate: number;
|
|
45
|
-
totalPnl: number;
|
|
46
|
-
avgPnl: number;
|
|
47
|
-
avgPnlPercent: number;
|
|
48
|
-
avgHoldDurationMs: number;
|
|
49
|
-
bestTrade: DecisionEventRecord | null;
|
|
50
|
-
worstTrade: DecisionEventRecord | null;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Parse a period string like "7d", "30d", "90d" into milliseconds.
|
|
54
|
-
*/
|
|
55
|
-
export declare function parsePeriod(period: string): number;
|
|
56
|
-
export {};
|
|
57
|
-
//# sourceMappingURL=decisions.d.ts.map
|