Skip to content
All library documents

Tracking a Commodity Index and Diagnosing Roll-Date Mismatches

Article Quant Q&A · Author: Michael Stern

Summary

The document outlines an attempt to reproduce the Dow Jones-UBS Commodity Index from constituent futures prices. The described calculation applies annual commodity index multipliers to dollar-denominated prices, sums the products, and uses the change in that sum to update the index outside roll periods. Contract selection and currency conversion are also part of the procedure.

The example compares a calculated daily move with the published index move and finds a substantial discrepancy. A former index-team contributor suggests that generic front- and second-month futures series may not follow the index provider’s precise monthly roll rules. A mismatch in even one contract’s selected price can cause the difference, and a reversal on the following day may help identify a roll timing issue. The example does not establish the precise source of its discrepancy; reproducing an index requires matching its contract selection and roll conventions as well as using constituent prices.

Key ideas

  • Index tracking can be built from constituent prices multiplied by annual commodity index multipliers.
  • Contract selection, currency conversion, and roll rules affect the calculated index value.
  • A data provider’s generic futures series may not match the index provider’s contract commitments on every date.
  • A discrepancy that reverses the next day can be a clue that roll timing caused the mismatch.

Tags

Full text
# generating (or tracking) the DJUBS commodity index


# generating (or tracking) the DJUBS commodity index












Dow Jones and UBS publish one of the most popular commodity index families, the Dow Jones-UBS Commodity Index and its subindices. They provide a detailed manual describing the composition of the index and its daily changes, available at https://us.spindices.com/indices/commodities/dow-jones-commodity-index

I have tried to implement code that follows the description in the manual, but given the closing prices of the various components, I can't match the end-of-day values published by DJUBS.

Has anybody here succeeded in this task, and willing to share their work? Any programming language will probably do, the form of the computation is going to be the same however it's developed.

-- for those who want more detail, see the below

- Proper computation methodology is described in the DJUBS Commodity Index Handbook, which is available on the page I link to above. The best summary of the process appears on page 13 of the book, where it reads "Once the Commodity Index Multipliers are determined, the calculation of the DJ-UBS CI is an arithmetic process whereby the CIMs for the Index Commodities are multiplied by the respective prices in U.S. dollars for the applicable Designated Contracts. The products are then summed. The daily percentage change in this sum is then applied to the prior day's DJ-UBS CI value to calculate the then current DJ-UBS CI value." So we need to multiply the Commodity Index Multipliers (which are determined annually, and listed in the handbook) by the US Dollar prices for the designated contracts (the commodities in question are listed in the handbook, as is the table for selecting which future to own at any given time). Sum the CIM*DollarPrice for two dates and scale the index by the percentage change between the dates (assuming we are not in the roll period, which for the sake of simplicity, let's assume we're not).

- The CIMs appear on page 34 of the handbook.

- The future selection table appears on page 35

- Multipliers for USD price conversion appear on page 36

My code is in Mathematica and here since people are asking:

```
djubsCashFrom2012[dateList_List] := 
 Total[Table[
   preppedCIMs[[i]][[2]]*(1/
      preppedMultipliers[[i]][[2]])*
    priceFromDatabaseOrBBG[
     futureFromDate[dateList, preppedCIMs[[i]][[1]], 
      calendar -> "djubs", offset -> 0, rolloverRule -> "djubs"], 
     dateList], {i, 1, Length[preppedCIMs]}]]
```

So you have an idea of the components, here's the list of contracts involved

```
{{"Aluminum", "LAN2 Comdty"}, {"Brent Crude", 
  "COU2 Comdty"}, {"Coffee", "KCN2 Comdty"}, {"Copper", 
  "HGN2 Comdty"}, {"Corn", "C N2 Comdty"}, {"Cotton", 
  "CTN2 Comdty"}, {"Gold", "GCQ2 Comdty"}, {"Heating Oil", 
  "HON2 Comdty"}, {"Lean Hogs", "LHN2 Comdty"}, {"Live Cattle", 
  "LCQ2 Comdty"}, {"Natural Gas", "NGN2 Comdty"}, {"Nickel", 
  "LNN2 Comdty"}, {"Silver", "SIN2 Comdty"}, {"Soybean Oil", 
  "BON2 Comdty"}, {"Soybeans", "S N2 Comdty"}, {"Sugar", 
  "SBN2 Comdty"}, {"Unleaded Gasoline (RBOB)", 
  "XBN2 Comdty"}, {"Wheat", "W N2 Comdty"}, {"WTI Crude", 
  "CLN2 Comdty"}, {"Zinc", "LXN2 Comdty"}}
```

