Data to 5 October 2026

Methods

World markets: method

Code: pipeline/tipsheet/compute/world.py (build) and publish/world.py (bundles). Tests: pipeline/tests/test_world.py. Data bank adapters: src/databank/connectors/kite_global.py and ecb_exr.py in the Data bank.

The licence rule

Kite Connect data is licensed to the account holder for personal use (PLAN.md, decision 2), and index levels belong to their providers (S&P, Dow Jones, Nasdaq, FTSE Russell, Deutsche Börse, Euronext, Nikkei, Hang Seng Indexes, SSE, ASX). So this section publishes only derived statistics:

No index level, price, quote or rebased growth curve is published for any index here. A growth-of-100 curve is a level series in disguise, so there is none. Every bundle repeats the rule in meta.licence_rule, and the licence gate (publish/licence_gate.py) refuses any world/ column whose name suggests a level, close, price or rebased value. The Data bank contract for the Kite dataset carries licence.redistribution: internal_only.

MSCI index data: internal use only (validation/research). MSCI’s terms prohibit redistribution and derived works; not published (decision 2026-10-02). An earlier owner approval to publish MSCI-derived returns was withdrawn the same day on reading msci.com/terms-of-use. The licence gate refuses any bundle whose name or columns contain “msci”, whose meta.source* mentions MSCI, or that names the msci_index_levels dataset. See “MSCI (internal only)” at the end.

What is measured

For Nifty 50 and 11 overseas indices (S&P 500, Dow Jones Industrial Average, Nasdaq Composite, Nasdaq-100, FTSE 100, DAX, CAC 40, Nikkei 225, Hang Seng, Shanghai Composite, S&P/ASX 200):

Sources

WhatDataset (Data bank warehouse)FromLicence
Overseas indiceskite_global_index_history (Kite GLOBAL daily candles, 12 instruments)2004 (US100 and US10YRYIELD 2024-11)internal only
S&P 500, officialfred_series SP5002016-05-31 (FRED carries 10 years)derived only
Nasdaq Composite and Nasdaq-100, officialnasdaq_giw_index_history COMP, NDX1990derived only
Nifty 50nifty_index_history NIFTY_50, price return1990derived only
FX for rupee terms and the euro, pound and yen rowsecb_exr_daily (ECB euro reference rates, 14:15 CET)1999; INR and CNY from 2000-01-13public, attribute the ECB
USD/INR row and Brent in rupeesindia_data_hub_series FMFXUSDINR11D (CCIL)2000derived only
Dollar indexindia_data_hub_series FMFXDXYIDX11D (ICE)2001% moves only
Fed broad dollar, Brentfred_series DTWEXBGS, DCOILBRENTEU2006, 1987public
Goldgoldhub_gold_price (USD; domestic INR via compute/assets.gold_inr)1978; INR 2005% moves only
Global proxiesetf_issuer_nav_history (iShares workbooks and screener; SPDR NAV history)fund inception, 1996 to 2014internal (issuer website terms); derived returns only

Where an official public series exists it replaces Kite: the S&P 500 uses FRED from 2016-05-31 and Kite before (Kite equals the official close on all 2,125 overlapping days before the break), and both Nasdaq indices use Nasdaq’s own history throughout. The other eight overseas indices are Kite only.

Nifty 50 is the price index, not the total-return index, so it compares like for like with the overseas price indices. The DAX is the exception among those: it is a total-return index by construction, so its returns include dividends.

Rupee terms. Rupee return = (1 + local return) × (1 + change in rupees per unit of the local currency) − 1. Rupees per unit come from ECB reference rates: (INR per euro) ÷ (currency per euro), taking the rate on or before each close, within 4 days. ECB-derived USD/INR agrees with CCIL’s: median gap 0.04% over 5,136 days, 99th percentile 0.56%. The ECB fixing is at 14:15 CET, so for Asian and US closes the FX rate is a few hours off the close. That matters only for 1-week figures and only at the margin.

Kite: access, storage and cleaning

