@spfunctions/cli 1.7.19 → 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 -833
- package/package.json +5 -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 -246
- 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 -116
- 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 -10
- 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 -52
- package/dist/utils.js +0 -146
- package/dist/utils.test.d.ts +0 -1
- package/dist/utils.test.js +0 -111
package/dist/commands/orders.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ordersCommand = ordersCommand;
|
|
4
|
-
const kalshi_js_1 = require("../kalshi.js");
|
|
5
|
-
const utils_js_1 = require("../utils.js");
|
|
6
|
-
async function ordersCommand(opts) {
|
|
7
|
-
const status = opts.status || 'resting';
|
|
8
|
-
const result = await (0, kalshi_js_1.getOrders)({ status, limit: 100 });
|
|
9
|
-
if (!result)
|
|
10
|
-
throw new Error('Kalshi not configured. Set KALSHI_API_KEY_ID + KALSHI_PRIVATE_KEY_PATH.');
|
|
11
|
-
if (opts.json) {
|
|
12
|
-
console.log(JSON.stringify(result.orders, null, 2));
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
if (result.orders.length === 0) {
|
|
16
|
-
console.log(`${utils_js_1.c.dim}No ${status} orders.${utils_js_1.c.reset}`);
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
console.log(`${utils_js_1.c.bold}${utils_js_1.c.cyan}Orders (${status})${utils_js_1.c.reset}`);
|
|
20
|
-
console.log(`${utils_js_1.c.dim}${'─'.repeat(80)}${utils_js_1.c.reset}`);
|
|
21
|
-
for (const o of result.orders) {
|
|
22
|
-
const price = o.yes_price_dollars ? `${parseFloat(o.yes_price_dollars) * 100}¢` : `${o.yes_price || '?'}¢`;
|
|
23
|
-
const side = o.side === 'yes' ? `${utils_js_1.c.green}YES${utils_js_1.c.reset}` : `${utils_js_1.c.red}NO${utils_js_1.c.reset}`;
|
|
24
|
-
const remaining = o.remaining_count_fp || o.remaining_count || '?';
|
|
25
|
-
console.log(` ${(o.ticker || '').padEnd(35)} ${side} ${price.padEnd(8)} qty ${remaining}`);
|
|
26
|
-
}
|
|
27
|
-
console.log(`\n${utils_js_1.c.dim}${result.orders.length} order(s)${utils_js_1.c.reset}`);
|
|
28
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* sf performance — Portfolio P&L over time with thesis event annotations
|
|
3
|
-
*
|
|
4
|
-
* Layout: each row is a position, with inline sparkline and current P&L.
|
|
5
|
-
* Scales from 7 days to months — sparkline adapts to available data.
|
|
6
|
-
*/
|
|
7
|
-
export declare function performanceCommand(opts: {
|
|
8
|
-
ticker?: string;
|
|
9
|
-
since?: string;
|
|
10
|
-
json?: boolean;
|
|
11
|
-
}): Promise<void>;
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* sf performance — Portfolio P&L over time with thesis event annotations
|
|
4
|
-
*
|
|
5
|
-
* Layout: each row is a position, with inline sparkline and current P&L.
|
|
6
|
-
* Scales from 7 days to months — sparkline adapts to available data.
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.performanceCommand = performanceCommand;
|
|
10
|
-
const client_js_1 = require("../client.js");
|
|
11
|
-
const kalshi_js_1 = require("../kalshi.js");
|
|
12
|
-
const config_js_1 = require("../config.js");
|
|
13
|
-
const utils_js_1 = require("../utils.js");
|
|
14
|
-
function fmtDate(d) {
|
|
15
|
-
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
16
|
-
return `${months[d.getMonth()]} ${String(d.getDate()).padStart(2, '0')}`;
|
|
17
|
-
}
|
|
18
|
-
function fmtDollar(cents) {
|
|
19
|
-
const abs = Math.abs(cents / 100);
|
|
20
|
-
const str = abs >= 1000 ? `${(abs / 1000).toFixed(1)}k` : abs >= 100 ? abs.toFixed(0) : abs.toFixed(2);
|
|
21
|
-
return cents >= 0 ? `+$${str}` : `-$${str}`;
|
|
22
|
-
}
|
|
23
|
-
function dateKey(d) {
|
|
24
|
-
return d.toISOString().slice(0, 10);
|
|
25
|
-
}
|
|
26
|
-
/** Build a sparkline string from an array of values */
|
|
27
|
-
function sparkline(values, colorFn) {
|
|
28
|
-
if (values.length === 0)
|
|
29
|
-
return '';
|
|
30
|
-
const min = Math.min(...values);
|
|
31
|
-
const max = Math.max(...values);
|
|
32
|
-
const range = max - min || 1;
|
|
33
|
-
const blocks = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
|
|
34
|
-
return values.map(v => {
|
|
35
|
-
const idx = Math.round(((v - min) / range) * (blocks.length - 1));
|
|
36
|
-
const ch = blocks[idx];
|
|
37
|
-
if (colorFn)
|
|
38
|
-
return colorFn(v) + ch + utils_js_1.c.reset;
|
|
39
|
-
return ch;
|
|
40
|
-
}).join('');
|
|
41
|
-
}
|
|
42
|
-
async function performanceCommand(opts) {
|
|
43
|
-
if (!(0, kalshi_js_1.isKalshiConfigured)()) {
|
|
44
|
-
console.log(`${utils_js_1.c.yellow}Kalshi not configured.${utils_js_1.c.reset} Run ${utils_js_1.c.cyan}sf setup --kalshi${utils_js_1.c.reset} first.`);
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
// 1. Fetch fills
|
|
48
|
-
const fillsResult = await (0, kalshi_js_1.getFills)({ limit: 500 });
|
|
49
|
-
if (!fillsResult || fillsResult.fills.length === 0) {
|
|
50
|
-
console.log(`${utils_js_1.c.dim}No fills found.${utils_js_1.c.reset}`);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const tickerMap = new Map();
|
|
54
|
-
for (const fill of fillsResult.fills) {
|
|
55
|
-
const ticker = fill.ticker || fill.market_ticker || '';
|
|
56
|
-
if (!ticker)
|
|
57
|
-
continue;
|
|
58
|
-
const action = fill.action || 'buy';
|
|
59
|
-
const side = fill.side || 'yes';
|
|
60
|
-
const count = Math.round(parseFloat(fill.count_fp || fill.count || '0'));
|
|
61
|
-
const yesPrice = Math.round(parseFloat(fill.yes_price_dollars || '0') * 100);
|
|
62
|
-
// buy yes = +count, sell yes = -count
|
|
63
|
-
// buy no = -count (short yes), sell no = +count (close short)
|
|
64
|
-
let delta = count;
|
|
65
|
-
if (action === 'sell')
|
|
66
|
-
delta = -delta;
|
|
67
|
-
if (side === 'no')
|
|
68
|
-
delta = -delta;
|
|
69
|
-
const info = tickerMap.get(ticker) || { ticker, netQty: 0, totalCostCents: 0, totalContracts: 0, earliestFillTs: Infinity };
|
|
70
|
-
info.netQty += delta;
|
|
71
|
-
if (delta > 0) {
|
|
72
|
-
// Entering a position — accumulate cost
|
|
73
|
-
const costPerContract = side === 'no' ? (100 - yesPrice) : yesPrice;
|
|
74
|
-
info.totalCostCents += costPerContract * count;
|
|
75
|
-
info.totalContracts += count;
|
|
76
|
-
}
|
|
77
|
-
const fillTime = fill.created_time || fill.ts || fill.created_at;
|
|
78
|
-
if (fillTime) {
|
|
79
|
-
const ts = Math.floor(new Date(fillTime).getTime() / 1000);
|
|
80
|
-
if (ts < info.earliestFillTs)
|
|
81
|
-
info.earliestFillTs = ts;
|
|
82
|
-
}
|
|
83
|
-
tickerMap.set(ticker, info);
|
|
84
|
-
}
|
|
85
|
-
let tickers = [...tickerMap.values()].filter(t => t.netQty !== 0);
|
|
86
|
-
if (opts.ticker) {
|
|
87
|
-
const needle = opts.ticker.toLowerCase();
|
|
88
|
-
tickers = tickers.filter(t => t.ticker.toLowerCase().includes(needle));
|
|
89
|
-
}
|
|
90
|
-
if (tickers.length === 0) {
|
|
91
|
-
console.log(`${utils_js_1.c.dim}No open positions found${opts.ticker ? ` matching "${opts.ticker}"` : ''}.${utils_js_1.c.reset}`);
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
// 3. Fetch candlesticks
|
|
95
|
-
const sinceTs = opts.since
|
|
96
|
-
? Math.floor(new Date(opts.since).getTime() / 1000)
|
|
97
|
-
: Math.min(...tickers.map(t => t.earliestFillTs === Infinity ? Math.floor(Date.now() / 1000) - 30 * 86400 : t.earliestFillTs));
|
|
98
|
-
const nowTs = Math.floor(Date.now() / 1000);
|
|
99
|
-
const candleData = await (0, kalshi_js_1.getBatchCandlesticks)({
|
|
100
|
-
tickers: tickers.map(t => t.ticker),
|
|
101
|
-
startTs: sinceTs,
|
|
102
|
-
endTs: nowTs,
|
|
103
|
-
periodInterval: 1440,
|
|
104
|
-
});
|
|
105
|
-
// Build candlestick lookup: ticker -> sorted [{ date, closeCents }]
|
|
106
|
-
const candleMap = new Map();
|
|
107
|
-
for (const mc of candleData) {
|
|
108
|
-
const entries = [];
|
|
109
|
-
for (const candle of (mc.candlesticks || [])) {
|
|
110
|
-
const bidClose = parseFloat(candle.yes_bid?.close_dollars || '0');
|
|
111
|
-
const askClose = parseFloat(candle.yes_ask?.close_dollars || '0');
|
|
112
|
-
const mid = bidClose > 0 && askClose > 0 ? (bidClose + askClose) / 2 : bidClose || askClose;
|
|
113
|
-
const closeDollars = parseFloat(candle.price?.close_dollars || '0') || mid;
|
|
114
|
-
const closeCents = Math.round(closeDollars * 100);
|
|
115
|
-
const ts = candle.end_period_ts || candle.period_end_ts || candle.ts;
|
|
116
|
-
if (ts)
|
|
117
|
-
entries.push({ date: dateKey(new Date(ts * 1000)), close: closeCents });
|
|
118
|
-
}
|
|
119
|
-
entries.sort((a, b) => a.date.localeCompare(b.date));
|
|
120
|
-
candleMap.set(mc.market_ticker, entries);
|
|
121
|
-
}
|
|
122
|
-
// Collect all dates for total P&L
|
|
123
|
-
const allDates = new Set();
|
|
124
|
-
for (const [, entries] of candleMap)
|
|
125
|
-
for (const e of entries)
|
|
126
|
-
allDates.add(e.date);
|
|
127
|
-
const sortedDates = [...allDates].sort();
|
|
128
|
-
// Entry prices
|
|
129
|
-
const entryPrices = new Map();
|
|
130
|
-
for (const t of tickers) {
|
|
131
|
-
entryPrices.set(t.ticker, t.totalContracts > 0 ? Math.round(t.totalCostCents / t.totalContracts) : 0);
|
|
132
|
-
}
|
|
133
|
-
const events = [];
|
|
134
|
-
try {
|
|
135
|
-
const config = (0, config_js_1.loadConfig)();
|
|
136
|
-
const client = new client_js_1.SFClient(config.apiKey, config.apiUrl);
|
|
137
|
-
const feedData = await client.getFeed(720);
|
|
138
|
-
const feedItems = feedData?.feed || feedData?.items || feedData || [];
|
|
139
|
-
if (Array.isArray(feedItems)) {
|
|
140
|
-
for (const item of feedItems) {
|
|
141
|
-
const confDelta = item.delta ?? item.confidenceDelta ?? 0;
|
|
142
|
-
if (Math.abs(confDelta) >= 0.02) {
|
|
143
|
-
const itemDate = item.evaluatedAt || item.createdAt || item.timestamp || '';
|
|
144
|
-
if (itemDate) {
|
|
145
|
-
events.push({
|
|
146
|
-
date: dateKey(new Date(itemDate)),
|
|
147
|
-
direction: confDelta > 0 ? 'up' : 'down',
|
|
148
|
-
deltaPct: Math.round(confDelta * 100),
|
|
149
|
-
summary: item.summary || '',
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
catch { /* feed unavailable */ }
|
|
157
|
-
const perfs = [];
|
|
158
|
-
for (const t of tickers) {
|
|
159
|
-
const entry = entryPrices.get(t.ticker) || 0;
|
|
160
|
-
const entries = candleMap.get(t.ticker) || [];
|
|
161
|
-
const current = entries.length > 0 ? entries[entries.length - 1].close : entry;
|
|
162
|
-
const pnlCents = (current - entry) * t.netQty;
|
|
163
|
-
const costBasis = entry * t.netQty;
|
|
164
|
-
const pnlPct = costBasis !== 0 ? (pnlCents / Math.abs(costBasis)) * 100 : 0;
|
|
165
|
-
const dailyPnl = entries.map(e => (e.close - entry) * t.netQty);
|
|
166
|
-
perfs.push({ ticker: t.ticker, qty: t.netQty, entry, current, pnlCents, pnlPct, dailyPnl });
|
|
167
|
-
}
|
|
168
|
-
// Sort by absolute P&L descending
|
|
169
|
-
perfs.sort((a, b) => Math.abs(b.pnlCents) - Math.abs(a.pnlCents));
|
|
170
|
-
// Total daily P&L
|
|
171
|
-
const totalDailyPnl = sortedDates.map(dk => {
|
|
172
|
-
let total = 0;
|
|
173
|
-
for (const t of tickers) {
|
|
174
|
-
const entries = candleMap.get(t.ticker) || [];
|
|
175
|
-
const entry = entryPrices.get(t.ticker) || 0;
|
|
176
|
-
const dayEntry = entries.find(e => e.date === dk);
|
|
177
|
-
if (dayEntry)
|
|
178
|
-
total += (dayEntry.close - entry) * t.netQty;
|
|
179
|
-
}
|
|
180
|
-
return total;
|
|
181
|
-
});
|
|
182
|
-
// Summary
|
|
183
|
-
const totalCostCents = tickers.reduce((sum, t) => sum + t.totalCostCents, 0);
|
|
184
|
-
const totalPnlCents = perfs.reduce((sum, p) => sum + p.pnlCents, 0);
|
|
185
|
-
const totalPnlPct = totalCostCents > 0 ? (totalPnlCents / totalCostCents) * 100 : 0;
|
|
186
|
-
// 6. JSON output
|
|
187
|
-
if (opts.json) {
|
|
188
|
-
console.log(JSON.stringify({
|
|
189
|
-
positions: perfs.map(p => ({
|
|
190
|
-
ticker: p.ticker, qty: p.qty, entry: p.entry, current: p.current,
|
|
191
|
-
pnl: p.pnlCents, pnlPct: Math.round(p.pnlPct * 10) / 10,
|
|
192
|
-
})),
|
|
193
|
-
totalDailyPnl: sortedDates.map((d, i) => ({ date: d, pnl: totalDailyPnl[i] })),
|
|
194
|
-
events,
|
|
195
|
-
summary: { cost: totalCostCents, pnl: totalPnlCents, pnlPct: Math.round(totalPnlPct * 10) / 10 },
|
|
196
|
-
}, null, 2));
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
// 7. Formatted output — rows are positions
|
|
200
|
-
const startDate = sortedDates.length > 0 ? fmtDate(new Date(sortedDates[0])) : '?';
|
|
201
|
-
const endDate = fmtDate(new Date());
|
|
202
|
-
console.log();
|
|
203
|
-
console.log(` ${utils_js_1.c.bold}Portfolio Performance${utils_js_1.c.reset} ${utils_js_1.c.dim}(${startDate} → ${endDate})${utils_js_1.c.reset}`);
|
|
204
|
-
console.log(` ${utils_js_1.c.dim}${'─'.repeat(76)}${utils_js_1.c.reset}`);
|
|
205
|
-
console.log();
|
|
206
|
-
// Header
|
|
207
|
-
const maxTickerLen = Math.max(...perfs.map(p => p.ticker.length), 5) + 2;
|
|
208
|
-
const w = maxTickerLen + 50;
|
|
209
|
-
const pad2 = (s, n) => s.padEnd(n);
|
|
210
|
-
console.log(` ${utils_js_1.c.dim}${pad2('Ticker', maxTickerLen)} Qty Entry Now P&L Trend${utils_js_1.c.reset}`);
|
|
211
|
-
for (const p of perfs) {
|
|
212
|
-
const pnlStr = fmtDollar(p.pnlCents);
|
|
213
|
-
const pnlColor = p.pnlCents > 0 ? utils_js_1.c.green : p.pnlCents < 0 ? utils_js_1.c.red : utils_js_1.c.dim;
|
|
214
|
-
const spark = sparkline(p.dailyPnl, v => v >= 0 ? utils_js_1.c.green : utils_js_1.c.red);
|
|
215
|
-
console.log(` ${pad2(p.ticker, maxTickerLen)} ` +
|
|
216
|
-
`${(0, utils_js_1.rpad)(String(p.qty), 8)}` +
|
|
217
|
-
`${(0, utils_js_1.rpad)(p.entry + '¢', 7)}` +
|
|
218
|
-
`${(0, utils_js_1.rpad)(p.current + '¢', 7)}` +
|
|
219
|
-
`${pnlColor}${(0, utils_js_1.rpad)(pnlStr, 13)}${utils_js_1.c.reset}` +
|
|
220
|
-
spark);
|
|
221
|
-
}
|
|
222
|
-
// Total row
|
|
223
|
-
console.log(` ${utils_js_1.c.dim}${'─'.repeat(w)}${utils_js_1.c.reset}`);
|
|
224
|
-
const totalPnlStr = fmtDollar(totalPnlCents);
|
|
225
|
-
const totalPctStr = `${totalPnlPct >= 0 ? '+' : ''}${totalPnlPct.toFixed(1)}%`;
|
|
226
|
-
const totalColor = totalPnlCents >= 0 ? utils_js_1.c.green : utils_js_1.c.red;
|
|
227
|
-
const totalSpark = sparkline(totalDailyPnl, v => v >= 0 ? utils_js_1.c.green : utils_js_1.c.red);
|
|
228
|
-
console.log(` ${utils_js_1.c.bold}${pad2('TOTAL', maxTickerLen)}${utils_js_1.c.reset} ` +
|
|
229
|
-
`${(0, utils_js_1.rpad)('', 22)}` +
|
|
230
|
-
`${totalColor}${utils_js_1.c.bold}${(0, utils_js_1.rpad)(`${totalPnlStr} (${totalPctStr})`, 13)}${utils_js_1.c.reset}` +
|
|
231
|
-
totalSpark);
|
|
232
|
-
// Events
|
|
233
|
-
if (events.length > 0) {
|
|
234
|
-
const dateSet = new Set(sortedDates);
|
|
235
|
-
const relevant = events.filter(e => dateSet.has(e.date));
|
|
236
|
-
if (relevant.length > 0) {
|
|
237
|
-
console.log();
|
|
238
|
-
for (const ev of relevant.slice(0, 8)) {
|
|
239
|
-
const arrow = ev.direction === 'up' ? `${utils_js_1.c.green}▲${utils_js_1.c.reset}` : `${utils_js_1.c.red}▼${utils_js_1.c.reset}`;
|
|
240
|
-
const summary = ev.summary.length > 55 ? ev.summary.slice(0, 54) + '…' : ev.summary;
|
|
241
|
-
console.log(` ${arrow} ${utils_js_1.c.dim}${fmtDate(new Date(ev.date))}${utils_js_1.c.reset} ${ev.deltaPct > 0 ? '+' : ''}${ev.deltaPct}% → ${summary}`);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
// Summary
|
|
246
|
-
console.log();
|
|
247
|
-
const costStr = `$${(totalCostCents / 100).toFixed(0)}`;
|
|
248
|
-
console.log(` ${utils_js_1.c.dim}Cost basis:${utils_js_1.c.reset} ${costStr} ${utils_js_1.c.dim}|${utils_js_1.c.reset} ${totalColor}${utils_js_1.c.bold}${totalPnlStr} (${totalPctStr})${utils_js_1.c.reset}`);
|
|
249
|
-
console.log();
|
|
250
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* sf positions — Show Kalshi positions with thesis edge overlay
|
|
3
|
-
*
|
|
4
|
-
* Flow:
|
|
5
|
-
* 1. Call local kalshi.getPositions() (Kalshi SDK + local private key) → real positions
|
|
6
|
-
* 2. Call SF API /api/thesis (via SF_API_KEY) → all theses' edge_analysis
|
|
7
|
-
* 3. Local merge: match position ticker to edge marketId
|
|
8
|
-
* 4. Output
|
|
9
|
-
*
|
|
10
|
-
* No server involvement for positions. Kalshi credentials never leave the machine.
|
|
11
|
-
*/
|
|
12
|
-
interface PositionsOpts {
|
|
13
|
-
json?: boolean;
|
|
14
|
-
thesis?: string;
|
|
15
|
-
apiKey?: string;
|
|
16
|
-
apiUrl?: string;
|
|
17
|
-
}
|
|
18
|
-
export declare function positionsCommand(opts: PositionsOpts): Promise<void>;
|
|
19
|
-
export {};
|
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* sf positions — Show Kalshi positions with thesis edge overlay
|
|
4
|
-
*
|
|
5
|
-
* Flow:
|
|
6
|
-
* 1. Call local kalshi.getPositions() (Kalshi SDK + local private key) → real positions
|
|
7
|
-
* 2. Call SF API /api/thesis (via SF_API_KEY) → all theses' edge_analysis
|
|
8
|
-
* 3. Local merge: match position ticker to edge marketId
|
|
9
|
-
* 4. Output
|
|
10
|
-
*
|
|
11
|
-
* No server involvement for positions. Kalshi credentials never leave the machine.
|
|
12
|
-
*/
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.positionsCommand = positionsCommand;
|
|
15
|
-
const client_js_1 = require("../client.js");
|
|
16
|
-
const kalshi_js_1 = require("../kalshi.js");
|
|
17
|
-
const polymarket_js_1 = require("../polymarket.js");
|
|
18
|
-
const config_js_1 = require("../config.js");
|
|
19
|
-
const utils_js_1 = require("../utils.js");
|
|
20
|
-
async function positionsCommand(opts) {
|
|
21
|
-
const client = new client_js_1.SFClient(opts.apiKey, opts.apiUrl);
|
|
22
|
-
// ── Step 1: Fetch Kalshi positions (local) ──
|
|
23
|
-
let positions = null;
|
|
24
|
-
if ((0, kalshi_js_1.isKalshiConfigured)()) {
|
|
25
|
-
console.log(`${utils_js_1.c.dim}Fetching Kalshi positions...${utils_js_1.c.reset}`);
|
|
26
|
-
positions = await (0, kalshi_js_1.getPositions)();
|
|
27
|
-
}
|
|
28
|
-
// ── Step 1b: Fetch Polymarket positions (if wallet configured) ──
|
|
29
|
-
const config = (0, config_js_1.loadConfig)();
|
|
30
|
-
let polyPositions = [];
|
|
31
|
-
if (config.polymarketWalletAddress) {
|
|
32
|
-
console.log(`${utils_js_1.c.dim}Fetching Polymarket positions...${utils_js_1.c.reset}`);
|
|
33
|
-
try {
|
|
34
|
-
polyPositions = await (0, polymarket_js_1.polymarketGetPositions)(config.polymarketWalletAddress);
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
// skip
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
// ── Step 2: Fetch all theses and their edges (via SF API) ──
|
|
41
|
-
console.log(`${utils_js_1.c.dim}Fetching thesis edges...${utils_js_1.c.reset}`);
|
|
42
|
-
let theses = [];
|
|
43
|
-
try {
|
|
44
|
-
const data = await client.listTheses();
|
|
45
|
-
theses = data.theses || [];
|
|
46
|
-
}
|
|
47
|
-
catch (err) {
|
|
48
|
-
console.warn(`${utils_js_1.c.yellow}Warning: Could not fetch theses: ${err}${utils_js_1.c.reset}`);
|
|
49
|
-
}
|
|
50
|
-
// If filtering by thesis, only fetch that one's context
|
|
51
|
-
let allEdges = [];
|
|
52
|
-
if (opts.thesis) {
|
|
53
|
-
try {
|
|
54
|
-
const ctx = await client.getContext(opts.thesis);
|
|
55
|
-
for (const edge of (ctx.edges || [])) {
|
|
56
|
-
allEdges.push({
|
|
57
|
-
thesisId: ctx.thesisId,
|
|
58
|
-
thesisTitle: ctx.thesis || ctx.title || '',
|
|
59
|
-
edge,
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
catch (err) {
|
|
64
|
-
console.warn(`${utils_js_1.c.yellow}Warning: Could not fetch context for ${opts.thesis}: ${err}${utils_js_1.c.reset}`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
// Fetch context for all monitoring theses
|
|
69
|
-
const monitoringTheses = theses.filter(t => t.status === 'monitoring' || t.status === 'active');
|
|
70
|
-
for (const thesis of monitoringTheses.slice(0, 5)) { // limit to 5 to avoid rate limits
|
|
71
|
-
try {
|
|
72
|
-
const ctx = await client.getContext(thesis.id);
|
|
73
|
-
for (const edge of (ctx.edges || [])) {
|
|
74
|
-
allEdges.push({
|
|
75
|
-
thesisId: thesis.id,
|
|
76
|
-
thesisTitle: ctx.thesis || ctx.title || thesis.title || '',
|
|
77
|
-
edge,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
// skip failed
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// ── Step 2.5: Enrich positions with live prices ──
|
|
87
|
-
if (positions && positions.length > 0) {
|
|
88
|
-
console.log(`${utils_js_1.c.dim}Fetching live prices for ${positions.length} positions...${utils_js_1.c.reset}`);
|
|
89
|
-
for (const pos of positions) {
|
|
90
|
-
try {
|
|
91
|
-
const livePrice = await (0, kalshi_js_1.getMarketPrice)(pos.ticker);
|
|
92
|
-
if (livePrice !== null) {
|
|
93
|
-
pos.current_value = livePrice;
|
|
94
|
-
// P&L in cents: (currentPrice - avgEntry) * quantity
|
|
95
|
-
pos.unrealized_pnl = (livePrice - pos.average_price_paid) * pos.quantity;
|
|
96
|
-
}
|
|
97
|
-
// Small delay to avoid rate limits
|
|
98
|
-
await new Promise(r => setTimeout(r, 100));
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
// skip — live price optional
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
// ── Step 3: Merge ──
|
|
106
|
-
// Build a lookup from ticker → edge
|
|
107
|
-
const edgeByTicker = new Map();
|
|
108
|
-
for (const item of allEdges) {
|
|
109
|
-
const ticker = item.edge.marketId;
|
|
110
|
-
if (!edgeByTicker.has(ticker))
|
|
111
|
-
edgeByTicker.set(ticker, []);
|
|
112
|
-
edgeByTicker.get(ticker).push(item);
|
|
113
|
-
}
|
|
114
|
-
if (opts.json) {
|
|
115
|
-
console.log(JSON.stringify({
|
|
116
|
-
kalshiConfigured: (0, kalshi_js_1.isKalshiConfigured)(),
|
|
117
|
-
polymarketConfigured: !!config.polymarketWalletAddress,
|
|
118
|
-
positions: positions || [],
|
|
119
|
-
polymarketPositions: polyPositions,
|
|
120
|
-
edges: allEdges.map(e => ({ ...e.edge, thesisId: e.thesisId })),
|
|
121
|
-
}, null, 2));
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
// ── Step 4: Display ──
|
|
125
|
-
// A) Positioned edges (positions that match thesis edges)
|
|
126
|
-
if (positions && positions.length > 0) {
|
|
127
|
-
(0, utils_js_1.header)('Your Positions (via Kalshi)');
|
|
128
|
-
console.log(' ' + utils_js_1.c.bold +
|
|
129
|
-
(0, utils_js_1.pad)('Ticker', 25) +
|
|
130
|
-
(0, utils_js_1.rpad)('Side', 5) +
|
|
131
|
-
(0, utils_js_1.rpad)('Qty', 7) +
|
|
132
|
-
(0, utils_js_1.rpad)('Avg', 6) +
|
|
133
|
-
(0, utils_js_1.rpad)('Now', 6) +
|
|
134
|
-
(0, utils_js_1.rpad)('P&L', 9) +
|
|
135
|
-
(0, utils_js_1.rpad)('Edge', 7) +
|
|
136
|
-
' Signal' +
|
|
137
|
-
utils_js_1.c.reset);
|
|
138
|
-
console.log(' ' + utils_js_1.c.dim + '─'.repeat(85) + utils_js_1.c.reset);
|
|
139
|
-
for (const pos of positions) {
|
|
140
|
-
// Try to get current price
|
|
141
|
-
const nowPrice = pos.current_value || null;
|
|
142
|
-
const avgPrice = pos.average_price_paid || 0;
|
|
143
|
-
const pnl = pos.unrealized_pnl || 0;
|
|
144
|
-
const pnlColor = pnl > 0 ? utils_js_1.c.green : pnl < 0 ? utils_js_1.c.red : utils_js_1.c.dim;
|
|
145
|
-
const pnlStr = pnl >= 0 ? `+$${(pnl / 100).toFixed(2)}` : `-$${(Math.abs(pnl) / 100).toFixed(2)}`;
|
|
146
|
-
// Find matching edge
|
|
147
|
-
const matchingEdges = edgeByTicker.get(pos.ticker) || [];
|
|
148
|
-
const topEdge = matchingEdges[0];
|
|
149
|
-
const edgeSize = topEdge?.edge?.edge ?? topEdge?.edge?.edgeSize ?? 0;
|
|
150
|
-
const edgeColor = Math.abs(edgeSize) > 10 ? utils_js_1.c.green : Math.abs(edgeSize) > 5 ? utils_js_1.c.yellow : utils_js_1.c.dim;
|
|
151
|
-
// Signal: HOLD if edge still positive in same direction, WATCH otherwise
|
|
152
|
-
let signal = 'HOLD';
|
|
153
|
-
if (topEdge) {
|
|
154
|
-
const posDirection = pos.side;
|
|
155
|
-
const edgeDirection = topEdge.edge.direction;
|
|
156
|
-
if (posDirection === edgeDirection && edgeSize > 3) {
|
|
157
|
-
signal = 'HOLD';
|
|
158
|
-
}
|
|
159
|
-
else if (edgeSize < -3) {
|
|
160
|
-
signal = 'CLOSE';
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
signal = 'HOLD';
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
signal = '—';
|
|
168
|
-
}
|
|
169
|
-
const signalColor = signal === 'HOLD' ? utils_js_1.c.dim : signal === 'CLOSE' ? utils_js_1.c.red : utils_js_1.c.yellow;
|
|
170
|
-
console.log(' ' +
|
|
171
|
-
(0, utils_js_1.pad)(pos.ticker, 25) +
|
|
172
|
-
(0, utils_js_1.rpad)(pos.side.toUpperCase(), 5) +
|
|
173
|
-
(0, utils_js_1.rpad)(String(pos.quantity), 7) +
|
|
174
|
-
(0, utils_js_1.rpad)(`${avgPrice}¢`, 6) +
|
|
175
|
-
(0, utils_js_1.rpad)(nowPrice ? `${nowPrice}¢` : '-', 6) +
|
|
176
|
-
`${pnlColor}${(0, utils_js_1.rpad)(pnlStr, 9)}${utils_js_1.c.reset}` +
|
|
177
|
-
`${edgeColor}${(0, utils_js_1.rpad)(edgeSize ? `${edgeSize > 0 ? '+' : ''}${edgeSize.toFixed(0)}` : '-', 7)}${utils_js_1.c.reset}` +
|
|
178
|
-
` ${signalColor}${signal}${utils_js_1.c.reset}`);
|
|
179
|
-
}
|
|
180
|
-
console.log('');
|
|
181
|
-
}
|
|
182
|
-
else if ((0, kalshi_js_1.isKalshiConfigured)()) {
|
|
183
|
-
console.log(`\n ${utils_js_1.c.dim}No open Kalshi positions.${utils_js_1.c.reset}\n`);
|
|
184
|
-
}
|
|
185
|
-
else {
|
|
186
|
-
console.log(`\n ${utils_js_1.c.dim}Kalshi not configured. Run: ${utils_js_1.c.cyan}sf setup --kalshi${utils_js_1.c.reset}\n`);
|
|
187
|
-
}
|
|
188
|
-
// C) Polymarket positions
|
|
189
|
-
if (polyPositions.length > 0) {
|
|
190
|
-
(0, utils_js_1.header)('Polymarket Positions');
|
|
191
|
-
console.log(' ' + utils_js_1.c.bold +
|
|
192
|
-
(0, utils_js_1.pad)('Market', 35) +
|
|
193
|
-
(0, utils_js_1.rpad)('Side', 5) +
|
|
194
|
-
(0, utils_js_1.rpad)('Size', 8) +
|
|
195
|
-
(0, utils_js_1.rpad)('Avg', 6) +
|
|
196
|
-
(0, utils_js_1.rpad)('Now', 6) +
|
|
197
|
-
(0, utils_js_1.rpad)('P&L', 9) +
|
|
198
|
-
utils_js_1.c.reset);
|
|
199
|
-
console.log(' ' + utils_js_1.c.dim + '─'.repeat(75) + utils_js_1.c.reset);
|
|
200
|
-
for (const pos of polyPositions) {
|
|
201
|
-
const title = (pos.title || pos.slug || pos.asset || '').slice(0, 34);
|
|
202
|
-
const side = pos.outcome || 'YES';
|
|
203
|
-
const size = pos.size || 0;
|
|
204
|
-
const avgPrice = Math.round((pos.avgPrice || 0) * 100);
|
|
205
|
-
const curPrice = Math.round((pos.curPrice || pos.currentPrice || 0) * 100);
|
|
206
|
-
const pnl = pos.cashPnl || ((curPrice - avgPrice) * size / 100);
|
|
207
|
-
const pnlColor = pnl >= 0 ? utils_js_1.c.green : utils_js_1.c.red;
|
|
208
|
-
const pnlStr = pnl >= 0 ? `+$${pnl.toFixed(2)}` : `-$${Math.abs(pnl).toFixed(2)}`;
|
|
209
|
-
console.log(' ' +
|
|
210
|
-
(0, utils_js_1.pad)(title, 35) +
|
|
211
|
-
(0, utils_js_1.rpad)(side.toUpperCase(), 5) +
|
|
212
|
-
(0, utils_js_1.rpad)(String(Math.round(size)), 8) +
|
|
213
|
-
(0, utils_js_1.rpad)(`${avgPrice}¢`, 6) +
|
|
214
|
-
(0, utils_js_1.rpad)(`${curPrice}¢`, 6) +
|
|
215
|
-
`${pnlColor}${(0, utils_js_1.rpad)(pnlStr, 9)}${utils_js_1.c.reset}`);
|
|
216
|
-
}
|
|
217
|
-
console.log('');
|
|
218
|
-
}
|
|
219
|
-
else if (config.polymarketWalletAddress) {
|
|
220
|
-
console.log(`${utils_js_1.c.dim}No open positions on Polymarket.${utils_js_1.c.reset}\n`);
|
|
221
|
-
}
|
|
222
|
-
// B) Unpositioned edges (edges without matching positions)
|
|
223
|
-
const positionedTickers = new Set((positions || []).map(p => p.ticker));
|
|
224
|
-
const unpositionedEdges = allEdges.filter(e => !positionedTickers.has(e.edge.marketId));
|
|
225
|
-
if (unpositionedEdges.length > 0) {
|
|
226
|
-
// Sort by absolute edge size descending
|
|
227
|
-
unpositionedEdges.sort((a, b) => Math.abs(b.edge.edge ?? b.edge.edgeSize ?? 0) - Math.abs(a.edge.edge ?? a.edge.edgeSize ?? 0));
|
|
228
|
-
// Pre-fetch orderbooks locally for top Kalshi edges that don't already have server OB data
|
|
229
|
-
const topEdgesForOB = unpositionedEdges.slice(0, 10).filter(item => item.edge.venue === 'kalshi' && !item.edge.orderbook && Math.abs(item.edge.edge ?? item.edge.edgeSize ?? 0) > 5);
|
|
230
|
-
const localObMap = new Map();
|
|
231
|
-
if (topEdgesForOB.length > 0 && (0, kalshi_js_1.isKalshiConfigured)()) {
|
|
232
|
-
console.log(`${utils_js_1.c.dim}Fetching orderbooks for ${topEdgesForOB.length} edges...${utils_js_1.c.reset}`);
|
|
233
|
-
for (const item of topEdgesForOB) {
|
|
234
|
-
try {
|
|
235
|
-
const ob = await (0, kalshi_js_1.getOrderbook)(item.edge.marketId);
|
|
236
|
-
if (ob)
|
|
237
|
-
localObMap.set(item.edge.marketId, ob);
|
|
238
|
-
await new Promise(r => setTimeout(r, 150));
|
|
239
|
-
}
|
|
240
|
-
catch {
|
|
241
|
-
// skip
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
const thesisLabel = opts.thesis ? ` (thesis ${(0, utils_js_1.shortId)(opts.thesis)})` : '';
|
|
246
|
-
(0, utils_js_1.header)(`Unpositioned Edges${thesisLabel}`);
|
|
247
|
-
console.log(' ' + utils_js_1.c.bold +
|
|
248
|
-
(0, utils_js_1.pad)('Market', 30) +
|
|
249
|
-
(0, utils_js_1.rpad)('Mkt', 6) +
|
|
250
|
-
(0, utils_js_1.rpad)('Thesis', 8) +
|
|
251
|
-
(0, utils_js_1.rpad)('Edge', 7) +
|
|
252
|
-
(0, utils_js_1.rpad)('Spread', 8) +
|
|
253
|
-
(0, utils_js_1.rpad)('Liq', 8) +
|
|
254
|
-
' Signal' +
|
|
255
|
-
utils_js_1.c.reset);
|
|
256
|
-
console.log(' ' + utils_js_1.c.dim + '─'.repeat(85) + utils_js_1.c.reset);
|
|
257
|
-
for (const item of unpositionedEdges.slice(0, 20)) {
|
|
258
|
-
const e = item.edge;
|
|
259
|
-
const edgeSize = e.edge ?? e.edgeSize ?? 0;
|
|
260
|
-
const edgeColor = edgeSize > 10 ? utils_js_1.c.green : edgeSize > 5 ? utils_js_1.c.yellow : edgeSize > 0 ? utils_js_1.c.dim : utils_js_1.c.red;
|
|
261
|
-
const mktPrice = e.marketPrice ?? 0;
|
|
262
|
-
const thesisPrice = e.thesisPrice ?? e.thesisImpliedPrice ?? 0;
|
|
263
|
-
const title = (e.market || e.marketTitle || e.marketId || '?').slice(0, 29);
|
|
264
|
-
// Orderbook: prefer server data, fallback to local fetch
|
|
265
|
-
const serverOb = e.orderbook;
|
|
266
|
-
const localOb = localObMap.get(e.marketId);
|
|
267
|
-
const ob = serverOb || localOb;
|
|
268
|
-
const spreadStr = ob ? `${ob.spread}¢` : '-';
|
|
269
|
-
const liqStr = ob ? ob.liquidityScore : '-';
|
|
270
|
-
const liqColor = ob?.liquidityScore === 'high' ? utils_js_1.c.green : ob?.liquidityScore === 'medium' ? utils_js_1.c.yellow : utils_js_1.c.dim;
|
|
271
|
-
// Signal
|
|
272
|
-
let signal = 'WATCH';
|
|
273
|
-
if (edgeSize > 10 && ob?.liquidityScore !== 'low') {
|
|
274
|
-
signal = 'CONSIDER';
|
|
275
|
-
}
|
|
276
|
-
else if (edgeSize > 5 && ob?.liquidityScore === 'high') {
|
|
277
|
-
signal = 'CONSIDER';
|
|
278
|
-
}
|
|
279
|
-
const signalColor = signal === 'CONSIDER' ? utils_js_1.c.green : utils_js_1.c.dim;
|
|
280
|
-
console.log(' ' +
|
|
281
|
-
(0, utils_js_1.pad)(title, 30) +
|
|
282
|
-
(0, utils_js_1.rpad)(`${mktPrice.toFixed(0)}¢`, 6) +
|
|
283
|
-
(0, utils_js_1.rpad)(`${thesisPrice.toFixed(0)}¢`, 8) +
|
|
284
|
-
`${edgeColor}${(0, utils_js_1.rpad)(`${edgeSize > 0 ? '+' : ''}${edgeSize.toFixed(0)}`, 7)}${utils_js_1.c.reset}` +
|
|
285
|
-
(0, utils_js_1.rpad)(spreadStr, 8) +
|
|
286
|
-
`${liqColor}${(0, utils_js_1.rpad)(liqStr, 8)}${utils_js_1.c.reset}` +
|
|
287
|
-
` ${signalColor}${signal}${utils_js_1.c.reset}`);
|
|
288
|
-
}
|
|
289
|
-
console.log('');
|
|
290
|
-
}
|
|
291
|
-
else if (allEdges.length === 0) {
|
|
292
|
-
console.log(`\n${utils_js_1.c.dim}No thesis edges found.${utils_js_1.c.reset}\n`);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* sf prompt [thesisId] — Get dynamic system prompt for an agent
|
|
3
|
-
*
|
|
4
|
-
* Outputs a ready-to-use system prompt with live thesis state.
|
|
5
|
-
* Pipe-friendly: sf prompt f582bf76 >> agent_context.txt
|
|
6
|
-
*/
|
|
7
|
-
export declare function promptCommand(thesisId: string | undefined, opts: {
|
|
8
|
-
sections?: string;
|
|
9
|
-
maxLength?: string;
|
|
10
|
-
json?: boolean;
|
|
11
|
-
apiKey?: string;
|
|
12
|
-
apiUrl?: string;
|
|
13
|
-
}): Promise<void>;
|
package/dist/commands/prompt.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* sf prompt [thesisId] — Get dynamic system prompt for an agent
|
|
4
|
-
*
|
|
5
|
-
* Outputs a ready-to-use system prompt with live thesis state.
|
|
6
|
-
* Pipe-friendly: sf prompt f582bf76 >> agent_context.txt
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.promptCommand = promptCommand;
|
|
10
|
-
async function promptCommand(thesisId, opts) {
|
|
11
|
-
const baseUrl = (opts.apiUrl || process.env.SF_API_URL || 'https://simplefunctions.dev').replace(/\/$/, '');
|
|
12
|
-
const apiKey = opts.apiKey || process.env.SF_API_KEY || '';
|
|
13
|
-
const params = new URLSearchParams();
|
|
14
|
-
if (opts.sections)
|
|
15
|
-
params.set('sections', opts.sections);
|
|
16
|
-
if (opts.maxLength)
|
|
17
|
-
params.set('maxLength', opts.maxLength);
|
|
18
|
-
if (opts.json)
|
|
19
|
-
params.set('format', 'json');
|
|
20
|
-
const path = thesisId
|
|
21
|
-
? `/api/thesis/${thesisId}/prompt`
|
|
22
|
-
: '/api/prompt';
|
|
23
|
-
const qs = params.toString() ? `?${params.toString()}` : '';
|
|
24
|
-
const res = await fetch(`${baseUrl}${path}${qs}`, {
|
|
25
|
-
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
26
|
-
});
|
|
27
|
-
if (!res.ok) {
|
|
28
|
-
const text = await res.text();
|
|
29
|
-
throw new Error(`API error ${res.status}: ${text}`);
|
|
30
|
-
}
|
|
31
|
-
const body = await res.text();
|
|
32
|
-
process.stdout.write(body);
|
|
33
|
-
if (!body.endsWith('\n'))
|
|
34
|
-
process.stdout.write('\n');
|
|
35
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* sf publish / sf unpublish
|
|
3
|
-
*
|
|
4
|
-
* Publish a thesis for public viewing or remove it from public.
|
|
5
|
-
*/
|
|
6
|
-
export declare function publishCommand(thesisId: string, opts: {
|
|
7
|
-
slug: string;
|
|
8
|
-
description?: string;
|
|
9
|
-
apiKey?: string;
|
|
10
|
-
apiUrl?: string;
|
|
11
|
-
}): Promise<void>;
|
|
12
|
-
export declare function unpublishCommand(thesisId: string, opts: {
|
|
13
|
-
apiKey?: string;
|
|
14
|
-
apiUrl?: string;
|
|
15
|
-
}): Promise<void>;
|