@kuandotdev/indicator 0.1.2 → 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 +21 -24
@@ -0,0 +1,419 @@
1
+ # Indicator
2
+
3
+ **TradingView integration for agents and humans.**
4
+ PineScript authoring (skill) + market data (Python) + browser automation (Playwright),
5
+ exposed as both a **terminal CLI** (`training-view ...`) and **MCP servers** for Claude/Cursor/pi/Cline.
6
+
7
+ ```
8
+ +--------------------------------------------------------------+
9
+ | Agent (Claude) |
10
+ | |
11
+ | #2 Pine v6 skill ---> authors .pine files locally |
12
+ | #3 data MCP / CLI --> OHLCV + screener + ratings |
13
+ | #5 browser MCP/CLI -> paste into TV, save, screenshot |
14
+ +--------------------------------------------------------------+
15
+ |
16
+ v
17
+ Your TradingView Premium account
18
+ ```
19
+
20
+ ---
21
+
22
+ ## Quick start
23
+
24
+ ```bash
25
+ make install # idempotent core install + terminal wizard for .env, login, agent/MCP setup
26
+
27
+ make rating SYMBOL=NASDAQ:TSLA
28
+ make screenshot SYMBOL=NASDAQ:TSLA
29
+ make push SCRIPT=scripts/indicators/example_rsi_bands.pine APPLY=NASDAQ:TSLA SHOT=1
30
+ ```
31
+
32
+ For a visual, local-only integration guide, open:
33
+
34
+ ```bash
35
+ open docs/integration.html
36
+ ```
37
+
38
+ > Runtime screenshots are intentionally **not committed**. The repository tracks
39
+ > only `screenshots/.gitkeep`; generated `screenshots/*.png` files stay local.
40
+
41
+ ---
42
+
43
+ ## What's inside
44
+
45
+ | Path | What |
46
+ |---|---|
47
+ | `skills/pinescript-v6/` | **Canonical Pine v6 skill** (edit here); reference + templates + v5->v6 migration |
48
+ | Market prompt skills | Protected market-analysis startup behavior and local-development update workflow |
49
+ | `skills/agent-docs/` | Skill for agents to read the skill/MCP capability directory |
50
+ | `docs/agent-skill-directory.md` | Generated directory of available skills, MCP tools, and routing rules |
51
+ | `docs/agent-install.md` | Step-by-step installation/setup guide written for AI agents (Pi/Claude/Codex/Gemini/Cursor) |
52
+ | `.claude/skills/`, `.pi/agent/skills/`, `.pi/skills/` | Symlinks into canonical skills for Claude Code / pi |
53
+ | Pi startup context | Generated Pi agent startup context |
54
+ | `.cursor/rules/*.mdc` | Cursor rules (auto-generated thin pointers to canonical skills) |
55
+ | `AGENTS.md`, `CLAUDE.md`, `GEMINI.md` | Project-root agent instructions/startup prompt (auto-generated) for Codex/OpenCode/Aider/Claude/Gemini |
56
+ | `tools/install_skills.sh` | Idempotent installer that wires skills/startup files into all agent dirs |
57
+ | `tools/interactive_install.sh` | New-user terminal wizard for platform selection, optional .env values, login, and agent/MCP import |
58
+ | `tools/import_agent_tools.sh` | Detects/configures Pi/Claude Desktop/Claude Code/Codex/Gemini/Cursor package/context/MCP tooling |
59
+ | `src/tv_indicator/data/` | OHLCV via `tvdatafeed`, screener + ratings via `tradingview-screener` |
60
+ | `src/tv_indicator/browser/` | Playwright flows: login, push script, screenshot |
61
+ | `src/tv_indicator/model/` | Server-side stock/ETF/index forecast API client |
62
+ | `src/tv_indicator/cli/` | `training-view` CLI (Typer + Rich) |
63
+ | `src/tv_indicator/mcp/` | MCP servers exposing the same functions as the CLI |
64
+ | `scripts/{indicators,strategies}/` | Your Pine source of truth (git-tracked) |
65
+ | `docs/integration.html` | Local static visual guide showing how CLI, agents, MCP, data, browser automation, and Pine files connect |
66
+ | `screenshots/` | Browser screenshots (gitignored except `screenshots/.gitkeep`) |
67
+ | `Makefile` | All workflows: install, run, lint, skills, clean |
68
+ | `conda-env-active.sh` / `conda-env-deactive.sh` | Standalone env scripts (sourced) |
69
+
70
+ ---
71
+
72
+ ## Install (conda + make)
73
+
74
+ Prereq: [Miniforge](https://github.com/conda-forge/miniforge) (or Miniconda / Anaconda).
75
+
76
+ ```bash
77
+ # The one command. Idempotent — safe to re-run anytime.
78
+ # Creates the conda env if missing, installs deps, then opens an interactive
79
+ # wizard for language, agent selection, TradingView login, and MCP config.
80
+ make install
81
+
82
+ # Verify everything:
83
+ make doctor
84
+ ```
85
+
86
+ > Edge cases: pass `FORCE_INSTALL=1` only when you need to force a re-pip-install
87
+ > (corrupted env, manual `pyproject.toml` edits). Normal upgrades don't need it.
88
+
89
+ Local development reinstall path:
90
+
91
+ ```bash
92
+ make uninstall
93
+ make install FORCE_INSTALL=1
94
+ make agent-import PLATFORM=auto
95
+ make check-skills
96
+ ```
97
+
98
+ Published package install path for normal users:
99
+
100
+ ```bash
101
+ npx @kuandotdev/indicator install
102
+ npx @kuandotdev/indicator install --force
103
+ ```
104
+
105
+ When run outside an existing checkout, the npm wrapper clones this repo into
106
+ `~/.indicator` first. Override with `TV_INDICATOR_INSTALL_DIR=/path/to/indicator`.
107
+
108
+ To use the `training-view` CLI directly in your shell (without `make` or `conda run`):
109
+
110
+ ```bash
111
+ source conda-env-active.sh tv-indicator
112
+
113
+ training-view status
114
+ training-view data ohlcv NASDAQ:AAPL --bars 50
115
+ ```
116
+
117
+ When done:
118
+
119
+ ```bash
120
+ conda deactivate
121
+ # Or to wipe the env entirely (mirrors skin_type_regonize_model's pattern):
122
+ source conda-env-deactive.sh tv-indicator
123
+ ```
124
+
125
+ ### TradingView login / `.env`
126
+
127
+ `make install` creates `.env` if needed, detects the preferred agent output language from the terminal locale (`LC_ALL`, `LC_MESSAGES`, `LANG`; fallback `en`), supports common codes such as `en`, `zhtw`, `zhcn`, `jp`, and `ko`, and skips optional API/session values unless you opt in with `TV_INSTALL_PROMPT_ENV=1`.
128
+
129
+ Preferred login path: let Playwright capture a persistent browser profile during setup. You can rerun manually:
130
+
131
+ ```bash
132
+ make login # opens a visible Chromium window; log in once
133
+ make session-check # should now show signed_in: true
134
+ ```
135
+
136
+ ### Model forecast API
137
+
138
+ The stock/ETF/index forecast model runs server-side. Configure the client with:
139
+
140
+ ```env
141
+ TV_MODEL_API_URL=https://model.example/forecast
142
+ TV_MODEL_API_KEY=optional-bearer-token
143
+ ```
144
+
145
+ Then verify with `make model-status` and fetch with `make model-forecast SYMBOL=NASDAQ:TSLA MODEL_JSON=1`.
146
+
147
+ ---
148
+
149
+ ## Usage -- two equivalent paths
150
+
151
+ Everything has both a **`make` shortcut** and the underlying **`training-view` CLI command**.
152
+
153
+ ### Via Make (no need to activate conda)
154
+
155
+ ```bash
156
+ make status
157
+ make doctor
158
+ make agent-import PLATFORM=auto # detect/import supported tooling
159
+ make agent-import PLATFORM=pi,claude-code # configure specific agents
160
+
161
+ # Data
162
+ make ohlcv SYMBOL=NASDAQ:AAPL INTERVAL=1D BARS=500
163
+ make search Q=tesla
164
+ make rating SYMBOL=NASDAQ:AAPL
165
+ make screener MARKET=america FILTER='RSI < 30' LIMIT=30
166
+
167
+ # Server-side model forecast (requires TV_MODEL_API_URL)
168
+ make model-status
169
+ make model-forecast SYMBOL=NASDAQ:TSLA MODEL_JSON=1
170
+
171
+ # Pine scaffolding
172
+ make pine-new KIND=indicator NAME=my_rsi
173
+ make pine-new KIND=strategy NAME=momentum_breakout
174
+ make pine-new KIND=webhook NAME=trend_follower
175
+ make pine-list
176
+ make pine-validate SCRIPT=scripts/indicators/my_rsi.pine
177
+
178
+ # Browser
179
+ make login # one-time interactive login
180
+ make session-check
181
+ make push SCRIPT=scripts/indicators/my_rsi.pine APPLY=NASDAQ:AAPL SHOT=1
182
+ make screenshot SYMBOL=NASDAQ:TSLA
183
+
184
+ # MCP servers (foreground, for debugging)
185
+ make mcp-data
186
+ make mcp-browser
187
+ make mcp-agent
188
+
189
+ # Print config snippets to register with Claude Desktop / pi
190
+ make agent-import PLATFORM=auto # writes supported MCP configs automatically
191
+ make mcp-config-claude # print Claude Desktop snippet only
192
+ make mcp-config-pi # print Pi snippet only
193
+ ```
194
+
195
+ Run `make help` for the full list.
196
+
197
+ ### Via the `training-view` CLI directly
198
+
199
+ After `source conda-env-active.sh tv-indicator`:
200
+
201
+ ```bash
202
+ training-view status
203
+ training-view version
204
+
205
+ training-view data ohlcv NASDAQ:AAPL --interval 1D --bars 500
206
+ training-view data ohlcv NASDAQ:AAPL -i 1H -n 200 --csv aapl.csv
207
+ training-view data search "tesla"
208
+ training-view data screener -m america -f "RSI < 30" -c name -c close -c RSI -n 30
209
+ training-view data rating NASDAQ:AAPL
210
+
211
+ training-view model status
212
+ training-view model forecast NASDAQ:TSLA --json
213
+
214
+ training-view pine new indicator my_rsi
215
+ training-view pine validate scripts/indicators/my_rsi.pine
216
+ training-view pine show scripts/indicators/my_rsi.pine
217
+
218
+ training-view browser login
219
+ training-view browser session-check
220
+ training-view browser push scripts/indicators/my_rsi.pine --apply NASDAQ:AAPL --screenshot
221
+ training-view browser screenshot --symbol NASDAQ:TSLA
222
+ ```
223
+
224
+ ---
225
+
226
+ ## MCP server setup
227
+
228
+ The same functions are exposed as MCP servers. Register them in your agent's config.
229
+
230
+ The easiest way is to let `make` generate the snippet with the correct absolute path
231
+ to your conda-installed entry points:
232
+
233
+ ```bash
234
+ make mcp-config-claude # prints JSON for Claude Desktop
235
+ make mcp-config-pi # prints TOML for pi
236
+ ```
237
+
238
+ ### Claude Desktop (manual)
239
+
240
+ `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
241
+
242
+ ```json
243
+ {
244
+ "mcpServers": {
245
+ "training-view-data": {
246
+ "command": "/abs/path/to/conda/envs/tv-indicator/bin/training-view-mcp-data",
247
+ "env": { "TV_SESSIONID": "paste-here", "TV_MODEL_API_URL": "https://model.example/forecast" }
248
+ },
249
+ "training-view-browser": {
250
+ "command": "/abs/path/to/conda/envs/tv-indicator/bin/training-view-mcp-browser",
251
+ "env": { "TV_SESSIONID": "paste-here", "TV_BROWSER_HEADLESS": "true" }
252
+ },
253
+ "training-view-agent": {
254
+ "command": "/abs/path/to/conda/envs/tv-indicator/bin/training-view-mcp-agent"
255
+ }
256
+ }
257
+ }
258
+ ```
259
+
260
+ Find the absolute path with:
261
+
262
+ ```bash
263
+ conda run -n tv-indicator which training-view-mcp-data
264
+ conda run -n tv-indicator which training-view-mcp-agent
265
+ ```
266
+
267
+ ### pi (manual)
268
+
269
+ Add to `.pi/config.toml` or your global pi config:
270
+
271
+ ```toml
272
+ [mcp_servers.training-view-data]
273
+ command = "/abs/path/to/conda/envs/tv-indicator/bin/training-view-mcp-data"
274
+ env = { TV_SESSIONID = "...", TV_MODEL_API_URL = "https://model.example/forecast" }
275
+
276
+ [mcp_servers.training-view-browser]
277
+ command = "/abs/path/to/conda/envs/tv-indicator/bin/training-view-mcp-browser"
278
+ env = { TV_SESSIONID = "...", TV_BROWSER_HEADLESS = "true" }
279
+
280
+ [mcp_servers.training-view-agent]
281
+ command = "/abs/path/to/conda/envs/tv-indicator/bin/training-view-mcp-agent"
282
+ ```
283
+
284
+ ### MCP tools exposed
285
+
286
+ | Server | Tool | Args |
287
+ |---|---|---|
288
+ | `training-view-data` | `get_ohlcv` | symbol, interval, n_bars, exchange, extended_session |
289
+ | `training-view-data` | `search_symbol` | query, limit |
290
+ | `training-view-data` | `screener` | market, columns, filters, order_by, limit |
291
+ | `training-view-data` | `technical_rating` | symbol, interval |
292
+ | `training-view-data` | `model_forecast` | symbol, refresh, period |
293
+ | `training-view-browser` | `session_check` | -- |
294
+ | `training-view-browser` | `push_script` | script_path, apply_to, screenshot, script_name |
295
+ | `training-view-browser` | `screenshot_chart` | symbol, layout_url, out_path |
296
+ | `training-view-agent` | `list_skills` | -- |
297
+ | `training-view-agent` | `read_agent_docs` | -- |
298
+ | `training-view-agent` | `read_install_docs` | -- |
299
+ | `training-view-agent` | `get_prompt_status` | -- |
300
+ | `training-view-agent` | `init_custom_stock_prompt` | local dev only, requires `TV_AGENT_ENABLE_PROMPT_WRITE=1` |
301
+ | `training-view-agent` | `set_custom_stock_prompt` | local dev only, requires `TV_AGENT_ENABLE_PROMPT_WRITE=1` |
302
+ | `training-view-agent` | `append_custom_stock_prompt` | local dev only, requires `TV_AGENT_ENABLE_PROMPT_WRITE=1` |
303
+ | `training-view-agent` | `reset_custom_stock_prompt` | local dev only, requires `TV_AGENT_ENABLE_PROMPT_WRITE=1` |
304
+ | `training-view-agent` | `apply_stock_prompt` | local dev only, requires `TV_AGENT_ENABLE_PROMPT_WRITE=1` |
305
+
306
+ ---
307
+
308
+ ## The Pine v6 skill
309
+
310
+ `skills/pinescript-v6/SKILL.md` is the **canonical source of truth** — edit it
311
+ there, and every agent's discovery point updates automatically.
312
+
313
+ What it supplies:
314
+
315
+ - Pine v6 language reference (`reference/v6-language.md`)
316
+ - Built-in namespaces cheat sheet (`reference/built-ins.md`)
317
+ - v5 -> v6 migration rules (`reference/v5-to-v6-migration.md`)
318
+ - Validation checklist
319
+ - Templates for indicators, strategies, and webhook-emitting strategies
320
+
321
+ ### One install, many agents
322
+
323
+ The project ships with `tools/install_skills.sh` (wrapped by
324
+ `make install-skills`) that wires the canonical skill into every supported
325
+ agent's convention:
326
+
327
+ | Agent / tool | Discovery path | Mechanism |
328
+ |---|---|---|
329
+ | **Claude Code** | `.claude/skills/pinescript-v6/SKILL.md` | symlink |
330
+ | **pi** | `.pi/agent/skills/pinescript-v6/SKILL.md` | symlink |
331
+ | **Cursor** | `.cursor/rules/pinescript-v6.mdc` | generated thin pointer (with `@`-include of SKILL.md) |
332
+ | **Codex CLI / OpenCode / Aider** | `AGENTS.md` (project root) | generated, includes link + project conventions |
333
+ | **Gemini CLI** | `GEMINI.md` (project root) | generated, same content |
334
+ | **Claude Code (user-global)** | `~/.claude/skills/pinescript-v6/` | symlink, opt-in via `make install-skills-global` |
335
+
336
+ First-time setup:
337
+
338
+ ```bash
339
+ make install-skills # project-local for all agents
340
+ make install-skills-global # also adds ~/.claude/skills/ symlink
341
+ make check-skills # verify everything is wired
342
+ ```
343
+
344
+ Update cycle (after editing the canonical skill):
345
+
346
+ ```bash
347
+ # 1. Edit the source
348
+ $EDITOR skills/pinescript-v6/SKILL.md
349
+ # 2. Refresh autogen files (symlinks were already live)
350
+ make update-skills
351
+ ```
352
+
353
+ Removal:
354
+
355
+ ```bash
356
+ make uninstall-skills # removes managed symlinks + autogen files
357
+ ```
358
+
359
+ ### How updates propagate
360
+
361
+ - **Symlinked locations** (`.claude/skills/`, `.pi/agent/skills/`, user-global):
362
+ changes to `skills/pinescript-v6/` are visible **instantly** — no command
363
+ needed. The next time the agent reads the skill, it sees the new content.
364
+ - **Generated files** (`.cursor/rules/*.mdc`, `AGENTS.md`, `GEMINI.md`):
365
+ these contain a static template that points at the canonical skill. They
366
+ rarely need to change after the first install. Run `make update-skills`
367
+ whenever you want to refresh them (e.g. after editing the script that
368
+ generates them or after a Pine skill rename).
369
+ - **Respect for hand edits**: if you remove the `<!-- AUTOGENERATED BY ... -->`
370
+ marker from `AGENTS.md`, `GEMINI.md`, or the `.mdc` file, the installer
371
+ treats it as user-owned and never overwrites it. To re-auto-generate, simply
372
+ delete the file and re-run `make update-skills`.
373
+
374
+ ---
375
+
376
+ ## Project conventions (parity with skin_type_regonize_model)
377
+
378
+ This project follows the same environment conventions as the
379
+ `skin_type_regonize_model` repo in this workspace:
380
+
381
+ - **Conda + Miniforge** for the Python env (no venv).
382
+ - `conda-env-active.sh <env-name>` -- create + activate + install deps. Sourced.
383
+ - `conda-env-deactive.sh <env-name>` -- deactivate + remove env. Sourced.
384
+ - `Makefile` with `.DEFAULT_GOAL := help`, sectioned by feature.
385
+ - All run commands flow through `conda run -n $(CONDA_ENV)` so users don't need to
386
+ pre-activate the env when using `make`.
387
+ - Python version pinned via `TV_PYTHON_VERSION` env (default `3.11`).
388
+
389
+ If you're already used to that repo, the workflow here is identical:
390
+ `make install`, `source conda-env-active.sh ENV`, etc.
391
+
392
+ ---
393
+
394
+ ## Caveats / risks
395
+
396
+ 1. **`tvdatafeed` violates TradingView's ToS** in letter. Enforcement against personal
397
+ use is rare but not zero. Use at your own risk; for production, use a real data
398
+ provider (Polygon, Alpaca, IBKR).
399
+ 2. **Session cookies expire** (~2 weeks). Re-export from your browser.
400
+ 3. **Pine Editor DOM changes** can break Playwright selectors. Fix them in
401
+ `src/tv_indicator/browser/selectors.py` -- one place.
402
+ 4. **No PineScript upload API.** Browser automation is the only path; it's slower and
403
+ more brittle than a real API would be.
404
+ 5. **Premium features** (multiple alerts, fast data, custom timeframes) need a paid
405
+ TradingView plan -- Indicator doesn't grant them.
406
+ 6. **Don't auto-publish indicators publicly.** Drafts and chart application are fine;
407
+ public publishing is a manual decision.
408
+
409
+ ---
410
+
411
+ ## Roadmap / not yet built
412
+
413
+ - [ ] Webhook receiver server (for Pro+ alert -> broker pipeline)
414
+ - [ ] Backtester that runs Pine-equivalent logic in Python (vectorbt) for offline iteration
415
+ - [ ] Auto-screenshot diff (compare before/after when editing an indicator)
416
+ - [ ] Alerts-config sync (set up alert rules via Playwright)
417
+ - [ ] Pine v6 LSP / proper syntax linter
418
+
419
+ PRs / suggestions welcome.
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env bash
2
+ # Create (if needed), activate a conda environment, and install project dependencies.
3
+ # Usage: source conda-env-active.sh <env-name>
4
+ #
5
+ # Must be sourced (not executed) so that `conda activate` affects the current shell.
6
+ _CONDA_ACTIVE_OLDOPTS=$(set +o) # snapshot current shell options
7
+ set -eo pipefail
8
+
9
+ # -------------------------------------------------------------------------
10
+ # 1. Parameter handling
11
+ # -------------------------------------------------------------------------
12
+ ENV_NAME="${1:-}"
13
+ if [[ -z "${ENV_NAME}" ]]; then
14
+ echo "ERROR: Environment name is required."
15
+ echo "Usage: source $0 <env-name>"
16
+ return 1 2>/dev/null || exit 1
17
+ fi
18
+
19
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
+ PYTHON_VERSION="${TV_PYTHON_VERSION:-3.11}"
21
+
22
+ # -------------------------------------------------------------------------
23
+ # 2. Prereq check
24
+ # -------------------------------------------------------------------------
25
+ if ! command -v conda &>/dev/null; then
26
+ echo "ERROR: conda not found. Install Miniforge / Miniconda first."
27
+ echo " Recommended (macOS): brew install miniforge"
28
+ echo " Or download from: https://github.com/conda-forge/miniforge"
29
+ return 1 2>/dev/null || exit 1
30
+ fi
31
+
32
+ # -------------------------------------------------------------------------
33
+ # 3. Create env if it doesn't exist
34
+ # -------------------------------------------------------------------------
35
+ if conda env list | awk '{print $1}' | grep -qx "${ENV_NAME}"; then
36
+ echo "Conda env '${ENV_NAME}' already exists. Skipping creation."
37
+ else
38
+ echo "Creating conda env '${ENV_NAME}' (python=${PYTHON_VERSION})..."
39
+ conda create -y -n "${ENV_NAME}" python="${PYTHON_VERSION}"
40
+ fi
41
+
42
+ # -------------------------------------------------------------------------
43
+ # 4. Activate
44
+ # -------------------------------------------------------------------------
45
+ eval "$(conda shell.bash hook 2>/dev/null)"
46
+ conda activate "${ENV_NAME}"
47
+ hash -r 2>/dev/null || true
48
+ echo "Activated conda env '${ENV_NAME}'."
49
+
50
+ # -------------------------------------------------------------------------
51
+ # 5. Install the project (editable) + optional extras
52
+ #
53
+ # SKIP_INSTALL=1 skip pip install entirely
54
+ # EXTRAS=... which extras to install (default: "data,dev")
55
+ # valid: data | dev | model | data,dev | all
56
+ # SKIP_PLAYWRIGHT=1 skip `playwright install chromium`
57
+ # -------------------------------------------------------------------------
58
+ EXTRAS="${EXTRAS:-data,dev}"
59
+
60
+ if [[ "${SKIP_INSTALL:-0}" != "1" ]]; then
61
+ echo "Installing tv-indicator (editable) with extras '[${EXTRAS}]'..."
62
+ python -m pip install --upgrade pip >/dev/null
63
+ python -m pip install -e "${SCRIPT_DIR}[${EXTRAS}]"
64
+ else
65
+ echo "SKIP_INSTALL=1 set — skipping pip install."
66
+ fi
67
+
68
+ if [[ "${SKIP_PLAYWRIGHT:-0}" != "1" ]]; then
69
+ if python -c "import playwright" &>/dev/null; then
70
+ echo "Installing Playwright Chromium browser (if missing)..."
71
+ python -m playwright install chromium
72
+ else
73
+ echo "WARNING: playwright not installed yet — skipping browser download."
74
+ fi
75
+ else
76
+ echo "SKIP_PLAYWRIGHT=1 set — skipping browser download."
77
+ fi
78
+
79
+ # -------------------------------------------------------------------------
80
+ # 6. Summary
81
+ # -------------------------------------------------------------------------
82
+ PYTHON_VER="$(python --version 2>&1)"
83
+ PKG_COUNT="$(python -m pip list --format=columns 2>/dev/null | tail -n +3 | wc -l | tr -d ' ')"
84
+
85
+ echo ""
86
+ echo "=== Environment Ready ==="
87
+ echo " Env name: ${ENV_NAME}"
88
+ echo " Python: ${PYTHON_VER}"
89
+ echo " Packages: ${PKG_COUNT} installed"
90
+ echo ""
91
+ echo "Try:"
92
+ echo " training-view status"
93
+ echo " training-view data ohlcv NASDAQ:AAPL --bars 50"
94
+ echo ""
95
+
96
+ # Restore original shell options so set -e doesn't leak into interactive shell
97
+ eval "${_CONDA_ACTIVE_OLDOPTS}"
98
+ unset _CONDA_ACTIVE_OLDOPTS
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env bash
2
+ # Deactivate and remove a conda environment.
3
+ # Usage: source conda-env-deactive.sh <env-name>
4
+ #
5
+ # Must be sourced (not executed) so that `conda deactivate` affects the current shell.
6
+ _CONDA_DEACT_OLDOPTS=$(set +o) # snapshot current shell options
7
+ set -eo pipefail
8
+
9
+ # -------------------------------------------------------------------------
10
+ # 1. Parameter handling
11
+ # -------------------------------------------------------------------------
12
+ ENV_NAME="${1:-}"
13
+ if [[ -z "${ENV_NAME}" ]]; then
14
+ echo "ERROR: Environment name is required."
15
+ echo "Usage: source $0 <env-name>"
16
+ return 1 2>/dev/null || exit 1
17
+ fi
18
+
19
+ # -------------------------------------------------------------------------
20
+ # 2. Deactivate if currently active
21
+ # -------------------------------------------------------------------------
22
+ eval "$(conda shell.bash hook 2>/dev/null)"
23
+
24
+ if [[ "${CONDA_DEFAULT_ENV:-}" == "${ENV_NAME}" ]]; then
25
+ echo "Deactivating conda env '${ENV_NAME}'..."
26
+ conda deactivate
27
+ fi
28
+
29
+ # -------------------------------------------------------------------------
30
+ # 3. Remove environment
31
+ # -------------------------------------------------------------------------
32
+ if conda env list | awk '{print $1}' | grep -qx "${ENV_NAME}"; then
33
+ echo "Removing conda env '${ENV_NAME}'..."
34
+ conda env remove -y -n "${ENV_NAME}"
35
+ echo "Conda env '${ENV_NAME}' has been removed."
36
+ else
37
+ echo "WARNING: Conda env '${ENV_NAME}' does not exist. Nothing to remove."
38
+ fi
39
+
40
+ # Restore original shell options
41
+ eval "${_CONDA_DEACT_OLDOPTS}"
42
+ unset _CONDA_DEACT_OLDOPTS