@kuandotdev/indicator 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +2 -7
  2. package/package.json +4 -1
  3. package/project/.cursor/rules/agent-docs.mdc +16 -0
  4. package/project/.cursor/rules/api-credential-storage.mdc +16 -0
  5. package/project/.cursor/rules/pinescript-v6.mdc +16 -0
  6. package/project/.cursor/rules/stock-model-forecast.mdc +16 -0
  7. package/project/.cursor/rules/system-prompt-injection.mdc +16 -0
  8. package/project/.cursor/rules/system-prompt-updater.mdc +16 -0
  9. package/project/.cursor/rules/tradingview-stock-data.mdc +16 -0
  10. package/project/.env.example +44 -0
  11. package/project/.npm-packaged-project +1 -0
  12. package/project/.pi/APPEND_SYSTEM.md +338 -0
  13. package/project/.pi/settings.json +8 -0
  14. package/project/AGENTS.md +538 -0
  15. package/project/CLAUDE.md +538 -0
  16. package/project/GEMINI.md +538 -0
  17. package/project/Makefile +488 -0
  18. package/project/README.md +419 -0
  19. package/project/conda-env-active.sh +98 -0
  20. package/project/conda-env-deactive.sh +42 -0
  21. package/project/docs/agent-install.md +446 -0
  22. package/project/docs/agent-skill-directory.md +222 -0
  23. package/project/docs/integration.html +271 -0
  24. package/project/packages/indicator/README.md +39 -0
  25. package/project/packages/indicator/package.json +40 -0
  26. package/project/packages/indicator/scripts/build-project-snapshot.js +57 -0
  27. package/project/packages/indicator/src/cli.js +368 -0
  28. package/project/packages/tradingview-stock-data-skill/README.md +112 -0
  29. package/project/packages/tradingview-stock-data-skill/extensions/stock-prompt-injector.ts +121 -0
  30. package/project/packages/tradingview-stock-data-skill/package.json +35 -0
  31. package/project/packages/tradingview-stock-data-skill/scripts/postinstall.sh +73 -0
  32. package/project/packages/tradingview-stock-data-skill/skills/tradingview-stock-data/SKILL.md +241 -0
  33. package/project/pyproject.toml +68 -0
  34. package/project/screenshots/.gitkeep +0 -0
  35. package/project/scripts/indicators/example_rsi_bands.pine +27 -0
  36. package/project/scripts/indicators/tsla_levels.pine +57 -0
  37. package/project/skills/agent-docs/SKILL.md +56 -0
  38. package/project/skills/api-credential-storage/SKILL.md +83 -0
  39. package/project/skills/api-credential-storage/scripts/upsert_env.py +151 -0
  40. package/project/skills/pinescript-v6/SKILL.md +129 -0
  41. package/project/skills/pinescript-v6/reference/built-ins.md +219 -0
  42. package/project/skills/pinescript-v6/reference/templates/alert-webhook.pine +76 -0
  43. package/project/skills/pinescript-v6/reference/templates/indicator.pine +48 -0
  44. package/project/skills/pinescript-v6/reference/templates/strategy.pine +50 -0
  45. package/project/skills/pinescript-v6/reference/v5-to-v6-migration.md +102 -0
  46. package/project/skills/pinescript-v6/reference/v6-language.md +202 -0
  47. package/project/skills/stock-model-forecast/SKILL.md +192 -0
  48. package/project/skills/system-prompt-injection/CUSTOM_SYSTEM_PROMPT.md +333 -0
  49. package/project/skills/system-prompt-injection/DEFAULT_SYSTEM_PROMPT.md +327 -0
  50. package/project/skills/system-prompt-injection/SKILL.md +90 -0
  51. package/project/skills/system-prompt-injection/SYSTEM_PROMPT.md +23 -0
  52. package/project/skills/system-prompt-updater/SKILL.md +82 -0
  53. package/project/skills/system-prompt-updater/scripts/system_prompt_update.sh +106 -0
  54. package/project/skills/tradingview-stock-data/SKILL.md +272 -0
  55. package/project/src/tv_indicator/__init__.py +0 -0
  56. package/project/src/tv_indicator/browser/__init__.py +0 -0
  57. package/project/src/tv_indicator/browser/automation.py +541 -0
  58. package/project/src/tv_indicator/browser/selectors.py +70 -0
  59. package/project/src/tv_indicator/cli/__init__.py +0 -0
  60. package/project/src/tv_indicator/cli/browser_cmds.py +92 -0
  61. package/project/src/tv_indicator/cli/data_cmds.py +178 -0
  62. package/project/src/tv_indicator/cli/main.py +56 -0
  63. package/project/src/tv_indicator/cli/model_cmds.py +255 -0
  64. package/project/src/tv_indicator/cli/pine_cmds.py +140 -0
  65. package/project/src/tv_indicator/config.py +98 -0
  66. package/project/src/tv_indicator/data/__init__.py +0 -0
  67. package/project/src/tv_indicator/data/client.py +187 -0
  68. package/project/src/tv_indicator/data/screener.py +268 -0
  69. package/project/src/tv_indicator/mcp/__init__.py +0 -0
  70. package/project/src/tv_indicator/mcp/agent_server.py +398 -0
  71. package/project/src/tv_indicator/mcp/browser_server.py +133 -0
  72. package/project/src/tv_indicator/mcp/data_server.py +239 -0
  73. package/project/src/tv_indicator/model/__init__.py +19 -0
  74. package/project/src/tv_indicator/model/forecast.py +693 -0
  75. package/project/tools/import_agent_tools.sh +503 -0
  76. package/project/tools/install_skills.sh +673 -0
  77. package/project/tools/interactive_install.sh +917 -0
  78. package/project/tools/progress.sh +114 -0
  79. package/project/tools/uninstall_agent_tools.sh +373 -0
  80. package/src/cli.js +22 -25