Access. The Data bank adapter reads the Kite session from the Aftermarket Report’s .env (pointed to by KITE_ENV_FILE in the Data bank .env), so both projects share one set of tokens. The daily access token expires around 06:00 IST. Before each fetch the adapter checks it and, if expired, renews it from the stored long-lived refresh token and writes the new token back. This runs unattended. Verified on 2026-10-01: the stored token had expired and was renewed without a login. If the refresh token is ever revoked, renewal fails, only this dataset fails in the 06:00 Data bank run, the warehouse keeps the previous snapshot, and this section keeps publishing from it with stale flags set. Fix: run amr login once in the Aftermarket Report.

Storage. Data bank dataset kite_global_index_history: raw JSON artifacts, contract, audit, a daily update policy (10-day look-back, ending yesterday because today’s candle is still forming), and the 2004 backfill. The authorization header is redacted from stored metadata and is not part of any fingerprint.

Cleaning (counts from the 2026-10-01 build, 59,000 rows):

  1. Weekend rows dropped (918). None of these markets trades on a weekend. Most are US30’s forward-filled weekends from 2004-12; others are stray quotes, such as JAPAN225 Sundays in 2017 and a HANGSENG Sunday print 26% above the Friday close in 2008.
  2. Rows on exchange holidays dropped, using each exchange’s own session calendar (exchange_calendars: NYSE, LSE, Xetra, Euronext Paris, Tokyo, HKEX, Shanghai, ASX). Before the break this removes only real closures (Hong Kong typhoon days, Whit Monday on Xetra). After it, it removes holiday quotes, 1 to 42 per instrument.
  3. Forward-filled bars dropped (open = high = low = close = the previous close).
  4. Bars dated on or after the day they were fetched (IST) dropped: the candle is still forming.

Two source bars whose high-low range excluded the close (UK100 2011-08-05, USCOMPOSITE 2023-08-04) keep their close; the Data bank nulls their range and flags range_nulled.

The series break

Kite’s GLOBAL series changed character on 2024-11-07, the day US100 and US10YRYIELD first appear. The date is found from the data: the first run of five days on which Kite’s US500 departs from the official S&P 500 by more than 0.01%. KITE_AUDIT.md put the change at 2025-03; the data shows it starts in November 2024.

Since then the values are provider quotes, at times CFD prices on a fixed tick grid, not official closes. Measured where an official close is public:

Kite series vs officialDaysMedian gap90th pctMax1-week return error, median (90th pct)1-month return error, median (90th pct)
US500 vs S&P 500 (FRED)4660.32%0.95%1.80%0.05 pp (0.45)0.29 pp (0.70)
USCOMPOSITE vs Nasdaq Composite4660.10%1.04%2.59%0.05 pp (0.58)0.11 pp (1.13)
US100 vs Nasdaq-1004660.49%0.98%3.09%0.17 pp (0.80)0.45 pp (0.84)

Before the break, US500 matches the official close on 100% of 2,125 days and USCOMPOSITE on 97.4% of 5,246 days.

The three US series above use the official closes, so this error does not reach them. For the eight Kite-only markets (Dow, FTSE 100, DAX, CAC 40, Nikkei, Hang Seng, Shanghai, ASX 200), every current figure carries an error of about this size. Their rows are marked basis: provider_quote. The share of closes on a 0.25 tick grid shows where the quotes are clearly CFD-like: US500 59% of the time since the break against 9.5% before, Hang Seng 41% against 4%, Nasdaq-100 always, and the DAX in some recent months. The other markets look like official closes on this test, but the Nikkei check below shows they can still drift.

Checks

Calendar-year returns against the providers’ published figures (price returns; the DAX is total return):

S&P 500DowNasdaq CompNasdaq-100FTSE 100DAXCAC 40Nikkei 225Hang SengShanghaiASX 200Nifty 50
2023 published24.2313.7043.4253.813.7820.3116.5228.24−13.82−3.707.8420.03
2023 ours24.2313.7043.4253.813.7820.3116.5228.24−13.82−3.707.8420.03
2024 published23.3112.8828.6424.885.6918.85−2.1519.2217.6712.677.498.80
2024 ours23.3112.9528.6424.885.6918.85−2.1519.3917.6713.337.498.80

2023 matches exactly everywhere. In 2024 the year-end close falls after the break: the Dow is 0.07 pp off, the Nikkei 0.17 pp and Shanghai 0.66 pp, because Kite’s last 2024 bar is a provider quote (Shanghai 3,371.56 against the official 3,351.76; Nikkei 39,951.90 against 39,894.54). The others match. These comparisons run on every build and are stored in world/returns_grid under meta.checks.

