$npx -y skills add mphinance/alpha-skills --skill mph-pineBuild TradingView Pine Script v6 indicators in Michael's house style. Synthwave dashboard, faithful math, v6-compliant, no em dashes. Triggers on "pine script", "tradingview indicator", "write a pine indicator", "/mph-pine".
| 1 | # Mph Pine |
| 2 | |
| 3 | Build TradingView Pine Script v6 indicators that look and behave like the mphinance house stable (channels.pine, ghost_dashboard.pine, ghost_alpha.pine). Faithful math, clean v6, a synthwave dashboard, and a compressed AI-readable payload row so Gemini or Sam can read the chart. |
| 4 | |
| 5 | ## When to invoke |
| 6 | |
| 7 | Use when the user asks to build, port, or extend a TradingView indicator or strategy: "write a pine indicator", "tradingview indicator for X", "port this Python signal to Pine", "add alerts to my script", "/mph-pine". If the user names an existing engine (a Python scanner, a screener rule), treat that as the source of truth and port it faithfully before adding extras. |
| 8 | |
| 9 | ## Flow |
| 10 | |
| 11 | 1. **Ground on v6 first.** Pull current docs (the context7 / pine-script docs MCP, or tradingview.com/pine-script-docs) before writing. Do not trust v5 muscle memory. Confirm the version line is `//@version=6`. |
| 12 | 2. **Find the source of truth.** If porting, read the Python or existing Pine end to end and match field names, constants, and thresholds exactly. Cite the constants in a header comment. Only add new behavior after the faithful port is in place, and say plainly which parts are new. |
| 13 | 3. **Scaffold in house style.** Header comment block, palette consts, grouped inputs, calculations, draw, plots, alerts, dashboard. See the templates below. |
| 14 | 4. **Run the v6 landmine checklist** (below) against the finished file. |
| 15 | 5. **Scan for em dashes.** Search the file for U+2014 and U+2013, including code comments and string literals. Replace with a hyphen or comma. This is the single most common house-rule miss in generated code. |
| 16 | 6. **Hand off for compile.** There is no offline Pine compiler. Load the finished script onto the user's clipboard and tell them to paste it into TradingView's Pine Editor, Save, Add to chart, and report any red error. Fix reported errors and reload the clipboard. |
| 17 | 7. **Save and offer to ship.** Write to `docs/pine/<name>.pine` in the relevant repo. Offer `/ship`. Never commit without being asked. |
| 18 | |
| 19 | ## v6 landmine checklist |
| 20 | |
| 21 | These are the v6 breaking changes and gotchas that bite when porting from v5 or from memory: |
| 22 | |
| 23 | - **`bool` cannot be `na`.** Never write `var bool x = na`. Use an `int` flag (0 / 1 / -1) for tri-state. `na()`, `nz()`, `fixnan()` no longer accept bool. |
| 24 | - **No implicit int or float to bool cast.** Write explicit comparisons: `if count > 0`, not `if count`. |
| 25 | - **`and` / `or` are lazy.** Short-circuit is fine, but do not rely on side effects in the right operand. |
| 26 | - **Enums and `input.enum`.** Declare `enum Name` with optional `field = "Title"` strings, then `input.enum(Name.first, "Label")`. Compare with `==`. Cleaner than magic strings. |
| 27 | - **Dynamic `request.security`.** A single call can take a `series string` symbol or timeframe. Use `lookahead=barmerge.lookahead_off` to stay non-repainting. |
| 28 | - **`input.timeframe("")` off-slot trick.** An empty timeframe means the chart timeframe. For an optional higher-TF confirm, never gate `request.security` behind a ternary on the empty string (Pine evaluates both branches). Instead call `request.security` on a fallback (`htf_on ? htf_tf : timeframe.period`) and ignore the result when off. |
| 29 | - **`plotchar` / `plotshape` args must be const.** `char`, `text`, and `location` cannot be series. Split a direction-dependent marker into two calls with fixed `location.belowbar` / `location.abovebar`. |
| 30 | - **User functions must be global.** Declare every `f_*()` at top level, never inside an `if` block or a local scope. |
| 31 | - **Medians.** Pine has no `ta.median`. Use `ta.percentile_linear_interpolation(src, len, 50)`. |
| 32 | - **Pine gives you no slope or r2 directly.** Hand-roll least squares (snippet below). |
| 33 | - Set generous `max_bars_back`, `max_lines_count`, `max_labels_count` on `indicator()` when drawing persistent objects or looping over history. |
| 34 | - Heavy per-bar loops (pivot scans, multi-pass fits) can trip the execution-time limit on long intraday histories. Keep lookbacks modest and note the tradeoff. |
| 35 | |
| 36 | ## House style template |
| 37 | |
| 38 | ```pine |
| 39 | // <Name> [mph1nance] - <one line purpose> |
| 40 | // (c) mph1nance + Sam the Quant Ghost |
| 41 | // |
| 42 | // PURPOSE: <what it does and why it beats the generic version> |
| 43 | // Faithful port of <source>. Constants: <list them>. |
| 44 | |
| 45 | //@version=6 |
| 46 | indicator("<Name> [mph1nance]", "<glyph>", overlay=true, max_bars_back=600, max_lines_count=30, max_labels_count=50) |
| 47 | |
| 48 | // Synthwave palette (reuse these names) |
| 49 | const color C_BULL = #00FFFF |
| 50 | const color C_BEAR = #FF00FF |
| 51 | const color C_NEUTRAL = #9C27B0 |
| 52 | const color C_BREAK = #FF3D00 |
| 53 | const color C_CONF = #00FFCC |
| 54 | const color C_WARN = #FFD740 |
| 55 | const color C_BG = #090014 |
| 56 | const color C_BORDER = #FF00FF |
| 57 | const color C_TEXT = #00FFFF |
| 58 | |
| 59 | // Grouped inputs |
| 60 | g_main = "--- Main -- |