perp-cli 0.7.9 → 0.7.10

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.
@@ -365,6 +365,14 @@ async function executeActions(adapter, symbol, actions, log, dryRun = false) {
365
365
  }
366
366
  // ── Enriched snapshot ──
367
367
  async function getEnrichedSnapshot(adapter, symbol) {
368
+ // Multi-symbol strategies use "ALL" — skip market-specific data
369
+ if (symbol.toUpperCase() === "ALL") {
370
+ return {
371
+ price: 0, high24h: 0, low24h: 0, volume24h: 0,
372
+ fundingRate: 0, volatility24h: 0, rsi: NaN, spreadPct: 0,
373
+ klines: [], orderbook: { bids: [], asks: [] }, openInterest: "0",
374
+ };
375
+ }
368
376
  const base = await getMarketSnapshot(adapter, symbol);
369
377
  const [orderbook, klines] = await Promise.all([
370
378
  adapter.getOrderbook(symbol).catch(() => ({ bids: [], asks: [] })),
@@ -56,10 +56,10 @@ export function BotDashboard({ initialState, onQuit, onPause, subscribe }) {
56
56
  exit();
57
57
  }, [onQuit, exit]);
58
58
  useInput((input, key) => {
59
- if (input === "q" || (key.ctrl && input === "c")) {
59
+ if (input === "q" || input === "Q" || (key.ctrl && input === "c")) {
60
60
  handleQuit();
61
61
  }
62
- if (input === "p") {
62
+ if (input === "p" || input === "P") {
63
63
  setPaused((v) => !v);
64
64
  onPause();
65
65
  }
@@ -430,12 +430,26 @@ export function registerBotCommands(program, getAdapter, getAdapterFor, isJson)
430
430
  });
431
431
  // ── bot run <strategy> <symbol> ──
432
432
  bot
433
- .command("run <strategy> [symbol]")
433
+ .command("run [strategy] [symbol]")
434
434
  .description("Run a strategy (use 'perp bot list-strategies' to see all). Symbol optional for multi-symbol strategies.")
435
435
  .option("--config <path>", "YAML/JSON config file")
436
436
  .option("--headless", "Run without TUI dashboard")
437
437
  .option("--param <key=value>", "Strategy parameter (repeatable)", (val, acc) => [...acc, val], [])
438
438
  .action(async (strategyName, symbol, opts) => {
439
+ if (!strategyName) {
440
+ await import("../bot/engine.js");
441
+ const { listStrategies: listStrats } = await import("../bot/strategy-registry.js");
442
+ const available = listStrats();
443
+ if (isJson()) {
444
+ printJson(jsonOk({ strategies: available }));
445
+ return;
446
+ }
447
+ console.log(chalk.cyan.bold("\n Available Strategies:\n"));
448
+ for (const s of available)
449
+ console.log(` ${chalk.green(s)}`);
450
+ console.log(chalk.gray(`\n Usage: perp bot run <strategy> [symbol]\n`));
451
+ return;
452
+ }
439
453
  const sym = symbol?.toUpperCase() || "ALL";
440
454
  // Strategies that require an explicit symbol
441
455
  const symbolRequiredStrategies = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perp-cli",
3
- "version": "0.7.9",
3
+ "version": "0.7.10",
4
4
  "description": "Multi-DEX Perpetual Futures CLI - Pacifica, Hyperliquid, Lighter, Aster",
5
5
  "bin": {
6
6
  "perp": "dist/index.js",