@sentimentor/pinenode-cli
v1.3.1
Published
Sentimentor PineNode CLI — run strategies, fetch market data, optimize parameters, and activate validated Alpaca Paper runners.
Maintainers
Readme
@sentimentor/pinenode-cli 1.3.0
The PineNode command-line interface. Run PineNode strategies, fetch market data, optimize parameters, and activate validated Alpaca Paper runners — all from your terminal.
Install
npm install -g @sentimentor/[email protected]This installs a pn binary.
pn version # 1.3.0
pn helpEverything runs under pn <verb>. The longer pn run <verb> form is also accepted for backwards compatibility with the 1.0 docs.
Authentication
The CLI is free to install. Most features need a Sentimentor account:
pn loginThat opens https://www.sentimentor.ai/account/cli-tokens. Click Generate token, copy the value, paste it back at the CLI prompt. The token is stored in ~/.config/sentimentor/credentials.json (mode 600). To check what's saved:
pn whoamiSign out (revokes the token server-side too):
pn logoutCommands
Backtest (pn backtest)
Local backtest against your own data — free:
pn backtest --strategy strategy.pinenode --bars bars.json
pn backtest --strategy strategy.pine --bars bars.csv --capital 25000 --json
pn backtest --strategy strategy.pinenode --bars bars.json --params params.json--strategy defaults to ./strategy.pinenode when omitted.
Fetched bars + optional Sentimentor inputs — Pro:
pn backtest --strategy strategy.pinenode --ticker NVDA --days 365 --timeframe 1d
pn backtest --strategy strategy.pinenode --ticker NVDA --sentimentorRisk guardrails
Layer engine-level risk management onto any backtest — a trend-regime filter (only trade with the primary trend), a trailing stop (let winners run, cap give-back), a hard stop, and position sizing. These apply on top of the strategy's own logic:
pn backtest --strategy strategy.pinenode --ticker NVDA \
--trend-filter 200 \ # only go long above the 200-bar SMA (short below it)
--trailing-stop 20 \ # exit on a 20% retrace from the position's peak
--stop-loss 15 \ # hard stop at 15% loss
--position-size 100 # % of capital deployed per tradeBenchmark metrics + equity export
Every report carries a buy-and-hold benchmark over the same window:
buyHoldReturnPercent, alphaPercent (strategy return − buy-hold, in points),
and upsideCapturePercent (the fraction of a buy-hold uptrend the strategy
captured — the participation metric). Export the daily equity curve (for
portfolio blending / external analysis) with --equity-out; it writes just the
bar-aligned series so large multi-year runs don't overflow stdout:
pn backtest --strategy strategy.pinenode --bars bars.json --json --equity-out equity.jsonData (pn fetch)
Pull historical OHLCV bars to disk — Pro:
pn fetch --ticker AAPL --days 730 --timeframe 1d --out aapl.jsonWithout --out, the bars stream as JSON to stdout so you can pipe them into other tools.
Market selection (expanded in 1.3.0)
fetch, backtest --ticker, and optimize all target the stocks market by default (which also covers ETFs like SPY / QQQ / GLD). Pick a different asset class with one of these mutually-exclusive flags:
| Flag | Class | Example |
| ------------ | ---------------- | --------------------------------------------- |
| (none) | Stocks & ETFs | pn fetch --ticker AAPL |
| --crypto | Cryptocurrency | pn fetch --ticker BTCUSD --crypto |
| --forex | Forex pairs | pn fetch --ticker EURUSD --forex |
| --indices | Market indices | pn fetch --ticker SPX --indices |
| --futures | Futures contracts| pn fetch --ticker ESZ6 --futures |
Symbols are always in the bare form — the CLI adds any provider prefix behind the scenes based on the market flag. Only one market flag may be set at a time; passing more than one is a validation error.
When a fetch on the stocks market returns zero bars, the CLI prints a hint suggesting the crypto/forex/indices/futures flag — a common mistake is running pn fetch --ticker BTCUSD and getting nothing back because BTCUSD is not a stock.
Optimize (pn optimize)
Evaluate every pn.param(...) range with the bundled PineNode engine — Elite or Trader. Runs are local; fetched bars still come from Sentimentor:
pn optimize --ticker NVDA --days 365
pn optimize --ticker BTCUSD --days 365 --crypto
pn optimize --strategy strategy.pinenode --ticker NVDA --grid grid.json --json
pn optimize --strategy strategy.pinenode --bars bars.json --grid grid.jsongrid.json shape:
{
"Fast Period": { "min": 5, "max": 50, "step": 5 },
"Slow Period": { "min": 20, "max": 200, "step": 10 }
}When --grid is omitted, the optimizer uses the bounds declared in each pn.param(...) call.
The CLI limits a grid to 2,000 combinations and ranks valid runs by Sharpe, then return. Use --json for every result.
Robustness validation (pn validate)
Run the same server-owned protocol as the Strategy Tester — Pro, Elite, or Trader:
pn validate --strategy strategy.pinenode --ticker SPY --days 3650 --timeframe 1d --embargo 5
pn validate --strategy "SPY Trend v4" --ticker SPY --project 59af... --jsonThe output separately reports Discovery, Rolling validation, and Final lockbox, including every failed rule. Discovery must pass before rolling validation is inspected; rolling validation must pass before the one-time lockbox is opened. A cloud strategy automatically stores the exact issued protocol so it can later qualify for a runner. By default, the CLI derives a stable project ID from the strategy source, ticker, and timeframe so repeated trials are counted together. Pass --project to continue the same lineage across renamed/moved files; use a new UUID only for a genuinely new thesis. The final lockbox cannot be reopened merely by renaming or slightly editing a failed strategy.
Safety analysis and debugger
pn analyze --strategy strategy.pinenode
pn debug --strategy strategy.pinenode --bars bars.json \
--break-bars 20,50 --break-if "bar.close > 200" \
--watch "bar.close,barIndex"analyze performs the same static repaint, lookahead, bar-state, alert, order, and multi-timeframe checks as the web editor. debug executes bar-by-bar with bar/condition breakpoints, watches, console capture, snapshots, trades, and the completed report. Add --json for automation.
Pine conversion, custom indicators, and templates
pn convert strategy.pine --out strategy.pinenode
pn indicator init --out study.pinenode
pn indicator convert study.pine --out study.pinenode
pn indicator run study.pinenode --bars bars.json --params params.json --out plots.json
pn library list
pn library get golden-cross --out strategy.pinenodeConversion is deterministic and reports unsupported Pine constructs. Custom indicators cannot place orders or access browser/network globals; their output is a JSON collection of plot series.
Augur research and refinement
pn augur --prompt "Research a robust daily SPY trend hypothesis" --ticker SPY
pn augur --prompt "Reduce fragility without changing the thesis" \
--strategy strategy.pinenode --out refined.pinenodeThis uses Sentimentor's existing multi-round Augur service and plan quota. Generated code remains an editable draft: run pn analyze, pn backtest, and pn validate explicitly. Validation never silently rewrites manual or generated source.
Cloud library (pn push / pn pull)
Round-trip strategies through your Sentimentor cloud library — Elite or Trader:
pn push --name "NVDA EMA Cross"
pn pull # list saved strategies
pn pull <id> --out strat.pinenode
pn strategies rename <id-or-name> --name "New name"
pn strategies describe <id-or-name> --description "Trend thesis"
pn strategies archive <id-or-name>
pn strategies delete <id-or-name>Forward runners and proof
# Simulated forward evidence after a final-lockbox pass
pn forward --strategy <cloud-id> --ticker SPY --timeframe 1d
pn runners list
pn runners history <runner-id>
pn runners pause <runner-id> --strategy <cloud-id>
pn runners resume <runner-id> --strategy <cloud-id>
pn runners remove <runner-id> --strategy <cloud-id>
# Public, inspectable proof surfaces
pn verify publish --strategy strategy.pinenode --ticker SPY
pn ledger --ticker SPY --passed-onlyRunner history is the immutable record of completed-bar evaluations. Simulated forward results answer what happened after research ended; they are distinct from discovery, rolling validation, and the final lockbox.
Alpaca Paper deployment (pn deploy)
Paper trading is available on Elite and Trader. First connect Alpaca Paper under Profile → Account Settings → Broker connections. The strategy must be saved in Sentimentor and have a current server-owned final-lockbox pass.
pn deploy --strategy "NVDA EMA Cross v3" --ticker NVDA --paper \
--max-order-notional 1000 \
--max-orders-per-day 10 \
--daily-loss-limit 250The CLI resolves --strategy by exact cloud name or ID and sends only that ID
to the server. The server loads the saved code, reconstructs the frozen
validated parameters, and applies the same ticker, timeframe, configuration,
broker, quota, and final-lockbox checks as the web UI. Arbitrary local files
and activation-time changes to capital, sizing, stops, or parameters are
rejected; make the change in PineNode, revalidate, and save a new version.
The optional limits above are forward-execution safeguards, not research
inputs. Live brokerage support is planned for December 2026 and is not
currently available; --live exits without deploying.
Stop a running deployment:
pn deploy stop <runner-id>Pausing prevents future scans. It does not cancel accepted orders or close paper positions; review those directly in Alpaca.
File formats
Strategies
| Extension | Treated as |
|---|---|
| .pinenode, .js, .ts | PineNode JS — executed as-is |
| .pine | Supported Pine v3-v6 subset — auto-transpiled before execution; warnings are surfaced |
Bars
JSON:
[
{ "time": 1735689600000, "open": 100.5, "high": 101.2, "low": 100.1, "close": 100.8, "volume": 1234567 }
]CSV (header required, columns order-independent):
time,open,high,low,close,volume
2024-01-02T09:30:00Z,100.5,101.2,100.1,100.8,1234567time accepts Unix milliseconds, an integer string, or any ISO-8601 datetime.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Command completed successfully |
| 1 | Usage error / bad input |
| 2 | Strategy failed to load (transpile / sandbox error) |
| 3 | Backtest runtime failure, robustness protocol did not pass, or a requested Augur strategy artifact was absent |
| 4 | Upgrade required — your plan doesn't include this command |
| 5 | Not logged in — run pn login |
| 6 | API error from auth.sentimentor.ai |
| 99 | Unexpected CLI bug — please file an issue |
Environment overrides
| Variable | Default | Use case |
|---|---|---|
| SENTIMENTOR_API_BASE | https://auth.sentimentor.ai | Point at staging / dev environments |
| SENTIMENTOR_WEB_BASE | https://www.sentimentor.ai | Same, for the login URL |
| NO_COLOR | 0 | Disable ANSI colors |
| XDG_CONFIG_HOME | ~/.config | Move credentials file location |
Capabilities matrix
Aligned with cliAuthService.ts in the auth service.
| Command | Trial / Free | Pro | Elite | Trader |
|---|---|---|---|---|
| login / logout / whoami / help | ✓ | ✓ | ✓ | ✓ |
| backtest --bars <file> (local, offline) | ✓ | ✓ | ✓ | ✓ |
| backtest --ticker / fetch (cloud bar data) | — | ✓ | ✓ | ✓ |
| backtest --sentimentor (dark pool / options flow / sentiment inputs) | — | ✓ | ✓ | ✓ |
| analyze, convert, library, local indicator/backtest | ✓ | ✓ | ✓ | ✓ |
| validate, augur, fetched bars/indicators | — | ✓ | ✓ | ✓ |
| optimize (local grid evaluation) | — | — | ✓ | ✓ |
| cloud CRUD, verification publish, runners | — | — | ✓ | ✓ |
| deploy --paper (validated cloud strategy) | — | — | ✓ | ✓ |
| deploy --live (planned December 2026) | — | — | — | — |
License
Apache-2.0
