Fixes two confirmed bugs where the exchange parameter was ignored or incorrectly resolved when querying US ETFs (GDX, GLD, XLE) and other non-crypto assets.
Closes #_ (relate to PR #23 which added TWSE/TPEX — same category of exchange-routing bugs)
Symptom: Calling multi_timeframe_analysis(symbol="GDX", exchange="AMEX") returned data for KUCOIN:GDX with all timeframes showing "No data for {tf}".
Root cause: sanitize_exchange("AMEX", "KUCOIN") returned "KUCOIN" (the fallback default) because "amex" was not in EXCHANGE_SCREENER. The subsequent symbol construction f"{exchange.upper()}:{symbol.upper()}" then produced KUCOIN:GDX.
Fix (src/tradingview_mcp/core/utils/validators.py):
- Added
"amex","nysearca","pcx"to bothEXCHANGE_SCREENER(→"america"screener) andSTOCK_EXCHANGES - Added
get_tv_exchange_prefix(exchange)helper that returns the correct TradingView symbol prefix (e.g."AMEX"for"nysearca") - Updated
multi_timeframe_analysisinserver.pyto useget_tv_exchange_prefix(exchange)instead ofexchange.upper()
Bug 2: combined_analysis / coin_analysis returned "No data found" for AMEX-listed ETFs (medium severity)
Symptom: combined_analysis(symbol="GDX", exchange="NYSE", timeframe="1D") returned error: "No data found for GDX on nyse".
Root cause: TradingView lists NYSE Arca ETFs (GDX, GLD, XLE, SPY, QQQ, etc.) under the AMEX: exchange prefix, not NYSE:. analyze_coin built the symbol as NYSE:GDX, which returns no data.
Fix (src/tradingview_mcp/core/services/screener_service.py):
analyze_coinnow usesget_tv_exchange_prefix(exchange)for symbol construction- Users passing
exchange="NYSE"getNYSE:GDX(for actual NYSE stocks), while ETF users should now passexchange="AMEX","NYSEARCA", or"PCX"to getAMEX:GDX
TradingView uses AMEX as its canonical prefix for all NYSE Arca (formerly American Stock Exchange / Pacific Exchange) listings. This PR adds three accepted aliases that all resolve to AMEX::
| User input | Screener | Symbol prefix |
|---|---|---|
AMEX |
america |
AMEX: |
NYSEARCA |
america |
AMEX: |
PCX |
america |
AMEX: |
Examples that now work:
multi_timeframe_analysis(symbol="GDX", exchange="AMEX") → AMEX:GDX ✓
multi_timeframe_analysis(symbol="GLD", exchange="NYSEARCA") → AMEX:GLD ✓
combined_analysis(symbol="XLE", exchange="PCX", timeframe="1D") → AMEX:XLE ✓
coin_analysis(symbol="SPY", exchange="AMEX", timeframe="1D") → AMEX:SPY ✓
TWSE and TPEX were already present in EXCHANGE_SCREENER (added in PR #23). Taiwan stocks like 2330, 0050, 0056 already work correctly. The get_tv_exchange_prefix function now makes this routing explicit and testable.
Added tests/unit/test_exchange_fixes.py with 32 tests covering:
sanitize_exchangeacceptsAMEX,NYSEARCA,PCXEXCHANGE_SCREENERandSTOCK_EXCHANGEScontain all three new aliasesget_tv_exchange_prefixmaps all aliases to"AMEX"and handles crypto fallback- End-to-end symbol construction:
GDX/GLD/XLEwith any alias →AMEX:<sym> - Regression:
NYSE,NASDAQ,TWSE,TPEX,KUCOIN,BINANCEunchanged
73 passed in 0.17s (69 new + 4 pre-existing)
| File | Change |
|---|---|
src/tradingview_mcp/core/utils/validators.py |
Add AMEX/NYSEARCA/PCX to maps; add get_tv_exchange_prefix() |
src/tradingview_mcp/core/services/screener_service.py |
analyze_coin: use get_tv_exchange_prefix for symbol |
src/tradingview_mcp/server.py |
multi_timeframe_analysis: use get_tv_exchange_prefix; update docstrings |
tests/unit/test_exchange_fixes.py |
32 new unit tests |
tests/unit/test_exchange_aliases.py |
37 additional unit tests (TWSE/TPEX symbol construction, pre-qualified symbol guard) |
pyproject.toml / uv.lock |
Add pytest as dev dependency |