tradingview-mcp 26.0.0__py3-none-any.whl → 26.3.0__py3-none-any.whl

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.
@@ -3,9 +3,11 @@ Constants for TradingView Screener integration.
3
3
 
4
4
  Contains API URLs, headers, supported markets, and column definitions.
5
5
  """
6
-
7
6
  from __future__ import annotations
8
7
 
8
+ import json
9
+ from pathlib import Path
10
+
9
11
  # API Configuration
10
12
  URL = "https://scanner.tradingview.com/{market}/scan"
11
13
 
@@ -30,129 +32,107 @@ HEADERS = {
30
32
 
31
33
  DEFAULT_RANGE = [0, 50]
32
34
 
33
- # Supported Markets (76 total)
34
- MARKETS = {
35
- # Financial Instruments
36
- "bonds",
37
- "cfd",
38
- "coin",
39
- "crypto",
40
- "economics2",
41
- "forex",
42
- "futures",
43
- "options",
44
- # Countries (67)
45
- "america",
46
- "argentina",
47
- "australia",
48
- "austria",
49
- "bahrain",
50
- "bangladesh",
51
- "belgium",
52
- "brazil",
53
- "canada",
54
- "chile",
55
- "china",
56
- "colombia",
57
- "cyprus",
58
- "czech",
59
- "denmark",
60
- "egypt",
61
- "estonia",
62
- "finland",
63
- "france",
64
- "germany",
65
- "greece",
66
- "hongkong",
67
- "hungary",
68
- "iceland",
69
- "india",
70
- "indonesia",
71
- "israel",
72
- "italy",
73
- "japan",
74
- "kenya",
75
- "korea",
76
- "ksa",
77
- "kuwait",
78
- "latvia",
79
- "lithuania",
80
- "luxembourg",
81
- "malaysia",
82
- "mexico",
83
- "morocco",
84
- "netherlands",
85
- "newzealand",
86
- "nigeria",
87
- "norway",
88
- "pakistan",
89
- "peru",
90
- "philippines",
91
- "poland",
92
- "portugal",
93
- "qatar",
94
- "romania",
95
- "rsa",
96
- "russia",
97
- "serbia",
98
- "singapore",
99
- "slovakia",
100
- "spain",
101
- "srilanka",
102
- "sweden",
103
- "switzerland",
104
- "taiwan",
105
- "thailand",
106
- "tunisia",
107
- "turkey",
108
- "uae",
109
- "uk",
110
- "venezuela",
111
- "vietnam",
112
- }
113
-
114
- # Exchange to Screener Mapping
35
+ # =============================================================================
36
+ # Load Data from JSON (Dynamic)
37
+ # =============================================================================
38
+
39
+ _DATA_DIR = Path(__file__).parent / "data"
40
+
41
+ def _load_markets() -> set[str]:
42
+ """Load supported markets from JSON."""
43
+ try:
44
+ with open(_DATA_DIR / "markets.json", "r", encoding="utf-8") as f:
45
+ data = json.load(f)
46
+ return set(data.get("countries", []) + data.get("other", []))
47
+ except Exception:
48
+ # Fallback if file not found (dev/test env)
49
+ return {"america", "crypto", "forex"}
50
+
51
+ def _load_columns() -> dict[str, str]:
52
+ """
53
+ Load column definitions from JSON.
54
+ Returns: Dict[Display Name, Field Name] (Reverse of JSON)
55
+ """
56
+ try:
57
+ with open(_DATA_DIR / "column_display_names.json", "r", encoding="utf-8") as f:
58
+ data = json.load(f)
59
+ fields = data.get("fields", {})
60
+ # Reverse mapping: Display Name -> Field Name
61
+ # e.g. "Relative Strength Index (14)" -> "RSI"
62
+ return {v: k for k, v in fields.items()}
63
+ except Exception:
64
+ return {}
65
+
66
+ # Public Constants
67
+ MARKETS = _load_markets()
68
+ COLUMNS = _load_columns()
69
+
70
+ # Exchange to Screener Mapping (Expanded)
115
71
  EXCHANGE_SCREENER = {
116
- # Crypto Exchanges
72
+ # Crypto
117
73
  "all": "crypto",
118
- "huobi": "crypto",
119
- "kucoin": "crypto",
120
- "coinbase": "crypto",
121
- "gateio": "crypto",
122
74
  "binance": "crypto",
123
- "bitfinex": "crypto",
124
- "bitget": "crypto",
125
- "bybit": "crypto",
126
- "okx": "crypto",
75
+ "coinbase": "crypto",
127
76
  "kraken": "crypto",
77
+ "kucoin": "crypto",
78
+ "bitfinex": "crypto",
128
79
  "bitstamp": "crypto",
80
+ "okx": "crypto",
81
+ "bybit": "crypto",
82
+ "gateio": "crypto",
83
+ "huobi": "crypto",
129
84
  "gemini": "crypto",
130
85
  "poloniex": "crypto",
131
- # Stock Exchanges
132
- "bist": "turkey",
86
+ "bittrex": "crypto",
87
+ "bitmex": "crypto",
88
+ "deribit": "crypto",
89
+ "mexc": "crypto",
90
+ "bingx": "crypto",
91
+ "phemex": "crypto",
92
+ "bitget": "crypto",
93
+ # Forex
94
+ "fx": "forex",
95
+ "fx_idc": "forex",
96
+ "oanda": "forex",
97
+ "forex": "forex",
98
+ "ice": "forex", # Often forex/futures
99
+ "saxo": "forex",
100
+ "cityindex": "forex",
101
+ # Futures
102
+ "cme": "futures",
103
+ "cbot": "futures",
104
+ "comex": "futures",
105
+ "nymex": "futures",
106
+ "eurex": "futures",
107
+ # US Stocks
133
108
  "nasdaq": "america",
134
109
  "nyse": "america",
135
110
  "amex": "america",
136
- # Malaysia
137
- "bursa": "malaysia",
138
- "myx": "malaysia",
139
- "klse": "malaysia",
140
- "ace": "malaysia",
141
- "leap": "malaysia",
142
- # Hong Kong
111
+ "arca": "america",
112
+ "otc": "america",
113
+ # Global Stocks
114
+ "lse": "uk", # London
115
+ "tsx": "canada", # Toronto
116
+ "asx": "australia",
117
+ "sse": "china", # Shanghai
118
+ "szse": "china", # Shenzhen
143
119
  "hkex": "hongkong",
144
120
  "hk": "hongkong",
145
- "hsi": "hongkong",
146
- # Others
147
- "lse": "uk",
148
- "tsx": "canada",
149
- "asx": "australia",
121
+ "tse": "japan", # Tokyo
122
+ "tyo": "japan",
123
+ "ebs": "switzerland", # Swiss SIX
124
+ "six": "switzerland",
125
+ "xetra": "germany",
126
+ "fwb": "germany",
127
+ "euronext": "france", # Generic Euronext
150
128
  "nse": "india",
151
129
  "bse": "india",
152
- "sse": "china",
153
- "szse": "china",
154
- "tse": "japan",
155
130
  "krx": "korea",
131
+ "kosdaq": "korea",
132
+ "b3": "brazil",
133
+ "moex": "russia",
134
+ "sgx": "singapore",
135
+ "twse": "taiwan",
156
136
  }
157
137
 
158
138
  # Allowed Timeframes
@@ -172,226 +152,6 @@ TIMEFRAME_MAP = {
172
152
  "1M": "1M",
173
153
  }
174
154
 
175
- # Column Definitions - Human readable names to API column names
176
- COLUMNS = {
177
- # Technical Indicators
178
- "Average Day Range (14)": "ADR",
179
- "Average Directional Index (14)": "ADX",
180
- "Positive Directional Indicator (14)": "ADX+DI",
181
- "Negative Directional Indicator (14)": "ADX-DI",
182
- "Awesome Oscillator": "AO",
183
- "Average True Range (14)": "ATR",
184
- "Aroon Down (14)": "Aroon.Down",
185
- "Aroon Up (14)": "Aroon.Up",
186
- "Bollinger Lower Band (20)": "BB.lower",
187
- "Bollinger Upper Band (20)": "BB.upper",
188
- "Bull Bear Power": "BBPower",
189
- "Commodity Channel Index (20)": "CCI20",
190
- "Chaikin Money Flow (20)": "ChaikinMoneyFlow",
191
- "Donchian Channels Lower Band (20)": "DonchCh20.Lower",
192
- "Donchian Channels Upper Band (20)": "DonchCh20.Upper",
193
- # EMAs
194
- "Exponential Moving Average (5)": "EMA5",
195
- "Exponential Moving Average (10)": "EMA10",
196
- "Exponential Moving Average (20)": "EMA20",
197
- "Exponential Moving Average (30)": "EMA30",
198
- "Exponential Moving Average (50)": "EMA50",
199
- "Exponential Moving Average (100)": "EMA100",
200
- "Exponential Moving Average (200)": "EMA200",
201
- # Highs/Lows
202
- "1-Month High": "High.1M",
203
- "3-Month High": "High.3M",
204
- "6-Month High": "High.6M",
205
- "All Time High": "High.All",
206
- "1-Month Low": "Low.1M",
207
- "3-Month Low": "Low.3M",
208
- "6-Month Low": "Low.6M",
209
- "All Time Low": "Low.All",
210
- # Hull MA
211
- "Hull Moving Average (9)": "HullMA9",
212
- # Ichimoku
213
- "Ichimoku Base Line (9, 26, 52, 26)": "Ichimoku.BLine",
214
- "Ichimoku Conversion Line (9, 26, 52, 26)": "Ichimoku.CLine",
215
- "Ichimoku Leading Span A (9, 26, 52, 26)": "Ichimoku.Lead1",
216
- "Ichimoku Leading Span B (9, 26, 52, 26)": "Ichimoku.Lead2",
217
- # Keltner Channels
218
- "Keltner Channels Lower Band (20)": "KltChnl.lower",
219
- "Keltner Channels Upper Band (20)": "KltChnl.upper",
220
- # MACD
221
- "MACD Level (12, 26)": "MACD.macd",
222
- "MACD Signal (12, 26)": "MACD.signal",
223
- # Other Indicators
224
- "Momentum (10)": "Mom",
225
- "Money Flow (14)": "MoneyFlow",
226
- "Parabolic SAR": "P.SAR",
227
- # Performance
228
- "Monthly Performance": "Perf.1M",
229
- "3-Month Performance": "Perf.3M",
230
- "5Y Performance": "Perf.5Y",
231
- "6-Month Performance": "Perf.6M",
232
- "All Time Performance": "Perf.All",
233
- "Weekly Performance": "Perf.W",
234
- "Yearly Performance": "Perf.Y",
235
- "YTD Performance": "Perf.YTD",
236
- # Pivot Points (Classic)
237
- "Pivot Classic P": "Pivot.M.Classic.Middle",
238
- "Pivot Classic R1": "Pivot.M.Classic.R1",
239
- "Pivot Classic R2": "Pivot.M.Classic.R2",
240
- "Pivot Classic R3": "Pivot.M.Classic.R3",
241
- "Pivot Classic S1": "Pivot.M.Classic.S1",
242
- "Pivot Classic S2": "Pivot.M.Classic.S2",
243
- "Pivot Classic S3": "Pivot.M.Classic.S3",
244
- # Pivot Points (Fibonacci)
245
- "Pivot Fibonacci P": "Pivot.M.Fibonacci.Middle",
246
- "Pivot Fibonacci R1": "Pivot.M.Fibonacci.R1",
247
- "Pivot Fibonacci R2": "Pivot.M.Fibonacci.R2",
248
- "Pivot Fibonacci R3": "Pivot.M.Fibonacci.R3",
249
- "Pivot Fibonacci S1": "Pivot.M.Fibonacci.S1",
250
- "Pivot Fibonacci S2": "Pivot.M.Fibonacci.S2",
251
- "Pivot Fibonacci S3": "Pivot.M.Fibonacci.S3",
252
- # Rate of Change
253
- "Rate Of Change (9)": "ROC",
254
- # RSI
255
- "Relative Strength Index (14)": "RSI",
256
- "Relative Strength Index (7)": "RSI7",
257
- # Recommendations
258
- "Technical Rating": "Recommend.All",
259
- "Moving Averages Rating": "Recommend.MA",
260
- "Oscillators Rating": "Recommend.Other",
261
- # SMAs
262
- "Simple Moving Average (5)": "SMA5",
263
- "Simple Moving Average (10)": "SMA10",
264
- "Simple Moving Average (20)": "SMA20",
265
- "Simple Moving Average (30)": "SMA30",
266
- "Simple Moving Average (50)": "SMA50",
267
- "Simple Moving Average (100)": "SMA100",
268
- "Simple Moving Average (200)": "SMA200",
269
- # Stochastic
270
- "Stochastic %D (14, 3, 3)": "Stoch.D",
271
- "Stochastic %K (14, 3, 3)": "Stoch.K",
272
- "Stochastic RSI Slow (3, 3, 14, 14)": "Stoch.RSI.D",
273
- "Stochastic RSI Fast (3, 3, 14, 14)": "Stoch.RSI.K",
274
- # Other
275
- "Ultimate Oscillator (7, 14, 28)": "UO",
276
- "Volume Weighted Average Price": "VWAP",
277
- "Volume Weighted Moving Average (20)": "VWMA",
278
- "Volume*Price": "Value.Traded",
279
- "Volatility": "Volatility.D",
280
- "Volatility Month": "Volatility.M",
281
- "Volatility Week": "Volatility.W",
282
- "Williams Percent Range (14)": "W.R",
283
- # Fundamentals
284
- "Net Margin (TTM)": "after_tax_margin",
285
- "Average Volume (10 day)": "average_volume_10d_calc",
286
- "Average Volume (30 day)": "average_volume_30d_calc",
287
- "Average Volume (60 day)": "average_volume_60d_calc",
288
- "Average Volume (90 day)": "average_volume_90d_calc",
289
- "Basic EPS (FY)": "basic_eps_net_income",
290
- "1-Year Beta": "beta_1_year",
291
- "Cash & Equivalents (MRQ)": "cash_n_equivalents_fq",
292
- "Cash & Equivalents (FY)": "cash_n_equivalents_fy",
293
- # Price/Change
294
- "Change %": "change",
295
- "Change": "change_abs",
296
- "Change from Open %": "change_from_open",
297
- "Change from Open": "change_from_open_abs",
298
- "Price": "close",
299
- "Country": "country",
300
- "Currency": "currency",
301
- # Debt
302
- "Current Ratio (MRQ)": "current_ratio",
303
- "Debt to Equity Ratio (MRQ)": "debt_to_equity",
304
- # Dividends
305
- "Dividend Yield Forward": "dividend_yield_recent",
306
- "Dividends Paid (FY)": "dividends_paid",
307
- "Dividends per Share (MRQ)": "dividends_per_share_fq",
308
- # EPS
309
- "Basic EPS (TTM)": "earnings_per_share_basic_ttm",
310
- "EPS Diluted (TTM)": "earnings_per_share_diluted_ttm",
311
- "EPS Forecast (MRQ)": "earnings_per_share_forecast_next_fq",
312
- "EPS Diluted (MRQ)": "earnings_per_share_fq",
313
- # Earnings
314
- "Recent Earnings Date": "earnings_release_date",
315
- "Upcoming Earnings Date": "earnings_release_next_date",
316
- "EBITDA (TTM)": "ebitda",
317
- # Enterprise Value
318
- "Enterprise Value/EBITDA (TTM)": "enterprise_value_ebitda_ttm",
319
- "Enterprise Value (MRQ)": "enterprise_value_fq",
320
- # Basic Info
321
- "Exchange": "exchange",
322
- "Shares Float": "float_shares_outstanding",
323
- # Gap
324
- "Gap %": "gap",
325
- # Margins
326
- "Gross Margin (TTM)": "gross_margin",
327
- "Gross Profit (FY)": "gross_profit",
328
- # OHLCV
329
- "High": "high",
330
- "Low": "low",
331
- "Open": "open",
332
- "Volume": "volume",
333
- # Identification
334
- "Industry": "industry",
335
- "Sector": "sector",
336
- "Market": "market",
337
- "Name": "name",
338
- "Description": "description",
339
- "Type": "type",
340
- # Market Cap
341
- "Market Capitalization": "market_cap_basic",
342
- # Net Income
343
- "Net Debt (MRQ)": "net_debt",
344
- "Net Income (FY)": "net_income",
345
- # P/E Ratios
346
- "Price to Earnings Ratio (TTM)": "price_earnings_ttm",
347
- "Price to Book (MRQ)": "price_book_fq",
348
- "Price to Sales (FY)": "price_sales_ratio",
349
- "Price to Free Cash Flow (TTM)": "price_free_cash_flow_ttm",
350
- # 52 Week
351
- "52 Week High": "price_52_week_high",
352
- "52 Week Low": "price_52_week_low",
353
- # Pre/Post Market
354
- "Pre-market Change %": "premarket_change",
355
- "Pre-market Change": "premarket_change_abs",
356
- "Pre-market Close": "premarket_close",
357
- "Pre-market High": "premarket_high",
358
- "Pre-market Low": "premarket_low",
359
- "Pre-market Open": "premarket_open",
360
- "Pre-market Volume": "premarket_volume",
361
- "Pre-market Gap %": "premarket_gap",
362
- "Post-market Change %": "postmarket_change",
363
- "Post-market Change": "postmarket_change_abs",
364
- "Post-market Close": "postmarket_close",
365
- "Post-market High": "postmarket_high",
366
- "Post-market Low": "postmarket_low",
367
- "Post-market Open": "postmarket_open",
368
- "Post-market Volume": "postmarket_volume",
369
- # Relative Volume
370
- "Relative Volume": "relative_volume_10d_calc",
371
- "Relative Volume at Time": "relative_volume_intraday|5",
372
- # Returns
373
- "Return on Assets (TTM)": "return_on_assets",
374
- "Return on Equity (TTM)": "return_on_equity",
375
- "Return on Invested Capital (TTM)": "return_on_invested_capital",
376
- # Revenue
377
- "Total Revenue (FY)": "total_revenue",
378
- "Revenue per Employee (FY)": "revenue_per_employee",
379
- # Shares
380
- "Total Shares Outstanding": "total_shares_outstanding_fundamental",
381
- # Assets
382
- "Total Assets (MRQ)": "total_assets",
383
- "Total Current Assets (MRQ)": "total_current_assets",
384
- "Total Debt (MRQ)": "total_debt",
385
- "Total Liabilities (MRQ)": "total_liabilities_fq",
386
- # Crypto specific
387
- "24h Volume": "24h_vol|5",
388
- "24h Change %": "24h_close_change|5",
389
- "24h Volume Change %": "24h_vol_change|5",
390
- "24h Volume to Market Cap": "24h_vol_to_market_cap",
391
- # Quick ratio
392
- "Quick Ratio (MRQ)": "quick_ratio",
393
- }
394
-
395
155
  # Default columns for different query types
396
156
  # Always include 'description' for full name (e.g., "Apple Inc." instead of just "AAPL")
397
157
  DEFAULT_COLUMNS = ["name", "description", "close", "change", "volume", "market_cap_basic"]
@@ -421,7 +181,16 @@ TECHNICAL_COLUMNS = [
421
181
  "Stoch.D",
422
182
  ]
423
183
 
424
-
425
184
  def get_column_name(name: str) -> str:
426
185
  """Get the API column name from a human-readable name or return as-is."""
427
- return COLUMNS.get(name, name)
186
+ # Try exact match first
187
+ if name in COLUMNS:
188
+ return COLUMNS[name]
189
+
190
+ # Try case-insensitive keys
191
+ name_lower = name.lower()
192
+ for k, v in COLUMNS.items():
193
+ if k.lower() == name_lower:
194
+ return v
195
+
196
+ return name