Calculate how much every holding (or sector) of a fund added to or took off its return over the period: the holding’s weight at the start of the period times its return over the period, in decimals and in points of the fund’s price (or of an index, e.g. the S&P 500 for SPY). It answers questions such as “how many points did technology take off the S&P 500 this month?” and shows when a few large holdings carry an index while most of its stocks fall, or the other way around.

The period runs from the close before the Toolkit’s start date to the close on its end date, so a start date of January 1 gives the return so far this year. Returns are price returns of the split-adjusted close, as an index level such as the S&P 500 is a price index; dividends are not included.

A fund publishes only its current holdings, so the weights are those of the close the holdings were last published for (the last close 16 hours or more before the update, as for the NAV), rolled back to the start of the period with every holding’s own price change relative to the fund’s: w_start = w × (P_start / P_holdings_date) × (F_holdings_date / F_start), with F the fund’s price. That is exact for a market capitalization weighted index between rebalancings and drifts with every rebalancing, share issuance, buyback and index change in between, so the longer (or the further back) the period, the less precise the split. The Remainder row holds what the priced holdings do not explain: cash, holdings without a symbol or price (bonds, futures) and that drift. The Total row is the fund’s own price return, so the rows add up to it.

Also known as: contribution to return, index contribution, attribution of an index move, points contribution, sector contribution.

Contribution in Python or via the MCP

Install the Finance Toolkit with:

pip install financetoolkit -U

Then call get_contribution as shown below.

from financetoolkit import Toolkit

toolkit = Toolkit(
    ["SPY"],
    api_key="FINANCIAL_MODELING_PREP_KEY",
    start_date="2026-10-01",
    end_date="2026-10-31",
    benchmark_ticker=None,
)

toolkit.etf.get_contribution(group_by="sector", index="^GSPC")

Or, after setting up the Finance Toolkit MCP, ask:

Which sectors added the most to SPY's return in October 2026, and how many S&P 500 points did each contribute?

Which returns:

  Start Weight Return Contribution Points
Healthcare 0.0918 0.0974 0.0089 68.4349
Financial Services 0.1122 0.0574 0.0064 49.3077
Consumer Defensive 0.0432 0.1157 0.005 38.2649
Energy 0.0342 0.1384 0.0047 36.2639
Consumer Cyclical 0.0859 0.0418 0.0036 27.4788
Utilities 0.0188 0.1011 0.0019 14.5331
Basic Materials 0.0167 0.0555 0.0009 7.0788
Real Estate 0.017 0.0498 0.0008 6.4553
Industrials 0.0738 -0.0021 -0.0002 -1.1988
Communication Services 0.0975 -0.1502 -0.0147 -112.129
Technology 0.4082 -0.0662 -0.027 -206.655
Remainder 0.0006 nan 0.0004 2.8372
Total 1 -0.0091 -0.0091 -69.3287

Parameters

get_contribution accepts the following parameters.

ParameterTypeDescriptionExample
group_bystr“holding” for every holding or “sector” for every sector (from the holdings’ company profiles). Defaults to “holding”."holding"
holdingsint | NoneThe number of largest holdings (by weight) to price, one request each; the rest counts towards the Remainder. Defaults to None, which prices every holding with a symbol.None, which prices every holding with a symbol
indexstr | NoneThe ticker of an index whose level at the start of the period converts the contributions into index points, e.g. “^GSPC” for SPY. Defaults to None, which gives points of the fund’s own price.None, which gives points of the fund's own price
roundingint | NoneThe number of decimals to round the results to. Defaults to None, which uses the rounding of the Toolkit.2
Share