Five tools across three asset classes: forex (quote, convert), crypto (snapshot, movers), and indices (snapshot). Same Protocol-shaped data layer, same downstream math. The point is not breadth for its own sake — it's that USDJPY, BTC, and ^GSPC all decompose into the same risk question when the desk needs to answer it before lunch.
Notes from Surendra Singh.
# forex — ISO 4217 currency pairs forex_quote(from_currency: str, to_currency: str) -> str forex_convert(from_currency: str, to_currency: str, amount: float = 1.0) -> str # crypto — symbol-keyed, exchange-aware via Massive crypto_snapshot(ticker: str) -> str crypto_movers(direction: str = "gainers", limit: int = 10) -> str # indices — the benchmark layer indices_snapshot(tickers: str) -> str # ^GSPC, ^DJI, ^IXIC, ^VIX, ...
The asymmetry is deliberate. FX has convert because users actually need to denominate one currency in another (a real workflow — "what's this €120k retainer in USD?"). Crypto has movers because the asset class is dominated by sentiment-driven leaderboards. Indices have only snapshot because they exist to be benchmarks, not to be traded directly.
Two tools that look similar and answer different questions. forex_quote returns the rate ("EUR to USD is 1.0842"). forex_convert applies the rate to an amount and returns the converted value with the rate inlined. Naive wrappers around the same call — but the wording matters. A user who asks "how much is €50,000 in dollars" wants a number, not an exchange-rate fact sheet.
# under the hood: same provider call, different framing rate = provider.get_fx_rate(from_currency, to_currency) result = amount * rate return format_output(f"{amount} {from_currency} = {result:.2f} {to_currency} (rate {rate:.4f})")
ISO 4217 codes are non-negotiable. "Yen" is ambiguous (CNY? JPY?); "JPY" is not. The tool rejects unrecognized codes and returns the canonical list, because silent currency mismatches are the kind of bug that ends up in regulatory letters.
Crypto markets do not close. There is no "previous close" the way there is for equities — there is the price 24 hours ago. Volatility is annualized by √365, not √252, because the asset class trades every day. Volume figures are exchange-fragmented; a single canonical "BTC volume" requires aggregating across spot exchanges, and providers disagree on which exchanges count.
# crypto-specific defaults TRADING_DAYS_PER_YEAR = 365 # equities use 252 RETURN_BASIS = "24h" # equities use "previous close" VOLUME_AGGREGATION = "exchange_weighted"
crypto_movers returns the top gainers or losers over the last 24 hours. Useful as a sentiment scan, dangerous as a trading signal — leaderboards are dominated by low-cap names with thin liquidity, and the move you see at 9 AM is rarely the move you can transact at 9:01.
Indices exist to be the denominator. Beta is computed against ^GSPC; sector rotation is read against ^IXIC vs. ^DJI; risk-on/risk-off is read against ^VIX. indices_snapshot returns the level, the day's change, and the year-to-date — three numbers that frame everything else on the screen.
| Symbol | Index | Use |
|---|---|---|
| ^GSPC | S&P 500 | The default beta benchmark. Large-cap US equity. |
| ^DJI | Dow Jones Industrial | 30 names, price-weighted. Cyclical proxy. |
| ^IXIC | NASDAQ Composite | Tech-heavy. Use for sector decomposition. |
| ^RUT | Russell 2000 | Small-cap. Liquidity and credit signal. |
| ^VIX | CBOE Volatility | 30-day implied vol on S&P options. Fear gauge. |
The reason this page exists as a single category, not three: correlations regime-shift in stress. In calm markets, BTC and ^GSPC have low correlation. In a March-2020-style flight-to-cash, every asset class correlates to 1 against the dollar. A risk system that treats stocks, crypto, and FX in separate silos misses that, structurally.
"Diversification is a property of the regime, not of the portfolio. The portfolio you held does not know it stopped being diversified."
The toolset exposes the data needed to see the shift — pull crypto and equity index returns through the same correlation_map, and the regime change is visible. Acting on it is still the analyst's job.