# Trading Strategy Analysis using Python and the FFN Package – Part 1

In this post I will be reviewing and running through examples of using the brilliant python module, “ffn – Financial Functions for **Python**“, which has been created by Philippe Morissette and released on the MIT license. The github page can be found here (http://pmorissette.github.io/ffn/index.html)

The module helps quickly carry out analysis of trading strategies and financial asset price series/history. It can deal with single series using the “PerformanceStats” class, or multiple combined assets simultaneously using the “GroupStats” class.

Let’s begin with the simple, one asset/strategy case and run through some examples.

We begin by importing the relevant modules (and if working in a Jupyter notebook, the call to allow matplotlib objects to be rendered in the browser).

1 2 3 4 |
import pandas as pd import numpy as np import ffn %matplotlib inline |

Now lets generate a set of random performance data, spanning a 1000 day period. We start by setting the number of days we want (i.e. 1000), then we use the numpy “randn” call to generate an array of 1000 numbers drawn from the normal distribution. To give our data a slight upward bias, I have then added to these figures a random value chosen from the uniform distribution with a maximum value of 0.2 and a minimum value of 0.0. These random figures represent the daily returns of our trading strategy, or stock price.

I have then created a Pandas DataFrame from this “returns” data and added a column of the cumulative sum of those returns, adding 100 to represent starting capital – these represent the strategy “equity” or the amount of cash we have in our trading account.

The ffn package does allow the direct download of historic stock price data from Yahoo Finance but thought i would use random data in the first instance. I will go over the download of data later in the post.

1 2 3 4 5 6 |
num_days = 1000 data = (np.random.randn(num_days) + np.random.uniform(low=0.0, high=0.2, size=num_days)) index = pd.date_range('01/01/2010',periods=num_days, freq='D') data = pd.DataFrame(data,index=index,columns=['Returns']) data['Equity'] = data.cumsum() + 100 data.iloc[0] = 100 |

So the “Equity” column of our DataFrame is the one we are most interested in as this is our theoretical trading account equity. We start by using the “calc_stats” method on this data and assigning that to a variable called “perf”

1 |
perf = data['Equity'].calc_stats() |

If we lok at what “perf” actually is by looking at its “type”, we can see it is a ffn.core.PerformanceStats object. This means we can use any of the PerformanceStats object methods on it.

1 |
type(perf) |

“ffn.core.PerformanceStats”

Let’s start by plotting the equity curve. This is very similar to just calling the usual “plot()” syntax from Pandas.

1 |
perf.plot() |

Great stuff, so we now have a visual representation of our equity curve. Let’s move on to some statistics; we can very easily do this using ffn by calling the “display()” method. This will print out the following set of comprehensive statistics.

1 |
perf.display() |

That is a pretty comprehensive set of statistics – the Sharpe Ratio, Calmar Ratio, Total Returns, CAGR, Max Drawdown, Periodic Returns plus more…that’s not a bad time saver – if we were to have to calculate these all ourselves it could take quite some time.

The next ffn method we might be interested in is that to represent a table of monthly returns. Again, it’s as easy as this:

1 |
perf.display_monthly_returns() |

How about plotting a visual representation of our strategy drawdown series…it can be carried out with a single line of code:

1 |
ffn.to_drawdown_series(data['Equity']).plot(figsize=(15,7),grid=True) |

And plotting a histogram of returns is again as simple as:

1 |
perf.plot_histogram() |

If we want to get hold of the set of comprehensive analysis statistics mentioned above, but this time in a Pandas series, rather than printed out as a table, we can get hold of it as follows:

1 |
perf.stats |

This Series object is index-able, just like any other Pandas Series so we can pick out any relevant items we need using the following syntax – for example if we wanted the Yearly Sharpe Ratio:

1 |
perf.stats['yearly_sharpe'] |

“1.9283569892842471”

Finally for the “PerformanceStats” object, we can extract the series of “Lookback Returns” as simply as follows (this can also be indexed similarly to the “perf.stats” object mentioned above).

1 |
perf.display_lookback_returns() |

I’ll leave it here for this post, and in the upcoming post will deal with using the FFN package when considering multiple price/equity series simultaneously using the “GroupStats” object.

Until next time!

so nice thanks