suggestion for splitting backtest() method into single and multiple
Closed this issue · 2 comments
Currently the backtest()
method tries to support both single policy + multiple policies.
The API of backtest()
could get confusing as more functionality is built out with single backtest vs multi backtest in mind. And the fact that it returns either an object or list of objects is generally frowned upon.
Suggest breaking backtest()
into:
backtest()
- keep the current API (exceptparallel
) but only accept single policy and single objects for the rest of the parametersbacktest_multiple()
- only support lists of policies. Just a suggestion but perhaps have some kwargs implementation so one can link the policies with holdings (and potentially other params), i.e.,:
multiple_policies = [
{'policy': policy_1,'h': holdings_1,},
{'policy': policy_2,'h': holdings_2,}, ...
]
backtest_multiple(multiple_policies) # would call backtest() with the first and second dicts as kwargs
Ok, maybe you have memories of the original API: We had MarketSimulator.run_backtest
and MarketSimulator.run_multiple_backtests
. I wanted to simplify the interface and so I merged them. Yes, currently when doing many backtests it returns a list of results, but the plan is to have a CombinedResults
class with __iter__
and __getitem__
(so it acts like a list) but also methods specific for combined results, like making a risk-reward plot, getting the Pareto-optimal backtests, etc. Again, I refer to what was implemented in the 2017 examples in https://github.com/cvxgrp/cvxportfolio/tree/0.0.X ), which should become part of the main api. But your point is valid, and we may split the two functionalities in two methods. I suggest MarketSimulator.backtest
and MarketSimulator.backtest_many
(multiple is too long a word). Regarding args, I would do each of: policies, start_times, end_times, h, value_init, ... take either an iterable or a non-iterable. If you pass more than one iterable they must have the same length. All non-iterables are broadcasted.
Actually, although I do agree with your concern, let me think about it. Numpy-style broadcasting is a powerful and very natural syntax, I think once we have the combined results rather than a list of results as return value the current syntax won't be too bad (and simpler than having 2 methods).