Other checks: ECB-derived USD/INR against CCIL (above); the pipeline-wide licence gate; strict JSON (every bundle is serialised with NaN and infinity forbidden).

Caveats

Global proxies: US-listed ETFs’ official NAVs

Rebuilt 2026-10-01. Code: build_proxies, total_return_index, alignment_check and their helpers in compute/world.py, _publish_proxies in publish/world.py. Data bank dataset etf_issuer_nav_history (source etf_issuers).

The first version of this section used Indian international funds’ NAVs from AMFI. The owner rejected them as stale. Many are struck a day late against overseas closes, several are active portfolios, and the Indian-listed international ETFs trade at large premiums under the overseas investment limit. That code path is removed. Every proxy is now the official NAV of a US-listed ETF, taken from the issuer, with basis: issuer_nav.

Where the NAVs come from

Probed on 2026-10-01, in the order the brief set:

IssuerWhat worksResult
State Street SPDRssga.com/.../fund-data/etfs/us/navhist-us-en-<ticker>.xlsx, plain GETWorks. Daily NAV, shares outstanding and net assets from 2003 (SPY) or 2004 (GLD). No distributions, and few country funds. Used for cross-checks.
iShares (BlackRock)blackrock.com/varnish-api/.../get-fund-document?...&portfolioId=<id>&component=fundDownloadWorks with no cookie or disclaimer step. Excel 2003 XML workbook with daily NAV per share, the distribution going ex each day, shares outstanding and a non-fair-valued NAV, all from the fund’s inception. The legacy /<id>.ajax?fileType=xls link returns the HTML product page, even inside a cookie session. Chosen.
iShares screenerishares.com/us/product-screener/product-screener-v3.jsnOne JSON with every fund’s latest NAV and the issuer’s year-to-date total NAV return. It is the cheap daily feed.
Invesco (QQQ)product pages and dng-api.invesco.comHTTP 406 to non-browser clients, even with browser headers. Not used, so there is no Nasdaq-100 proxy; the world grid already has the official Nasdaq-100.
USCF (USO)NAV history behind a bearer-token script APINot used. No oil proxy; Brent is in the FX and commodities panel.
Vanguard, FranklinJavaScript apps with no static downloadNot used.
WisdomTree; Global XHTTP 403; no history fileNot used.

Terms. BlackRock’s website terms grant personal, non-commercial use, forbid redistributing site content for public purposes, and forbid robots that copy site materials without permission. SSGA’s material says it may not be reproduced without consent. The dataset is therefore marked internal_only in the Data bank, like Kite. Only derived statistics are published: returns, drawdown in percent and correlations. No NAV, level or rebased curve is published. The Data bank fetches one screener file and two or three workbooks a day. The owner should decide whether this use is acceptable or whether to ask BlackRock for permission.

The proxies

All iShares, all passive. History starts at the fund’s inception.

KeyMarketETFIndexFrom
us_sp500US large capsIVVS&P 5002000-05-15
developed_ex_usDeveloped ex-US and CanadaEFAMSCI EAFE2001-08-14
europeEuropeIEVS&P Europe 3502000-07-25
japanJapanEWJMSCI Japan1996-03-12
chinaChinaMCHIMSCI China2011-03-29
hong_kongHong KongEWHMSCI Hong Kong1996-03-12
taiwanTaiwanEWTMSCI Taiwan 25/502000-06-20
koreaSouth KoreaEWYMSCI Korea 25/502000-05-09
brazilBrazilEWZMSCI Brazil 25/502000-07-10
mexicoMexicoEWWMSCI Mexico IMI 25/501996-03-12
emergingEmerging marketsEEMMSCI Emerging Markets2003-04-07
india_usdIndia in dollars (a check)INDAMSCI India2012-02-02
us_treasuries_7_10yUS Treasuries 7-10yIEFICE US Treasury 7-10 Year2002-07-22
us_treasuries_20yUS Treasuries 20y+TLTICE US Treasury 20+ Year2002-07-22
us_tipsUS TIPSTIPICE US Treasury Inflation Linked2003-12-04
global_reitsGlobal REITsREETFTSE EPRA Nareit Global REITs2014-07-08
us_reitsUS real estateIYRDow Jones US Real Estate Capped2000-06-12
goldGoldIAULBMA gold (physical)2005-01-21
silverSilverSLVLBMA silver (physical)2006-04-21
commoditiesBroad commoditiesGSGS&P GSCI Total Return (futures)2006-07-10

