# Is there an equivalent to MovingMap[] for functions that work on more than one TimeSeries?

I have a family of functions that require two TimeSeries (A and B). As a trivial example, imagine a function called beta[tsA_,tsB_] that determines the slope of the linear regression line for the changes in TimeSeries A relative to changes in TimeSeries B. It is easy to apply such a function to the entire series, but what if I want to apply it on a rolling basis?

MovingMap[] is no help because it allows only one TimeSeries as an argument. MapThread[] works but requires sacrificing all of MovingMap[]'s sophistication about TimeSeries.

Any suggestions?

You can create a time series with multiple values and apply an arbitrary function.

dates = DateRange[{2015, 10, 1}, DatePlus[{2015, 10, 1}, 29]];
data = RandomInteger[{1, 5}, {Length[dates], 2}];
tsdata = TimeSeries[data, {dates}];


Now, you can apply MovingMap on the function of your choice:

rollstd = MovingMap[StandardDeviation, tsdata, Quantity[4, "Days"]]
DateListPlot[rollstd, PlotTheme -> "Detailed"]


Further, you can define a function betafun as Covariance[series1,series2]/Variance[series2] and use this function on the time series.

betafun = N[Apply[Covariance, Transpose[#]]/Last[MapAt[Variance, Transpose[#], 2]]] &;
rollbeta = MovingMap[betafun, tsdata, Quantity[4, "Days"]];
DateListPlot[rollbeta]


This is an interesting question!

The short answer is that there doesn't seem to be any built-in that could perform the required task, something which is already alluded to in the question,

There is, however, a way to use MovingMap on any number of series in a way reminiscent of using MapThread on ordinary expressions.

The idea is to first bundle the series in a single TemporalObject with appropriate ValueDimensions and then feed it to MovingMap.

Such a solution has the downside that one needs to pick the series apart and put them back together again. It could also be argued that if it comes down to extracting "Paths" and/or "Values" from the series, one can simply then use ListConvolve or probably Partition to get the job done without having to reconstruct a new TimeSeries in order to feed it to MovingMap.

Even though this doesn't sound altogether unreasonable, it wouldn't seem completely useless to attempt a solution along the lines of 'solving a TimeSeries problem using TimeSeries', even in a somewhat roundabout way:

(* one series, two paths *)
bundle = TemporalData[{tsA, tsB}, ResamplingMethod -> None];

(* resample using avail t-val pairs *)
union = TimeSeriesResample[bundle, "Union"]

(* take the 'ResamplingMethod' value with a grain of salt *)
tsopts = {ResamplingMethod -> {None, None}, ValueDimensions -> 2,
MissingDataMethod -> {"Interpolation", InterpolationOrder -> 0}};

(* one series, vector-valued single path *)
tsx = TimeSeries[Transpose[union["Values", All]], {union["Times"]},
Apply[Sequence][tsopts]]


finally,

MovingMap[f[Differences[#]] &, tsx, Quantity[30, "Events"]]


should do the trick. Obviously, Quantity[30, "Events"] can be replaced with any other desirable wspec and f is used as a stand-in for an appropriate fitting function; probably Differences is something that can be incorporated later into f, too.