@tradingboy/cli 0.3.8

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.
Files changed (142) hide show
  1. package/README.md +8 -0
  2. package/dist/api-client.d.ts +35 -0
  3. package/dist/api-client.d.ts.map +1 -0
  4. package/dist/api-client.js +165 -0
  5. package/dist/api-client.js.map +1 -0
  6. package/dist/cli.d.ts +5 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +143 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/commands/audit.d.ts +18 -0
  11. package/dist/commands/audit.d.ts.map +1 -0
  12. package/dist/commands/audit.js +73 -0
  13. package/dist/commands/audit.js.map +1 -0
  14. package/dist/commands/behavioral.d.ts +73 -0
  15. package/dist/commands/behavioral.d.ts.map +1 -0
  16. package/dist/commands/behavioral.js +349 -0
  17. package/dist/commands/behavioral.js.map +1 -0
  18. package/dist/commands/benchmark-cmd.d.ts +3 -0
  19. package/dist/commands/benchmark-cmd.d.ts.map +1 -0
  20. package/dist/commands/benchmark-cmd.js +196 -0
  21. package/dist/commands/benchmark-cmd.js.map +1 -0
  22. package/dist/commands/billing.d.ts +12 -0
  23. package/dist/commands/billing.d.ts.map +1 -0
  24. package/dist/commands/billing.js +117 -0
  25. package/dist/commands/billing.js.map +1 -0
  26. package/dist/commands/catalysts.d.ts +17 -0
  27. package/dist/commands/catalysts.d.ts.map +1 -0
  28. package/dist/commands/catalysts.js +151 -0
  29. package/dist/commands/catalysts.js.map +1 -0
  30. package/dist/commands/coaching-cmd.d.ts +16 -0
  31. package/dist/commands/coaching-cmd.d.ts.map +1 -0
  32. package/dist/commands/coaching-cmd.js +231 -0
  33. package/dist/commands/coaching-cmd.js.map +1 -0
  34. package/dist/commands/config-cmd.d.ts +30 -0
  35. package/dist/commands/config-cmd.d.ts.map +1 -0
  36. package/dist/commands/config-cmd.js +378 -0
  37. package/dist/commands/config-cmd.js.map +1 -0
  38. package/dist/commands/context.d.ts +41 -0
  39. package/dist/commands/context.d.ts.map +1 -0
  40. package/dist/commands/context.js +391 -0
  41. package/dist/commands/context.js.map +1 -0
  42. package/dist/commands/decisions.d.ts +57 -0
  43. package/dist/commands/decisions.d.ts.map +1 -0
  44. package/dist/commands/decisions.js +352 -0
  45. package/dist/commands/decisions.js.map +1 -0
  46. package/dist/commands/edge-cmd.d.ts +78 -0
  47. package/dist/commands/edge-cmd.d.ts.map +1 -0
  48. package/dist/commands/edge-cmd.js +185 -0
  49. package/dist/commands/edge-cmd.js.map +1 -0
  50. package/dist/commands/edge-guard-cmd.d.ts +36 -0
  51. package/dist/commands/edge-guard-cmd.d.ts.map +1 -0
  52. package/dist/commands/edge-guard-cmd.js +174 -0
  53. package/dist/commands/edge-guard-cmd.js.map +1 -0
  54. package/dist/commands/events.d.ts +3 -0
  55. package/dist/commands/events.d.ts.map +1 -0
  56. package/dist/commands/events.js +117 -0
  57. package/dist/commands/events.js.map +1 -0
  58. package/dist/commands/infra.d.ts +20 -0
  59. package/dist/commands/infra.d.ts.map +1 -0
  60. package/dist/commands/infra.js +130 -0
  61. package/dist/commands/infra.js.map +1 -0
  62. package/dist/commands/journal.d.ts +3 -0
  63. package/dist/commands/journal.d.ts.map +1 -0
  64. package/dist/commands/journal.js +281 -0
  65. package/dist/commands/journal.js.map +1 -0
  66. package/dist/commands/login.d.ts +18 -0
  67. package/dist/commands/login.d.ts.map +1 -0
  68. package/dist/commands/login.js +121 -0
  69. package/dist/commands/login.js.map +1 -0
  70. package/dist/commands/logout.d.ts +7 -0
  71. package/dist/commands/logout.d.ts.map +1 -0
  72. package/dist/commands/logout.js +39 -0
  73. package/dist/commands/logout.js.map +1 -0
  74. package/dist/commands/narratives.d.ts +3 -0
  75. package/dist/commands/narratives.d.ts.map +1 -0
  76. package/dist/commands/narratives.js +259 -0
  77. package/dist/commands/narratives.js.map +1 -0
  78. package/dist/commands/onboarding.d.ts +7 -0
  79. package/dist/commands/onboarding.d.ts.map +1 -0
  80. package/dist/commands/onboarding.js +126 -0
  81. package/dist/commands/onboarding.js.map +1 -0
  82. package/dist/commands/query.d.ts +32 -0
  83. package/dist/commands/query.d.ts.map +1 -0
  84. package/dist/commands/query.js +132 -0
  85. package/dist/commands/query.js.map +1 -0
  86. package/dist/commands/replay-cmd.d.ts +43 -0
  87. package/dist/commands/replay-cmd.d.ts.map +1 -0
  88. package/dist/commands/replay-cmd.js +215 -0
  89. package/dist/commands/replay-cmd.js.map +1 -0
  90. package/dist/commands/review.d.ts +3 -0
  91. package/dist/commands/review.d.ts.map +1 -0
  92. package/dist/commands/review.js +443 -0
  93. package/dist/commands/review.js.map +1 -0
  94. package/dist/commands/risk.d.ts +47 -0
  95. package/dist/commands/risk.d.ts.map +1 -0
  96. package/dist/commands/risk.js +156 -0
  97. package/dist/commands/risk.js.map +1 -0
  98. package/dist/commands/social.d.ts +43 -0
  99. package/dist/commands/social.d.ts.map +1 -0
  100. package/dist/commands/social.js +318 -0
  101. package/dist/commands/social.js.map +1 -0
  102. package/dist/commands/strategy-cmd.d.ts +44 -0
  103. package/dist/commands/strategy-cmd.d.ts.map +1 -0
  104. package/dist/commands/strategy-cmd.js +367 -0
  105. package/dist/commands/strategy-cmd.js.map +1 -0
  106. package/dist/commands/subscribe.d.ts +72 -0
  107. package/dist/commands/subscribe.d.ts.map +1 -0
  108. package/dist/commands/subscribe.js +480 -0
  109. package/dist/commands/subscribe.js.map +1 -0
  110. package/dist/commands/suggestions-cmd.d.ts +24 -0
  111. package/dist/commands/suggestions-cmd.d.ts.map +1 -0
  112. package/dist/commands/suggestions-cmd.js +142 -0
  113. package/dist/commands/suggestions-cmd.js.map +1 -0
  114. package/dist/commands/thesis-cmd.d.ts +3 -0
  115. package/dist/commands/thesis-cmd.d.ts.map +1 -0
  116. package/dist/commands/thesis-cmd.js +132 -0
  117. package/dist/commands/thesis-cmd.js.map +1 -0
  118. package/dist/commands/trader.d.ts +29 -0
  119. package/dist/commands/trader.d.ts.map +1 -0
  120. package/dist/commands/trader.js +292 -0
  121. package/dist/commands/trader.js.map +1 -0
  122. package/dist/commands/watch.d.ts +16 -0
  123. package/dist/commands/watch.d.ts.map +1 -0
  124. package/dist/commands/watch.js +88 -0
  125. package/dist/commands/watch.js.map +1 -0
  126. package/dist/commands/whoami.d.ts +14 -0
  127. package/dist/commands/whoami.d.ts.map +1 -0
  128. package/dist/commands/whoami.js +89 -0
  129. package/dist/commands/whoami.js.map +1 -0
  130. package/dist/credentials.d.ts +18 -0
  131. package/dist/credentials.d.ts.map +1 -0
  132. package/dist/credentials.js +168 -0
  133. package/dist/credentials.js.map +1 -0
  134. package/dist/index.d.ts +33 -0
  135. package/dist/index.d.ts.map +1 -0
  136. package/dist/index.js +28 -0
  137. package/dist/index.js.map +1 -0
  138. package/dist/utils.d.ts +51 -0
  139. package/dist/utils.d.ts.map +1 -0
  140. package/dist/utils.js +118 -0
  141. package/dist/utils.js.map +1 -0
  142. package/package.json +38 -0
