docs: def static_transition(timestamp, contract_dates, transition, holidays=None,
                        validate_inputs=True):
      """
      An implementation of *get_weights* parameter in roller().
      Return weights to tradeable instruments for a given date based on a
      transition DataFrame which indicates how to roll through the roll period.
  
      Parameters
      ----------
      timestamp: pandas.Timestamp
          The timestamp to return instrument weights for
      contract_dates: pandas.Series
          Series with index of tradeable contract names and pandas.Timestamps
          representing the last date of the roll as values, sorted by values.
          Index must be unique and values must be strictly monotonic.
      transition: pandas.DataFrame
          A DataFrame with a index of integers representing business day offsets
          from the last roll date and a column which is a MultiIndex where the
          top level is generic instruments and the second level is
          ['front', 'back'] which refer to the front month contract and the back
          month contract of the roll. Note that for different generics, e.g. CL1,
          CL2, the front and back month contract during a roll would refer to
          different underlying instruments. The values represent the fraction of
          the roll on each day during the roll period. The first row of the
          transition period should be completely allocated to the front contract
          and the last row should be completely allocated to the back contract.
      holidays: array_like of datetime64[D]
          Holidays to exclude when calculating business day offsets from the last
          roll date. See numpy.busday_count.
      validate_inputs: Boolean
          Whether or not to validate ordering of contract_dates and transition.
          **Caution** this is provided for speed however if this is set to False
          and inputs are not defined properly algorithm may return incorrect
          data.
  
      Returns
      -------
      A list of tuples consisting of the generic instrument name, the tradeable
      contract as a string, the weight on this contract as a float and the date
      as a pandas.Timestamp.
  
      Examples
      --------
      >>> import pandas as pd
      >>> import mapping.mappings as mappings
      >>> cols = pd.MultiIndex.from_product([["CL1", "CL2"], ['front', 'back']])
      >>> idx = [-2, -1, 0]
      >>> transition = pd.DataFrame([[1.0, 0.0, 1.0, 0.0], [0.5, 0.5, 0.5, 0.5],
      ...                            [0.0, 1.0, 0.0, 1.0]],
      ...                           index=idx, columns=cols)
      >>> contract_dates = pd.Series([pd.Timestamp('2016-10-20'),
      ...                             pd.Timestamp('2016-11-21'),
      ...                             pd.Timestamp('2016-12-20')],
      ...                            index=['CLX16', 'CLZ16', 'CLF17'])
      >>> ts = pd.Timestamp('2016-10-19')
      >>> wts = mappings.static_transition(ts, contract_dates, transition)
      """
  
      if validate_inputs:
          # required for MultiIndex slicing
          _check_static(transition.sort_index(axis=1))
          # the algorithm below will return invalid results if contract_dates is
          # not as expected so better to fail explicitly
          _check_contract_dates(contract_dates)
  
      if not holidays:
          holidays = []
  
      # further speedup can be obtained using contract_dates.loc[timestamp:]
      # but this requires swapping contract_dates index and values
      after_contract_dates = contract_dates.loc[contract_dates >= timestamp]
      contracts = after_contract_dates.index
      front_expiry_dt = after_contract_dates.iloc[0]
      days_to_expiry = np.busday_count(front_expiry_dt.date(), timestamp.date(),
                                       holidays=holidays)
  
      name2num = dict(zip(transition.columns.levels[0],
                          range(len(transition.columns.levels[0]))))
      if days_to_expiry in transition.index:
          weights_iter = transition.loc[days_to_expiry].iteritems()
      # roll hasn't started yet
      elif days_to_expiry < transition.index.min():
          # provides significant speedup over transition.iloc[0].iteritems()
          vals = transition.values[0]
          weights_iter = zip(transition.columns.tolist(), vals)
      # roll is finished
      else:
          vals = transition.values[-1]
          weights_iter = zip(transition.columns.tolist(), vals)
  
      cwts = []
      for idx_tuple, weighting in weights_iter:
          gen_name, position = idx_tuple
          if weighting != 0:
              if position == "front":
                  cntrct_idx = name2num[gen_name]
              elif position == "back":
                  cntrct_idx = name2num[gen_name] + 1
              try:
                  cntrct_name = contracts[cntrct_idx]
              except IndexError as e:
                  raise type(e)(("index {0} is out of bounds in\n{1}\nas of {2} "
                                 "resulting from {3} mapping")
                                .format(cntrct_idx, after_contract_dates,
                                        timestamp, idx_tuple)
                                ).with_traceback(sys.exc_info()[2])
              cwts.append((gen_name, cntrct_name, weighting, timestamp))
  
      return cwts