@@ -0,0 +1,129 @@
1
+ ---
2
+ name: pinescript-v6
3
+ description: |
4
+ Use this skill whenever authoring, editing, reviewing, or migrating PineScript code,
5
+ and whenever a market-analysis workflow needs PineScript-compatible indicator semantics
6
+ such as default MACD analysis or user-requested RSI/SMA/EMA/Bollinger/ATR/VWAP logic.
7
+ Code triggers include .pine files, `//@version=`, `indicator(...)`, `strategy(...)`,
8
+ `library(...)`, `request.security`, `ta.*`, `strategy.*`, `array.*`, `matrix.*`,
9
+ `map.*`, etc. The skill encodes Pine Script v6 syntax, common patterns, and v5→v6
10
+ migration rules so generated code compiles in TradingView's Pine Editor.
11
+ Trigger phrases: "write a pine indicator", "pinescript strategy", "convert v5 to v6",
12
+ "fix this pine script", "create alert with webhook", "tradingview indicator".
13
+ ---
14
+
15
+ # PineScript v6 authoring skill
16
+
17
+ ## Market-analysis indicator workflow
18
+
19
+ For stock/ETF/crypto/forex/futures/index analysis requests, use this skill for PineScript-compatible indicator semantics even when no `.pine` file is being edited.
20
+
21
+ Default behavior:
22
+
23
+ 1. Pull recent OHLCV through `tradingview-stock-data`.
24
+ 2. Compute/interpret MACD by default using Pine-compatible `ta.macd` semantics: EMA fast 12, EMA slow 26, signal EMA 9, plus histogram.
25
+ 3. Classify the signal as bullish, bearish, improving, weakening, or neutral from MACD line vs signal line, histogram direction, zero-line position, and recent crossovers.
26
+ 4. If the user requests another indicator, use that indicator instead or in addition: RSI, SMA/EMA, Bollinger Bands, ATR, VWAP, or custom PineScript logic.
27
+ 5. Feed the indicator result into the agent-evaluated `Rating: {Buy | Sell | hold}` plus Buy/Sell score. Do not treat TradingView's aggregate rating as the report rating.
28
+
29
+ Only create or edit a Pine file when the user asks for code, a reusable indicator/strategy, or a TradingView chart script. If a `.pine` file is written or modified, run the validation checklist below before claiming it is ready.
30
+
31
+ ## ⚠️ Always check version first
32
+
33
+ Every PineScript file MUST start with a version directive:
34
+
35
+ ```pinescript
36
+ //@version=6
37
+ ```
38
+
39
+ If the user provides code without `//@version=`, ask which version OR default to **v6**.
40
+ **Never silently mix v4/v5/v6 syntax** — it will not compile.
41
+
42
+ ## Required reading before writing Pine code
43
+
44
+ Load these in order based on the task:
45
+
46
+ | Task | Files to read |
47
+ |---|---|
48
+ | New indicator from scratch | `reference/v6-language.md`, `reference/built-ins.md`, `reference/templates/indicator.pine` |
49
+ | New strategy from scratch | `reference/v6-language.md`, `reference/built-ins.md`, `reference/templates/strategy.pine` |
50
+ | Strategy with webhook alerts (for automation) | `reference/templates/alert-webhook.pine` |
51
+ | Convert / migrate existing code | `reference/v5-to-v6-migration.md` first, then `reference/built-ins.md` |
52
+ | Fix compile errors | `reference/v5-to-v6-migration.md` (most errors are v5-isms) |
53
+
54
+ Paths are relative to this SKILL.md's directory.
55
+
56
+ ## Core authoring rules (apply every time)
57
+
58
+ 1. **One declaration statement per script**: exactly one `indicator()`, `strategy()`, or `library()` call near the top, after `//@version=6`.
59
+ 2. **Use namespaces explicitly**:
60
+ - `ta.sma()` not `sma()` (the un-namespaced form is v4)
61
+ - `math.abs()` not `abs()`
62
+ - `array.new<float>()` not `array.new_float()` (v6 prefers typed generics)
63
+ - `str.tostring()` not `tostring()`
64
+ 3. **Series vs simple types**: most TA functions need series; constants are `simple`/`const`. If you see `Cannot call X with arguments...` errors, this is usually the cause.
65
+ 4. **`request.security` lookahead**: always pass `barmerge.lookahead_off` unless intentionally peeking. Lookahead-on without `[1]` offset = repainting.
66
+ 5. **Strategy realism**: in `strategy(...)` declarations include `process_orders_on_close=true` and `calc_on_every_tick=false` for realistic backtests unless the user asks otherwise.
67
+ 6. **Alert messages for webhook automation**: use `alert(message, alert.freq_once_per_bar_close)` with a JSON-shaped string. See `reference/templates/alert-webhook.pine`.
68
+ 7. **No `var` abuse**: `var` initializes once. Use it for state that persists across bars; don't use it for values that should recompute.
69
+ 8. **Plot return values**: indicator() must produce at least one `plot()`, `plotshape()`, `plotchar()`, `bgcolor()`, or `hline()` to be valid.
70
+ 9. **Keep the declaration on one line**: TV's parser does NOT reliably accept the multi-line
71
+ `indicator(\n title = "...",\n ... \n )` style — it produces
72
+ "Syntax error at input ..." errors. Always write the `indicator(...)`, `strategy(...)`,
73
+ or `library(...)` call on a single line, even if long. (Local lint won't catch this;
74
+ only TV's compiler will.)
75
+
76
+ ## Quick reference: things that changed from v5 → v6
77
+
78
+ | v5 | v6 |
79
+ |---|---|
80
+ | `array.new_float(0)` | `array.new<float>(0)` |
81
+ | `matrix.new<float>(rows, cols, 0.0)` | unchanged ✓ |
82
+ | `if barstate.islast` | unchanged ✓ |
83
+ | Type declarations optional | Stronger inference; explicit types still allowed |
84
+ | `request.security(syminfo.tickerid, "D", close)` | unchanged ✓ but prefer keyword args |
85
+ | `input(...)` | `input.int / input.float / input.bool / input.source` (already true in v5) |
86
+ | Maximum 500 bars `lookback` default | v6 raised some limits — check `reference/v6-language.md` |
87
+
88
+ See `reference/v5-to-v6-migration.md` for the full delta.
89
+
90
+ ## Validation checklist before declaring "done"
91
+
92
+ When the user asks you to write/edit Pine code, before responding:
93
+
94
+ - [ ] First line is `//@version=6`
95
+ - [ ] Exactly one `indicator()` / `strategy()` / `library()` call
96
+ - [ ] All built-ins use correct namespace (`ta.`, `math.`, `str.`, `array.`, `request.`, `strategy.`, `input.`)
97
+ - [ ] Every `input.*()` call has a `title=` and a sensible `defval`
98
+ - [ ] `request.security` calls specify `lookahead` explicitly
99
+ - [ ] For strategies: at least one `strategy.entry` / `strategy.close` / `strategy.exit`
100
+ - [ ] For indicators: at least one visible output (`plot`, `plotshape`, `bgcolor`, `hline`)
101
+ - [ ] If the script generates alerts for the user's webhook pipeline (`tv_browser` MCP / live trading), the `alert()` payload is a JSON string that downstream code can parse
102
+ - [ ] No tabs (Pine Editor uses spaces); 4-space indent
103
+
104
+ ## Project conventions
105
+
106
+ - Indicators live in `scripts/indicators/*.pine`
107
+ - Strategies live in `scripts/strategies/*.pine`
108
+ - File names use `snake_case.pine`
109
+ - Each file starts with a header comment block:
110
+ ```
111
+ // ─────────────────────────────────────────────────────────────
112
+ // Title: <Display name>
113
+ // Author: <user>
114
+ // Description: <one paragraph>
115
+ // Version: v6, <date>
116
+ // ─────────────────────────────────────────────────────────────
117
+ ```
118
+
119
+ ## Pushing to TradingView
120
+
121
+ After writing a `.pine` file, the user can push it to their TradingView Premium account via:
122
+
123
+ ```bash
124
+ training-view browser push scripts/indicators/<file>.pine --apply NASDAQ:AAPL --screenshot
125
+ ```
126
+
127
+ This logs in via session cookie, pastes into the Pine Editor, saves, applies to a chart,
128
+ and screenshots. The screenshot ends up in `screenshots/` — read it back to visually
129
+ verify the indicator looks correct before iterating.
@@ -0,0 +1,219 @@
1
+ # PineScript v6 — built-in namespaces cheat sheet
2
+
3
+ ## `ta.*` — technical analysis
4
+
5
+ ```
6
+ ta.sma(src, len) // Simple MA
7
+ ta.ema(src, len) // Exponential MA
8
+ ta.wma(src, len) // Weighted MA
9
+ ta.rma(src, len) // Wilder's smoothing (used by RSI/ATR)
10
+ ta.vwma(src, len) // Volume-weighted MA
11
+ ta.hma(src, len) // Hull MA
12
+
13
+ ta.rsi(src, len) // RSI
14
+ ta.macd(src, fast, slow, sig) // returns [macd, signal, hist]
15
+ ta.bb(src, len, mult) // returns [basis, upper, lower]
16
+ ta.atr(len) // Average True Range (uses high/low/close internally)
17
+ ta.tr(handle_na = true) // True Range
18
+ ta.stoch(src, hi, lo, len) // Stochastic
19
+ ta.cci(src, len)
20
+ ta.mom(src, len)
21
+ ta.roc(src, len)
22
+
23
+ ta.highest(src, len) // Rolling max
24
+ ta.lowest(src, len) // Rolling min
25
+ ta.highestbars(src, len) // Bars-ago index of highest
26
+ ta.lowestbars(src, len)
27
+
28
+ ta.change(src, len = 1) // src - src[len]
29
+ ta.cum(src) // Cumulative sum
30
+ ta.valuewhen(cond, src, occ) // src value at the Nth occurrence of cond
31
+
32
+ ta.crossover(a, b) // bool: a crossed above b this bar
33
+ ta.crossunder(a, b)
34
+ ta.cross(a, b) // either direction
35
+
36
+ ta.pivothigh(src, left, right)
37
+ ta.pivotlow(src, left, right)
38
+ ta.barssince(cond) // bars since cond was true; na if never
39
+ ```
40
+
41
+ ## `math.*`
42
+
43
+ ```
44
+ math.abs(x) math.sign(x)
45
+ math.min(a, b) math.max(a, b)
46
+ math.round(x, precision = 0)
47
+ math.floor(x) math.ceil(x)
48
+ math.pow(b, e) math.sqrt(x)
49
+ math.log(x) math.log10(x) math.exp(x)
50
+ math.sin(x) math.cos(x) math.tan(x)
51
+ math.atan(x) math.atan2(y, x)
52
+ math.random(min, max, seed)
53
+ math.sum(src, len)
54
+ math.avg(...) // up to 10 args
55
+ ```
56
+
57
+ ## `str.*`
58
+
59
+ ```
60
+ str.tostring(value, format = "#.##")
61
+ str.tonumber(s)
62
+ str.format("Price: {0,number,#.##}", close)
63
+ str.length(s)
64
+ str.contains(s, sub)
65
+ str.startswith(s, sub) str.endswith(s, sub)
66
+ str.replace(s, from, to, occurrence = 0)
67
+ str.replace_all(s, from, to)
68
+ str.split(s, sep) // returns array<string>
69
+ str.upper(s) str.lower(s)
70
+ ```
71
+
72
+ ## `array.*`
73
+
74
+ ```
75
+ array.new<float>(size = 0, init_value = na)
76
+ array.from(v1, v2, ...) // literal
77
+ array.size(arr)
78
+ array.get(arr, i) array.set(arr, i, v)
79
+ array.push(arr, v) array.pop(arr)
80
+ array.unshift(arr, v) array.shift(arr)
81
+ array.insert(arr, i, v) array.remove(arr, i)
82
+ array.clear(arr)
83
+ array.includes(arr, v) array.indexof(arr, v)
84
+ array.slice(arr, from, to)
85
+ array.sort(arr, order = order.ascending)
86
+ array.reverse(arr)
87
+ array.sum(arr) array.avg(arr) array.min(arr) array.max(arr)
88
+ array.stdev(arr) array.variance(arr) array.median(arr)
89
+ array.join(arr, sep = ",")
90
+ ```
91
+
92
+ ## `map.*`
93
+
94
+ ```
95
+ map.new<keyType, valueType>()
96
+ map.put(m, k, v) map.get(m, k)
97
+ map.contains(m, k) map.remove(m, k)
98
+ map.keys(m) map.values(m)
99
+ map.size(m) map.clear(m)
100
+ ```
101
+
102
+ ## `request.*`
103
+
104
+ ```
105
+ request.security(symbol, timeframe, expression,
106
+ gaps = barmerge.gaps_off,
107
+ lookahead = barmerge.lookahead_off,
108
+ ignore_invalid_symbol = false,
109
+ currency = syminfo.currency)
110
+
111
+ request.security_lower_tf(symbol, timeframe, expression)
112
+ // get array of intrabar values
113
+
114
+ request.financial(symbol, financial_id, period)
115
+ // e.g. "TOTAL_REVENUE", period = "FY"|"FQ"|"TTM"
116
+
117
+ request.dividends(symbol, field, gaps, lookahead)
118
+ request.earnings(symbol, field, gaps, lookahead)
119
+ request.splits(symbol, field, gaps, lookahead)
120
+ request.economic(country_code, field)
121
+ request.quandl(...) // legacy
122
+ ```
123
+
124
+ ## `strategy.*`
125
+
126
+ ```
127
+ strategy.entry(id, direction, qty = na, limit = na, stop = na,
128
+ oca_name, oca_type, comment, alert_message)
129
+ strategy.order(id, direction, qty, limit, stop, oca_name, oca_type, comment, alert_message)
130
+ strategy.exit(id, from_entry, qty, qty_percent, profit, limit, loss, stop,
131
+ trail_price, trail_points, trail_offset,
132
+ oca_name, comment, alert_message)
133
+ strategy.close(id, comment, qty, qty_percent, alert_message)
134
+ strategy.close_all(comment, alert_message)
135
+ strategy.cancel(id) strategy.cancel_all()
136
+
137
+ // Direction constants
138
+ strategy.long strategy.short
139
+
140
+ // State
141
+ strategy.position_size // signed: + long, - short, 0 flat
142
+ strategy.position_avg_price
143
+ strategy.opentrades // count
144
+ strategy.openprofit
145
+ strategy.netprofit
146
+ strategy.equity
147
+ strategy.initial_capital
148
+
149
+ // Risk management (declarative)
150
+ strategy.risk.allow_entry_in(strategy.direction.long)
151
+ strategy.risk.max_position_size(10)
152
+ strategy.risk.max_drawdown(20, strategy.percent_of_equity)
153
+ strategy.risk.max_intraday_loss(5, strategy.percent_of_equity)
154
+ ```
155
+
156
+ ## `input.*`
157
+
158
+ ```
159
+ input.int(defval, title, minval, maxval, step, options, tooltip, inline, group)
160
+ input.float(defval, title, minval, maxval, step, options, tooltip, inline, group)
161
+ input.bool(defval, title, ...)
162
+ input.string(defval, title, options = [...], ...)
163
+ input.color(defval, title, ...)
164
+ input.source(defval, title, ...) // returns series: close, hl2, hlc3, etc.
165
+ input.symbol(defval, title, ...) // returns string ticker
166
+ input.timeframe(defval, title, options, ...)
167
+ input.session(defval, title, ...) // e.g. "0930-1600"
168
+ input.time(defval, title, ...)
169
+ input.price(defval, title, ...)
170
+ ```
171
+
172
+ ## `color.*`
173
+
174
+ ```
175
+ color.new(base, transp) // transp 0 (opaque) - 100 (invisible)
176
+ color.rgb(r, g, b, transp = 0)
177
+ color.from_gradient(value, bottom_value, top_value, bottom_color, top_color)
178
+ color.red color.green color.blue color.yellow color.orange color.purple
179
+ color.white color.black color.gray color.silver color.maroon color.navy
180
+ color.lime color.teal color.aqua color.fuchsia color.olive
181
+ ```
182
+
183
+ ## `syminfo.*` (read-only)
184
+
185
+ ```
186
+ syminfo.ticker // "AAPL"
187
+ syminfo.tickerid // "NASDAQ:AAPL"
188
+ syminfo.prefix // "NASDAQ"
189
+ syminfo.description // "Apple Inc."
190
+ syminfo.currency // "USD"
191
+ syminfo.basecurrency
192
+ syminfo.type // "stock", "futures", "crypto", "forex", ...
193
+ syminfo.mintick // minimum price increment
194
+ syminfo.pointvalue
195
+ syminfo.session
196
+ syminfo.timezone
197
+ ```
198
+
199
+ ## `timeframe.*`
200
+
201
+ ```
202
+ timeframe.period // current chart TF as string "1", "5", "60", "D", "W"
203
+ timeframe.multiplier
204
+ timeframe.isintraday
205
+ timeframe.isdaily
206
+ timeframe.isweekly
207
+ timeframe.ismonthly
208
+ timeframe.in_seconds(tf = timeframe.period)
209
+ ```
210
+
211
+ ## `barstate.*` — see v6-language.md
212
+
213
+ ## `alert*`
214
+
215
+ ```
216
+ alert(message, freq)
217
+ // freq: alert.freq_once_per_bar, alert.freq_once_per_bar_close, alert.freq_all
218
+ alertcondition(condition, title, message)
219
+ ```
@@ -0,0 +1,76 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // Title: Webhook-Ready Strategy Template
3
+ // Description:
4
+ // Strategy that emits JSON-shaped alert messages on entry and exit.
5
+ // Pair with TradingView's alert webhook (Pro+ plan) — set the
6
+ // webhook URL to your agent / broker bridge endpoint.
7
+ //
8
+ // Webhook payload contract (per alert):
9
+ // {
10
+ // "action": "buy" | "sell" | "exit_long" | "exit_short",
11
+ // "symbol": "<TICKER>",
12
+ // "price": <float>,
13
+ // "qty": <float>,
14
+ // "time": <unix ms>,
15
+ // "tag": "<strategy-name>"
16
+ // }
17
+ // ─────────────────────────────────────────────────────────────
18
+ //@version=6
19
+ strategy(
20
+ title = "Webhook Strategy",
21
+ overlay = true,
22
+ initial_capital = 10000,
23
+ default_qty_type = strategy.percent_of_equity,
24
+ default_qty_value = 10,
25
+ process_orders_on_close = true
26
+ )
27
+
28
+ fastLen = input.int(10, "Fast")
29
+ slowLen = input.int(30, "Slow")
30
+ tag = input.string("webhook-strat", "Strategy tag")
31
+
32
+ fast = ta.ema(close, fastLen)
33
+ slow = ta.ema(close, slowLen)
34
+
35
+ longCond = ta.crossover(fast, slow)
36
+ shortCond = ta.crossunder(fast, slow)
37
+
38
+ // Build JSON payload helper
39
+ buildPayload(simple string action) =>
40
+ '{' +
41
+ '"action":"' + action + '",' +
42
+ '"symbol":"' + syminfo.ticker + '",' +
43
+ '"price":' + str.tostring(close) + ',' +
44
+ '"qty":' + str.tostring(strategy.position_size) + ',' +
45
+ '"time":' + str.tostring(time) + ',' +
46
+ '"tag":"' + tag + '"' +
47
+ '}'
48
+
49
+ if longCond
50
+ strategy.entry("L", strategy.long)
51
+ alert(buildPayload("buy"), alert.freq_once_per_bar_close)
52
+
53
+ if shortCond
54
+ strategy.entry("S", strategy.short)
55
+ alert(buildPayload("sell"), alert.freq_once_per_bar_close)
56
+
57
+ // Exit on opposite signal
58
+ if strategy.position_size > 0 and shortCond
59
+ alert(buildPayload("exit_long"), alert.freq_once_per_bar_close)
60
+
61
+ if strategy.position_size < 0 and longCond
62
+ alert(buildPayload("exit_short"), alert.freq_once_per_bar_close)
63
+
64
+ plot(fast, "Fast", color=color.aqua)
65
+ plot(slow, "Slow", color=color.orange)
66
+
67
+ // ─────────────────────────────────────────────────────────────
68
+ // HOW TO USE:
69
+ // 1. Save this script in TradingView's Pine Editor.
70
+ // 2. Add to chart. Open the alerts dialog (clock icon).
71
+ // 3. Condition: select this strategy → "Any alert() function call".
72
+ // 4. Notifications → Webhook URL → paste your endpoint
73
+ // (e.g. https://yourdomain.com/tv-webhook)
74
+ // 5. Message: leave blank (the alert() calls in code provide the payload)
75
+ // 6. Save. TradingView will POST the JSON above on each signal.
76
+ // ─────────────────────────────────────────────────────────────
@@ -0,0 +1,48 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // Title: <Indicator Name>
3
+ // Author: <user>
4
+ // Description: <one-paragraph description>
5
+ // Version: v6, <date>
6
+ // ─────────────────────────────────────────────────────────────
7
+ //@version=6
8
+ // NOTE: TV's compiler is picky about multi-line function calls — keep the
9
+ // declaration on a single line (or use line continuations with a comma on
10
+ // each line and the closing paren tight on the last line, NO leading space).
11
+ indicator("<Indicator Name>", shorttitle="<short>", overlay=true, max_bars_back=500, max_labels_count=50, max_lines_count=50)
12
+
13
+ // ───── Inputs ────────────────────────────────────────────────
14
+ length = input.int(14, "Length", minval=1, group="Core")
15
+ src = input.source(close, "Source", group="Core")
16
+ smoothing = input.string("EMA", "Smoothing", options=["SMA", "EMA", "RMA", "WMA"], group="Core")
17
+ showSignals = input.bool(true, "Show buy/sell signals", group="Display")
18
+
19
+ // ───── Calculations ──────────────────────────────────────────
20
+ smoothMA(series float source, simple int len, simple string method) =>
21
+ switch method
22
+ "SMA" => ta.sma(source, len)
23
+ "EMA" => ta.ema(source, len)
24
+ "RMA" => ta.rma(source, len)
25
+ "WMA" => ta.wma(source, len)
26
+ => ta.ema(source, len)
27
+
28
+ basis = smoothMA(src, length, smoothing)
29
+ upper = basis + ta.atr(length)
30
+ lower = basis - ta.atr(length)
31
+
32
+ longSignal = ta.crossover(close, upper)
33
+ shortSignal = ta.crossunder(close, lower)
34
+
35
+ // ───── Plots ─────────────────────────────────────────────────
36
+ plot(basis, "Basis", color=color.new(color.blue, 0), linewidth=2)
37
+ plot(upper, "Upper Band", color=color.new(color.gray, 30))
38
+ plot(lower, "Lower Band", color=color.new(color.gray, 30))
39
+
40
+ plotshape(showSignals and longSignal, "Long", shape.triangleup, location.belowbar, color.lime, size=size.tiny)
41
+ plotshape(showSignals and shortSignal, "Short", shape.triangledown, location.abovebar, color.red, size=size.tiny)
42
+
43
+ bgcolor(longSignal ? color.new(color.lime, 92) : na)
44
+ bgcolor(shortSignal ? color.new(color.red, 92) : na)
45
+
46
+ // ───── Alerts ────────────────────────────────────────────────
47
+ alertcondition(longSignal, "Long signal", "Long signal on {{ticker}} at {{close}}")
48
+ alertcondition(shortSignal, "Short signal", "Short signal on {{ticker}} at {{close}}")
@@ -0,0 +1,50 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // Title: <Strategy Name>
3
+ // Author: <user>
4
+ // Description: <one-paragraph description of entry/exit logic>
5
+ // Version: v6, <date>
6
+ // ─────────────────────────────────────────────────────────────
7
+ //@version=6
8
+ // NOTE: keep the declaration on a single line (TV is picky about multi-line
9
+ // function calls). Wrap with line continuations if needed for readability.
10
+ strategy("<Strategy Name>", shorttitle="<short>", overlay=true, initial_capital=10000, currency=currency.USD, default_qty_type=strategy.percent_of_equity, default_qty_value=10, commission_type=strategy.commission.percent, commission_value=0.05, slippage=2, pyramiding=0, process_orders_on_close=true, calc_on_every_tick=false, max_bars_back=500)
11
+
12
+ // ───── Inputs ────────────────────────────────────────────────
13
+ fastLen = input.int(10, "Fast MA", minval=1, group="MA")
14
+ slowLen = input.int(30, "Slow MA", minval=1, group="MA")
15
+ useATRStop = input.bool(true, "Use ATR stop", group="Risk")
16
+ atrLen = input.int(14, "ATR length", minval=1, group="Risk")
17
+ atrMult = input.float(2.0, "ATR multiplier", minval=0.1, step=0.1, group="Risk")
18
+ rrRatio = input.float(2.0, "Reward:Risk", minval=0.1, step=0.1, group="Risk")
19
+
20
+ // Session / time filter (optional)
21
+ useTime = input.bool(false, "Limit to session", group="Time")
22
+ sess = input.session("0930-1600", "Session", group="Time")
23
+ inSession = not useTime or not na(time(timeframe.period, sess))
24
+
25
+ // ───── Calculations ──────────────────────────────────────────
26
+ fastMA = ta.ema(close, fastLen)
27
+ slowMA = ta.ema(close, slowLen)
28
+ atr = ta.atr(atrLen)
29
+
30
+ longCond = ta.crossover(fastMA, slowMA) and inSession
31
+ shortCond = ta.crossunder(fastMA, slowMA) and inSession
32
+
33
+ // ───── Orders ────────────────────────────────────────────────
34
+ if longCond
35
+ stopPx = close - atrMult * atr
36
+ targetPx = close + atrMult * atr * rrRatio
37
+ strategy.entry("L", strategy.long)
38
+ if useATRStop
39
+ strategy.exit("L-exit", from_entry="L", stop=stopPx, limit=targetPx)
40
+
41
+ if shortCond
42
+ stopPx = close + atrMult * atr
43
+ targetPx = close - atrMult * atr * rrRatio
44
+ strategy.entry("S", strategy.short)
45
+ if useATRStop
46
+ strategy.exit("S-exit", from_entry="S", stop=stopPx, limit=targetPx)
47
+
48
+ // ───── Plots ─────────────────────────────────────────────────
49
+ plot(fastMA, "Fast MA", color=color.new(color.aqua, 0))
50
+ plot(slowMA, "Slow MA", color=color.new(color.orange, 0))
@@ -0,0 +1,102 @@
1
+ # v5 → v6 migration guide
2
+
3
+ Most v5 code runs unchanged when you bump the version directive, but a few patterns
4
+ need updating. Common compile errors and their fixes:
5
+
6
+ ## 1. Generic type constructors
7
+
8
+ ```pinescript
9
+ // v5 (still works but deprecated)
10
+ arr = array.new_float(10, 0.0)
11
+ mat = matrix.new_float(3, 3, 0.0)
12
+
13
+ // v6 (preferred)
14
+ arr = array.new<float>(10, 0.0)
15
+ mat = matrix.new<float>(3, 3, 0.0)
16
+ ```
17
+
18
+ Same applies to `int`, `bool`, `string`, `color`, `label`, `line`, `box`, custom types.
19
+
20
+ ## 2. Anonymous types in arrays/maps
21
+
22
+ ```pinescript
23
+ // v5
24
+ type Bar
25
+ float o
26
+ float c
27
+
28
+ var bars = array.new<Bar>()
29
+
30
+ // v6 — same syntax ✓ but you can now use methods
31
+ method body(Bar self) =>
32
+ math.abs(self.c - self.o)
33
+
34
+ method is_bull(Bar self) =>
35
+ self.c > self.o
36
+
37
+ // Call site
38
+ b = Bar.new(100, 110)
39
+ size = b.body() // method-style
40
+ ```
41
+
42
+ ## 3. Boolean optimization changes
43
+
44
+ v6 short-circuits `and`/`or` more aggressively. Side effects in the second operand may
45
+ not execute. Move side effects out:
46
+
47
+ ```pinescript
48
+ // v5 may have worked; v6 may skip the second call
49
+ ok = check_a() and (counter := counter + 1) > 0
50
+
51
+ // v6 safe
52
+ a_ok = check_a()
53
+ counter := counter + 1
54
+ ok = a_ok and counter > 0
55
+ ```
56
+
57
+ ## 4. `request.security` parameter ordering
58
+
59
+ v6 enforces stricter type checking on the `expression` parameter. If you pass tuples,
60
+ they must use the explicit form:
61
+
62
+ ```pinescript
63
+ // v5 — implicit tuple
64
+ [h, l, c] = request.security(sym, "D", [high, low, close])
65
+
66
+ // v6 — same syntax ✓ but each element must be the same series type
67
+ // If you need mixed types, use multiple calls
68
+ ```
69
+
70
+ ## 5. `strategy.exit` profit/loss in points vs ticks
71
+
72
+ No behavioral change but stricter validation. Make sure `profit` and `loss` are in
73
+ **points** (price units), or use `profit_percent`/`loss_percent`.
74
+
75
+ ## 6. Color transparency
76
+
77
+ `color.new(color.red, 50)` — second arg is 0 (opaque) to 100 (transparent). Same in v6.
78
+ If you used `transp=50` in `plot()`, that param still exists.
79
+
80
+ ## 7. Removed / renamed (rare)
81
+
82
+ - `tickerid()` → `ticker.new()` (renamed in v5 already; remove any remaining v4 form)
83
+ - `security()` (unprefixed) → `request.security()` (v5 already, but worth checking)
84
+ - `sma()`, `ema()`, etc. unprefixed → `ta.sma()`, `ta.ema()` (v5 already)
85
+
86
+ ## 8. New in v6 (use these if helpful)
87
+
88
+ - **Dynamic requests**: `request.security(sym, tf, expr)` where `sym` can change per bar (with caveats — check official docs)
89
+ - **`chart.point`**: convenience type for line/label coordinates
90
+ - **Polylines**: `polyline.new(points, ...)` for connected segments
91
+ - **Improved `runtime.error()`**: clearer error surfaces
92
+
93
+ ## Compile error decoder
94
+
95
+ | Error message | Likely cause |
96
+ |---|---|
97
+ | `Cannot call '...' with arguments (series int, ...)` | Passing series where simple expected. Cast or use `int(x)` if literal. |
98
+ | `Undeclared identifier 'sma'` | Missing `ta.` prefix |
99
+ | `The 'expression' has wrong type` in `request.security` | Mixing series types inside a tuple |
100
+ | `Pine cannot determine the referencing length` | Add `max_bars_back=N` to `indicator()`/`strategy()` |
101
+ | `Function should be called on each calculation` | `var`-initialized inside a conditional; move it out |
102
+ | `Script must have at least one output` | Indicator without any `plot*` / `bgcolor` / `hline` |