Skip to content

Latest commit

 

History

81 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ProShares

One of the app's features lets you select ProShares ETFs in the Watchlist and aggregate their holdings to see how often each ticker appears across the selected funds. Repeated holdings make overlapping exposure visible: the more selected funds include a ticker, the greater its potential influence on the portfolio; gains in that holding may help, while declines may hurt, and actual impact also depends on each fund's position size. Another feature makes it faster and easier to find funds with stronger growth over different periods, higher dividend yields or distributions, greater Total Return (price performance plus dividends), and other key performance metrics. A single-file client-side tool reading the generated ./api/proshares static feed (the official ProShares ETF finder, per-fund product pages and distribution summary, plus the official daily holdings, NAV history, performance and split files) into a searchable ETF/asset-class catalog with per-fund tabs, watchlist aggregation, ticker copy and CSV/TXT export — the same look, feel, columns and business logic as the sibling applications.

Using Bun

bunx degit daggerok/ProShares#main ./12345 && cd $_
bunx serve . -p 1234
open http://0:1234

The published application is available at https://daggerok.github.io/ProShares/. No build step, no bundler, no server — index.html carries the markup and a Babel-standalone bootstrap that transpiles app.tsx in the browser. The app reads only relative ./api/proshares/** files generated by scripts/update-data.ts; the committed feed is complete, so the site works offline with no update run at all.

Updating the static ProShares data

Run the updater with Bun:

bun test scripts/update-data.test.ts
./scripts/update-data.ts

Run ./scripts/update-data.ts -h (or --help) to print every configuration variable with its default and usage examples.

