@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.
- package/README.md +2 -7
- package/package.json +4 -1
- package/project/.cursor/rules/agent-docs.mdc +16 -0
- package/project/.cursor/rules/api-credential-storage.mdc +16 -0
- package/project/.cursor/rules/pinescript-v6.mdc +16 -0
- package/project/.cursor/rules/stock-model-forecast.mdc +16 -0
- package/project/.cursor/rules/system-prompt-injection.mdc +16 -0
- package/project/.cursor/rules/system-prompt-updater.mdc +16 -0
- package/project/.cursor/rules/tradingview-stock-data.mdc +16 -0
- package/project/.env.example +44 -0
- package/project/.npm-packaged-project +1 -0
- package/project/.pi/APPEND_SYSTEM.md +338 -0
- package/project/.pi/settings.json +8 -0
- package/project/AGENTS.md +538 -0
- package/project/CLAUDE.md +538 -0
- package/project/GEMINI.md +538 -0
- package/project/Makefile +488 -0
- package/project/README.md +419 -0
- package/project/conda-env-active.sh +98 -0
- package/project/conda-env-deactive.sh +42 -0
- package/project/docs/agent-install.md +446 -0
- package/project/docs/agent-skill-directory.md +222 -0
- package/project/docs/integration.html +271 -0
- package/project/packages/indicator/README.md +39 -0
- package/project/packages/indicator/package.json +40 -0
- package/project/packages/indicator/scripts/build-project-snapshot.js +57 -0
- package/project/packages/indicator/src/cli.js +368 -0
- package/project/packages/tradingview-stock-data-skill/README.md +112 -0
- package/project/packages/tradingview-stock-data-skill/extensions/stock-prompt-injector.ts +121 -0
- package/project/packages/tradingview-stock-data-skill/package.json +35 -0
- package/project/packages/tradingview-stock-data-skill/scripts/postinstall.sh +73 -0
- package/project/packages/tradingview-stock-data-skill/skills/tradingview-stock-data/SKILL.md +241 -0
- package/project/pyproject.toml +68 -0
- package/project/screenshots/.gitkeep +0 -0
- package/project/scripts/indicators/example_rsi_bands.pine +27 -0
- package/project/scripts/indicators/tsla_levels.pine +57 -0
- package/project/skills/agent-docs/SKILL.md +56 -0
- package/project/skills/api-credential-storage/SKILL.md +83 -0
- package/project/skills/api-credential-storage/scripts/upsert_env.py +151 -0
- package/project/skills/pinescript-v6/SKILL.md +129 -0
- package/project/skills/pinescript-v6/reference/built-ins.md +219 -0
- package/project/skills/pinescript-v6/reference/templates/alert-webhook.pine +76 -0
- package/project/skills/pinescript-v6/reference/templates/indicator.pine +48 -0
- package/project/skills/pinescript-v6/reference/templates/strategy.pine +50 -0
- package/project/skills/pinescript-v6/reference/v5-to-v6-migration.md +102 -0
- package/project/skills/pinescript-v6/reference/v6-language.md +202 -0
- package/project/skills/stock-model-forecast/SKILL.md +192 -0
- package/project/skills/system-prompt-injection/CUSTOM_SYSTEM_PROMPT.md +333 -0
- package/project/skills/system-prompt-injection/DEFAULT_SYSTEM_PROMPT.md +327 -0
- package/project/skills/system-prompt-injection/SKILL.md +90 -0
- package/project/skills/system-prompt-injection/SYSTEM_PROMPT.md +23 -0
- package/project/skills/system-prompt-updater/SKILL.md +82 -0
- package/project/skills/system-prompt-updater/scripts/system_prompt_update.sh +106 -0
- package/project/skills/tradingview-stock-data/SKILL.md +272 -0
- package/project/src/tv_indicator/__init__.py +0 -0
- package/project/src/tv_indicator/browser/__init__.py +0 -0
- package/project/src/tv_indicator/browser/automation.py +541 -0
- package/project/src/tv_indicator/browser/selectors.py +70 -0
- package/project/src/tv_indicator/cli/__init__.py +0 -0
- package/project/src/tv_indicator/cli/browser_cmds.py +92 -0
- package/project/src/tv_indicator/cli/data_cmds.py +178 -0
- package/project/src/tv_indicator/cli/main.py +56 -0
- package/project/src/tv_indicator/cli/model_cmds.py +255 -0
- package/project/src/tv_indicator/cli/pine_cmds.py +140 -0
- package/project/src/tv_indicator/config.py +98 -0
- package/project/src/tv_indicator/data/__init__.py +0 -0
- package/project/src/tv_indicator/data/client.py +187 -0
- package/project/src/tv_indicator/data/screener.py +268 -0
- package/project/src/tv_indicator/mcp/__init__.py +0 -0
- package/project/src/tv_indicator/mcp/agent_server.py +398 -0
- package/project/src/tv_indicator/mcp/browser_server.py +133 -0
- package/project/src/tv_indicator/mcp/data_server.py +239 -0
- package/project/src/tv_indicator/model/__init__.py +19 -0
- package/project/src/tv_indicator/model/forecast.py +693 -0
- package/project/tools/import_agent_tools.sh +503 -0
- package/project/tools/install_skills.sh +673 -0
- package/project/tools/interactive_install.sh +917 -0
- package/project/tools/progress.sh +114 -0
- package/project/tools/uninstall_agent_tools.sh +373 -0
- package/src/cli.js +22 -25
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"""MCP server: TradingView data and server-side model forecasts.
|
|
2
|
+
|
|
3
|
+
Exposes the same functions as `training-view data ...` and
|
|
4
|
+
`training-view model forecast ...` so any MCP-aware agent can call them.
|
|
5
|
+
|
|
6
|
+
Register in claude_desktop_config.json:
|
|
7
|
+
{
|
|
8
|
+
"mcpServers": {
|
|
9
|
+
"training-view-data": {
|
|
10
|
+
"command": "training-view-mcp-data",
|
|
11
|
+
"env": { "TV_SESSIONID": "..." }
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
"""
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import asyncio
|
|
19
|
+
import json
|
|
20
|
+
from typing import Any
|
|
21
|
+
|
|
22
|
+
from mcp.server import Server
|
|
23
|
+
from mcp.server.stdio import stdio_server
|
|
24
|
+
from mcp.types import TextContent, Tool
|
|
25
|
+
|
|
26
|
+
server = Server("training-view-data")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# ─── Tool definitions ──────────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@server.list_tools()
|
|
33
|
+
async def list_tools() -> list[Tool]:
|
|
34
|
+
return [
|
|
35
|
+
Tool(
|
|
36
|
+
name="get_ohlcv",
|
|
37
|
+
description=(
|
|
38
|
+
"Fetch OHLCV candles for a TradingView symbol. "
|
|
39
|
+
"Returns JSON with `index` (timestamps) and column arrays."
|
|
40
|
+
),
|
|
41
|
+
inputSchema={
|
|
42
|
+
"type": "object",
|
|
43
|
+
"properties": {
|
|
44
|
+
"symbol": {"type": "string", "description": "e.g. 'NASDAQ:AAPL' or 'AAPL'"},
|
|
45
|
+
"interval": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"enum": ["1", "3", "5", "15", "30", "45", "60", "120", "180", "240", "1D", "1W", "1M"],
|
|
48
|
+
"default": "1D",
|
|
49
|
+
},
|
|
50
|
+
"n_bars": {"type": "integer", "default": 500, "minimum": 1, "maximum": 5000},
|
|
51
|
+
"exchange": {"type": "string", "description": "Optional if not in symbol"},
|
|
52
|
+
"extended_session": {"type": "boolean", "default": False},
|
|
53
|
+
},
|
|
54
|
+
"required": ["symbol"],
|
|
55
|
+
},
|
|
56
|
+
),
|
|
57
|
+
Tool(
|
|
58
|
+
name="search_symbol",
|
|
59
|
+
description="Search TradingView symbols by ticker or company name.",
|
|
60
|
+
inputSchema={
|
|
61
|
+
"type": "object",
|
|
62
|
+
"properties": {
|
|
63
|
+
"query": {"type": "string"},
|
|
64
|
+
"limit": {"type": "integer", "default": 20, "minimum": 1, "maximum": 100},
|
|
65
|
+
},
|
|
66
|
+
"required": ["query"],
|
|
67
|
+
},
|
|
68
|
+
),
|
|
69
|
+
Tool(
|
|
70
|
+
name="screener",
|
|
71
|
+
description=(
|
|
72
|
+
"Run a TradingView screener query. Filters are tuples of (column, op, value). "
|
|
73
|
+
"Ops: >, <, >=, <=, =, !="
|
|
74
|
+
),
|
|
75
|
+
inputSchema={
|
|
76
|
+
"type": "object",
|
|
77
|
+
"properties": {
|
|
78
|
+
"market": {"type": "string", "default": "america"},
|
|
79
|
+
"columns": {"type": "array", "items": {"type": "string"}},
|
|
80
|
+
"filters": {
|
|
81
|
+
"type": "array",
|
|
82
|
+
"items": {
|
|
83
|
+
"type": "array",
|
|
84
|
+
"prefixItems": [
|
|
85
|
+
{"type": "string"},
|
|
86
|
+
{"type": "string"},
|
|
87
|
+
{},
|
|
88
|
+
],
|
|
89
|
+
"minItems": 3,
|
|
90
|
+
"maxItems": 3,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
"order_by": {
|
|
94
|
+
"type": "array",
|
|
95
|
+
"prefixItems": [{"type": "string"}, {"type": "boolean"}],
|
|
96
|
+
"minItems": 2,
|
|
97
|
+
"maxItems": 2,
|
|
98
|
+
},
|
|
99
|
+
"limit": {"type": "integer", "default": 50},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
),
|
|
103
|
+
Tool(
|
|
104
|
+
name="technical_rating",
|
|
105
|
+
description="Get TradingView's Strong Buy/Buy/Neutral/Sell/Strong Sell rating for a symbol.",
|
|
106
|
+
inputSchema={
|
|
107
|
+
"type": "object",
|
|
108
|
+
"properties": {
|
|
109
|
+
"symbol": {"type": "string"},
|
|
110
|
+
"interval": {"type": "string", "default": "1D"},
|
|
111
|
+
},
|
|
112
|
+
"required": ["symbol"],
|
|
113
|
+
},
|
|
114
|
+
),
|
|
115
|
+
Tool(
|
|
116
|
+
name="model_forecast",
|
|
117
|
+
description="Fetch the server-side xs_range 20-trading-day forecast for a stock/ETF/index symbol.",
|
|
118
|
+
inputSchema={
|
|
119
|
+
"type": "object",
|
|
120
|
+
"properties": {
|
|
121
|
+
"symbol": {"type": "string", "description": "e.g. 'NASDAQ:TSLA' or 'TSLA'"},
|
|
122
|
+
"refresh": {"type": "boolean", "default": False},
|
|
123
|
+
"period": {"type": "string", "default": "10y"},
|
|
124
|
+
},
|
|
125
|
+
"required": ["symbol"],
|
|
126
|
+
},
|
|
127
|
+
),
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# ─── Tool dispatch ─────────────────────────────────────────────────────────
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@server.call_tool()
|
|
135
|
+
async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
|
|
136
|
+
if name == "get_ohlcv":
|
|
137
|
+
return await _get_ohlcv(arguments)
|
|
138
|
+
if name == "search_symbol":
|
|
139
|
+
return await _search_symbol(arguments)
|
|
140
|
+
if name == "screener":
|
|
141
|
+
return await _screener(arguments)
|
|
142
|
+
if name == "technical_rating":
|
|
143
|
+
return await _technical_rating(arguments)
|
|
144
|
+
if name == "model_forecast":
|
|
145
|
+
return await _model_forecast(arguments)
|
|
146
|
+
return [TextContent(type="text", text=f"Unknown tool: {name}")]
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
async def _get_ohlcv(args: dict[str, Any]) -> list[TextContent]:
|
|
150
|
+
from ..data.client import get_ohlcv
|
|
151
|
+
|
|
152
|
+
df = await asyncio.to_thread(
|
|
153
|
+
get_ohlcv,
|
|
154
|
+
args["symbol"],
|
|
155
|
+
args.get("interval", "1D"),
|
|
156
|
+
args.get("n_bars", 500),
|
|
157
|
+
args.get("exchange"),
|
|
158
|
+
args.get("extended_session", False),
|
|
159
|
+
)
|
|
160
|
+
payload = {
|
|
161
|
+
"symbol": args["symbol"],
|
|
162
|
+
"interval": args.get("interval", "1D"),
|
|
163
|
+
"rows": len(df),
|
|
164
|
+
"index": [str(i) for i in df.index],
|
|
165
|
+
"columns": {c: df[c].tolist() for c in df.columns},
|
|
166
|
+
}
|
|
167
|
+
return [TextContent(type="text", text=json.dumps(payload, default=str))]
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
async def _search_symbol(args: dict[str, Any]) -> list[TextContent]:
|
|
171
|
+
from ..data.screener import search_symbol
|
|
172
|
+
|
|
173
|
+
results = await asyncio.to_thread(
|
|
174
|
+
search_symbol, args["query"], args.get("limit", 20)
|
|
175
|
+
)
|
|
176
|
+
return [TextContent(type="text", text=json.dumps(results, default=str))]
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
async def _screener(args: dict[str, Any]) -> list[TextContent]:
|
|
180
|
+
from ..data.screener import screener
|
|
181
|
+
|
|
182
|
+
filters_raw = args.get("filters") or []
|
|
183
|
+
filters = [(f[0], f[1], f[2]) for f in filters_raw]
|
|
184
|
+
order_by_raw = args.get("order_by")
|
|
185
|
+
order_by = (order_by_raw[0], bool(order_by_raw[1])) if order_by_raw else None
|
|
186
|
+
|
|
187
|
+
df = await asyncio.to_thread(
|
|
188
|
+
screener,
|
|
189
|
+
args.get("market", "america"),
|
|
190
|
+
args.get("columns"),
|
|
191
|
+
filters or None,
|
|
192
|
+
order_by,
|
|
193
|
+
args.get("limit", 50),
|
|
194
|
+
)
|
|
195
|
+
payload = {
|
|
196
|
+
"rows": len(df),
|
|
197
|
+
"columns": list(df.columns),
|
|
198
|
+
"data": df.to_dict(orient="records"),
|
|
199
|
+
}
|
|
200
|
+
return [TextContent(type="text", text=json.dumps(payload, default=str))]
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
async def _technical_rating(args: dict[str, Any]) -> list[TextContent]:
|
|
204
|
+
from ..data.screener import technical_rating
|
|
205
|
+
|
|
206
|
+
r = await asyncio.to_thread(
|
|
207
|
+
technical_rating, args["symbol"], args.get("interval", "1D")
|
|
208
|
+
)
|
|
209
|
+
return [TextContent(type="text", text=json.dumps(r, default=str))]
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
async def _model_forecast(args: dict[str, Any]) -> list[TextContent]:
|
|
213
|
+
from ..model.forecast import forecast_for_symbol
|
|
214
|
+
|
|
215
|
+
payload = await asyncio.to_thread(
|
|
216
|
+
forecast_for_symbol,
|
|
217
|
+
args["symbol"],
|
|
218
|
+
refresh=bool(args.get("refresh", False)),
|
|
219
|
+
period=args.get("period", "10y"),
|
|
220
|
+
)
|
|
221
|
+
return [TextContent(type="text", text=json.dumps(payload, default=str))]
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
# ─── Entry point ───────────────────────────────────────────────────────────
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
async def _run() -> None:
|
|
228
|
+
async with stdio_server() as (read_stream, write_stream):
|
|
229
|
+
await server.run(
|
|
230
|
+
read_stream, write_stream, server.create_initialization_options()
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def main() -> None:
|
|
235
|
+
asyncio.run(_run())
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
if __name__ == "__main__":
|
|
239
|
+
main()
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Server-side stock-forecast model API helpers."""
|
|
2
|
+
|
|
3
|
+
from .forecast import (
|
|
4
|
+
DEFAULT_MODEL_ROOT,
|
|
5
|
+
DEFAULT_MODEL_REPO,
|
|
6
|
+
MODEL_UNIVERSE,
|
|
7
|
+
forecast_for_symbol,
|
|
8
|
+
model_status,
|
|
9
|
+
setup_model_env,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"DEFAULT_MODEL_ROOT",
|
|
14
|
+
"DEFAULT_MODEL_REPO",
|
|
15
|
+
"MODEL_UNIVERSE",
|
|
16
|
+
"forecast_for_symbol",
|
|
17
|
+
"model_status",
|
|
18
|
+
"setup_model_env",
|
|
19
|
+
]
|