FXI (China large caps, from 2004) is also held in the Data bank but not published; MCHI is the MSCI fund. SPY and GLD (SSGA) are held for cross-checks.

Building a total return

Each fund’s total-return index chains the workbook day by day: (NAV + the distribution going ex that day) × split factor ÷ the previous NAV. It is held in memory only. Checked against the issuer’s own monthly total NAV returns in the same workbook, the chain matches to within 0.03 pp a month for most funds. The largest gap is 0.37 pp, in one EWW month in 2010. One SLV and IAU month (November 2014) is wrong in the issuer’s Performance sheet, which repeats December’s value.

Days after a fund’s last workbook come from the screener. Their distributions are not yet known, so they are chained from the issuer’s year-to-date total NAV return: value = value at the prior year-end × (1 + YTD). That figure matched the workbook chain to 4 decimals for TLT, IEF, TIP, EWJ, IVV, EEM and IAU. On every overlapping day the build compares the two (ytd_check_max_abs_pp: 0.0 on 2026-10-01). Workbooks are refreshed on a 10-business-day rotation, so distributions_through trails as_of by at most two weeks.

Data quirks (Data bank parser):

Returns, drawdown and rupee terms

Returns are in US dollars, the fund’s own terms, and in rupees using ECB-derived rupees per dollar (14:15 CET). Drawdown runs from each fund’s inception, in both currencies. Calendar years run from 2005, and a year needs a value in the last 10 days of the prior year.

Time zones and the Nifty correlation

NAVs are struck at 4 pm New York time, after India’s close. Non-US funds value their holdings at local closes, adjusted to the US close by iShares’ fair-value pricing. The pipeline measures two pairings against Nifty from 2016: the fund’s NAV and Nifty’s close on the same calendar date, and the NAV of day t against Nifty’s next session. Same-date pairing gives the higher weekly correlation for 14 of 20 funds (IVV 0.524 against 0.506; EWJ 0.478 against 0.427; INDA 0.929 against 0.778). The six exceptions are the three Treasury funds (correlations near zero; the gap is 0.04 to 0.07), the two REIT funds (0.012 and 0.025) and GSG (0.007). So world/proxies_correlation_weekly uses Friday-ending weeks on the same calendar date, each side in its own currency (fund in dollars, Nifty in rupees), the same convention as world/correlation_weekly. A rolling correlation needs at least 40 of 52 weeks. Both pairings are stored per fund in world/proxies_grid under meta.checks.nifty_alignment.

Validation against indices

The warehouse holds indices for four proxies. All comparisons are in US dollars and use monthly returns. The indices are price returns. The fund’s NAV price return (distributions left out) isolates tracking and index-definition gaps; the total-return gap adds the yield.

Proxy vs indexMonthsMonthly corr (TR)Tracking error, TRGap 1y / 3y / 5y ann., TR (pp)NAV price-return gap 1y / 3y / 5y (pp)
IVV vs S&P 500 (FRED)2710.99990.20%+1.30 / +1.56 / +1.58−0.05 / −0.01 / +0.01; calendar years −0.22 to +0.17
IAU vs LBMA gold (WGC)2590.9941.98%+0.29 / −0.10 / −0.17same (no distributions)
INDA vs Nifty 50 in USD1740.9873.32%+4.89 / +2.12 / +0.69MSCI India includes mid caps
EWJ vs Nikkei 225 in USD2710.9326.31%−14.2 / −5.0 / −0.8MSCI Japan is cap-weighted; the Nikkei is price-weighted
EWH vs Hang Seng in USD2710.9268.04%+16.8 / +2.5 / +2.3MSCI Hong Kong excludes mainland Chinese companies