@@ -0,0 +1,352 @@
1
+ import { Option } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { createLogger } from '@trading-boy/core';
4
+ import { padRight, parseIntOption, formatDate } from '../utils.js';
5
+ import { apiRequest, ApiError } from '../api-client.js';
6
+ // ─── Logger ───
7
+ const logger = createLogger('cli-decisions');
8
+ // ─── Default Trader ───
9
+ const DEFAULT_TRADER_ID = 'default';
10
+ // ─── Formatters ───
11
+ /**
12
+ * Format a PnL value with color coding.
13
+ */
14
+ function formatPnl(pnl) {
15
+ if (pnl === null) {
16
+ return chalk.dim('-');
17
+ }
18
+ const sign = pnl >= 0 ? '+' : '';
19
+ const str = `${sign}$${pnl.toFixed(2)}`;
20
+ return pnl > 0 ? chalk.green(str) : pnl < 0 ? chalk.red(str) : chalk.dim(str);
21
+ }
22
+ /**
23
+ * Format a percentage with color coding.
24
+ */
25
+ function formatPercent(pct) {
26
+ if (pct === null) {
27
+ return chalk.dim('-');
28
+ }
29
+ const sign = pct >= 0 ? '+' : '';
30
+ const str = `${sign}${pct.toFixed(2)}%`;
31
+ return pct > 0 ? chalk.green(str) : pct < 0 ? chalk.red(str) : chalk.dim(str);
32
+ }
33
+ /**
34
+ * Format a win rate as a colored percentage.
35
+ */
36
+ function formatWinRate(rate) {
37
+ const str = `${(rate * 100).toFixed(1)}%`;
38
+ if (rate >= 0.6) {
39
+ return chalk.green(str);
40
+ }
41
+ if (rate >= 0.4) {
42
+ return chalk.yellow(str);
43
+ }
44
+ return chalk.red(str);
45
+ }
46
+ /**
47
+ * Format milliseconds into a human-readable duration.
48
+ */
49
+ function formatDuration(ms) {
50
+ if (ms === 0) {
51
+ return chalk.dim('-');
52
+ }
53
+ const hours = Math.floor(ms / (1000 * 60 * 60));
54
+ const days = Math.floor(hours / 24);
55
+ const remainingHours = hours % 24;
56
+ if (days > 0) {
57
+ return `${days}d ${remainingHours}h`;
58
+ }
59
+ if (hours > 0) {
60
+ return `${hours}h`;
61
+ }
62
+ const minutes = Math.floor(ms / (1000 * 60));
63
+ return `${minutes}m`;
64
+ }
65
+ /**
66
+ * Format a decision record row for the decisions table.
67
+ */
68
+ function formatDecisionRow(d) {
69
+ const date = d.eventTime ? formatDate(d.eventTime) : '-';
70
+ const token = d.tokenSymbol ?? '-';
71
+ const setup = d.setupType ?? '-';
72
+ const dir = d.direction ?? '-';
73
+ const formatPrice = (p) => p < 0.01 ? p.toPrecision(3) : p.toFixed(2);
74
+ const price = d.entryPrice !== null
75
+ ? `$${formatPrice(d.entryPrice)}`
76
+ : d.exitPrice !== null
77
+ ? `$${formatPrice(d.exitPrice)}`
78
+ : '-';
79
+ const pnl = formatPnl(d.pnlAbsolute);
80
+ const pnlPct = formatPercent(d.pnlPercent);
81
+ return (' ' +
82
+ padRight(date, 14) +
83
+ padRight(token, 8) +
84
+ padRight(d.decisionType, 14) +
85
+ padRight(dir, 8) +
86
+ padRight(setup, 18) +
87
+ padRight(price, 12) +
88
+ padRight(pnl, 14) +
89
+ pnlPct);
90
+ }
91
+ /**
92
+ * Format the decisions list output.
93
+ */
94
+ export function formatDecisionsOutput(decisions) {
95
+ const lines = [];
96
+ lines.push('');
97
+ lines.push(chalk.bold.cyan(' Trade Decisions'));
98
+ lines.push(chalk.gray(' ' + '\u2500'.repeat(100)));
99
+ lines.push('');
100
+ if (decisions.length === 0) {
101
+ lines.push(` ${chalk.dim('No trade decisions found.')}`);
102
+ lines.push('');
103
+ return lines.join('\n');
104
+ }
105
+ // Header
106
+ lines.push(' ' +
107
+ padRight('Date', 14) +
108
+ padRight('Token', 8) +
109
+ padRight('Type', 14) +
110
+ padRight('Dir', 8) +
111
+ padRight('Setup', 18) +
112
+ padRight('Price', 12) +
113
+ padRight('PnL', 14) +
114
+ 'PnL %');
115
+ lines.push(' ' + '\u2500'.repeat(100));
116
+ for (const d of decisions) {
117
+ lines.push(formatDecisionRow(d));
118
+ }
119
+ lines.push('');
120
+ lines.push(` ${chalk.gray(`Total: ${decisions.length} decision(s)`)}`);
121
+ lines.push('');
122
+ return lines.join('\n');
123
+ }
124
+ /**
125
+ * Format the stats output.
126
+ */
127
+ export function formatStatsOutput(stats, label = 'Overall') {
128
+ const lines = [];
129
+ lines.push('');
130
+ lines.push(chalk.bold.cyan(` Trading Statistics: ${label}`));
131
+ lines.push(chalk.gray(' ' + '\u2500'.repeat(50)));
132
+ lines.push('');
133
+ if (stats.totalTrades === 0) {
134
+ lines.push(` ${chalk.dim('No completed trades with outcome data.')}`);
135
+ lines.push('');
136
+ return lines.join('\n');
137
+ }
138
+ lines.push(` ${chalk.gray('Total Trades:')} ${chalk.white(String(stats.totalTrades))}`);
139
+ lines.push(` ${chalk.gray('Win Rate:')} ${formatWinRate(stats.winRate)}`);
140
+ lines.push(` ${chalk.gray('Wins / Losses:')} ${chalk.green(String(stats.wins))} / ${chalk.red(String(stats.losses))}${stats.breakeven > 0 ? ` / ${chalk.dim(String(stats.breakeven) + ' BE')}` : ''}`);
141
+ lines.push('');
142
+ lines.push(` ${chalk.gray('Total PnL:')} ${formatPnl(stats.totalPnl)}`);
143
+ lines.push(` ${chalk.gray('Avg PnL:')} ${formatPnl(stats.avgPnl)}`);
144
+ lines.push(` ${chalk.gray('Avg PnL %:')} ${formatPercent(stats.avgPnlPercent)}`);
145
+ lines.push(` ${chalk.gray('Avg Hold Time:')} ${formatDuration(stats.avgHoldDurationMs)}`);
146
+ if (stats.bestTrade) {
147
+ const best = stats.bestTrade;
148
+ lines.push('');
149
+ lines.push(` ${chalk.gray('Best Trade:')} ${chalk.green(`+$${best.pnlAbsolute.toFixed(2)}`)} ${chalk.dim(`(${best.tokenSymbol} ${best.setupType ?? ''})`).trim()}`);
150
+ }
151
+ if (stats.worstTrade) {
152
+ const worst = stats.worstTrade;
153
+ lines.push(` ${chalk.gray('Worst Trade:')} ${chalk.red(`$${worst.pnlAbsolute.toFixed(2)}`)} ${chalk.dim(`(${worst.tokenSymbol} ${worst.setupType ?? ''})`).trim()}`);
154
+ }
155
+ lines.push('');
156
+ return lines.join('\n');
157
+ }
158
+ /**
159
+ * Format stats grouped by setup type as a summary table.
160
+ */
161
+ export function formatSetupTypeStats(statsBySetup) {
162
+ const lines = [];
163
+ lines.push('');
164
+ lines.push(chalk.bold(' Performance by Setup Type:'));
165
+ lines.push('');
166
+ if (statsBySetup.size === 0) {
167
+ lines.push(` ${chalk.dim('No setup type data available.')}`);
168
+ lines.push('');
169
+ return lines.join('\n');
170
+ }
171
+ lines.push(' ' +
172
+ padRight('Setup', 20) +
173
+ padRight('Trades', 8) +
174
+ padRight('Win Rate', 10) +
175
+ padRight('Avg PnL', 12) +
176
+ padRight('Total PnL', 14));
177
+ lines.push(' ' + '\u2500'.repeat(64));
178
+ // Sort by total PnL descending
179
+ const sorted = [...statsBySetup.entries()].sort((a, b) => b[1].totalPnl - a[1].totalPnl);
180
+ for (const [setup, s] of sorted) {
181
+ lines.push(' ' +
182
+ padRight(setup, 20) +
183
+ padRight(String(s.totalTrades), 8) +
184
+ padRight(formatWinRate(s.winRate), 10) +
185
+ padRight(formatPnl(s.avgPnl), 12) +
186
+ formatPnl(s.totalPnl));
187
+ }
188
+ lines.push('');
189
+ return lines.join('\n');
190
+ }
191
+ // ─── Command Registration ───
192
+ export function registerDecisionsCommand(program) {
193
+ // ─── decisions command ───
194
+ program
195
+ .command('decisions')
196
+ .description('Show trade decision history with outcomes')
197
+ .option('--token <symbol>', 'Filter by token symbol')
198
+ .option('--setup <type>', 'Filter by setup type (BREAKOUT, MOMENTUM, etc.)')
199
+ .option('--limit <n>', 'Maximum number of results', parseIntOption, 20)
200
+ .option('--trader <traderId>', 'Trader ID')
201
+ .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
202
+ .action(async (options) => {
203
+ try {
204
+ const params = new URLSearchParams();
205
+ if (options.trader)
206
+ params.set('traderId', options.trader);
207
+ if (options.token)
208
+ params.set('tokenSymbol', options.token.toUpperCase());
209
+ if (options.setup)
210
+ params.set('setupType', options.setup);
211
+ if (options.limit)
212
+ params.set('limit', String(options.limit));
213
+ const qs = params.toString() ? `?${params.toString()}` : '';
214
+ const result = await apiRequest(`/api/v1/decisions${qs}`);
215
+ const decisions = result.decisions ?? [];
216
+ if (options.format === 'json') {
217
+ console.log(JSON.stringify(decisions, null, 2));
218
+ }
219
+ else {
220
+ console.log(formatDecisionsOutput(decisions));
221
+ }
222
+ }
223
+ catch (error) {
224
+ const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
225
+ logger.error({ error: message }, 'Failed to fetch decisions');
226
+ console.error(chalk.red(`Error: ${message}`));
227
+ process.exitCode = error instanceof ApiError ? 2 : 1;
228
+ }
229
+ });
230
+ // ─── stats command ───
231
+ program
232
+ .command('stats')
233
+ .description('Show aggregate trading statistics (win rate, avg PnL, best/worst setups)')
234
+ .option('--period <period>', 'Time period (e.g., 7d, 30d, 90d)', '30d')
235
+ .option('--trader <traderId>', 'Trader ID', DEFAULT_TRADER_ID)
236
+ .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
237
+ .action(async (options) => {
238
+ try {
239
+ const params = new URLSearchParams();
240
+ if (options.trader && options.trader !== DEFAULT_TRADER_ID)
241
+ params.set('traderId', options.trader);
242
+ if (options.limit)
243
+ params.set('limit', String(options.limit));
244
+ const qs = params.toString() ? `?${params.toString()}` : '';
245
+ const result = await apiRequest(`/api/v1/decisions${qs}`);
246
+ const decisions = result.decisions ?? [];
247
+ // Compute stats client-side from decisions with outcomes
248
+ const stats = computeStatsFromDecisions(decisions, options.period);
249
+ if (options.format === 'json') {
250
+ const bySetupType = {};
251
+ for (const [key, value] of stats.bySetupType) {
252
+ bySetupType[key] = value;
253
+ }
254
+ console.log(JSON.stringify({ overall: stats.overall, bySetupType }, null, 2));
255
+ }
256
+ else {
257
+ console.log(formatStatsOutput(stats.overall, `Last ${options.period}`));
258
+ if (stats.bySetupType.size > 0) {
259
+ console.log(formatSetupTypeStats(stats.bySetupType));
260
+ }
261
+ }
262
+ }
263
+ catch (error) {
264
+ const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
265
+ logger.error({ error: message }, 'Failed to fetch stats');
266
+ console.error(chalk.red(`Error: ${message}`));
267
+ process.exitCode = error instanceof ApiError ? 2 : 1;
268
+ }
269
+ });
270
+ }
271
+ // ─── Client-Side Stats Computation ───
272
+ function computeStatsFromDecisions(decisions, _periodLabel) {
273
+ // Filter to decisions with outcome data
274
+ const withOutcomes = decisions.filter((d) => d.pnlAbsolute !== null && d.pnlAbsolute !== undefined);
275
+ const overall = computeStats(withOutcomes);
276
+ const bySetupType = new Map();
277
+ // Group by setup type
278
+ const grouped = new Map();
279
+ for (const d of withOutcomes) {
280
+ const setup = d.setupType ?? 'UNKNOWN';
281
+ if (!grouped.has(setup))
282
+ grouped.set(setup, []);
283
+ grouped.get(setup).push(d);
284
+ }
285
+ for (const [setup, group] of grouped) {
286
+ bySetupType.set(setup, computeStats(group));
287
+ }
288
+ return { overall, bySetupType };
289
+ }
290
+ function computeStats(decisions) {
291
+ if (decisions.length === 0) {
292
+ return {
293
+ totalTrades: 0, wins: 0, losses: 0, breakeven: 0, winRate: 0,
294
+ totalPnl: 0, avgPnl: 0, avgPnlPercent: 0, avgHoldDurationMs: 0,
295
+ bestTrade: null, worstTrade: null,
296
+ };
297
+ }
298
+ let wins = 0, losses = 0, breakeven = 0;
299
+ let totalPnl = 0, totalPnlPct = 0, totalHold = 0;
300
+ let best = null;
301
+ let worst = null;
302
+ for (const d of decisions) {
303
+ const pnl = d.pnlAbsolute ?? 0;
304
+ totalPnl += pnl;
305
+ totalPnlPct += d.pnlPercent ?? 0;
306
+ totalHold += d.holdDurationMs ?? 0;
307
+ if (pnl > 0)
308
+ wins++;
309
+ else if (pnl < 0)
310
+ losses++;
311
+ else
312
+ breakeven++;
313
+ if (!best || pnl > (best.pnlAbsolute ?? 0))
314
+ best = d;
315
+ if (!worst || pnl < (worst.pnlAbsolute ?? 0))
316
+ worst = d;
317
+ }
318
+ return {
319
+ totalTrades: decisions.length,
320
+ wins, losses, breakeven,
321
+ winRate: decisions.length > 0 ? wins / decisions.length : 0,
322
+ totalPnl,
323
+ avgPnl: totalPnl / decisions.length,
324
+ avgPnlPercent: totalPnlPct / decisions.length,
325
+ avgHoldDurationMs: totalHold / decisions.length,
326
+ bestTrade: best,
327
+ worstTrade: worst,
328
+ };
329
+ }
330
+ // ─── Helpers ───
331
+ /**
332
+ * Parse a period string like "7d", "30d", "90d" into milliseconds.
333
+ */
334
+ export function parsePeriod(period) {
335
+ const match = period.match(/^(\d+)([dhm])$/);
336
+ if (!match) {
337
+ return 30 * 24 * 60 * 60 * 1000; // Default 30 days
338
+ }
339
+ const value = parseInt(match[1], 10);
340
+ const unit = match[2];
341
+ switch (unit) {
342
+ case 'd':
343
+ return value * 24 * 60 * 60 * 1000;
344
+ case 'h':
345
+ return value * 60 * 60 * 1000;
346
+ case 'm':
347
+ return value * 60 * 1000;
348
+ default:
349
+ return 30 * 24 * 60 * 60 * 1000;
350
+ }
351
+ }
352
+ //# sourceMappingURL=decisions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions.js","sourceRoot":"","sources":["../../src/commands/decisions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import { Command } from 'commander';
2
+ interface EdgeRatioResult {
3
+ edgeRatio: number;
4
+ avgMfeAtr: number;
5
+ avgMaeAtr: number;
6
+ sampleSize: number;
7
+ }
8
+ interface EfficiencyResult {
9
+ entryEfficiency: number;
10
+ exitEfficiency: number;
11
+ combinedEfficiency: number;
12
+ }
13
+ interface EdgeAnalysis {
14
+ traderId: string;
15
+ analysis: {
16
+ edgeRatio: {
17
+ overall: EdgeRatioResult;
18
+ bySetupType: Record<string, EdgeRatioResult>;
19
+ byRegime: Record<string, EdgeRatioResult>;
20
+ };
21
+ efficiency: {
22
+ overall: EfficiencyResult;
23
+ bySetupType: Record<string, EfficiencyResult>;
24
+ confidenceCorrelation: number | null;
25
+ };
26
+ trades: Array<{
27
+ decisionId: string;
28
+ tokenSymbol: string;
29
+ setupType: string | null;
30
+ direction: string | null;
31
+ entryPrice: number;
32
+ exitPrice: number;
33
+ mfeAtr: number;
34
+ maeAtr: number;
35
+ entryEfficiency: number;
36
+ exitEfficiency: number;
37
+ combinedEfficiency: number;
38
+ pnlPercent: number;
39
+ }>;
40
+ excludedCount: number;
41
+ } | null;
42
+ message?: string;
43
+ }
44
+ interface TradeAttribution {
45
+ decisionId: string;
46
+ tokenSymbol: string;
47
+ direction: string;
48
+ realizedPnl: number;
49
+ signalAlpha: number;
50
+ executionCost: number;
51
+ timingVariance: number;
52
+ }
53
+ interface AttributionAnalysis {
54
+ traderId: string;
55
+ analysis: {
56
+ attributions: TradeAttribution[];
57
+ overall: {
58
+ trades: number;
59
+ avgSignalAlphaPct: number;
60
+ avgExecutionCostPct: number;
61
+ avgTimingVariancePct: number;
62
+ totalPnlUsd: number;
63
+ };
64
+ bySetupType: Record<string, {
65
+ trades: number;
66
+ avgSignalAlphaPct: number;
67
+ avgExecutionCostPct: number;
68
+ avgTimingVariancePct: number;
69
+ }>;
70
+ excludedCount: number;
71
+ } | null;
72
+ message?: string;
73
+ }
74
+ export declare function formatEdgeOutput(data: EdgeAnalysis): string;
75
+ export declare function formatAttributionOutput(data: AttributionAnalysis): string;
76
+ export declare function registerEdgeCommand(program: Command): void;
77
+ export {};
78
+ //# sourceMappingURL=edge-cmd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-cmd.d.ts","sourceRoot":"","sources":["../../src/commands/edge-cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAM5C,UAAU,eAAe;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,gBAAgB;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE;QACR,SAAS,EAAE;YACT,OAAO,EAAE,eAAe,CAAC;YACzB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YAC7C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;SAC3C,CAAC;QACF,UAAU,EAAE;YACV,OAAO,EAAE,gBAAgB,CAAC;YAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;YAC9C,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;SACtC,CAAC;QACF,MAAM,EAAE,KAAK,CAAC;YACZ,UAAU,EAAE,MAAM,CAAC;YACnB,WAAW,EAAE,MAAM,CAAC;YACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;YACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;YACzB,UAAU,EAAE,MAAM,CAAC;YACnB,SAAS,EAAE,MAAM,CAAC;YAClB,MAAM,EAAE,MAAM,CAAC;YACf,MAAM,EAAE,MAAM,CAAC;YACf,eAAe,EAAE,MAAM,CAAC;YACxB,cAAc,EAAE,MAAM,CAAC;YACvB,kBAAkB,EAAE,MAAM,CAAC;YAC3B,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC,CAAC;QACH,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,IAAI,CAAC;IACT,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,gBAAgB;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE;QACR,YAAY,EAAE,gBAAgB,EAAE,CAAC;QACjC,OAAO,EAAE;YACP,MAAM,EAAE,MAAM,CAAC;YACf,iBAAiB,EAAE,MAAM,CAAC;YAC1B,mBAAmB,EAAE,MAAM,CAAC;YAC5B,oBAAoB,EAAE,MAAM,CAAC;YAC7B,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE;YAC1B,MAAM,EAAE,MAAM,CAAC;YACf,iBAAiB,EAAE,MAAM,CAAC;YAC1B,mBAAmB,EAAE,MAAM,CAAC;YAC5B,oBAAoB,EAAE,MAAM,CAAC;SAC9B,CAAC,CAAC;QACH,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,IAAI,CAAC;IACT,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAWD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAwE3D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CA6DzE;AA6BD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgD1D"}
@@ -0,0 +1,185 @@
1
+ import { Option } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { isRemoteMode, apiRequest, ApiError } from '../api-client.js';
4
+ // ─── Formatters ───
5
+ export function formatEdgeOutput(data) {
6
+ const lines = [];
7
+ lines.push('');
8
+ lines.push(chalk.bold.cyan(` Edge Ratio Analysis — ${data.traderId}`));
9
+ lines.push(chalk.gray(' ' + '─'.repeat(50)));
10
+ if (!data.analysis) {
11
+ lines.push(` ${chalk.dim(data.message ?? 'No data available')}`);
12
+ lines.push('');
13
+ return lines.join('\n');
14
+ }
15
+ const a = data.analysis;
16
+ const overall = a.edgeRatio?.overall;
17
+ const eff = a.efficiency?.overall;
18
+ // Overall edge ratio
19
+ const edgeVal = overall?.edgeRatio ?? 0;
20
+ lines.push(` ${chalk.gray('Edge Ratio:')} ${colorEdge(edgeVal)}`);
21
+ lines.push(` ${chalk.gray('Avg MFE/ATR:')} ${(overall?.avgMfeAtr ?? 0).toFixed(3)}`);
22
+ lines.push(` ${chalk.gray('Avg MAE/ATR:')} ${(overall?.avgMaeAtr ?? 0).toFixed(3)}`);
23
+ lines.push(` ${chalk.gray('Sample Size:')} ${overall?.sampleSize ?? 0}`);
24
+ lines.push('');
25
+ // Efficiency
26
+ if (eff) {
27
+ lines.push(chalk.bold(' Efficiency'));
28
+ lines.push(` ${chalk.gray('Entry:')} ${formatPct(eff.entryEfficiency)}`);
29
+ lines.push(` ${chalk.gray('Exit:')} ${formatPct(eff.exitEfficiency)}`);
30
+ lines.push(` ${chalk.gray('Combined:')} ${formatPct(eff.combinedEfficiency)}`);
31
+ if (a.efficiency.confidenceCorrelation !== null && a.efficiency.confidenceCorrelation !== undefined) {
32
+ lines.push(` ${chalk.gray('Confidence Corr:')} ${a.efficiency.confidenceCorrelation.toFixed(3)}`);
33
+ }
34
+ lines.push('');
35
+ }
36
+ // By Setup Type
37
+ const setupEntries = Object.entries(a.edgeRatio?.bySetupType ?? {});
38
+ if (setupEntries.length > 0) {
39
+ lines.push(chalk.bold(' By Setup Type'));
40
+ lines.push(` ${chalk.gray('Setup'.padEnd(20))}${'Edge'.padStart(8)}${'MFE/ATR'.padStart(10)}${'MAE/ATR'.padStart(10)}${'N'.padStart(5)}`);
41
+ lines.push(chalk.gray(' ' + '─'.repeat(53)));
42
+ for (const [setup, er] of setupEntries) {
43
+ lines.push(` ${setup.padEnd(20)}${colorEdge(er.edgeRatio).padStart(8)}${er.avgMfeAtr.toFixed(3).padStart(10)}${er.avgMaeAtr.toFixed(3).padStart(10)}${String(er.sampleSize).padStart(5)}`);
44
+ }
45
+ lines.push('');
46
+ }
47
+ // By Regime
48
+ const regimeEntries = Object.entries(a.edgeRatio?.byRegime ?? {});
49
+ if (regimeEntries.length > 0) {
50
+ lines.push(chalk.bold(' By Regime'));
51
+ lines.push(` ${chalk.gray('Regime'.padEnd(20))}${'Edge'.padStart(8)}${'MFE/ATR'.padStart(10)}${'MAE/ATR'.padStart(10)}${'N'.padStart(5)}`);
52
+ lines.push(chalk.gray(' ' + '─'.repeat(53)));
53
+ for (const [regime, er] of regimeEntries) {
54
+ lines.push(` ${regime.padEnd(20)}${colorEdge(er.edgeRatio).padStart(8)}${er.avgMfeAtr.toFixed(3).padStart(10)}${er.avgMaeAtr.toFixed(3).padStart(10)}${String(er.sampleSize).padStart(5)}`);
55
+ }
56
+ lines.push('');
57
+ }
58
+ // Trade summary
59
+ if (a.trades.length > 0) {
60
+ lines.push(` ${chalk.dim(`${a.trades.length} trades analyzed, ${a.excludedCount} excluded (missing ATR)`)}`);
61
+ lines.push('');
62
+ }
63
+ return lines.join('\n');
64
+ }
65
+ export function formatAttributionOutput(data) {
66
+ const lines = [];
67
+ lines.push('');
68
+ lines.push(chalk.bold.cyan(` PnL Attribution — ${data.traderId}`));
69
+ lines.push(chalk.gray(' ' + '─'.repeat(50)));
70
+ if (!data.analysis) {
71
+ lines.push(` ${chalk.dim(data.message ?? 'No data available')}`);
72
+ lines.push('');
73
+ return lines.join('\n');
74
+ }
75
+ const s = data.analysis.overall;
76
+ if (!s) {
77
+ lines.push(` ${chalk.dim('No attribution data available')}`);
78
+ lines.push('');
79
+ return lines.join('\n');
80
+ }
81
+ lines.push(chalk.bold(' Summary'));
82
+ lines.push(` ${chalk.gray('Total PnL:')} ${colorPnl(s.totalPnlUsd ?? 0)}`);
83
+ lines.push(` ${chalk.gray('Signal Alpha:')} ${formatPct(s.avgSignalAlphaPct ?? 0)}`);
84
+ lines.push(` ${chalk.gray('Execution Cost:')} ${formatPct(s.avgExecutionCostPct ?? 0)}`);
85
+ lines.push(` ${chalk.gray('Timing Variance:')} ${formatPct(s.avgTimingVariancePct ?? 0)}`);
86
+ lines.push(` ${chalk.gray('Trade Count:')} ${s.trades ?? 0}`);
87
+ // By Setup Type
88
+ const setupEntries = Object.entries(data.analysis.bySetupType ?? {});
89
+ if (setupEntries.length > 0) {
90
+ lines.push('');
91
+ lines.push(chalk.bold(' By Setup Type'));
92
+ lines.push(` ${chalk.gray('Setup'.padEnd(20))}${'Signal%'.padStart(10)}${'Exec%'.padStart(10)}${'Timing%'.padStart(10)}${'N'.padStart(5)}`);
93
+ lines.push(chalk.gray(' ' + '─'.repeat(55)));
94
+ for (const [setup, v] of setupEntries) {
95
+ lines.push(` ${setup.padEnd(20)}${formatPct(v.avgSignalAlphaPct).padStart(10)}${formatPct(v.avgExecutionCostPct).padStart(10)}${formatPct(v.avgTimingVariancePct).padStart(10)}${String(v.trades).padStart(5)}`);
96
+ }
97
+ }
98
+ if (data.analysis.attributions.length > 0) {
99
+ lines.push('');
100
+ lines.push(chalk.bold(' Per-Trade Breakdown'));
101
+ lines.push(` ${chalk.gray('Token'.padEnd(10))}${'PnL'.padStart(12)}${'Signal'.padStart(12)}${'Exec'.padStart(12)}${'Timing'.padStart(12)}`);
102
+ lines.push(chalk.gray(' ' + '─'.repeat(58)));
103
+ const shown = data.analysis.attributions.slice(0, 20);
104
+ for (const t of shown) {
105
+ lines.push(` ${t.tokenSymbol.padEnd(10)}${formatUsd(t.realizedPnl ?? 0).padStart(12)}${formatUsd(t.signalAlpha ?? 0).padStart(12)}${formatUsd(t.executionCost ?? 0).padStart(12)}${formatUsd(t.timingVariance ?? 0).padStart(12)}`);
106
+ }
107
+ if (data.analysis.attributions.length > 20) {
108
+ lines.push(chalk.dim(` ... and ${data.analysis.attributions.length - 20} more`));
109
+ }
110
+ }
111
+ lines.push('');
112
+ return lines.join('\n');
113
+ }
114
+ function colorEdge(ratio) {
115
+ const r = ratio ?? 0;
116
+ const str = r.toFixed(3);
117
+ if (r >= 1.0)
118
+ return chalk.green(str);
119
+ if (r >= 0.5)
120
+ return chalk.yellow(str);
121
+ return chalk.red(str);
122
+ }
123
+ function colorPnl(usd) {
124
+ const v = usd ?? 0;
125
+ const str = formatUsd(v);
126
+ return v >= 0 ? chalk.green(str) : chalk.red(str);
127
+ }
128
+ function formatUsd(val) {
129
+ const v = val ?? 0;
130
+ const sign = v >= 0 ? '+' : '';
131
+ return `${sign}$${v.toFixed(2)}`;
132
+ }
133
+ function formatPct(val) {
134
+ const v = val ?? 0;
135
+ return `${v >= 0 ? '+' : ''}${(v * 100).toFixed(1)}%`;
136
+ }
137
+ // ─── Command Registration ───
138
+ export function registerEdgeCommand(program) {
139
+ program
140
+ .command('edge <traderId>')
141
+ .description('Analyze trade quality — edge ratio and PnL attribution')
142
+ .option('--attribution', 'Show PnL attribution breakdown instead of edge ratio')
143
+ .option('--token <symbol>', 'Filter by token symbol')
144
+ .option('--limit <n>', 'Number of trades to analyze (1-500)', '100')
145
+ .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
146
+ .action(async (traderId, options) => {
147
+ try {
148
+ if (!(await isRemoteMode())) {
149
+ console.error(chalk.red('Error: edge command requires remote mode. Run `trading-boy login` first.'));
150
+ process.exitCode = 1;
151
+ return;
152
+ }
153
+ const query = new URLSearchParams();
154
+ if (options.token)
155
+ query.set('tokenSymbol', options.token.toUpperCase());
156
+ if (options.limit !== '100')
157
+ query.set('limit', options.limit);
158
+ const qs = query.toString() ? `?${query.toString()}` : '';
159
+ if (options.attribution) {
160
+ const data = await apiRequest(`/api/v1/traders/${encodeURIComponent(traderId)}/attribution${qs}`);
161
+ if (options.format === 'json') {
162
+ console.log(JSON.stringify(data, null, 2));
163
+ }
164
+ else {
165
+ console.log(formatAttributionOutput(data));
166
+ }
167
+ }
168
+ else {
169
+ const data = await apiRequest(`/api/v1/traders/${encodeURIComponent(traderId)}/edge${qs}`);
170
+ if (options.format === 'json') {
171
+ console.log(JSON.stringify(data, null, 2));
172
+ }
173
+ else {
174
+ console.log(formatEdgeOutput(data));
175
+ }
176
+ }
177
+ }
178
+ catch (error) {
179
+ const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
180
+ console.error(chalk.red(`Error: ${message}`));
181
+ process.exitCode = error instanceof ApiError ? 2 : 1;
182
+ }
183
+ });
184
+ }
185
+ //# sourceMappingURL=edge-cmd.js.map