Monday, 2 November 2015

Typo in definition of carry rule for futures in "Systematic Trading" book

A thousand apologies but the definition of the carry rule for futures in Appendix B of my book "Systematic Trading" is incorrect.

On page 287 of the print edition (Heading: The carry trading rule )

For 'Futures: If not trading nearest contract'

Instead of Current contract price minus nearer contract price

It should read Nearer contract price minus current contract price

For 'Futures: If trading nearest contract'

Instead of Next contract price minus current contract price

It should read Current contract price minus next contract price

The spreadsheet here was also wrong and is now corrected.

My python code was already correct; which is a relief as I use this rule in my own trading :-).

The figures and explanations of the rule in chapter seven are fine, as are the calculations for other asset classes in Appendix B.

I'd like to thank the reader (Raphael C) who pointed this error out to me.


  1. Hello Rob,

    I would like to bring your attention to another moment in your calculations on this website and your book (really great book, thanks!).

    Defining volatility:
    1. In appendix D, page 298, you define volatility with STDEV function as well as using EWMA calculations. You define Return as B2 = (A2-A1)/A1.
    2. In "Spreadsheet: EWMAC calculation example" for Ch.7 available on your website you define Return as difference between prices D21=C21-C2 and then calculate std deviation with EWMA rule.
    3. In code from GitHub you define Return again using difference and calculate everything using Python func:
    stdev_returns=pd.ewmstd(price - price.shift(1), span=vol_lookback)

    So I would like to ask you if it is by design. Seems like all three methods give different numbers when applied to the same data.

    Thank you,

    1. Hi Pavel

      I use two different kinds of volatility:

      % price volatility (i.e. standard deviation of [price_t - price_t_1] / price). I use this to calculate volatility for the purposes of scaling positions.

      price difference volatility (i.e. standard deviatoin of [price_t - price _t-t]). I use this to adjust the EWMAC forecast and the carry forecast (and most other trading rules).

      Note that in eithier case you can calculate volatility using eithier the ewma function in python (also shown in the chapter 7 spreadsheet) or simple moving average (this is identical to using STDEV in excel with a fixed window).

  2. Yes, it is clear now. Thank you.

    1. Hi Rob,

      I am facing another interesting moment with portfolio from Ch. 15. Trying to model its past behavior in 2005 and noticed one thing. When price vol is too low I get too large corn positions for my account.

      To be specific, for instance for 3rd Jan 2005 I am getting from your corn data the price = 326.5, block value = $163.25, Price Volatility, % (G) = 0.48%, Volatility Scalar = 39.9, and Rounded Target Position in blocks is short 35 contracts which appears too much for $250000 account. I have these calculations in excel spreadsheet, but unfortunately cannot attach it here.

      so I would like to ask you if it makes sense to floor the price volatility somehow in the automated way so that it is possible to model any new strats in the past with your framework? or maybe I am not getting/missing something..

      PS Checked max possible position for this date. Getting 2 * 39.9 * 23.33% * 1.89 = 35 blocks.

      Thank you,

    2. Pavel,

      Two points

      a) if you connect with me on linked in, then you can email the spreadsheet so I can check your calculations - that does sound low

      b) yes it does make sense to floor vol.

      For example in python

      def robust_vol_calc(x, days=35, min_periods=10,
      floor_min_quant=0.05, floor_min_periods=100,
      Robust exponential volatility calculation, assuming daily series of prices
      We apply a volfloor based on lowest vol over recent history

      :param days: Number of days in lookback (*default* 35)
      :type days: int
      :param min_periods: The minimum number of observations (*default* 10)
      :type min_periods: int

      :param floor_min_quant: The quantile to use for volatility floor (eg 0.05 means we use 5% vol) (*default 0.05)
      :type floor_min_quant: float

      :param floor_days: The lookback for calculating volatility floor, in days (*default* 500)
      :type floor_days: int

      :param floor_min_periods: Minimum observations for floor - until reached floor is zero (*default* 100)
      :type floor_min_periods: int

      :returns: pd.DataFrame -- volatility measure


      ## Standard deviation will be nan for first 10 non nan values
      vol=pd.ewmstd(x, span=days,min_periods=min_periods)

      ## Find the rolling 5% quantile point to set as a minimum
      vol_min=pd.rolling_quantile(vol, floor_days, floor_min_quant, floor_min_periods)
      ## set this to zero for the first value then propogate forward, ensures we always have a value

      ## apply the vol floor
      vol_with_min=pd.concat([vol, vol_min], axis=1)
      vol_floored=vol_with_min.max(axis=1, skipna=False).to_frame()

      return vol_floored

  3. Hi Rob,
    Just wanted to mention that the calculation of the carry rule in the excel is still wrong.

  4. Hi Rob, just adding some detail to Max's comment. On the carry spreadsheet, it looks like you corrected the formulas in cells G20:G21. But the incorrect formulas remain in G22 and below.

  5. Hi, Rob. If I use your EWMAC spreadsheet for contracts for which you can only trade the front month, I assume no modification to the spreadsheet is necessary. The only difference is that I would be trading the nearer contract. The forecast is calculated the same way, whether I am trading the nearer or the farther. Is this correct? Thanks.

    1. No you need to multiply by -1 because the spreadsheet has nearer - current and if you replace nearer with a further out contract price (so column F is the back contract not the front relative to the traded contract) the forecast will be the wrong way round.

  6. You have written that, for contracts for which you must trade the front month, ideally you should use the spot price to represent the price of the nearer contract. So, the spot price of ESTX50 would be the the ESTX50 Index on IB? In using this spot price, I suppose that the quantity of days between the near and far contracts would change every day, since you would assume the date of the spot price to always be current date, versus the fixed delivery date of the front month contract. Thanks, as always.

    1. That's correct. I don't use the spot price myself, for all these reasons plus it's hard to get spot for most contracts, stock indices and STIR being the exception. Instead I use the second contract, which isn't ideal eithier of course.

  7. some of the carrydata.csv's in the "legacycsv" module are backwards? Wheat, Gas, Crude etc have the "carry contract" as the front month and "price contract" as back month. this is contrary to all other files in the legacycsv module. Most other have "carry" as the back month. Which is correct?

    1. Both are correct. Its preferable to have carry as a nearer contract than the priced contract. Where this isn't possible (because only the first contract is liquid) they are reversed.

      See Appendix B.