sn

SKILL.md

sn — SignalNGN CLI

sn is the unified CLI for the SignalNGN cryptocurrency trading platform. It wraps every API endpoint with a consistent interface: human table output by default, --json for scripting.

Setup

Install

# Homebrew (macOS / Linux)
brew tap spot-canvas/sn https://github.com/Spot-Canvas/sn
brew install spot-canvas/sn/sn

# Go toolchain
go install github.com/Spot-Canvas/sn/cmd/sn@latest

Configure

Config file: ~/.config/sn/config.yaml (created on first sn config set).

# Point at staging (ingestion server)
sn config set ingestion_url https://ingest.signalngn.com

# Point at staging (API server)
sn config set api_url https://api.signalngn.com

# Set tenant ID (for trading config operations)
sn config set tenant_id 00000000-0000-0000-0000-000000000001

# Show all resolved config and sources
sn config show

Priority (highest first): --flag > SN_* env var > ~/.config/sn/config.yaml > built-in default (http://localhost:8081 / http://localhost:8082).

Valid config keys: tenant_id, api_url, ingestion_url, nats_url, nats_creds_file


Products

Manage which coins the ingestion pipeline tracks.

Command Description
sn products list List all products
sn products list --enabled Only enabled products
sn products list --exchange coinbase Filter by exchange
sn products get coinbase BTC-USD Get a single product
sn products add coinbase SOL-USD Add a product
sn products enable coinbase SOL-USD Enable ingestion
sn products disable coinbase SOL-USD Pause ingestion
sn products delete coinbase SOL-USD Remove from pipeline
# Add and enable a new coin
sn products add coinbase NEAR-USD
sn products enable coinbase NEAR-USD

# List enabled coinbase products as JSON (pipe to jq)
sn products list --exchange coinbase --enabled --json | jq '.[].product_id'

Backfill

Trigger historical candle backfill jobs.

Command Description
sn backfill start <exchange> <product> Start a backfill job
sn backfill start ... --days 60 Backfill 60 days (default: 30)
sn backfill list <exchange> <product> List jobs for a product
sn backfill get <exchange> <product> <job-id> Get job status
sn backfill cancel <exchange> <product> <job-id> Cancel a pending or running job

Jobs are executed one at a time per tenant server — concurrent backfills are queued and run serially to avoid OOM. Use cancel to drain the queue if needed.

# Backfill 90 days of SOL-USD
sn backfill start coinbase SOL-USD --days 90

# Monitor progress
sn backfill list coinbase SOL-USD
sn backfill get coinbase SOL-USD <job-id>

# Cancel a specific job (pending or running)
sn backfill cancel binance BTC-USD <job-id>

# Cancel all pending/running backfill jobs for a product
sn backfill list binance BTC-USD --json \
  | jq -r '.[] | select(.status == "pending" or .status == "running") | .id' \
  | xargs -I{} sn backfill cancel binance BTC-USD {}

Backtest

Run and query backtests against historical data.

Command Description
sn backtest run Submit a backtest and wait for results (default)
sn backtest run --no-wait Submit and return immediately; prints poll command
sn backtest job <job-id> Poll a job; prints result when completed
sn backtest list List results
sn backtest get <id> Get a result by ID

Backtests run asynchronously on the tenant server. sn backtest run submits the job and then polls GET /jobs/{id} every 2 seconds (printing dots) until the job completes or fails, then prints the full result. Use --no-wait to get back a job ID immediately instead.

sn backtest run flags:

Flag Description Default
--exchange Exchange (required)
--product Product ID (required)
--strategy Strategy name (required)
--granularity Granularity e.g. ONE_HOUR (required)
--mode spot, futures-long, futures-short spot
--start Start date YYYY-MM-DD 1 year ago
--end End date YYYY-MM-DD today
--leverage Leverage (futures modes)
--trend-filter Enable trend filter false
--no-wait Return immediately after submitting false
# Spot backtest — waits and prints result when done
sn backtest run --exchange coinbase --product BTC-USD \
  --strategy macd_momentum --granularity ONE_HOUR

# Submit without waiting; prints job ID and poll command
sn backtest run --exchange coinbase --product BTC-USD \
  --strategy ml_xgboost --granularity ONE_HOUR --no-wait
# → Job ID: abc123  Status: pending
# → Poll:   sn backtest job abc123

# Poll an existing job (prints result table when done, dots while running)
sn backtest job abc123

# Futures with leverage
sn backtest run --exchange coinbase --product ETH-USD \
  --strategy rsi_mean_reversion --granularity THIRTY_MINUTES \
  --mode futures-long --leverage 2

# List all BTC-USD backtests
sn backtest list --product BTC-USD

# Get result and pipe to jq
sn backtest get 42 --json | jq '.metrics'

Trading Config

Manage server-side trading configuration (which strategies run on which products).

Command Description
sn trading list List all configs
sn trading list --enabled Only enabled configs
sn trading get <exchange> <product> Get config
sn trading set <exchange> <product> [flags] Create or update
sn trading delete <exchange> <product> Remove config
sn trading reload Hot-reload config into running engine

sn trading set flags (unset flags preserve existing values):

Flag Description
--granularity <g> Candle granularity
--long <strategies,...> Comma-separated long strategies
--short <strategies,...> Comma-separated short strategies
--spot <strategies,...> Comma-separated spot strategies
--long-leverage <n> Long leverage
--short-leverage <n> Short leverage
--trend-filter Enable trend filter
--no-trend-filter Disable trend filter
--enable Enable this config
--disable Disable this config
--params <strategy>:<key>=<value> Set a per-strategy parameter override (repeatable). Use <strategy>:clear to remove all overrides for a strategy.

--params merges into the existing strategy_params — other strategies and keys are preserved. Valid keys per strategy:

Strategy Valid keys
ml_xgboost atr_stop_mult, rr_ratio, confidence, exit_confidence
ml_transformer atr_stop_mult, rr_ratio, confidence, seq_len
ml_transformer_1h atr_stop_mult, rr_ratio, confidence, seq_len
alpha_beast atr_stop_mult, rr_ratio, rsi_buy_max, rsi_sell_min, vol_multiplier
zscore_mean_reversion entry, exit, max_pos, dampening
rsi_mean_reversion oversold, overbought
macd_momentum threshold
volume_momentum multiplier
combined_rsi_macd oversold, overbought
bollinger_rsi rsi_oversold, rsi_overbought
# Create a new trading config
sn trading set coinbase XRP-USD \
  --granularity ONE_HOUR \
  --long macd_momentum \
  --short macd_momentum,rsi_mean_reversion \
  --short-leverage 2 \
  --enable

# Disable a config without changing anything else
sn trading set coinbase XRP-USD --disable

# Widen SL/TP for ml_xgboost on ATOM-USD (strong trend market)
sn trading set coinbase ATOM-USD \
  --params ml_xgboost:atr_stop_mult=2.5 \
  --params ml_xgboost:rr_ratio=3.0

# Set exit confidence threshold (controls when ml_xgboost emits exit signals)
# Entry: P > confidence (default 0.72) → BUY/SHORT
# Exit:  P < exit_confidence (default 0.45) → SELL/COVER
# Lower = fewer exits (only exits when model is very sure the move is over)
# Set to 0 to disable exit signals entirely (rely on SL/TP/trailing only)
sn trading set coinbase BTC-USD \
  --params ml_xgboost:exit_confidence=0.25

# Set alpha_beast ATR multiplier and clear ml_xgboost overrides
sn trading set coinbase BTC-USD \
  --params alpha_beast:atr_stop_mult=3.0 \
  --params ml_xgboost:clear

# Reload engine after changes
sn trading reload

# List all enabled configs as table (includes PARAMS column)
sn trading list --enabled

User Strategies

Author, validate, and manage custom Starlark strategies.

Command Description
sn strategy list List all user strategies
sn strategy list --active Only active strategies
sn strategy get <id> Get strategy with source
sn strategy validate --name <n> --file <path> Validate source
sn strategy create --name <n> --file <path> Create strategy
sn strategy update <id> --file <path> Update source
sn strategy activate <id> Activate strategy
sn strategy deactivate <id> Deactivate strategy
sn strategy delete <id> Delete strategy
sn strategy backtest <id> Backtest a user strategy

sn strategy create flags:

Flag Description
--name <n> Strategy name (required)
--file <path> Path to .star source file (required)
--description <d> Optional description
--params <json> Parameters JSON, e.g. '{"THRESHOLD": 2.0}'
# Validate before creating
sn strategy validate --name my_strat --file ./my_strat.star

# Create and activate
sn strategy create --name my_strat --file ./my_strat.star \
  --description "RSI bounce with volume filter"
sn strategy activate 5

# Backtest a user strategy
sn strategy backtest 5 \
  --exchange coinbase --product BTC-USD \
  --granularity ONE_HOUR --mode spot \
  --start 2024-01-01 --end 2025-01-01

Strategies (built-in + user)

List all available strategies (both built-in and user-defined):

sn strategies list

# JSON output for scripting
sn strategies list --json | jq '.builtin[].name'

ML Model

Hot-reload an ML model from a GCS URI:

# Reload XGBoost model
sn ml reload --uri gs://spot-canvas-models/ml_xgboost/latest/model.onnx

# Reload Transformer model
sn ml reload --uri gs://spot-canvas-models/ml_transformer/latest/model.onnx

Built-in ML strategies:

Strategy Description Unique param
ml_xgboost XGBoost model; 39-feature indicator vector, outputs P(hold/long/short). Supports exit signals when confidence drops below exit_confidence. exit_confidence
ml_transformer Transformer (attention-based) model; operates over a rolling sequence of candles (seq_len). No exit-confidence concept — exits are handled via SL/TP. seq_len (default 64)
ml_transformer_1h Same transformer architecture as ml_transformer, trained specifically on 1-hour candle data. seq_len (default 64)

Shared params (confidence, atr_stop_mult, rr_ratio) work identically for both models.


Metrics

Display a live metrics dashboard from the ingestion server:

sn metrics

# Raw JSON metric map (pipe to jq)
sn metrics --json | jq '.spot_canvas_candles_processed_total'

Dashboard sections:

  • Uptime, goroutines, heap memory
  • Pipeline: candles received/processed, throughput
  • Batch writer: batch count, avg size, DB write latency
  • WebSocket: connections, reconnects, errors
  • Channel utilization bar chart (WARN above 80%)
  • Top 10 products by candles processed
  • Strategy evaluations, signals, signal rate
  • Indicator alert breakdown

Engine Status

Show indicator engine state (products, granularities, warming count):

sn engine status

sn engine status --json

Tenants

Manage tenants on the API server.

Command Description
sn tenants list List all tenants
sn tenants get <id> Get a tenant
sn tenants create --name <n> Create a tenant
sn tenants update <id> [flags] Update a tenant
# Create a paid tenant
sn tenants create --name acme --tier paid

# Update tier
sn tenants update <id> --tier paid

# Set always-on
sn tenants update <id> --always-on

# List all tenants
sn tenants list --json | jq '.[].name'

Price

Query the current live price for a product (or all enabled products).

Command Description
sn price <product> Show live price for a product
sn price <product> --exchange <e> Specify exchange (default: coinbase)
sn price <product> --granularity <g> Specify granularity (default: ONE_MINUTE)
sn price --all Show live prices for all enabled products
sn price --all --granularity ONE_HOUR All products at a coarser granularity

Output columns: EXCHANGE, PRODUCT, PRICE, OPEN, HIGH, LOW, VOLUME, AGE

AGE is the time since the last candle update (< 1s, 4s, 2m 30s, !1h 5m). Ages over 1 hour are prefixed with ! to signal potential staleness.

# Current BTC-USD price
sn price BTC-USD

# ETH-USD on the ONE_HOUR candle
sn price ETH-USD --granularity ONE_HOUR

# All enabled products, sorted by exchange then product
sn price --all

# All prices as JSON (only products with data)
sn price --all --json

# Single product as raw JSON
sn price BTC-USD --json | jq '.close'

Notes:

  • Backed by GET /prices/{exchange}/{product}?granularity= on the API server.
  • Returns the latest candle written by the ingestion server (updated ~every 50ms).
  • Products with no candle data yet show / no data in --all mode.

Signals

Stream live strategy signals from NATS in real time.

# All signals
sn signals

# Filter by product and exchange
sn signals --exchange coinbase --product BTC-USD

# Filter by strategy
sn signals --strategy macd_momentum

# Filter by granularity
sn signals --granularity ONE_HOUR

# NDJSON output (pipe to jq)
sn signals --json | jq 'select(.action == "BUY")'

Output format (one line per signal):

14:32:05  coinbase  BTC-USD  ONE_HOUR  macd_momentum  BUY   conf=0.82  sl=91200.00  tp=96800.00

Credentials: By default, uses embedded read-only NATS credentials scoped to signals.>. Override with:

sn config set nats_creds_file ~/.config/sn/custom.creds
# or
SN_NATS_CREDS_FILE=~/.config/sn/custom.creds sn signals

Exit: Press Ctrl-C to unsubscribe and exit cleanly.


Tips & Scripting

Global flags (available on all commands)

--ingestion-url <url>   Override ingestion server URL
--api-url <url>         Override API server URL
--json                  Output as JSON

Common scripting patterns

# Get all enabled product IDs for coinbase
sn products list --exchange coinbase --enabled --json | jq -r '.[].product_id'

# Run backtest for all products in trading config (waits for each result)
sn trading list --enabled --json | jq -r '.[] | .exchange + " " + .product_id' | while read e p; do
  sn backtest run --exchange $e --product $p --strategy macd_momentum --granularity ONE_HOUR --json
done

# Submit all at once without waiting, then poll each job
sn trading list --enabled --json | jq -r '.[] | .exchange + " " + .product_id' | while read e p; do
  sn backtest run --exchange $e --product $p --strategy macd_momentum --granularity ONE_HOUR --no-wait
done

# Check live price quickly
sn price BTC-USD

# Check all prices and highlight stale ones (AGE starts with !)
sn price --all | grep '!'

# Get close price as a number
sn price BTC-USD --json | jq '.close'

# Watch metrics (refresh every 30s)
watch -n 30 sn metrics

# Monitor signals and alert on low confidence
sn signals --json | jq 'select(.confidence < 0.5) | "LOW CONF: " + .product + " " + .action'

# Pipe backtest results to jq for analysis
sn backtest list --strategy macd_momentum --json | jq '[.results[] | {product: .product_id, return: .metrics.total_return}] | sort_by(-.return)'

Point at local development servers

SN_INGESTION_URL=http://localhost:8081 SN_API_URL=http://localhost:8082 sn products list

Or set permanently:

sn config set ingestion_url http://localhost:8081
sn config set api_url http://localhost:8082
Weekly Installs
9
Repository
spot-canvas/sn
First Seen
Feb 24, 2026
Installed on
github-copilot9
codex9
kimi-cli9
gemini-cli9
cursor9
amp9