@spfunctions/cli 1.7.17 → 1.7.20
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/101.index.js +1 -0
- package/dist/12.index.js +1 -0
- package/dist/160.index.js +1 -0
- package/dist/174.index.js +1 -0
- package/dist/278.index.js +6 -0
- package/dist/582.index.js +1 -0
- package/dist/641.index.js +324 -0
- package/dist/669.index.js +1 -0
- package/dist/722.index.js +1 -0
- package/dist/788.index.js +1 -0
- package/dist/816.index.js +12 -0
- package/dist/830.index.js +1 -0
- package/dist/921.index.js +1 -0
- package/dist/index.js +1 -813
- package/package.json +6 -2
- package/dist/cache.d.ts +0 -6
- package/dist/cache.js +0 -31
- package/dist/cache.test.d.ts +0 -1
- package/dist/cache.test.js +0 -73
- package/dist/client.d.ts +0 -56
- package/dist/client.js +0 -205
- package/dist/client.test.d.ts +0 -1
- package/dist/client.test.js +0 -89
- package/dist/commands/agent.d.ts +0 -20
- package/dist/commands/agent.js +0 -4119
- package/dist/commands/announcements.d.ts +0 -3
- package/dist/commands/announcements.js +0 -28
- package/dist/commands/augment.d.ts +0 -12
- package/dist/commands/augment.js +0 -56
- package/dist/commands/balance.d.ts +0 -3
- package/dist/commands/balance.js +0 -17
- package/dist/commands/book.d.ts +0 -17
- package/dist/commands/book.js +0 -220
- package/dist/commands/cancel.d.ts +0 -5
- package/dist/commands/cancel.js +0 -41
- package/dist/commands/context.d.ts +0 -6
- package/dist/commands/context.js +0 -208
- package/dist/commands/create.d.ts +0 -7
- package/dist/commands/create.js +0 -42
- package/dist/commands/dashboard.d.ts +0 -14
- package/dist/commands/dashboard.js +0 -215
- package/dist/commands/delta.d.ts +0 -16
- package/dist/commands/delta.js +0 -115
- package/dist/commands/edges.d.ts +0 -26
- package/dist/commands/edges.js +0 -237
- package/dist/commands/evaluate.d.ts +0 -4
- package/dist/commands/evaluate.js +0 -30
- package/dist/commands/explore.d.ts +0 -14
- package/dist/commands/explore.js +0 -115
- package/dist/commands/feed.d.ts +0 -13
- package/dist/commands/feed.js +0 -73
- package/dist/commands/fills.d.ts +0 -4
- package/dist/commands/fills.js +0 -29
- package/dist/commands/forecast.d.ts +0 -4
- package/dist/commands/forecast.js +0 -53
- package/dist/commands/get.d.ts +0 -5
- package/dist/commands/get.js +0 -98
- package/dist/commands/heartbeat.d.ts +0 -20
- package/dist/commands/heartbeat.js +0 -73
- package/dist/commands/history.d.ts +0 -3
- package/dist/commands/history.js +0 -38
- package/dist/commands/liquidity.d.ts +0 -14
- package/dist/commands/liquidity.js +0 -378
- package/dist/commands/list.d.ts +0 -5
- package/dist/commands/list.js +0 -38
- package/dist/commands/login.d.ts +0 -9
- package/dist/commands/login.js +0 -98
- package/dist/commands/markets.d.ts +0 -10
- package/dist/commands/markets.js +0 -39
- package/dist/commands/milestones.d.ts +0 -8
- package/dist/commands/milestones.js +0 -56
- package/dist/commands/orders.d.ts +0 -4
- package/dist/commands/orders.js +0 -28
- package/dist/commands/performance.d.ts +0 -11
- package/dist/commands/performance.js +0 -250
- package/dist/commands/positions.d.ts +0 -19
- package/dist/commands/positions.js +0 -294
- package/dist/commands/prompt.d.ts +0 -13
- package/dist/commands/prompt.js +0 -35
- package/dist/commands/publish.d.ts +0 -15
- package/dist/commands/publish.js +0 -39
- package/dist/commands/query.d.ts +0 -15
- package/dist/commands/query.js +0 -132
- package/dist/commands/rfq.d.ts +0 -5
- package/dist/commands/rfq.js +0 -35
- package/dist/commands/scan.d.ts +0 -11
- package/dist/commands/scan.js +0 -230
- package/dist/commands/schedule.d.ts +0 -3
- package/dist/commands/schedule.js +0 -38
- package/dist/commands/settlements.d.ts +0 -6
- package/dist/commands/settlements.js +0 -50
- package/dist/commands/setup.d.ts +0 -24
- package/dist/commands/setup.js +0 -700
- package/dist/commands/signal.d.ts +0 -6
- package/dist/commands/signal.js +0 -32
- package/dist/commands/strategies.d.ts +0 -11
- package/dist/commands/strategies.js +0 -130
- package/dist/commands/telegram.d.ts +0 -15
- package/dist/commands/telegram.js +0 -125
- package/dist/commands/trade.d.ts +0 -12
- package/dist/commands/trade.js +0 -112
- package/dist/commands/watch.d.ts +0 -19
- package/dist/commands/watch.js +0 -157
- package/dist/commands/whatif.d.ts +0 -17
- package/dist/commands/whatif.js +0 -209
- package/dist/commands/x.d.ts +0 -28
- package/dist/commands/x.js +0 -167
- package/dist/config.d.ts +0 -55
- package/dist/config.js +0 -139
- package/dist/config.test.d.ts +0 -1
- package/dist/config.test.js +0 -138
- package/dist/index.d.ts +0 -20
- package/dist/kalshi.d.ts +0 -144
- package/dist/kalshi.js +0 -498
- package/dist/polymarket.d.ts +0 -237
- package/dist/polymarket.js +0 -353
- package/dist/polymarket.test.d.ts +0 -1
- package/dist/polymarket.test.js +0 -424
- package/dist/share.d.ts +0 -4
- package/dist/share.js +0 -27
- package/dist/skills/loader.d.ts +0 -19
- package/dist/skills/loader.js +0 -86
- package/dist/telegram/agent-bridge.d.ts +0 -15
- package/dist/telegram/agent-bridge.js +0 -573
- package/dist/telegram/bot.d.ts +0 -10
- package/dist/telegram/bot.js +0 -297
- package/dist/telegram/commands.d.ts +0 -11
- package/dist/telegram/commands.js +0 -120
- package/dist/telegram/format.d.ts +0 -11
- package/dist/telegram/format.js +0 -51
- package/dist/telegram/format.test.d.ts +0 -1
- package/dist/telegram/format.test.js +0 -73
- package/dist/telegram/poller.d.ts +0 -6
- package/dist/telegram/poller.js +0 -32
- package/dist/topics.d.ts +0 -17
- package/dist/topics.js +0 -102
- package/dist/topics.test.d.ts +0 -1
- package/dist/topics.test.js +0 -131
- package/dist/tui/border.d.ts +0 -33
- package/dist/tui/border.js +0 -87
- package/dist/tui/chart.d.ts +0 -19
- package/dist/tui/chart.js +0 -117
- package/dist/tui/dashboard.d.ts +0 -9
- package/dist/tui/dashboard.js +0 -814
- package/dist/tui/layout.d.ts +0 -16
- package/dist/tui/layout.js +0 -41
- package/dist/tui/screen.d.ts +0 -33
- package/dist/tui/screen.js +0 -102
- package/dist/tui/state.d.ts +0 -40
- package/dist/tui/state.js +0 -36
- package/dist/tui/widgets/commandbar.d.ts +0 -8
- package/dist/tui/widgets/commandbar.js +0 -82
- package/dist/tui/widgets/detail.d.ts +0 -9
- package/dist/tui/widgets/detail.js +0 -151
- package/dist/tui/widgets/edges.d.ts +0 -4
- package/dist/tui/widgets/edges.js +0 -34
- package/dist/tui/widgets/liquidity.d.ts +0 -9
- package/dist/tui/widgets/liquidity.js +0 -142
- package/dist/tui/widgets/orders.d.ts +0 -4
- package/dist/tui/widgets/orders.js +0 -37
- package/dist/tui/widgets/portfolio.d.ts +0 -4
- package/dist/tui/widgets/portfolio.js +0 -59
- package/dist/tui/widgets/signals.d.ts +0 -4
- package/dist/tui/widgets/signals.js +0 -31
- package/dist/tui/widgets/statusbar.d.ts +0 -8
- package/dist/tui/widgets/statusbar.js +0 -72
- package/dist/tui/widgets/thesis.d.ts +0 -4
- package/dist/tui/widgets/thesis.js +0 -66
- package/dist/tui/widgets/trade.d.ts +0 -9
- package/dist/tui/widgets/trade.js +0 -117
- package/dist/tui/widgets/upcoming.d.ts +0 -4
- package/dist/tui/widgets/upcoming.js +0 -41
- package/dist/tui/widgets/whatif.d.ts +0 -7
- package/dist/tui/widgets/whatif.js +0 -113
- package/dist/types/output.d.ts +0 -412
- package/dist/types/output.js +0 -9
- package/dist/utils.d.ts +0 -42
- package/dist/utils.js +0 -124
- package/dist/utils.test.d.ts +0 -1
- package/dist/utils.test.js +0 -111
package/dist/commands/create.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createCommand = createCommand;
|
|
4
|
-
const client_js_1 = require("../client.js");
|
|
5
|
-
const utils_js_1 = require("../utils.js");
|
|
6
|
-
async function createCommand(thesis, opts) {
|
|
7
|
-
const client = new client_js_1.SFClient(opts.apiKey, opts.apiUrl);
|
|
8
|
-
const sync = !opts.async;
|
|
9
|
-
if (!opts.json) {
|
|
10
|
-
if (sync) {
|
|
11
|
-
console.log(`${utils_js_1.c.dim}Creating thesis (sync mode — waiting for formation)...${utils_js_1.c.reset}`);
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
console.log(`${utils_js_1.c.dim}Creating thesis (async mode)...${utils_js_1.c.reset}`);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
const result = await client.createThesis(thesis, sync);
|
|
18
|
-
const id = result.thesis?.id || result.thesisId || result.id || null;
|
|
19
|
-
if (opts.json) {
|
|
20
|
-
console.log(JSON.stringify({ id, status: result.thesis?.status || result.status || 'forming', result }, null, 2));
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
if (!id) {
|
|
24
|
-
console.error(`${utils_js_1.c.red}✗${utils_js_1.c.reset} Thesis creation returned no ID.`);
|
|
25
|
-
console.error(`${utils_js_1.c.dim}Response: ${JSON.stringify(result).slice(0, 200)}${utils_js_1.c.reset}`);
|
|
26
|
-
process.exit(1);
|
|
27
|
-
}
|
|
28
|
-
console.log(`\n${utils_js_1.c.green}✓${utils_js_1.c.reset} Thesis created`);
|
|
29
|
-
console.log(` ${utils_js_1.c.bold}ID:${utils_js_1.c.reset} ${id}`);
|
|
30
|
-
console.log(` ${utils_js_1.c.bold}Status:${utils_js_1.c.reset} ${result.thesis?.status || result.status}`);
|
|
31
|
-
if (result.thesis?.confidence) {
|
|
32
|
-
console.log(` ${utils_js_1.c.bold}Confidence:${utils_js_1.c.reset} ${Math.round(parseFloat(result.thesis.confidence) * 100)}%`);
|
|
33
|
-
}
|
|
34
|
-
if (result.thesis?.causalTree?.nodes) {
|
|
35
|
-
console.log(` ${utils_js_1.c.bold}Nodes:${utils_js_1.c.reset} ${result.thesis.causalTree.nodes.length}`);
|
|
36
|
-
}
|
|
37
|
-
if (result.thesis?.edgeAnalysis?.edges) {
|
|
38
|
-
console.log(` ${utils_js_1.c.bold}Edges:${utils_js_1.c.reset} ${result.thesis.edgeAnalysis.edges.length}`);
|
|
39
|
-
}
|
|
40
|
-
console.log(`\n${utils_js_1.c.dim}View: sf get ${(0, utils_js_1.shortId)(id)}${utils_js_1.c.reset}`);
|
|
41
|
-
console.log(`${utils_js_1.c.dim}Context: sf context ${(0, utils_js_1.shortId)(id)}${utils_js_1.c.reset}`);
|
|
42
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* sf dashboard — Commander entry point
|
|
3
|
-
*
|
|
4
|
-
* Three modes:
|
|
5
|
-
* --json → dump current state as JSON
|
|
6
|
-
* --once → one-time formatted print (no interactive TUI)
|
|
7
|
-
* default → launch interactive TUI dashboard
|
|
8
|
-
*/
|
|
9
|
-
export declare function dashboardCommand(opts?: {
|
|
10
|
-
json?: boolean;
|
|
11
|
-
once?: boolean;
|
|
12
|
-
apiKey?: string;
|
|
13
|
-
apiUrl?: string;
|
|
14
|
-
}): Promise<void>;
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* sf dashboard — Commander entry point
|
|
4
|
-
*
|
|
5
|
-
* Three modes:
|
|
6
|
-
* --json → dump current state as JSON
|
|
7
|
-
* --once → one-time formatted print (no interactive TUI)
|
|
8
|
-
* default → launch interactive TUI dashboard
|
|
9
|
-
*/
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.dashboardCommand = dashboardCommand;
|
|
12
|
-
const client_js_1 = require("../client.js");
|
|
13
|
-
const kalshi_js_1 = require("../kalshi.js");
|
|
14
|
-
const polymarket_js_1 = require("../polymarket.js");
|
|
15
|
-
const config_js_1 = require("../config.js");
|
|
16
|
-
const topics_js_1 = require("../topics.js");
|
|
17
|
-
const dashboard_js_1 = require("../tui/dashboard.js");
|
|
18
|
-
function categorize(ticker) {
|
|
19
|
-
const sorted = Object.keys(topics_js_1.RISK_CATEGORIES).sort((a, b) => b.length - a.length);
|
|
20
|
-
for (const prefix of sorted) {
|
|
21
|
-
if (ticker.startsWith(prefix))
|
|
22
|
-
return topics_js_1.RISK_CATEGORIES[prefix];
|
|
23
|
-
}
|
|
24
|
-
return 'Other';
|
|
25
|
-
}
|
|
26
|
-
function timeAgo(dateStr) {
|
|
27
|
-
const diff = Date.now() - new Date(dateStr).getTime();
|
|
28
|
-
const mins = Math.floor(diff / 60000);
|
|
29
|
-
if (mins < 60)
|
|
30
|
-
return `${mins}m ago`;
|
|
31
|
-
const hrs = Math.floor(mins / 60);
|
|
32
|
-
if (hrs < 24)
|
|
33
|
-
return `${hrs}h ago`;
|
|
34
|
-
const days = Math.floor(hrs / 24);
|
|
35
|
-
return `${days}d ago`;
|
|
36
|
-
}
|
|
37
|
-
async function dashboardCommand(opts) {
|
|
38
|
-
// ── Default: interactive TUI ──
|
|
39
|
-
if (!opts?.json && !opts?.once) {
|
|
40
|
-
await (0, dashboard_js_1.startDashboard)();
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
// ── JSON or one-time print modes (legacy behavior) ──
|
|
44
|
-
const client = new client_js_1.SFClient(opts?.apiKey, opts?.apiUrl);
|
|
45
|
-
const [thesesResult, positions] = await Promise.all([
|
|
46
|
-
client.listTheses(),
|
|
47
|
-
(0, kalshi_js_1.getPositions)().catch(() => null),
|
|
48
|
-
]);
|
|
49
|
-
const theses = thesesResult.theses || thesesResult;
|
|
50
|
-
// Fetch context for each thesis (edges)
|
|
51
|
-
const contexts = [];
|
|
52
|
-
for (const t of theses) {
|
|
53
|
-
try {
|
|
54
|
-
const ctx = await client.getContext(t.id);
|
|
55
|
-
contexts.push(ctx);
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
contexts.push(null);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// Enrich positions with live prices
|
|
62
|
-
if (positions) {
|
|
63
|
-
for (const pos of positions) {
|
|
64
|
-
const livePrice = await (0, kalshi_js_1.getMarketPrice)(pos.ticker);
|
|
65
|
-
if (livePrice !== null) {
|
|
66
|
-
pos.current_value = livePrice;
|
|
67
|
-
pos.unrealized_pnl = Math.round((livePrice - pos.average_price_paid) * pos.quantity);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// Collect all edges across all theses
|
|
72
|
-
const allEdges = [];
|
|
73
|
-
for (const ctx of contexts) {
|
|
74
|
-
if (!ctx?.edges)
|
|
75
|
-
continue;
|
|
76
|
-
for (const e of ctx.edges) {
|
|
77
|
-
allEdges.push(e);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
// Dedupe edges by marketId (keep highest absolute edge)
|
|
81
|
-
const edgeMap = new Map();
|
|
82
|
-
for (const e of allEdges) {
|
|
83
|
-
const existing = edgeMap.get(e.marketId);
|
|
84
|
-
if (!existing || Math.abs(e.edge) > Math.abs(existing.edge)) {
|
|
85
|
-
edgeMap.set(e.marketId, e);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
// Find positioned tickers
|
|
89
|
-
const positionedTickers = new Set(positions?.map((p) => p.ticker) || []);
|
|
90
|
-
// Unpositioned edges
|
|
91
|
-
const unpositionedEdges = [...edgeMap.values()]
|
|
92
|
-
.filter(e => !positionedTickers.has(e.marketId))
|
|
93
|
-
.sort((a, b) => Math.abs(b.edge) - Math.abs(a.edge))
|
|
94
|
-
.slice(0, 10);
|
|
95
|
-
// Fetch additional data for JSON mode
|
|
96
|
-
const [orders, balance, polyPositions] = await Promise.all([
|
|
97
|
-
opts?.json ? (0, kalshi_js_1.getOrders)({ status: 'resting' }).catch(() => []) : Promise.resolve([]),
|
|
98
|
-
opts?.json ? (0, kalshi_js_1.getBalance)().catch(() => null) : Promise.resolve(null),
|
|
99
|
-
opts?.json && (0, config_js_1.loadConfig)().polymarketWalletAddress
|
|
100
|
-
? (0, polymarket_js_1.polymarketGetPositions)((0, config_js_1.loadConfig)().polymarketWalletAddress).catch(() => [])
|
|
101
|
-
: Promise.resolve([]),
|
|
102
|
-
]);
|
|
103
|
-
// Fetch feed for recent evaluations
|
|
104
|
-
let feed = [];
|
|
105
|
-
if (opts?.json) {
|
|
106
|
-
try {
|
|
107
|
-
feed = (await client.getFeed(24, 20)).evaluations || [];
|
|
108
|
-
}
|
|
109
|
-
catch { /* skip */ }
|
|
110
|
-
}
|
|
111
|
-
// ── JSON output ──
|
|
112
|
-
if (opts?.json) {
|
|
113
|
-
console.log(JSON.stringify({
|
|
114
|
-
theses,
|
|
115
|
-
positions: positions || [],
|
|
116
|
-
polymarketPositions: polyPositions,
|
|
117
|
-
orders,
|
|
118
|
-
balance,
|
|
119
|
-
unpositionedEdges,
|
|
120
|
-
feed,
|
|
121
|
-
kalshiConfigured: (0, kalshi_js_1.isKalshiConfigured)(),
|
|
122
|
-
polymarketConfigured: !!(0, config_js_1.loadConfig)().polymarketWalletAddress,
|
|
123
|
-
timestamp: new Date().toISOString(),
|
|
124
|
-
}, null, 2));
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
// ── One-time formatted output ──
|
|
128
|
-
console.log();
|
|
129
|
-
console.log(' SimpleFunctions Dashboard');
|
|
130
|
-
console.log(' ' + '\u2500'.repeat(50));
|
|
131
|
-
console.log();
|
|
132
|
-
// Theses
|
|
133
|
-
console.log(' Theses');
|
|
134
|
-
if (theses.length === 0) {
|
|
135
|
-
console.log(' (none)');
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
for (let i = 0; i < theses.length; i++) {
|
|
139
|
-
const t = theses[i];
|
|
140
|
-
const ctx = contexts[i];
|
|
141
|
-
const id = t.id.slice(0, 8);
|
|
142
|
-
const title = (t.title || '').slice(0, 35).padEnd(35);
|
|
143
|
-
const conf = t.confidence != null ? `${Math.round(t.confidence * 100)}%` : '?%';
|
|
144
|
-
const edgeCount = ctx?.edges?.length || 0;
|
|
145
|
-
const updated = t.updatedAt ? timeAgo(t.updatedAt) : '?';
|
|
146
|
-
console.log(` ${id} ${title} ${conf.padStart(4)} ${String(edgeCount).padStart(2)} edges updated ${updated}`);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
console.log();
|
|
150
|
-
// Positions
|
|
151
|
-
console.log(' Positions');
|
|
152
|
-
if (!positions || positions.length === 0) {
|
|
153
|
-
console.log(' (no Kalshi positions or Kalshi not configured)');
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
let totalCost = 0;
|
|
157
|
-
let totalPnl = 0;
|
|
158
|
-
for (const p of positions) {
|
|
159
|
-
const ticker = (p.ticker || '').padEnd(22);
|
|
160
|
-
const qty = String(p.quantity || 0).padStart(5);
|
|
161
|
-
const avg = `${p.average_price_paid || 0}\u00A2`;
|
|
162
|
-
const now = typeof p.current_value === 'number' ? `${p.current_value}\u00A2` : '?\u00A2';
|
|
163
|
-
const pnlCents = p.unrealized_pnl || 0;
|
|
164
|
-
const pnlDollars = (pnlCents / 100).toFixed(2);
|
|
165
|
-
const pnlStr = pnlCents >= 0 ? `+$${pnlDollars}` : `-$${Math.abs(parseFloat(pnlDollars)).toFixed(2)}`;
|
|
166
|
-
const cost = (p.average_price_paid || 0) * (p.quantity || 0);
|
|
167
|
-
totalCost += cost;
|
|
168
|
-
totalPnl += pnlCents;
|
|
169
|
-
console.log(` ${ticker} ${qty} @ ${avg.padEnd(5)} now ${now.padEnd(5)} ${pnlStr}`);
|
|
170
|
-
}
|
|
171
|
-
console.log(' ' + '\u2500'.repeat(45));
|
|
172
|
-
const totalCostDollars = (totalCost / 100).toFixed(0);
|
|
173
|
-
const totalPnlDollars = (totalPnl / 100).toFixed(2);
|
|
174
|
-
const pnlDisplay = totalPnl >= 0 ? `+$${totalPnlDollars}` : `-$${Math.abs(parseFloat(totalPnlDollars)).toFixed(2)}`;
|
|
175
|
-
console.log(` Total cost: $${totalCostDollars} | P&L: ${pnlDisplay}`);
|
|
176
|
-
}
|
|
177
|
-
console.log();
|
|
178
|
-
// Risk Exposure
|
|
179
|
-
if (positions && positions.length > 0) {
|
|
180
|
-
console.log(' Risk Exposure');
|
|
181
|
-
const riskGroups = new Map();
|
|
182
|
-
for (const p of positions) {
|
|
183
|
-
const cat = categorize(p.ticker || '');
|
|
184
|
-
const existing = riskGroups.get(cat) || { cost: 0, contracts: 0, tickers: [] };
|
|
185
|
-
const cost = (p.average_price_paid || 0) * (p.quantity || 0);
|
|
186
|
-
existing.cost += cost;
|
|
187
|
-
existing.contracts += p.quantity || 0;
|
|
188
|
-
if (!existing.tickers.includes(p.ticker))
|
|
189
|
-
existing.tickers.push(p.ticker);
|
|
190
|
-
riskGroups.set(cat, existing);
|
|
191
|
-
}
|
|
192
|
-
const sorted = [...riskGroups.entries()].sort((a, b) => b[1].cost - a[1].cost);
|
|
193
|
-
for (const [category, data] of sorted) {
|
|
194
|
-
const costDollars = `$${(data.cost / 100).toFixed(0)}`;
|
|
195
|
-
const tickerSummary = data.tickers.length <= 2
|
|
196
|
-
? ` (${data.tickers.join('+')})`
|
|
197
|
-
: ` (${data.tickers.length} markets)`;
|
|
198
|
-
console.log(` ${(category + tickerSummary + ':').padEnd(35)} ${costDollars.padStart(7)} cost | ${String(data.contracts).padStart(5)} contracts`);
|
|
199
|
-
}
|
|
200
|
-
console.log();
|
|
201
|
-
}
|
|
202
|
-
// Top Unpositioned Edges
|
|
203
|
-
if (unpositionedEdges.length > 0) {
|
|
204
|
-
console.log(' Top Unpositioned Edges');
|
|
205
|
-
for (const e of unpositionedEdges) {
|
|
206
|
-
const name = (e.market || e.marketId || '').slice(0, 25).padEnd(25);
|
|
207
|
-
const mkt = `${e.marketPrice}\u00A2`;
|
|
208
|
-
const thesis = `${e.thesisPrice}\u00A2`;
|
|
209
|
-
const edge = e.edge > 0 ? `+${e.edge}` : `${e.edge}`;
|
|
210
|
-
const liq = e.orderbook?.liquidityScore || '?';
|
|
211
|
-
console.log(` ${name} ${mkt.padStart(5)} \u2192 ${thesis.padStart(5)} edge ${edge.padStart(4)} ${liq}`);
|
|
212
|
-
}
|
|
213
|
-
console.log();
|
|
214
|
-
}
|
|
215
|
-
}
|
package/dist/commands/delta.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* sf delta <thesisId> — Changes since a timestamp.
|
|
3
|
-
*
|
|
4
|
-
* Calls GET /api/thesis/:id/changes?since=<ts>
|
|
5
|
-
* Shows: confidence delta, new signals, node probability changes, edge movements.
|
|
6
|
-
*/
|
|
7
|
-
interface DeltaOpts {
|
|
8
|
-
since?: string;
|
|
9
|
-
hours?: string;
|
|
10
|
-
json?: boolean;
|
|
11
|
-
watch?: boolean;
|
|
12
|
-
apiKey?: string;
|
|
13
|
-
apiUrl?: string;
|
|
14
|
-
}
|
|
15
|
-
export declare function deltaCommand(thesisId: string, opts: DeltaOpts): Promise<void>;
|
|
16
|
-
export {};
|
package/dist/commands/delta.js
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* sf delta <thesisId> — Changes since a timestamp.
|
|
4
|
-
*
|
|
5
|
-
* Calls GET /api/thesis/:id/changes?since=<ts>
|
|
6
|
-
* Shows: confidence delta, new signals, node probability changes, edge movements.
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.deltaCommand = deltaCommand;
|
|
10
|
-
const client_js_1 = require("../client.js");
|
|
11
|
-
const utils_js_1 = require("../utils.js");
|
|
12
|
-
async function deltaCommand(thesisId, opts) {
|
|
13
|
-
const client = new client_js_1.SFClient(opts.apiKey, opts.apiUrl);
|
|
14
|
-
// Resolve "since" — either explicit timestamp or --hours offset
|
|
15
|
-
const sinceDate = opts.since
|
|
16
|
-
? new Date(opts.since)
|
|
17
|
-
: new Date(Date.now() - (parseInt(opts.hours || '6') * 3600000));
|
|
18
|
-
if (isNaN(sinceDate.getTime())) {
|
|
19
|
-
throw new Error(`Invalid timestamp: "${opts.since}". Use ISO 8601 format (e.g., 2026-03-28T14:00:00Z)`);
|
|
20
|
-
}
|
|
21
|
-
const run = async () => {
|
|
22
|
-
const since = sinceDate.toISOString();
|
|
23
|
-
const data = await client.getChanges(thesisId, since);
|
|
24
|
-
if (opts.json) {
|
|
25
|
-
console.log(JSON.stringify(data, null, 2));
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
if (!data.changed) {
|
|
29
|
-
console.log(`${utils_js_1.c.dim}No changes since ${sinceDate.toLocaleString()}.${utils_js_1.c.reset}`);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
// Header
|
|
33
|
-
const id = (0, utils_js_1.shortId)(thesisId);
|
|
34
|
-
console.log();
|
|
35
|
-
console.log(`${utils_js_1.c.bold}${utils_js_1.c.cyan}Delta: ${id}${utils_js_1.c.reset}${utils_js_1.c.dim} — since ${sinceDate.toLocaleString()}${utils_js_1.c.reset}`);
|
|
36
|
-
console.log(`${utils_js_1.c.dim}${'─'.repeat(65)}${utils_js_1.c.reset}`);
|
|
37
|
-
// Confidence change
|
|
38
|
-
if (data.confidence !== undefined) {
|
|
39
|
-
const conf = Math.round(data.confidence * 100);
|
|
40
|
-
const prev = data.previousConfidence !== undefined ? Math.round(data.previousConfidence * 100) : null;
|
|
41
|
-
const delta = prev !== null ? conf - prev : null;
|
|
42
|
-
let deltaStr = '';
|
|
43
|
-
if (delta !== null) {
|
|
44
|
-
deltaStr = delta > 0 ? `${utils_js_1.c.green} (+${delta}%)${utils_js_1.c.reset}` : delta < 0 ? `${utils_js_1.c.red} (${delta}%)${utils_js_1.c.reset}` : `${utils_js_1.c.dim} (0%)${utils_js_1.c.reset}`;
|
|
45
|
-
}
|
|
46
|
-
console.log(` Confidence: ${utils_js_1.c.bold}${conf}%${utils_js_1.c.reset}${deltaStr}`);
|
|
47
|
-
}
|
|
48
|
-
// Evaluation count
|
|
49
|
-
if (data.evaluationCount) {
|
|
50
|
-
console.log(` Evaluations: ${data.evaluationCount} cycle(s)`);
|
|
51
|
-
}
|
|
52
|
-
// Updated nodes
|
|
53
|
-
const nodes = data.updatedNodes || [];
|
|
54
|
-
if (nodes.length > 0) {
|
|
55
|
-
console.log();
|
|
56
|
-
console.log(` ${utils_js_1.c.bold}Node Changes (${nodes.length}):${utils_js_1.c.reset}`);
|
|
57
|
-
for (const n of nodes) {
|
|
58
|
-
const prob = Math.round((n.newProbability ?? n.newProb ?? 0) * 100);
|
|
59
|
-
const prev = n.previousProbability ?? n.prevProb;
|
|
60
|
-
let changeStr = '';
|
|
61
|
-
if (prev !== undefined && prev !== null) {
|
|
62
|
-
const prevPct = Math.round(prev * 100);
|
|
63
|
-
const d = prob - prevPct;
|
|
64
|
-
changeStr = d > 0 ? ` ${utils_js_1.c.green}+${d}%${utils_js_1.c.reset}` : d < 0 ? ` ${utils_js_1.c.red}${d}%${utils_js_1.c.reset}` : '';
|
|
65
|
-
}
|
|
66
|
-
const label = n.label || n.nodeId || '?';
|
|
67
|
-
console.log(` ${label.slice(0, 40).padEnd(40)} ${prob}%${changeStr}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
// New signals
|
|
71
|
-
const signals = data.newSignals || [];
|
|
72
|
-
if (signals.length > 0) {
|
|
73
|
-
console.log();
|
|
74
|
-
console.log(` ${utils_js_1.c.bold}New Signals (${signals.length}):${utils_js_1.c.reset}`);
|
|
75
|
-
for (const s of signals) {
|
|
76
|
-
const type = s.type || 'signal';
|
|
77
|
-
const content = (s.content || s.title || '').replace(/\n/g, ' ').slice(0, 70);
|
|
78
|
-
console.log(` ${utils_js_1.c.dim}[${type}]${utils_js_1.c.reset} ${content}`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
// Edge changes
|
|
82
|
-
const edges = data.edgeChanges || data.edges || [];
|
|
83
|
-
if (edges.length > 0) {
|
|
84
|
-
console.log();
|
|
85
|
-
console.log(` ${utils_js_1.c.bold}Edge Movements (${edges.length}):${utils_js_1.c.reset}`);
|
|
86
|
-
for (const e of edges.slice(0, 15)) {
|
|
87
|
-
const market = (e.market || e.marketId || '').slice(0, 35).padEnd(35);
|
|
88
|
-
const edge = e.edge ?? 0;
|
|
89
|
-
const prev = e.previousEdge ?? null;
|
|
90
|
-
const edgeStr = edge > 0 ? `+${edge}` : `${edge}`;
|
|
91
|
-
let changeStr = '';
|
|
92
|
-
if (prev !== null) {
|
|
93
|
-
const d = edge - prev;
|
|
94
|
-
changeStr = d > 0 ? ` ${utils_js_1.c.green}(+${d})${utils_js_1.c.reset}` : d < 0 ? ` ${utils_js_1.c.red}(${d})${utils_js_1.c.reset}` : '';
|
|
95
|
-
}
|
|
96
|
-
const color = edge > 0 ? utils_js_1.c.green : edge < 0 ? utils_js_1.c.red : utils_js_1.c.dim;
|
|
97
|
-
console.log(` ${market} ${color}${edgeStr}${utils_js_1.c.reset}${changeStr}`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
console.log(`${utils_js_1.c.dim}${'─'.repeat(65)}${utils_js_1.c.reset}`);
|
|
101
|
-
console.log();
|
|
102
|
-
};
|
|
103
|
-
if (opts.watch) {
|
|
104
|
-
console.log(`${utils_js_1.c.dim}Watching for changes every 60s... (Ctrl+C to stop)${utils_js_1.c.reset}`);
|
|
105
|
-
// eslint-disable-next-line no-constant-condition
|
|
106
|
-
while (true) {
|
|
107
|
-
await run();
|
|
108
|
-
await new Promise(r => setTimeout(r, 60_000));
|
|
109
|
-
console.clear();
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
await run();
|
|
114
|
-
}
|
|
115
|
-
}
|
package/dist/commands/edges.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* sf edges — Top edges across all active theses
|
|
3
|
-
*
|
|
4
|
-
* The most important output of the entire system: "what to trade now."
|
|
5
|
-
*
|
|
6
|
-
* Flow:
|
|
7
|
-
* 1. GET /api/thesis → all active theses
|
|
8
|
-
* 2. For each: GET /api/thesis/:id/context → edges with orderbook
|
|
9
|
-
* 3. Optional: getPositions() → Kalshi positions with live prices
|
|
10
|
-
* 4. Merge edges, dedupe by marketId (keep highest edge, note source thesis)
|
|
11
|
-
* 5. Sort by executableEdge descending
|
|
12
|
-
* 6. Display table with position overlay + summary
|
|
13
|
-
*/
|
|
14
|
-
interface EdgesOpts {
|
|
15
|
-
json?: boolean;
|
|
16
|
-
share?: boolean;
|
|
17
|
-
limit?: string;
|
|
18
|
-
thesis?: string;
|
|
19
|
-
minEdge?: string;
|
|
20
|
-
minLiquidity?: string;
|
|
21
|
-
sort?: string;
|
|
22
|
-
apiKey?: string;
|
|
23
|
-
apiUrl?: string;
|
|
24
|
-
}
|
|
25
|
-
export declare function edgesCommand(opts: EdgesOpts): Promise<void>;
|
|
26
|
-
export {};
|
package/dist/commands/edges.js
DELETED
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* sf edges — Top edges across all active theses
|
|
4
|
-
*
|
|
5
|
-
* The most important output of the entire system: "what to trade now."
|
|
6
|
-
*
|
|
7
|
-
* Flow:
|
|
8
|
-
* 1. GET /api/thesis → all active theses
|
|
9
|
-
* 2. For each: GET /api/thesis/:id/context → edges with orderbook
|
|
10
|
-
* 3. Optional: getPositions() → Kalshi positions with live prices
|
|
11
|
-
* 4. Merge edges, dedupe by marketId (keep highest edge, note source thesis)
|
|
12
|
-
* 5. Sort by executableEdge descending
|
|
13
|
-
* 6. Display table with position overlay + summary
|
|
14
|
-
*/
|
|
15
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.edgesCommand = edgesCommand;
|
|
17
|
-
const client_js_1 = require("../client.js");
|
|
18
|
-
const kalshi_js_1 = require("../kalshi.js");
|
|
19
|
-
const utils_js_1 = require("../utils.js");
|
|
20
|
-
const share_js_1 = require("../share.js");
|
|
21
|
-
async function edgesCommand(opts) {
|
|
22
|
-
const client = new client_js_1.SFClient(opts.apiKey, opts.apiUrl);
|
|
23
|
-
const limit = parseInt(opts.limit || '20');
|
|
24
|
-
const minEdge = opts.minEdge ? parseInt(opts.minEdge) : 0;
|
|
25
|
-
const minLiq = opts.minLiquidity?.toLowerCase() || '';
|
|
26
|
-
const sortBy = opts.sort || 'edge';
|
|
27
|
-
// Support both letter grades (A/B/C/D) and word grades (high/medium/low)
|
|
28
|
-
const liqRank = { a: 4, high: 4, b: 3, medium: 3, c: 2, low: 2, d: 1 };
|
|
29
|
-
// ── Step 1: Fetch theses (or single thesis) ────────────────────────────────
|
|
30
|
-
let theses;
|
|
31
|
-
if (opts.thesis) {
|
|
32
|
-
// Single thesis mode — skip listing, fetch context directly
|
|
33
|
-
console.log(`${utils_js_1.c.dim}Fetching edges for thesis ${opts.thesis}...${utils_js_1.c.reset}`);
|
|
34
|
-
theses = [{ id: opts.thesis }];
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
console.log(`${utils_js_1.c.dim}Fetching theses...${utils_js_1.c.reset}`);
|
|
38
|
-
const data = await client.listTheses();
|
|
39
|
-
const rawTheses = data.theses || data;
|
|
40
|
-
theses = (Array.isArray(rawTheses) ? rawTheses : []).filter((t) => t.status === 'active');
|
|
41
|
-
}
|
|
42
|
-
if (theses.length === 0) {
|
|
43
|
-
console.log(`${utils_js_1.c.yellow}No active theses found.${utils_js_1.c.reset} Create one: sf create "your thesis"`);
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
// ── Step 2: Fetch context for each thesis (parallel) ───────────────────────
|
|
47
|
-
console.log(`${utils_js_1.c.dim}Fetching edges from ${theses.length} ${theses.length === 1 ? 'thesis' : 'theses'}...${utils_js_1.c.reset}`);
|
|
48
|
-
const allEdges = [];
|
|
49
|
-
const contextPromises = theses.map(async (t) => {
|
|
50
|
-
try {
|
|
51
|
-
const ctx = await client.getContext(t.id);
|
|
52
|
-
return { thesisId: t.id, edges: ctx.edges || [] };
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
return { thesisId: t.id, edges: [] };
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
const results = await Promise.all(contextPromises);
|
|
59
|
-
for (const { thesisId, edges } of results) {
|
|
60
|
-
for (const e of edges) {
|
|
61
|
-
allEdges.push({
|
|
62
|
-
marketId: e.marketId || '',
|
|
63
|
-
market: e.market || e.marketTitle || e.marketId || '',
|
|
64
|
-
venue: e.venue || 'kalshi',
|
|
65
|
-
direction: e.direction || 'yes',
|
|
66
|
-
marketPrice: typeof e.marketPrice === 'number' ? e.marketPrice : 0,
|
|
67
|
-
thesisPrice: typeof e.thesisPrice === 'number' ? e.thesisPrice : 0,
|
|
68
|
-
edge: typeof e.edge === 'number' ? e.edge : 0,
|
|
69
|
-
executableEdge: typeof e.executableEdge === 'number' ? e.executableEdge : null,
|
|
70
|
-
spread: e.orderbook?.spread ?? null,
|
|
71
|
-
liquidityScore: e.orderbook?.liquidityScore ?? null,
|
|
72
|
-
thesisId,
|
|
73
|
-
position: null,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
if (allEdges.length === 0) {
|
|
78
|
-
console.log(`${utils_js_1.c.yellow}No edges found across ${theses.length} theses.${utils_js_1.c.reset}`);
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
// ── Step 3: Dedupe by marketId — keep highest absolute edge ────────────────
|
|
82
|
-
const deduped = new Map();
|
|
83
|
-
for (const edge of allEdges) {
|
|
84
|
-
const key = edge.marketId;
|
|
85
|
-
if (!key)
|
|
86
|
-
continue;
|
|
87
|
-
const existing = deduped.get(key);
|
|
88
|
-
if (!existing || Math.abs(edge.edge) > Math.abs(existing.edge)) {
|
|
89
|
-
deduped.set(key, edge);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
let merged = Array.from(deduped.values());
|
|
93
|
-
// ── Step 3b: Apply filters ─────────────────────────────────────────────────
|
|
94
|
-
if (minEdge > 0) {
|
|
95
|
-
merged = merged.filter(e => Math.abs(e.edge) >= minEdge);
|
|
96
|
-
}
|
|
97
|
-
if (minLiq && liqRank[minLiq]) {
|
|
98
|
-
merged = merged.filter(e => e.liquidityScore && (liqRank[e.liquidityScore.toLowerCase()] || 0) >= liqRank[minLiq]);
|
|
99
|
-
}
|
|
100
|
-
// ── Step 4: Fetch positions (optional) ─────────────────────────────────────
|
|
101
|
-
let positions = null;
|
|
102
|
-
if ((0, kalshi_js_1.isKalshiConfigured)()) {
|
|
103
|
-
console.log(`${utils_js_1.c.dim}Fetching Kalshi positions...${utils_js_1.c.reset}`);
|
|
104
|
-
positions = await (0, kalshi_js_1.getPositions)();
|
|
105
|
-
if (positions) {
|
|
106
|
-
// Enrich with live prices
|
|
107
|
-
for (const pos of positions) {
|
|
108
|
-
const livePrice = await (0, kalshi_js_1.getMarketPrice)(pos.ticker);
|
|
109
|
-
if (livePrice !== null) {
|
|
110
|
-
pos.current_value = livePrice;
|
|
111
|
-
pos.unrealized_pnl = Math.round((livePrice - pos.average_price_paid) * pos.quantity);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
// Match positions to edges
|
|
115
|
-
for (const edge of merged) {
|
|
116
|
-
const pos = positions.find(p => p.ticker === edge.marketId ||
|
|
117
|
-
(edge.marketId && p.ticker?.includes(edge.marketId)));
|
|
118
|
-
if (pos) {
|
|
119
|
-
edge.position = {
|
|
120
|
-
side: pos.side || 'yes',
|
|
121
|
-
quantity: pos.quantity,
|
|
122
|
-
avgPrice: pos.average_price_paid,
|
|
123
|
-
currentValue: pos.current_value,
|
|
124
|
-
pnl: pos.unrealized_pnl || 0,
|
|
125
|
-
totalCost: pos.total_cost || Math.round(pos.average_price_paid * pos.quantity),
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
// ── Step 5: Sort ────────────────────────────────────────────────────────────
|
|
132
|
-
if (sortBy === 'spread') {
|
|
133
|
-
merged.sort((a, b) => (a.spread ?? 999) - (b.spread ?? 999));
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
// Default: sort by executableEdge (or edge) descending
|
|
137
|
-
merged.sort((a, b) => {
|
|
138
|
-
const aVal = a.executableEdge !== null ? a.executableEdge : a.edge;
|
|
139
|
-
const bVal = b.executableEdge !== null ? b.executableEdge : b.edge;
|
|
140
|
-
return Math.abs(bVal) - Math.abs(aVal);
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
// Apply limit
|
|
144
|
-
const display = merged.slice(0, limit);
|
|
145
|
-
// ── Step 6: JSON / share output ────────────────────────────────────────────
|
|
146
|
-
const outputData = {
|
|
147
|
-
totalEdges: merged.length,
|
|
148
|
-
displayed: display.length,
|
|
149
|
-
thesesScanned: theses.length,
|
|
150
|
-
edges: display,
|
|
151
|
-
};
|
|
152
|
-
if (opts.share) {
|
|
153
|
-
await (0, share_js_1.shareOutput)('edges', '', outputData);
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
if (opts.json) {
|
|
157
|
-
console.log(JSON.stringify(outputData, null, 2));
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
// ── Step 6: Pretty output ──────────────────────────────────────────────────
|
|
161
|
-
console.log();
|
|
162
|
-
(0, utils_js_1.header)(`Top Edges Across ${theses.length} Theses`);
|
|
163
|
-
console.log();
|
|
164
|
-
// Header row
|
|
165
|
-
const hdr = [
|
|
166
|
-
(0, utils_js_1.pad)('Market', 32),
|
|
167
|
-
(0, utils_js_1.rpad)('Mkt', 5),
|
|
168
|
-
(0, utils_js_1.rpad)('Thesis', 7),
|
|
169
|
-
(0, utils_js_1.rpad)('Edge', 6),
|
|
170
|
-
(0, utils_js_1.rpad)('Exec', 6),
|
|
171
|
-
(0, utils_js_1.rpad)('Sprd', 5),
|
|
172
|
-
(0, utils_js_1.pad)('Liq', 5),
|
|
173
|
-
(0, utils_js_1.pad)('Thesis', 10),
|
|
174
|
-
(0, utils_js_1.pad)('Position', 20),
|
|
175
|
-
].join(' ');
|
|
176
|
-
console.log(`${utils_js_1.c.dim}${hdr}${utils_js_1.c.reset}`);
|
|
177
|
-
(0, utils_js_1.hr)(100);
|
|
178
|
-
for (const edge of display) {
|
|
179
|
-
const name = (0, utils_js_1.trunc)(edge.market, 31);
|
|
180
|
-
const mktStr = `${edge.marketPrice}¢`;
|
|
181
|
-
const thesisStr = `${edge.thesisPrice}¢`;
|
|
182
|
-
const edgeStr = edge.edge > 0 ? `+${edge.edge}` : `${edge.edge}`;
|
|
183
|
-
const execStr = edge.executableEdge !== null ? (edge.executableEdge > 0 ? `+${edge.executableEdge}` : `${edge.executableEdge}`) : '—';
|
|
184
|
-
const spreadStr = edge.spread !== null ? `${edge.spread}¢` : '—';
|
|
185
|
-
const liqStr = edge.liquidityScore || '—';
|
|
186
|
-
const thesisIdStr = (0, utils_js_1.shortId)(edge.thesisId);
|
|
187
|
-
// Color the edge values
|
|
188
|
-
const edgeColor = edge.edge > 0 ? utils_js_1.c.green : edge.edge < 0 ? utils_js_1.c.red : utils_js_1.c.dim;
|
|
189
|
-
const execColor = edge.executableEdge !== null ? (edge.executableEdge > 0 ? utils_js_1.c.green : utils_js_1.c.red) : utils_js_1.c.dim;
|
|
190
|
-
const liqColor = liqStr === 'high' ? utils_js_1.c.green : liqStr === 'medium' ? utils_js_1.c.yellow : utils_js_1.c.dim;
|
|
191
|
-
// Position string
|
|
192
|
-
let posStr = `${utils_js_1.c.dim}—${utils_js_1.c.reset}`;
|
|
193
|
-
if (edge.position) {
|
|
194
|
-
const p = edge.position;
|
|
195
|
-
const pnlStr = p.pnl >= 0 ? `${utils_js_1.c.green}+$${(p.pnl / 100).toFixed(0)}${utils_js_1.c.reset}` : `${utils_js_1.c.red}-$${(Math.abs(p.pnl) / 100).toFixed(0)}${utils_js_1.c.reset}`;
|
|
196
|
-
posStr = `${utils_js_1.c.green}${p.quantity}@${p.avgPrice}¢${utils_js_1.c.reset} ${pnlStr}`;
|
|
197
|
-
}
|
|
198
|
-
const row = [
|
|
199
|
-
edge.position ? `${utils_js_1.c.green}${(0, utils_js_1.pad)(name, 32)}${utils_js_1.c.reset}` : (0, utils_js_1.pad)(name, 32),
|
|
200
|
-
(0, utils_js_1.rpad)(mktStr, 5),
|
|
201
|
-
(0, utils_js_1.rpad)(thesisStr, 7),
|
|
202
|
-
`${edgeColor}${(0, utils_js_1.rpad)(edgeStr, 6)}${utils_js_1.c.reset}`,
|
|
203
|
-
`${execColor}${(0, utils_js_1.rpad)(execStr, 6)}${utils_js_1.c.reset}`,
|
|
204
|
-
(0, utils_js_1.rpad)(spreadStr, 5),
|
|
205
|
-
`${liqColor}${(0, utils_js_1.pad)(liqStr, 5)}${utils_js_1.c.reset}`,
|
|
206
|
-
`${utils_js_1.c.dim}${(0, utils_js_1.pad)(thesisIdStr, 10)}${utils_js_1.c.reset}`,
|
|
207
|
-
posStr,
|
|
208
|
-
].join(' ');
|
|
209
|
-
console.log(row);
|
|
210
|
-
}
|
|
211
|
-
// ── Summary ────────────────────────────────────────────────────────────────
|
|
212
|
-
(0, utils_js_1.hr)(100);
|
|
213
|
-
// Positioned summary
|
|
214
|
-
const positioned = display.filter(e => e.position);
|
|
215
|
-
if (positioned.length > 0) {
|
|
216
|
-
let totalCost = 0;
|
|
217
|
-
let totalPnl = 0;
|
|
218
|
-
for (const e of positioned) {
|
|
219
|
-
totalCost += e.position.totalCost;
|
|
220
|
-
totalPnl += e.position.pnl;
|
|
221
|
-
}
|
|
222
|
-
const costStr = `$${(totalCost / 100).toFixed(0)}`;
|
|
223
|
-
const pnlColor = totalPnl >= 0 ? utils_js_1.c.green : utils_js_1.c.red;
|
|
224
|
-
const pnlSign = totalPnl >= 0 ? '+' : '-';
|
|
225
|
-
const pnlStr = `${pnlColor}${pnlSign}$${(Math.abs(totalPnl) / 100).toFixed(0)}${utils_js_1.c.reset}`;
|
|
226
|
-
console.log(`${utils_js_1.c.bold}Total positioned:${utils_js_1.c.reset} ${costStr} cost | P&L: ${pnlStr}`);
|
|
227
|
-
}
|
|
228
|
-
// Top unpositioned
|
|
229
|
-
const unpositioned = display.filter(e => !e.position && e.edge > 0);
|
|
230
|
-
if (unpositioned.length > 0) {
|
|
231
|
-
const top = unpositioned[0];
|
|
232
|
-
const execLabel = top.executableEdge !== null ? `exec +${top.executableEdge}` : `edge +${top.edge}`;
|
|
233
|
-
const liq = top.liquidityScore ? `, ${top.liquidityScore} liq` : '';
|
|
234
|
-
console.log(`${utils_js_1.c.bold}Top unpositioned:${utils_js_1.c.reset} ${(0, utils_js_1.trunc)(top.market, 30)} @ ${top.marketPrice}¢ (${execLabel}${liq})`);
|
|
235
|
-
}
|
|
236
|
-
console.log();
|
|
237
|
-
}
|