IVV’s NAV tracks the S&P 500 to within 0.05 pp a year, and its total-return lead (about 1.3 to 1.6 pp) is the dividend yield. IAU’s tracking error against the WGC series reflects month-end timing; its long-run gap is the 0.25% fee. The Japan and Hong Kong gaps are index-definition differences, not data errors. The Hang Seng and Nikkei come from Kite and are internal. Cross-issuer checks on daily NAV price returns since 2016: IVV against SPY, correlation 0.99779 and median daily gap 0.0008 pp (ex-dates differ, so the 99th percentile is 0.45 pp); IAU against GLD, 0.99977 and 0.0012 pp. These checks are rebuilt on every run and stored under meta.checks in world/proxies_grid.

What the bundles hold

Caveats

MSCI (internal only)

Code: pipeline/tipsheet/compute/world_msci.py (build_msci_internal, called at the end of build_world; a failure there never blocks the world bundles). Tests: the MSCI block in pipeline/tests/test_world.py, and test_msci_derived_bundles_are_refused in test_licence_gate.py. Nothing here reaches publish/world.py or the manifest.

Source. Data bank msci_index_levels (the owner’s scraper of MSCI’s public end-of-day index search): 313 codes, USD, daily, three variants (STRD price, NETR net total return, GRTR gross total return). STRD runs from 1997; NETR and GRTR start 2000-12-29 for most codes, so calendar-year net returns start in 2001, not 1998. 224 codes have a blank index_name; names come from the comments in the Data bank’s configs/update/msci_index_levels.yaml (Cou country, Reg region). MSCI market class (DM/EM/FM/standalone) is a hardcoded table in the module; re-check it after each June review.

Outputs (.cache/derived/, never published): msci_countries_grid.parquet (79 countries and 11 regions; NETR returns 1w to 10y annualised in USD and INR, drawdown, 1y volatility, 1y correlation and beta with MSCI India in USD and with Nifty 50 TRI in rupees, ranks by 1y and YTD rupee return among fresh countries), msci_calendar_years.parquet, msci_india_relative.parquet (India against EM, ACWI and ACWI ex India: rolling 1y and 3y return gaps in pp and % change of the ratio; there is no EM ex India code in the dataset), msci_correlation_weekly.parquet (India’s 52-week correlation with USA, China, Japan, Korea, Taiwan, Brazil, EM, World), and msci_internal_checks.json. Every table is checked for level-like columns before it is written.

Coverage (2026-10-01 build). 23 DM, 24 EM, 21 FM and 11 standalone country indices. NETR from 2000-12-29 for all DM and most EM; Gulf markets from 2005, Saudi Arabia from 2014, frontier markets 2002 to 2016. Ghana (last 2017-11) and Botswana (last 2023-02) are dead series and are flagged stale.

Rupee terms. Rupees per dollar from ECB reference rates (14:15 CET), ratio-linked before 2000-01-13 to FRED DEXINUS. MSCI converts at WM/Reuters 4 pm London rates on the same date, so the two are about two hours apart.

Staleness. Measured from every warehouse snapshot: MSCI data lands one day old (three days after a weekend), and the Data bank refreshes it about weekly, so it is 6 to 13 days old just before the next run, and once 22 and once 34 days when runs were missed (August and June-July 2026). Rule: stale after 5 days, and no 1-week return then. If MSCI were ever published, a light daily refresh of the ~40 codes on display would be needed; for internal research the weekly run is enough.

Validation (2026-10-01, monthly returns in USD).

ComparisonMonthsMonthly corrTracking errorGap 1y / 3y / 5y ann. (pp)Note
MSCI India NETR vs Nifty 50 TRI in USD3080.990 (weekly 0.986)3.66%+3.04 / +1.66 / +0.39calendar-year gaps −7.4 to +17.9 pp (2009); MSCI India includes mid caps
MSCI USA STRD vs S&P 500 (FRED)1230.99920.65%−0.35 / +0.05 / −0.432020 +3.0 pp, 2021 −1.7 pp: broader index
MSCI USA NETR vs S&P 500 price1230.99920.67%+0.56 / +1.15 / +0.68the gap is the net dividend yield
EWJ NAV total return vs MSCI Japan NETR3080.9921.94%−0.83 / −0.56 / −0.41fund minus index: fee and cash drag, about −0.5 pp a year

Gross ≥ net ≥ price over 2000-2026 for India, USA and Japan (India: 1,050%, 990%, 458%).

This note is the repository file docs/methods/world.md, rendered as-is.