I've been reading last few posts between you and Rob on this topic and thinking about where does my system fit in, and I think I'm smack in the middle between very dynamic nature of Rob's system and static nature of yours.
I don't stitch functions together at runtime, but I also don't store static values in the DB.
The struggle for me was having the design of the system resemble an actual domain of a trading system, while still maintaining flexibility. This is vague, so here's what I mean when I say this, explained on the example of pandas.
Pandas structures that store data and allow efficient operations that we sometimes have to do, DataFrame and Series, really have no place in a sound system design. For example, if you have a series of prices, that tells you nothing about what you can do with those. Can you compute risk from these prices? Are they adjusted or not? Are they for the currently traded contract or carry? In which currency are they? In addition, the dynamic nature of DataFrames means any part of the system can easily add arbitrary columns, encapsulation is hard to that way (also, as a software engineer by trade, it was hard for me to do something like that). Aditionally, I look at pandas as an implementation detail. I'm using pandas today, but it might be something different tomorrow, who knows. If I have to change that, I don't want to have to change hundreds of places in my code.
I almost look at it this way: I'm not interested in this pandas dataframe or running a rolling mean on it, what I really want to do is compute instrument risk from historical adjusted prices.
However, one of the things I decided early on was that I have to be able to run the backtest on the same system I trade in production, so I do like some of the benefits that pandas gives me, mainly performant operations on a lot of data.
So the way I overcame the problem was to use pandas and DataFrames and all the stuff, but encapsulate it behind a well defined interface, that I defined in terms of the domain. For example, I have an AdjustedPrices class, that has a method calculate_risk(lookback). I have another class called MultiplePrices that has a method calculate_carry(). Both use DataFrames under the hood, but the rest of the system doesn't know that and doesn't care. It also prevents me from making a mistake of, say, calculating risk on carry prices.
As I mentioned above, I do use the same system for trading and backtesting. Just recently, I've been looking to extend backtesting capabilities a lot (price data store redesign - I posted a picture above, I'll be storing data for 100+ markets, and I'd also like better stats) so I looked around at how some other tools do backtesting and was surprised to see that this is not a solved problem at all, especially for futures.
I played with backtrader, quantstrat (in R) Amibroker (standalone application), even considering giving up on my "same system for backtests as for trading" mantra if I find something good, but TL;DR: if you have a multi-strategy futures system you're on your own. So now I'm hacking something on my own, currently trying to see if I can use pyfolio to just render the results. I'm not looking for much, just basic stats around performance, drawdowns, costs, trading speed and some charts.
I've seen how Rob does it in pysystemtrade, this is where things are really nice if you have all the interim data of your system in DataFrames, rendering charts and computing stats is super easy, but how do others do it?
What do you think of backtrader? Is it any good?
One of the other members who used to post built this
https://github.com/chrism2671/PyTrendFollow
). Aditionally, I look at pandas as an implementation detail. I'm using pandas today, but it might be something different tomorrow, who knows. If I have to change that, I don't want to have to change hundreds of places in my code.
