@nfwyst/pinets-cli
v0.1.15-nfwyst.4
Published
The nfwyst-maintained CLI for running Pine Script indicators with PineTS.
Maintainers
Readme
What is pinets-cli?
pinets-cli is a command-line interface for PineTS, the open-source Pine Script® transpiler and runtime. It lets you execute TradingView® Pine Script® indicators directly from your terminal, with live market data or custom JSON datasets.
pinets run rsi.pine --symbol BTCUSDT --timeframe 60No code to write. No project to set up. Just point it at a .pine file and go.
Disclaimer: pinets-cli and PineTS are independently developed open-source projects. LuxAlgo Global, LLC and the PineTS project are NOT affiliated with, sponsored by, endorsed by, or in any way officially associated with TradingView, Inc. "Pine Script®" and "TradingView®" are registered trademarks of TradingView, Inc.
pinets-cli executes supported Pine syntax through PineTS; it does not invoke TradingView's official compiler. A successful local run is not an official compilation result and does not demonstrate full static-semantic parity with TradingView.
Quick Start
Install
Bun 1.4 or newer is required. Bun installs, downloads, and executes the published CLI.
bun add -g @nfwyst/pinets-cliOr run directly without installing:
bunx --bun @nfwyst/pinets-cli run sma_cross.pine --symbol BTCUSDT --timeframe 60Run your first indicator
Create a file called sma_cross.pine:
//@version=5
indicator("SMA Cross", overlay=true)
fast = ta.sma(close, 9)
slow = ta.sma(close, 21)
plot(fast, "Fast SMA", color=color.blue)
plot(slow, "Slow SMA", color=color.red)Run it:
pinets run sma_cross.pine --symbol BTCUSDT --timeframe 60That's it. You'll get JSON output with the calculated SMA values for the last 500 hourly candles.
Usage
pinets run [options] [file]The run command executes a Pine Script® indicator and outputs the results as JSON.
Indicator source
Provide the indicator as a file argument or via piped stdin:
# From a file
pinets run my_indicator.pine --symbol BTCUSDT
# Piped from stdin (works on Linux, macOS, and Windows)
cat my_indicator.pine | pinets run --symbol BTCUSDTPiped input uses a 10-second inactivity timeout. Slow producers remain valid as long as they continue writing data.
Data source
Choose between live market data or a local JSON file:
# Live data from Binance
pinets run rsi.pine --symbol BTCUSDT --timeframe 60
# Custom data from a JSON file
pinets run rsi.pine --data ./my_candles.jsonOptions
Data Source
| Option | Short | Description | Default |
| ------------------- | ----- | -------------------------------------------------------- | ------- |
| --symbol <ticker> | -s | Symbol to query (e.g., BTCUSDT, ETHUSDT.P) | — |
| --timeframe <tf> | -t | Timeframe: 1, 3, 5, 15, 30, 45, 60, 120, 180, 240, D, W, M, 3M, 6M, 12M and aliases | 60 |
| --data <path> | -d | Path to a JSON data file (alternative to --symbol) | — |
| --request-timeout <ms> | — | Maximum duration of each market-data request | 30000 |
Output
| Option | Short | Description | Default |
| ----------------- | ------- | --------------------------------------------------- | --------- |
| --output <path> | -o | Write output to a file instead of stdout | stdout |
| --format <type> | -f | Output format: default or full | default |
| --pretty | — | Force pretty-printed JSON | auto |
| --clean | — | Filter out null, false, and empty values from plots | — |
| --plots <names> | — | Comma-separated list of plot names to include | all plots |
Candle Control
| Option | Short | Description | Default |
| ------------------- | ----- | ----------------------------------------------------------- | ------- |
| --candles <count> | -n | Number of candles in the output | 500 |
| --warmup <count> | -w | Extra candles for indicator warmup (not included in output) | 0 |
Other
| Option | Short | Description |
| ----------- | ------- | ---------------------------------------- |
| --debug | — | Show the transpiled code (for debugging) |
| --quiet | -q | Suppress all informational messages |
| --version | -v | Show version number |
| --help | -h | Show help |
Examples
Basic indicator with live data
pinets run rsi.pine --symbol BTCUSDT --timeframe 1D --candles 100Indicator warmup
Many indicators need historical data to initialize (e.g., a 200-period SMA needs at least 200 bars before producing meaningful output). Use --warmup to fetch extra candles that are processed but excluded from the output:
# Fetch 700 candles (200 warmup + 500 output), return only the last 500
pinets run ema200.pine --symbol ETHUSDT --timeframe 60 --candles 500 --warmup 200Save output to a file
pinets run macd.pine --symbol BTCUSDT --timeframe 15 -o results.jsonPipe into other tools
# Pretty-print with jq
pinets run rsi.pine -s BTCUSDT -t 60 -q | jq '.plots'
# Extract last RSI value
pinets run rsi.pine -s BTCUSDT -t 60 -q | jq '.plots.RSI.data[-1].value'Use custom JSON data
pinets run my_indicator.pine --data ./historical_btc.json --candles 50 --prettyPipe indicator from stdin
cat my_indicator.pine | pinets run --symbol BTCUSDT --timeframe 60
# Or on Windows PowerShell
Get-Content my_indicator.pine | pinets run --symbol BTCUSDT --timeframe 60Full execution context
pinets run rsi.pine --symbol BTCUSDT --format full --prettyDebug transpilation
pinets run my_indicator.pine --symbol BTCUSDT --debugFilter signals with --clean
For indicators that generate signals (like crossovers), most candles will have false values. Use --clean to filter them out:
# Without --clean: 500 entries, mostly false
pinets run ma_cross.pine -s BTCUSDT -t 1D -n 500
# With --clean: Only actual signals
pinets run ma_cross.pine -s BTCUSDT -t 1D -n 500 --cleanSelect specific plots
When you only need specific plots from an indicator:
# Get only the Fast SMA (ignore Slow SMA)
pinets run sma_cross.pine -s BTCUSDT --plots "Fast SMA"
# Get only Buy and Sell signals
pinets run signals.pine -s BTCUSDT --plots "Buy,Sell" --clean -q | jq '.plots'Use with AI agents
pinets-cli is designed to be driven programmatically. Indicators go in on stdin, structured JSON comes out on stdout, and there is no interactive prompt or project scaffolding to negotiate — which makes it usable as a tool call from an agent, a script, or a CI job without a wrapper.
Install the bundled pinets skill directly from this fork with the Skills CLI:
bunx --bun skills add nfwyst/pinets-cli --skill pinets --agent codex --global --yes --copyPlatform-specific skill definitions also live under SKILL.md/.
Three flags matter when an agent is the caller:
| Flag | Why it matters for automated callers |
| ----------------- | ------------------------------------------------------------------------ |
| --quiet / -q | Suppresses informational output so stdout is valid JSON and nothing else |
| --clean | Drops null, false, and empty plot values, cutting response size sharply |
| --plots <names> | Returns only the plots you asked for instead of everything the script emits |
# Generate an indicator, execute it, and return only the signal values
cat generated_strategy.pine | pinets run -s BTCUSDT -t 60 --plots "Buy,Sell" --clean -qBecause the runtime is self-contained and reads from stdin, the whole loop — write a script, execute it against real data, read the result — can run locally without a charting platform in the path.
Output Formats
default format
Contains the indicator metadata and all plot data:
{
"indicator": {
"title": "RSI",
"overlay": false
},
"plots": {
"RSI": {
"title": "RSI",
"options": { "color": "#7E57C2" },
"data": [
{ "time": 1704067200000, "value": 65.42 },
{ "time": 1704070800000, "value": 62.18 }
]
}
}
}full format
Everything in default, plus the raw execution result and market data:
{
"indicator": { ... },
"plots": { ... },
"result": { ... },
"marketData": [
{ "openTime": 1704067200000, "open": 42000, "high": 42500, "low": 41800, "close": 42300, "volume": 1234.5 },
...
]
}JSON Data Format
When using --data, provide a JSON file with an array of candle objects:
[
{
"openTime": 1704067200000,
"open": 42000.5,
"high": 42500.0,
"low": 41800.0,
"close": 42300.0,
"volume": 1234.56,
"closeTime": 1704070799999
}
]Required fields: open, high, low, close, volume
Recommended fields: openTime, closeTime (millisecond timestamps)
Every candle is validated. Required values and optional timestamps must be finite numbers; timestamped candles must be in chronological order.
How It Works
pinets-cli is a self-contained binary that bundles the PineTS library. When you run an indicator:
- The Pine Script® file is read and passed to the PineTS transpiler
- Market data is fetched from Binance (or loaded from your JSON file)
- The indicator is executed bar-by-bar with full time-series semantics
- Plot data is collected and output as structured JSON
There are no additional runtime package installs. The single bundled file includes PineTS and runs on Bun 1.4 or newer.
Supported Timeframes
| Value | Description |
| ----------- | ----------- |
| 1 | 1 minute |
| 3 | 3 minutes |
| 5 | 5 minutes |
| 15 | 15 minutes |
| 30 | 30 minutes |
| 45 | 45 minutes |
| 60 | 1 hour |
| 120 | 2 hours |
| 180 | 3 hours |
| 240 | 4 hours |
| 1D or D | 1 day |
| 1W or W | 1 week |
| 1M or M | 1 month |
| 3M | 3 months |
| 6M | 6 months |
| 12M | 12 months |
Related Projects
- PineTS : The underlying transpiler and runtime engine
Contributing
Contributions are welcome! Please feel free to open issues or submit pull requests.
License
Original pinets-cli code is AGPL-3.0-or-later. The bundled PineTS runtime is AGPL-3.0-only. See LICENSE and THIRD_PARTY_NOTICES for details.
