Filtering returns for a specific period
When we have VariableReturns over a long period, for instance, 1900 to 2017, it can be interesting to use a smaller period to simulate what would happen if the historical returns in a smaller period, say 50 years, would be repeated.
We are going to create a method in the VariableReturns class that will keep only the returns contained in a specific period. Here is the unit test in ReturnsSpec.scala:
"VariableReturns.fromUntil" should {
"keep only a window of the returns" in {
val variableReturns = VariableReturns(Vector.tabulate(12) { i =>
val d = (i + 1).toDouble
VariableReturn(f"2017.$d%02.0f", d)
})
variableReturns.fromUntil("2017.07", "2017.09").returns should ===
(Vector(
VariableReturn("2017.07", 7.0),
VariableReturn("2017.08", 8.0)
))
variableReturns.fromUntil("2017.10", "2018.01").returns should ===
(Vector(
VariableReturn("2017.10", 10.0),
VariableReturn("2017.11", 11.0),
VariableReturn("2017.12", 12.0)
))
}
}
First, we generate a sequence of returns and assign them to variableReturns using the function Vector.tabulate. It generates 12 elements, and each element is produced by an anonymous function, taking a parameter i that will go from 0 to 11. In the call to the VariableReturn constructor, for the monthId argument, we use the f interpolator to generate a string in the form 2017.01 when d = 1, 2017.02 when d = 2, and so on.
The function fromUntil that we are specifying will return a VariableReturns type that contains a specific window inside the original returns. For now, we assume that the arguments passed to fromUntil are valid months that are present in variableReturns. Ideally, we should add unit tests to specify what should happen if they are not.
Here is the implementation in Returns.scala:
case class VariableReturns(returns: Vector[VariableReturn]) extends Returns {
def fromUntil(monthIdFrom: String, monthIdUntil: String):
VariableReturns =
VariableReturns(
returns
.dropWhile(_.monthId != monthIdFrom)
.takeWhile(_.monthId != monthIdUntil))
}
We use the higher order function dropWhile to drop elements until we reach the condition monthId == monthIdFrom. Then, we call takeWhile on the resulting collection to keep all elements until monthId == monthIdUntil. This will return a collection that keeps only the elements in a window that starts at monthIdFrom and ends just before monthIdUntil.
Run ReturnsSpec, and it should pass.