Here's the list of USD multipliers

```
{{"Aluminum", 1}, {"Brent Crude", 1}, {"Coffee", 
    100}, {"Copper", 100}, {"Corn", 100}, {"Cotton", 100}, {"Gold", 
    1}, {"Heating Oil", 1}, {"Lean Hogs", 100}, {"Live Cattle", 
    100}, {"Natural Gas", 1}, {"Nickel", 1}, {"Silver", 
    100}, {"Soybean Oil", 100}, {"Soybeans", 100}, {"Sugar", 
    100}, {"Unleaded Gasoline (RBOB)", 1}, {"Wheat", 
    100}, {"WTI Crude", 1}, {"Zinc", 1}};
```

And here's the Commodity Index Multipliers

```
{{"Aluminum", 0.12200124`}, {"Brent Crude", 
    2.01846373`}, {"Coffee", 49.71828827`}, {"Copper", 
    88.13795172`}, {"Corn", 44.42764359`}, {"Cotton", 
    89.42000933`}, {"Gold", 0.25961493`}, {"Heating Oil", 
    48.39480046`}, {"Lean Hogs", 107.9219512`}, {"Live Cattle", 
    129.4759932`}, {"Natural Gas", 148.9289604`}, {"Nickel", 
    0.00589452`}, {"Silver", 4.1377227`}, {"Soybean Oil", 
    282.7408585`}, {"Soybeans", 25.37581892`}, {"Sugar", 
    691.6310707`}, {"Unleaded Gasoline (RBOB)", 
    52.80986115`}, {"Wheat", 34.03893139`}, {"WTI Crude", 
    4.07921265`}, {"Zinc", 0.07223231`}};
```

For a simple test, take the commodity prices on 5/15 and 5/16 of this year

5/15 prices

```
{{"Aluminum", 2013.}, {"Brent Crude", 111.45}, {"Coffee", 
  178.4}, {"Copper", 351.75}, {"Corn", 597.25}, {"Cotton", 
  79.16}, {"Gold", 1557.1}, {"Heating Oil", 293.86}, {"Lean Hogs", 
  86.4}, {"Live Cattle", 116.425}, {"Natural Gas", 2.568}, {"Nickel", 
  16977.}, {"Silver", 28.08}, {"Soybean Oil", 51.47}, {"Soybeans", 
  1413.}, {"Sugar", 20.4}, {"Unleaded Gasoline (RBOB)", 
  289.16}, {"Wheat", 608.5}, {"WTI Crude", 94.35}, {"Zinc", 1931.75}}
```

5/16 prices

```
{{"Aluminum", 2023.}, {"Brent Crude", 109.75}, {"Coffee", 
  178.}, {"Copper", 347.8}, {"Corn", 620.}, {"Cotton", 
  76.97}, {"Gold", 1536.6}, {"Heating Oil", 290.39}, {"Lean Hogs", 
  86.5}, {"Live Cattle", 116.875}, {"Natural Gas", 2.687}, {"Nickel", 
  16985.}, {"Silver", 27.196}, {"Soybean Oil", 50.43}, {"Soybeans", 
  1422.}, {"Sugar", 20.73}, {"Unleaded Gasoline (RBOB)", 
  286.51}, {"Wheat", 638.75}, {"WTI Crude", 93.19}, {"Zinc", 1895.75}}
```

The index change as published by DJUBS from June 15 to Jun 16 was +.328% but using my methodology I get -.866%.

## Answer by demully (score 3)

https://quant.stackexchange.com/a/57486

As it happens, I, in a past life, was part of the team that created the UBS-CMCI commodity indices...

Your problem will (probably) lie in mismatch between the methodology of monthly rolls a la the index's rolling methodology and the rolls on Bloomberg's generic front-vs-second month contracts. Most of the time, these will neatly equate. But every now and then, the finer points of the index providers' rules will not be mirrored in a data provider's generic assumptions.

So in your code below, there will be a different price in one of the commodities, looking at the broker's contractual commitments, to what a data provider's algo says about the same.

Does your problem (at least mostly) reverse itself out the next day? That's usually the big "tell" here (although roll timings can be hugely important in volatile times, not least that infamous -$34/bbl WTI in May)...

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.