The Update ProShares ETF data GitHub Actions workflow (.github/workflows/update-data.yml, workflow_dispatch only) exposes the same settings as manual inputs and commits api/proshares/** and nothing else — a data run never rewrites app code or CI config. All supplied filters use AND logic.

Updater output shows the catalog header, then numbered per-fund ok or FAILED lines on completion, followed by totals; it does not print per-fund start lines. Filtered funds appear in the final count only. Actual retry and fallback warnings are retained for diagnosis.

Data sources

Block Source Notes
Fund universe, name, asset class, marketing category, geared strategy, daily objective, index/benchmark, net assets, inception date, fact-sheet link /our-etfs/find-proshares-etfs (56 strategic ETFs) + /our-etfs/find-leveraged-and-inverse-etfs (117 geared ETFs) The two finder tables are server-rendered and carry the provider's own vocabulary. Their "All ETFs" counts (56 + 117 = 173) match the official data host's ticker set exactly — no fund is missing on either side.
CUSIP, expense ratio, NAV, market price, trading volume, 30-day median bid/ask spread, distribution frequency, SEC 30-Day Yield (where published), 12-Month Yield, characteristics (# holdings, P/E, P/B, average market cap, weighted average yield to maturity), exposures (country/currency/sector weights), month-end + quarter-end total returns per-fund product page https://www.proshares.com/our-etfs/strategic/<ticker> and https://www.proshares.com/our-etfs/leveraged-and-inverse/<ticker> Server-rendered HTML parsed by stable element ids (snapshot-*, price-*, characteristics-*, distributions-sec30DayYield, distributions-12MonthYield, month-end-total-returns*) plus the page-embedded exposure JSON blocks; no browser and no JavaScript execution is needed.
Daily holdings (every position of every fund) psdlyhld.csv — all funds — or …/ByFund/<TICKER>-psdlyhld.csv per fund The official ProShares/ProFunds data host (a plain Apache directory listing). The file starts with a 4-line preamble (PORTFOLIO HOLDINGS INFORMATION, AS OF <date>, a blank line) and then Fund Ticker, Fund Name, Security Ticker, Security Sedol, Security Description, Coupon, Maturity Date, Shares/Contracts, Exposure Value (Notional + G/L), Market Value. .xls twins exist; the CSV is used.
NAV, shares outstanding and total net assets history historical_nav.csv — all funds — or …/ByFund/<TICKER>-historical_nav.csv per fund The per-fund file is the "NAV History" link on every fund page. Columns: Date, ProShares Name, Ticker, NAV, Prior NAV, NAV Change (%), NAV Change ($), Shares Outstanding (000), Assets Under Management; dated MM/DD/YYYY, descending.
Returns (NAV and market price, month-end and quarter-end) etf_performance.csv Fund Name, Fund Symbol, Return Type (NAV/MARKET), Data Period (MONTH/QUARTER), Return Effective Date, 1-Month, 3-Month, 6-Month, Year-To-Date, 1-Year, 3-Year, 5-Year, 10-Year, Return Since Inception, Inception Date. The feed keeps the NAV basis, matching every other return figure.
Splits etf_splits.csv Symbol, Name, Pre Split Cusip, Post Split Cusip, Split Type, Ratio, Date of Split; the published NAV history is not split-adjusted, so returns always come from the official performance file and split dates are only reported in meta.json.
Distribution history (declare/ex/record/payable dates, cash, capital gains, return of capital) https://www.proshares.com/api/distributionsummary?fund=<TICKER>&year=<YYYY> The endpoint that hydrates the fund page's own Distributions tab. Plain JSON, one object per payout (CashDividendPerShare, Dividend, EffectiveDate, ExDate, PayableDate, RecordDate, LongTermCapGains, ShortTermCapGains, ReturnOfCapital, SpecialPerShare, OtherPerShare, Symbol). A year without payouts answers []; the year parameter is required (a blank year returns the site's HTTP 500 error page).
Listing exchange (Overview only) Nasdaq Trader symbol directory + otherlisted.txt ProShares does not print the listing exchange on its pages; the symbol directory resolves it by ticker. — when the ticker is not listed there.

Every one of those sources is official and machine-readable: the whole feed is built without scraping a single document, without a headless browser and without a third-party data vendor.

Why the ProShares/ProFunds data host

accounts.profunds.com/etfdata is the distribution host ProShares itself links to from every fund page ("NAV History" → ByFund/<TICKER>-historical_nav.csv). Its directory listing is the authoritative fund universe for the data files, and the bulk files (psdlyhld.csv, historical_nav.csv, etf_performance.csv, etf_splits.csv) are refreshed every trading day right after NAV publication — the same numbers the website renders.

Known value limitations

Metric Status Reason
SEC Yield (30-day) 41 populated / 132 — in the current feed Official ProShares field, not a universal data limitation. distributions-sec30DayYield reports NOBL 2.09%, IGHG 5.42%, HYHG 6.85% on sampled pages (as of 8/31/2026; values can change). The current 173-fund refresh records 132 fund pages without a published SEC 30-day field, including TQQQ, AGQ, BOIL, SPCF, IQMM, UCOP, UPAL and UPLT; their values stay null/—, even if they pay distributions. IGHG/HYHG also show a distinct Weighted Average Yield to Maturity; IQMM reports SEC 7-Day Yield, not SEC 30-Day Yield — do not substitute either. meta.yields.secYieldKind records the per-fund source or omission; these counts may change with future publications.
Dividend Yield — for 24 of 173 funds 21 have no payouts in the published official distribution histories: ACQQ, ACRT, ACSP, AGQ, BOIL, DAT, EUO, GLL, KOLD, OND, SCO, SVXY, UCO, UGL, ULE, UVXY, VIXM, VIXY, YCL, YCS, ZSL. 3 paid but have no published frequency: UCOP, UPAL, UPLT each have June/September payouts; without a provider cadence an annualized estimate would be a guess. Where a fund has a published cadence and an actual payout but no official 12-Month Yield, the updater instead labels a computed indicated yield (latest dividend × payments/yr ÷ NAV) with basis in meta.yields.effectiveYieldBasis / metrics.dividendYieldBasis. IQMM pays Weekly and has 3.6013% indicated (not an official 12-Month Yield); SPCF paid and shows 1.8668% indicated. Counts reflect the currently committed feed and may change on refresh.
Distribution Frequency 00 - None in the catalog for 19 funds The provider omits cadence for 16 without payouts and UCOP, UPAL, UPLT, which paid twice but still have no declared frequency. The raw feed retains the missing label —; the catalog formats it as 00 - None (no published schedule, not proof of no payouts), monthly as 01 - Monthly, quarterly 04 - Quarterly, semiannual 06 - Semi-annually, annual 12 - Annually, irregular 99 - Irregular. The updater reads distributions-distributionFrequency or snapshot-distributions. IQMM's published Weekly displays verbatim; no cadence is inferred from dates.
TR 1Y / 3Y / 5Y / 10Y, CAGR 3Y / 5Y / 10Y, SI Ann., mo1 / mo3 / mo6 — for funds without a published tenor Blanks match the official etf_performance.csv; do not treat them as zero or backfill an annualized figure with a cumulative one. In the current feed (generated 2026-09-24T04:14:19Z): tr1y 16 nulls, tr3y 37, tr5y 48, tr10y 60, cagr3y 37, cagr5y 48, cagr10y 60, siAnn 16, mo1 3, mo3 6, mo6 10. Many are young relative to the last official month-end cutoff (e.g. ACQQ/ACRT/ACSP, EQQQ, SKHU, SPCF, BUYB, IQMM). Quarter-end date missing for 5 (ACQQ, ACRT, ACSP, EQQQ, SKHU).
Expense Ratio (Gross / Net) 0 blank values in the current feed Some strategic funds publish only one Expense Ratio, so the updater uses that same published number for both display fields; it does not imply a separately published gross ratio. Funds that publish distinct gross/net values (e.g. TQQQ 0.97%/0.82%) retain both verbatim; the headline ter/terValue is net. Provenance and any waiver footnote live in meta.expenseRatio. In the current feed all 173 index terValue, terGrossValue, terNetValue and per-fund gross/net values are populated.
Expense Ratio (Net) footnote fixed Fixable gap — now fixed. 4 funds (EZJ, PEX, TOLZ, UCYB) publish 1.17%* etc with footnote markers. Updater now strips via cleanRatioText / ratioValue / expenseRatioFootnote — terValue now 0 nulls (was 4).
ISIN, FIGI, position CUSIP — when not officially supplied All 173 funds have a published fund-level CUSIP, but no fund-level ISIN in the current source (173 null); ProShares does not supply FIGI or per-position CUSIP in the holdings CSV. Positions with a Security Sedol use that SEDOL in the Identifier column, including bonds; derivatives/cash without one remain blank instead of inventing an identifier.
Premium / Discount computed, 0 blank in current feed The fund page renders NAV and market price but links to a separate tool for premium/discount. The feed computes (market price − NAV) / NAV × 100 from those two official numbers and says so in meta.json; no third-party value is substituted.
Listing exchange from Nasdaq Trader; 0 blank in current feed Not published on ProShares pages; the official Nasdaq Trader symbol directory resolves all 173 current tickers. A future newly listed fund absent from the directory would honestly show —.
Weight per position computed The official holdings file has no weight column. The updater computes position market value (or notional exposure for derivatives) ÷ fund net assets implied by the file's summed market values × 100, reproducing the published page weights (previously verified for NOBL BDX 1.73%, TQQQ NVDA 3.11% and a Barclays swap 29.64%, AGQ Silver DEC26 77.04%, IGHG Morgan Stanley 1.62%, and several others). ProShares renders -- for residual Net Other Assets (Liabilities) and its cash equivalents (TREASURY BILL, PROSHARES GENIUS MNY MKT ETF) → those keep weight — (isWeightlessRow). Bond/future/swap rows do carry a weight. Some geared funds legitimately total roughly −300% to +300%, not a feed error.
Cumulative TR 3Y/5Y/10Y derived from the official annualized figures ProShares publishes annualized 3Y/5Y/10Y (and since-inception) returns only; the cumulative tenors are derived as (1 + annualized)^n − 1 and labelled as derived in meta.json.
Holdings for brand-new funds 0 missing in current feed All 173 current funds have holdings/history pages and pass dev-run/check-feed.py. A future brand-new fund may precede its first published holdings file; only then should the Holdings tab show an explanatory empty state.

These counts describe the 2026-09-24T04:14:19Z committed feed, after a separately pushed data update that regenerated all 173 fund metadata files. python3 dev-run/check-feed.py reports 0 problems. The 132 missing SEC 30-day yields reflect pages without that field in this run, not a claim that those funds can never publish it; recheck on subsequent updates.

Update controls

Environment variable Default Meaning
MAX_FETCHES 0 Funds to process; 0 = full pass. A positive value resumes after the cursor in api/proshares/update-state.json.
TICKERS "" Space/comma separated ticker allowlist; ANDed with the other filters, never overriding them.
CATEGORY "" Substring match on the ProShares asset class (Equity, Fixed Income, Commodity, Crypto-Linked, Cash, Alternative, Volatility).
AUM / TER / DIVIDEND_YIELD ":" min:max ranges; AUM also accepts nano/micro/small/mid/large presets and K/M/B/T suffixes. DIVIDEND_YIELD matches the same official 12-Month or computed indicated value that the feed shows (requires fetching official distribution rows when 12-Month Yield is absent).
SEC_YIELD ":" Inclusive min:max range against the official SEC 30-Day Yield on each fund page; : imposes no restriction, but an active bound excludes a fund whose page omits this field.
CONCURRENCY / REQUEST_SLEEP 3 / 1.5 Politeness for the 173 fund pages and the JSON endpoint.
HOLDINGS_PAGE_SIZE / HISTORY_PAGE_SIZE 250 / 1000 Rows per generated JSON page (alias HISTORICAL_PAGE_SIZE).
HISTORY_RANGE max NAV-history window: max or a number of years/months/days such as 10y, 36m or 90d.
DISTRIBUTION_YEARS 10 Calendar years of distribution history fetched per fund (the endpoint is year-scoped).
MAX_RETRIES 3 Retries after the initial request for network errors and HTTP 408/425/429/5xx.
SKIP_PROSHARES off Legacy no-op in this official-source updater; it does not disable provider requests. Use TICKERS for bounded runs instead.
STORE_RAW_DOWNLOADS off Keep one raw sample of each source under api/proshares/raw.

There is no SKIP_YAHOO switch or Yahoo fallback: this updater uses the official ProShares pages, data host and distributions API. Setting SKIP_YAHOO has no effect.

TICKERS combines with the AUM/TER/yield filters using AND logic; it does not override them. A young fund that lacks a requested 3Y/5Y/10Y figure passes a return filter (nothing is invented), while a fund without AUM/TER under an active AUM/TER filter fails it. Funds that did not update successfully keep their previously published metadata and data files, so a bounded or partly failed run can never empty the site.

Examples

MAX_FETCHES=10 ./scripts/update-data.ts
TICKERS="NOBL TQQQ IGHG" ./scripts/update-data.ts
CATEGORY=Commodity AUM="300M:" ./scripts/update-data.ts
DISTRIBUTION_YEARS=20 HISTORY_RANGE=5y ./scripts/update-data.ts
STORE_RAW_DOWNLOADS=1 ./scripts/update-data.ts

Uploading the official holdings file in the browser

The dropzone in the toolbar accepts the official ProShares daily holdings download — either one fund's own file (NOBL-psdlyhld.csv, the "Download Holdings" link target of every fund page) or the all-funds psdlyhld.csv. It is parsed in the browser (no network call), merged into the catalog and overrides that fund's holdings for the session; the static feed is untouched and the upload disappears on reload. Holdings files for funds that are not in the catalog are added as Uploaded entries so a brand-new ETF can still be inspected.

TypeScript

The browser app is intentionally build-free: index.html carries the markup, styles and bootstrap, and app.tsx is TypeScript compiled in the browser with Babel standalone — no build step, no bundler, no tsconfig.json needed. Bun runs TypeScript out of the box.

Verification before every publish: bun install --frozen-lockfile, bun test, and git diff --check.

Brands table

Brand Where to get the data
abrdn (Aberdeen) aberdeeninvestments.com | aberdeen
Amplify amplifyetfs.com | Amplify
Capital Group capitalgroup.com | Capital-Group
Fidelity fidelity.com | Fidelity
First Trust ftportfolios.com | First-Trust
Franklin Templeton franklintempleton.com | Franklin
Global X globalxetfs.com/explore | Global X
Goldman Sachs am.gs.com | Goldman-Sachs
Invesco invesco.com | Invesco
iShares ishares.com | iShares
JPMorgan am.jpmorgan.com | JPMorgan
NEOS neosfunds.com | Neos
Northern Trust etfs.ntam.northerntrust.com | Northern-Trust
ProShares proshares.com | ProShares
Schwab schwabassetmanagement.com | Schwab
SPDR ssga.com | SPDR
VanEck vaneck.com | VanEck
Vanguard investor.vanguard.com | Vanguard
VictoryShares vcm.com VictoryShares ETFs | VictoryShares
WisdomTree wisdomtree.com | WisdomTree

Sibling applications

Application Data provider Repository
abrdn (Aberdeen) Official Aberdeen gateway + SEC N-PORT holdings fallback + Yahoo history/dividends aberdeen
Amplify Amplify ETFs (Firestore data feed) Amplify
Capital Group Official Capital Group fund data + SEC N-PORT holdings fallback + Yahoo history fallback Capital-Group
Fidelity SEC EDGAR N-PORT-P + Yahoo Finance Fidelity
First Trust ftportfolios.com official ETF list + fund summary, holdings, distribution and price-history export pages + SEC EDGAR N-PORT-P holdings fallback + Yahoo Finance history fallback First-Trust
Franklin Templeton franklintempleton.com ETF listings + product pages + SEC EDGAR N-PORT-P Franklin
Global X globalxetfs.com Next.js catalog and fund pages + dated full-holdings CSV Global X
Goldman Sachs am.gs.com fund finder + detail pages + SEC EDGAR N-PORT-P Goldman-Sachs
Invesco invesco.com CSV downloads + Yahoo Finance Invesco
iShares iShares (BlackRock) product workbooks iShares
JPMorgan am.jpmorgan.com fund explorer + product-data JSON JPMorgan
NEOS neosfunds.com lineup table + official fund pages + daily holdings CSV Neos
Northern Trust etfs.ntam.northerntrust.com funds list + per-fund CSV/JSON downloads Northern-Trust
ProShares proshares.com ETF finder + fund pages + official data host ProShares
Schwab schwabassetmanagement.com product pages + CSV exports Schwab
SPDR SSGA / State Street public feeds SPDR
VanEck vaneck.com ETF finder + product pages VanEck
Vanguard Vanguard product pages + SEC EDGAR N-PORT-P Vanguard
VictoryShares VCM VictoryShares catalog and product JSON + SEC EDGAR N-PORT-P holdings fallback + Yahoo Finance adjusted-market-price history VictoryShares
WisdomTree WisdomTree product table + SEC EDGAR N-PORT-P + Yahoo Finance WisdomTree

License

MIT — same as all sibling ETF repositories.

ProShares® and the fund names/tickers referenced here are trademarks of ProShares Trust and ProShare Advisors LLC. This is an independent, unofficial tool; it is not affiliated with, endorsed by, or sponsored by ProShares. All data is reproduced from ProShares' own public pages and downloads for research purposes. All other trademarks, including index names, are the property of their respective owners.

About

ProShares ETF. A single-file client-side tool reading ./api/proshares (ProShares ETF finder, product pages, official holdings, NAV history and performance data) into a searchable ETF/asset-class catalog with per-fund tabs, watchlist, CSV/TXT export. TailwindCSS, dark mode, Bun updater.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages