Production-Grade TradingView Pine Script Indicators & Strategies
Transform your TradingView Pine Script ideas into production-ready indicators and strategies with professional tooling, automated linting, structured versioning, and release pipelinesβall without leaving your editor.
Most Pine Script traders treat each indicator as a one-off script. Pine Script Skill treats them like real projects:
- π 59-Rule Linter β v6 compile errors, repainting traps, scope violations, performance costs, invisible dashboard text. Seven rules repair themselves with
--fix βΆοΈ It Runs The Code β a Pine interpreter in Python executes a script offline, bar by bar, with real series history. Not a lint pass: actual execution, with parameter sweeps and every approximation reported- π§ Real Static Analysis β A symbol table catches
:=to an undeclared name (TradingView'sUndeclared identifier) and variables written but never read. Loop nests are costed at their worst case against Pine's 500 ms limit - π¨ Formatter β
pine_fmt.py --checkin CI. It never touches block indentation, because in Pine that is structure, not style - π Professional Templates β Scaffold indicators/strategies with theme-aware dashboards, test blocks, and best-practice structure
- π‘οΈ Strategy Risk Modules β Risk-% sizing, ATR stops, breakeven + trailing, TP1/TP2 partials, session and date-window filters, account-level guards β wired together and ready to use
- β In-Script Testing β Assertions inside your Pine code; results show in a test-mode table
- 𧬠Tests That Are Themselves Tested β
mutate_check.pydisables each lint rule and confirms the suite goes red. Its first run found 16 of 59 rules with no test at all - π¦ Automated Releases β Lint report, version bump, changelog, git tag, publish description, and a generated table of every setting
- β‘ Live & Fast β Work-tiering and memoization so a dashboard tracks price tick-by-tick without re-running heavy scans
- π 12 Reference Guides β including a multi-timeframe guide, a symptom-first troubleshooting index, and a decision record
Perfect for traders who want repeatable workflows across multiple indicators, not just quick one-offs.
TradingView publishes no compiler CLI or API, so nothing here can guarantee a
script compiles. The linter matches patterns; it does not parse a syntax tree.
Every rule in it was either read out of TradingView's own docs or added after
a real paste failed β and when one gets missed, the fix is a new rule plus a
fixture in tests/fixtures/compile_errors/, not a louder claim. See
decisions.md D10.
git clone https://github.com/MoDarK-MK/PineScript-Skill.git
cd PineScript-Skillpython3 scripts/scaffold_project.py --kind indicator --name my_rsi_bands --title "My RSI Bands"This generates:
- Professional template with theme picker, dashboard, test block
version.jsontracking (starting at v0.1.0)- Empty
CHANGELOG.mdready to fill in
Edit indicators/my_rsi_bands/src/my_rsi_bands.pine with your indicator code.
python3 scripts/pine_lint.py indicators/my_rsi_bands/src/my_rsi_bands.pine
python3 scripts/pine_lint.py indicators/my_rsi_bands/src/my_rsi_bands.pine --fix
python3 scripts/pine_fmt.py indicators/my_rsi_bands/src/my_rsi_bands.pineCatches v6 errors, repainting traps, scope violations, performance issues and
style problems β offline, no TradingView compiler needed. --fix repairs
the six rules that have exactly one correct rewrite; anything needing intent
stays a finding, because a linter that guesses is worse than one that nags.
Add assertions to the Test Mode block in your script, then toggle Test Mode = true in TradingView. Results appear in a table; no test framework to learn.
python3 scripts/bump_version.py indicators/my_rsi_bands --bump minor --note "Added smoothing input"
python3 scripts/generate_release_bundle.py indicators/my_rsi_bandsOutputs:
- Linted
.pinefile with MPL 2.0 header - Pre-filled TradingView publish description
INPUTS.mdβ every setting with its default, range and explanation- Release checklist summary with a READY / NOT READY verdict
The bump also creates an annotated git tag my_rsi_bands/v0.2.0, namespaced per
project so several can share one repo.
Paste the .pine file into the Pine Editor, use the generated description, publish. Done.
| Project | Kind | Version | Lines | Lint | What it is |
|---|---|---|---|---|---|
pine_toolkit |
library | 0.1.0 |
192 | clean | Initial version of PineToolkit, the shared helper library. |
1 project(s). Generated by scripts/build_index.py.
pine_toolkitis the shared helper library.scaffold_project.pycreates your own projects alongside it β this repository ships the toolchain, and the indicators you build with it are yours.
PineScript-Skill/
βββ libraries/pine_toolkit/ # v0.1.0 (library)
βββ scripts/
β βββ backup_private.py
β βββ build_fa_reference.py
β βββ build_index.py
β βββ build_pine.py
β βββ bump_version.py
β βββ check_budget.py
β βββ check_inputs_compat.py
β βββ check_library_sync.py
β βββ complexity.py
β βββ doctor.py
β βββ generate_release_bundle.py
β βββ input_inventory.py
β βββ install_hooks.py
β βββ lint_all.py
β βββ mutate_check.py
β βββ new_rule.py
β βββ ollama_agent.py
β βββ pine_edit.py
β βββ pine_fmt.py
β βββ pine_lint.py
β βββ pine_run.py
β βββ publish.py
β βββ scaffold_project.py
β βββ strategy_to_indicator.py
β βββ strip_comments.py
βββ references/
β βββ alerts-guide.md
β βββ decisions.md
β βββ design-system.md
β βββ lint-rules.fa.md
β βββ lint-rules.md
β βββ mtf-guide.md
β βββ performance-guide.md
β βββ pine-v6-guide.md
β βββ publishing-guide.md
β βββ repo-structure.md
β βββ strategy-guide.md
β βββ style-guide.md
β βββ troubleshooting.md
βββ references/snippets/
β βββ glyphs.pine
β βββ live_update.pine
β βββ palette.pine
β βββ table_helpers.pine
βββ assets/templates/
β βββ CHANGELOG_template.md
β βββ dashboard_block_template.pine
β βββ indicator_template.pine
β βββ strategy_template.pine
β βββ test_block_template.pine
βββ tests/
β βββ test_backup_private.py
β βββ test_bump_version.py
β βββ test_compile_error_corpus.py
β βββ test_docs_consistency.py
β βββ test_generate_release_bundle.py
β βββ test_htf.py
β βββ test_new_tooling.py
β βββ test_pine_interp.py
β βββ test_pine_lint.py
β βββ test_project_quality.py
β βββ test_scaffold_project.py
β βββ test_sessions.py
β βββ test_shared_engine.py
β βββ test_skill_packaging.py
β βββ test_snapshots.py
β βββ test_strategy_to_indicator.py
β βββ test_strip_comments.py
β βββ test_untested_rules.py
βββ .github/workflows/ci.yml
Both blocks above are generated by
scripts/build_index.pyand checked in CI. The tree they replaced was hand-maintained, and by the time anyone looked it was missing four scripts and four reference docs.
Connects to your local Ollama instance (e.g., Llama 3) and uses this repository's skill rules to generate production-ready Pine Script completely offline.
# Generate code using the default model (llama3.1)
python3 scripts/ollama_agent.py "Write a volume weighted RSI indicator"
# Specify a different local model
python3 scripts/ollama_agent.py "Fix the repainting in this logic" --model codellamaOffline linting for v6 compliance and performance:
# Human-readable output
python3 scripts/pine_lint.py indicators/my_rsi_bands/src/my_rsi_bands.pine
# JSON for CI/CD integration
python3 scripts/pine_lint.py indicators/my_rsi_bands/src/my_rsi_bands.pine --json
# Strict mode: warnings also fail
python3 scripts/pine_lint.py indicators/my_rsi_bands/src/my_rsi_bands.pine --strict
python3 scripts/pine_lint.py FILE --profile dev # errors only, non-fatal
python3 scripts/pine_lint.py FILE --profile publish # everything, warnings fatal
python3 scripts/pine_lint.py FILE --watch # re-lint on every save
python3 scripts/pine_lint.py FILE --format editor # path:line:col, for editors
python3 scripts/pine_lint.py FILE --format github # CI annotations on the diff
# List all 59 rules (rules marked [--fix] can be repaired automatically)
python3 scripts/pine_lint.py --list-rules
# Explain one rule in full
python3 scripts/pine_lint.py --explain PINE045
# Apply the mechanical fixes
python3 scripts/pine_lint.py FILE --fix --dry-run
python3 scripts/pine_lint.py FILE --fixWhat it catches:
- β Hard v6 compile errors (
when=,transp=, missing switch defaults, etc.) - β Repainting traps (
and/orlazy evaluation, missinglookahead=, etc.) β οΈ Performance warnings (plot count, label/box/polyline limits)β οΈ Style violations (naming, line length, missing titles)
python3 scripts/scaffold_project.py --kind indicator --name my_indicator --title "My Indicator"
python3 scripts/scaffold_project.py --kind strategy --name my_strategy --title "My Strategy"Generates a complete project folder with:
- Professional template (theme picker, dashboard, test block)
version.jsonat v0.1.0- Empty
CHANGELOG.mdready to fill
python3 scripts/bump_version.py indicators/my_rsi_bands --bump patch --note "Fixed off-by-one"
python3 scripts/bump_version.py indicators/my_rsi_bands --bump minor --note "Added new input"
python3 scripts/bump_version.py indicators/my_rsi_bands --bump major --note "Changed plot behavior"Updates version.json, moves [Unreleased] to a dated entry in CHANGELOG.md,
and creates an annotated git tag <project>/vX.Y.Z β namespaced per project,
because several share this repo. Supports --dry-run, --json and --no-tag.
Tagging failure is reported, never fatal: a bump that succeeded must not be
undone because git was unavailable.
python3 scripts/generate_release_bundle.py indicators/my_rsi_bandsOutputs to release/:
- β
my_rsi_bands.pineβ Final linted script, MPL 2.0 header, comments stripped - β
PUBLISH_DESCRIPTION.mdβ Pre-filled TradingView publish template - β
INPUTS.mdβ Generated table of every setting, grouped as the panel groups them - β
RELEASE_SUMMARY.txtβ Lint results, test-mode check, readiness verdict
The released .pine carries no comments. This repo writes a lot of prose into its scripts on purpose, and all of it is for whoever changes the code β not for the person pasting the script into TradingView, who would otherwise read several hundred lines of it first. The source keeps every word.
Two things survive, because they are not really comments: //@version=N, which is a compiler directive, and the licence and copyright lines. Pass --keep-comments for the annotated copy.
Stripping is verified rather than assumed: tests/test_strip_comments.py runs every real indicator through the interpreter twice, with comments and without, and compares every drawing, plot and alert. A // inside a string is not a comment, and a stripper that thinks otherwise turns a tooltip containing a URL into a compile error.
python3 scripts/pine_fmt.py indicators/my_rsi_bands/src/my_rsi_bands.pine
python3 scripts/pine_fmt.py FILE --check # exit 1 if it would change (CI)
python3 scripts/pine_fmt.py FILE --diff # show the changes, write nothingTrailing whitespace, leading tabs, space after commas, spaces around
multi-character operators, blank-line runs. It never touches block indentation β
in Pine that is structure, so re-indenting is re-structuring β and it only ever
adds a missing space, never removes one, because this repo aligns = into
columns and a collapsing formatter would destroy every one of them.
python3 scripts/input_inventory.py indicators/my_rsi_bands
python3 scripts/input_inventory.py FILE --jsonEvery input with its type, default, range and tooltip, grouped the way the
settings panel groups them. Runs automatically as part of the release bundle
(release/INPUTS.md), and it is most of a TradingView publish description
written for you.
python3 scripts/mutate_check.py # every rule (~8 min)
python3 scripts/mutate_check.py --only PINE045Disables one lint rule at a time and re-runs the suite. A rule whose absence changes nothing has no test that can detect it breaking. The first run found 16 of 59 rules in exactly that state.
python3 scripts/strategy_to_indicator.py strategies/my_strategyRewrites the declaration, turns order calls into alert()s that keep their id
and direction, and comments out the risk guards. It refuses when the
strategy reads live position state, and names every blocking line β an indicator
has no position, and faking one would produce alerts that disagree with the
backtest they claim to mirror.
python3 scripts/pine_run.py FILE --bars 400
python3 scripts/pine_run.py FILE --csv data.csv --var swings --var boxesUsed
python3 scripts/pine_run.py FILE --set "Price Rows Per Swing=200"
python3 scripts/pine_run.py FILE --sweep "Price Rows Per Swing=30,60,120,240"The 59 lint rules match patterns. This runs the code β bar by bar, with
real series history, var persistence, user functions, UDTs, arrays and
if/for/while/switch as expressions β and reports what came out.
It is the difference between "this looks like it compiles" and "this produced
484 boxes across 4 swings with the POC at 104.22". Because input.*() reads
from an override map instead of the source, --sweep runs the same file under
many settings without editing anything.
Every run prints its approximations. Offline there is no intrabar data, no higher-timeframe series and no order execution, and a result depending on any of those is not exact. Saying so beside the number is the only honest way to show it.
What it does not do, stated because a partial interpreter that hides its edges
is worse than none: confirmed bars only (no realtime ticks, so tick-order bugs
belong to the linter), no request.* data, and an unimplemented builtin
raises instead of returning na β a value invented there would travel
silently into every result downstream.
python3 scripts/doctor.py --fast # everything except the 8-minute mutation run
python3 scripts/doctor.py --jsonTen checks, one table, one answer. Running them individually means occasionally forgetting one, and the one you forget is the one that would have caught something.
A check that cannot run in the current checkout is reported as skipped, by name, and never counted as a pass β the whole point is that a green line for a check that never executed is worse than a red one.
python3 scripts/build_pine.py PROJECT --split # one-time, at the section banners
python3 scripts/build_pine.py PROJECT # build
python3 scripts/build_pine.py PROJECT --check # CI: is the output current?Pine has no modules, so a growing script has nowhere to go but down. This repo's largest file passed 1800 lines and produced a compile error that was purely about ORDER β a declaration sitting below the function that read it β which nothing in a file that size makes visible.
Order comes from src/parts.json, not from filename prefixes, because Pine
resolves identifiers in textual order and that ordering is a real design
decision rather than a filing convention.
python3 scripts/complexity.py
python3 scripts/complexity.py --check # CI
python3 scripts/complexity.py --update-baselineLines, function count, longest function, nesting depth, input count.
Two kinds of limit, deliberately. The advisory thresholds are repo-wide and
never fail a run. What fails is a project exceeding the limit it declared in
its own budget.json. A repo-wide hard threshold applied to existing code
either fails from day one or is set so loose it never fires; a declared limit is
a ratchet, and raising one is a visible decision in a diff.
python3 scripts/check_budget.py
python3 scripts/check_budget.py PROJECT --initBoxes, lines, labels, plot counts and request.*() calls against the numbers
each project declared. TradingView's own limits are silent β over 500 boxes the
oldest simply stop drawing β and the point here is the declared number: an
intentional "this should use at most 3 requests" catches a fourth long before
the platform's ceiling would.
python3 scripts/check_inputs_compat.py PROJECTTradingView matches a saved chart setting to an input by its title. Rename one and every existing user silently loses that setting; remove one and the same happens. This is the only breaking change in a Pine script the author cannot see from their own chart, because their own settings are already saved.
Compares the current inputs against the last published INPUTS.md and names
what broke. Wired into the release bundle as a warning, not a blocker β renaming
an input is legitimate; doing it without noticing is not.
python3 scripts/publish.py PROJECT # release .pine -> clipboard
python3 scripts/publish.py PROJECT --notes # release notes, plain textCopies the release file, not src/ β the one that went through the gate.
--notes flattens the changelog entry into the plain text TradingView's
update-notes box actually accepts, instead of Markdown that renders as
punctuation.
python3 scripts/build_fa_reference.py
python3 scripts/build_fa_reference.py --check # CIGenerates references/lint-rules.fa.md from the
rule catalog, so codes and severities can never drift from the code. A rule with
no translation renders with its English summary and is listed as
untranslated, so the gap is visible rather than silently missing.
python3 scripts/check_library_sync.py
python3 scripts/check_library_sync.py --jsonTradingView's import only works against a library that has been published
to their servers, so until libraries/pine_toolkit is, every script carries its
own copy of formatVolume() and friends. This compares each exported function
against every same-named copy and reports the ones whose body differs.
Its first run found 6 of 7 copies drifted, including one indicator
formatting the same volume with a different number of decimals than the other
two. Nobody chose that. A copy that is deliberately specialised opts out with a
// library-sync-exempt: <reason> comment; two of them legitimately did.
python3 scripts/build_index.py # regenerate the marked regions
python3 scripts/build_index.py --check # exit 1 if stale (CI)Regenerates the project table and file tree in this README from the repo itself.
python3 scripts/lint_all.py # lint every source .pine at once
python3 scripts/install_hooks.py # pre-commit lint hook
python3 scripts/new_rule.py --next # scaffold a new lint ruleEvery script benefits from these docs; required reading before shipping:
| Guide | Purpose |
|---|---|
| mtf-guide.md | Multi-timeframe: the three lookahead combinations and which is the bug, security_lower_tf, gaps, the 40-call budget, repaint vs lookahead |
| alerts-guide.md | alertcondition vs alert(), frequency, placeholders, webhook JSON, and the security rules for alert payloads |
| troubleshooting.md | Symptom-first: every failure this repo hit, its cause, and the rule that now catches it |
| decisions.md | Decision record β what was decided, why, and what would change our mind |
| pine-v6-guide.md | v5βv6 breaking changes, platform limits, dynamic requests, repainting traps, var/varip semantics |
| style-guide.md | Official naming conventions (camelCase/SNAKE_CASE), section order, spacing, line wrapping |
| lint-rules.md | Full catalog of 59 lint rules (codes PINE001βPINE060; PINE024 unassigned) with examples and rationale |
| performance-guide.md | Keeping a script fast AND live: work tiering, memoization, buffer reuse, drawing updates, var vs varip |
| strategy-guide.md | Building strategies: signal design, position sizing math, the four risk modules, filters, overfitting, walk-forward |
| design-system.md | Theming, gradients, multi-color palettes, watermarks, dashboard patterns |
| publishing-guide.md | TradingView House Rules, description format, backtest realism, 15-min public edit window |
| repo-structure.md | Folder layout, version.json, CHANGELOG format, optional pre-commit hook |
# 1. Scaffold
python3 scripts/scaffold_project.py --kind indicator --name rsi_custom --title "Custom RSI"
# 2. Edit indicators/rsi_custom/src/rsi_custom.pine with your logic
# 3. Add test assertions to the Test Mode block
# 4. Lint
python3 scripts/pine_lint.py indicators/rsi_custom/src/rsi_custom.pine
# Output: β No errors
# 5. Bump version
python3 scripts/bump_version.py indicators/rsi_custom --bump minor --note "Initial release with bands"
# 6. Generate release
python3 scripts/generate_release_bundle.py indicators/rsi_custom
# 7. Check release/
# - rsi_custom.pine (ready to paste)
# - PUBLISH_DESCRIPTION.md (fill in the [bracketed] placeholders)
# - RELEASE_SUMMARY.txt (confirms READY status)
# 8. Publish to TradingView
# Copy rsi_custom.pine β Pine Editor β Publish Script (paste description)# 1. Scaffold β the template arrives with all four risk modules already wired
python3 scripts/scaffold_project.py --kind strategy --name breakout_atr --out ./strategies --title "ATR Breakout"
# 2. Replace ONLY the signal block in src/breakout_atr.pine:
# bool longSignal = ta.crossover(fastMa, slowMa)
# bool shortSignal = ta.crossunder(fastMa, slowMa)
# Everything else β sizing, stops, breakeven, trailing, partials, filters β
# is generic and stays as-is.
# 3. Lint in strict mode (warnings fail too)
python3 scripts/pine_lint.py strategies/breakout_atr/src/breakout_atr.pine --strict
# 4. Backtest on TradingView, then check the dashboard's Realism row:
# 100+ POSITIONS taken (not closed records β partials double that number)
# and profit factor above 1.
# 5. Release β the bundle blocks on lookahead bias, synthetic chart types,
# and zero-cost backtests, and pre-fills the disclosure section
python3 scripts/generate_release_bundle.py strategies/breakout_atrBefore trusting any equity curve, read strategy-guide.md Β§7 β a good-looking backtest is the default outcome, not evidence. The fastest sanity check: move your stop multiple Β±25% and see whether the result degrades gracefully or collapses.
| 59 lint rules | PINE001βPINE060 (PINE024 vacant), fact-checked against TradingView's docs; 7 auto-fixable |
| Offline execution | pine_run.py runs a script bar by bar over real or synthetic OHLCV, with series history and var semantics |
| Parameter sweeps | One file, many settings β input.*() reads from an override map |
| Symbol table | Undeclared := targets, unused and write-only variables |
| Cost analysis | Loop nests costed at their inputs' maxval; drawings made in loops checked against max_*_count |
| Formatter | --check gate in CI; never re-indents, never collapses alignment columns |
| 230 tests | stdlib unittest, zero dependencies |
| Mutation-checked | 59/59 rules verified to have a test that fails when the rule is disabled |
| Strategy risk modules | Risk-% sizing, ATR stops, breakeven, trailing, partials, filters, strategy.risk.* account guards |
| Backtest realism gate | Blocks lookahead bias, synthetic chart types, zero-cost backtests |
| In-script testing | Assertion counter inside the Pine file; no external runner |
| Release bundles | Lint β version β changelog β git tag β publish description β inputs table |
| Generated docs | Project registry, file tree and Persian rule reference built from the repo, --checked in CI |
| One-command verdict | doctor.py runs all ten checks; a skipped check is named, never counted as a pass |
| Part-file builds | Write src/parts/*.pine, ship one file; order declared in a manifest, not in filenames |
| Declared limits | Per-project resource and complexity budgets β a ratchet, so growth is a decision |
| Input compatibility | Catches the renames that silently reset every existing user's settings |
| 12 reference guides | v6, style, lint catalog, performance, strategy, design, publishing, repo structure, MTF, alerts, troubleshooting, decisions |
| Shared library | libraries/pine_toolkit β pure helpers as a real Pine library(), with inlined copies checked for drift |
| Snapshot tests | Publish description, inputs table and release summary compared against stored goldens |
| Offline | No compile-API dependency; everything runs on your machine |
The Python tooling has its own test suite (stdlib unittest, no dependencies):
python -m unittest discover -s tests -t . -v # 230 tests
python scripts/lint_all.py # every source .pine, strict
python scripts/pine_fmt.py FILE --check # formatting gate
python scripts/build_index.py --check # generated docs are current
python scripts/check_library_sync.py # inlined library copies match
python scripts/pine_run.py FILE --bars 300 # execute it, offline
python scripts/doctor.py --fast # all of the above, one verdict
python scripts/mutate_check.py # ~8 min; see belowGitHub Actions (.github/workflows/ci.yml) runs four
jobs: the test suite, the Pine lint + format sweep, the generated-docs check,
and β on pushes to main only β the mutation run.
Why a mutation job. A green suite proves the tests pass. It does not prove
they would fail if the thing they test broke, and a test that cannot fail is
worth nothing. mutate_check.py disables one lint rule at a time and re-runs
the suite; a rule whose absence changes nothing is one the next refactor can
delete silently. The first run found 16 of 59 rules in exactly that state β
nearly a third of the catalog, invisible while everything reported OK.
Adding a lint rule. scripts/new_rule.py scaffolds the catalog entry, the
check stub, the call site and the docs section. The consistency tests then fail
until the rule is documented and the counts line up, which is the point.
Without this skill:
- Write indicator β paste into TradingView β discover v6 error β debug β repeat
- Maintain 3+ indicators manually β inconsistent naming, no changelogs, versioning chaos
- Publish to TradingView β no release notes, no version tracking, hard to maintain
With Pine Script Skill:
- Write indicator β lint and format locally, catching most errors before TradingView
- Scaffold β Write β Lint β Test β Version β Tag β Release β Publish, repeatably
- Maintain 10+ indicators with independent versions, changelogs, git tags and release history
- When something does slip through, it becomes a fixture and a rule, so it cannot come back
- Spend more time trading, less time wrestling with process
See SKILL.md for complete details on:
- When to use which part of the toolchain
- Detailed scaffold & templating workflow
- In-script testing patterns
- Git integration & pre-commit hooks
- Advanced linting configuration
Start with troubleshooting.md when something is already wrong β it is indexed by symptom, and every row in it happened here.
- Python 3.8+ β for scripts (no external dependencies!)
- Pine Script v6 knowledge β TradingView docs
- TradingView Account β free or pro (for publishing)
- Git (optional) β for version control
All scripts and templates are licensed under the Mozilla Public License 2.0 (MPL 2.0).
Generated .pine files include the MPL 2.0 header automatically.
Found a bug in a lint rule? Spot a v6 edge case we missed? Spotted a typo in the guides?
Please open an issue or submit a PR. This is a working tool for traders building real indicatorsβyour feedback matters.
git clone https://github.com/MoDarK-MK/PineScript-Skill.git
cd PineScript-Skill
python3 scripts/scaffold_project.py --kind indicator --name my_first --title "My First Indicator"
# Start editing indicators/my_first/src/my_first.pineQuestions? Check SKILL.md or the reference guides in references/.
Happy trading. π