diff --git a/README.md b/README.md
index 9cfdf2f..2e3e641 100644
--- a/README.md
+++ b/README.md
@@ -52,51 +52,463 @@ $> make test
## Usage
-### Example:
+### Sample backtest
+
+You can run this example by putting the code into a Jupyter Notebook/Lab file in this directory.
-We'll run a backtest of a stock portfolio holding `$AAPL` and `$GOOG`, and simultaneously buying 10% OTM calls and puts on `$SPX` ([long strangle](https://www.investopedia.com/terms/s/strangle.asp)).
-We'll allocate 97% of our capital to stocks and the rest to options, and do a rebalance every month.
```python
-from backtester import Backtest, Type, Direction, Stock
-from backtester.strategy import Strategy, StrategyLeg
+import os
+import sys
+
+BACKTESTER_DIR = os.getcwd()
+TEST_DATA_DIR = os.path.join(BACKTESTER_DIR, 'backtester', 'test', 'test_data')
+SAMPLE_STOCK_DATA = os.path.join(TEST_DATA_DIR, 'test_data_stocks.csv')
+SAMPLE_OPTIONS_DATA = os.path.join(TEST_DATA_DIR, 'test_data_options.csv')
+```
+
+
+```python
+from backtester import Backtest, Stock, Type, Direction
from backtester.datahandler import HistoricalOptionsData, TiingoData
+from backtester.strategy import Strategy, StrategyLeg
+```
-# Stocks data
-stocks_data = TiingoData('stocks.csv')
-stocks = [Stock(symbol='AAPL', percentage=0.5), Stock(symbol='GOOG', percentage=0.5)]
+First we construct an options datahandler.
-# Options data
-options_data = HistoricalOptionsData('options.h5', key='/SPX')
-schema = options_data.schema
-# Long strangle
-leg_1 = StrategyLeg('leg_1', schema, option_type=Type.PUT, direction=Direction.BUY)
-leg_1.entry_filter = (schema.underlying == 'SPX') & (schema.dte >= 60) & (schema.underlying_last <=
- 1.1 * schema.strike)
-leg_1.exit_filter = (schema.dte <= 30)
+```python
+options_data = HistoricalOptionsData(SAMPLE_OPTIONS_DATA)
+options_schema = options_data.schema
+```
-leg_2 = StrategyLeg('leg_2', schema, option_type=Type.CALL, direction=Direction.BUY)
-leg_2.entry_filter = (schema.underlying == 'SPX') & (schema.dte >= 60) & (schema.underlying_last >=
- 0.9 * schema.strike)
-leg_2.exit_filter = (schema.dte <= 30)
+Next, we'll create a toy options strategy. It will simply buy a call and a put with `dte` between $80$ and $52$ and exit them a month later.
-strategy = Strategy(schema)
-strategy.add_legs([leg_1, leg_2])
-allocation = {'stocks': .97, 'options': .03}
-initial_capital = 1_000_000
-bt = Backtest(allocation, initial_capital)
+```python
+sample_strategy = Strategy(options_schema)
+
+leg1 = StrategyLeg('leg_1', options_schema, option_type=Type.CALL, direction=Direction.BUY)
+leg1.entry_filter = (options_schema.dte < 80) & (options_schema.dte > 52)
+
+leg1.exit_filter = (options_schema.dte <= 52)
+
+leg2 = StrategyLeg('leg_2', options_schema, option_type=Type.PUT, direction=Direction.BUY)
+leg2.entry_filter = (options_schema.dte < 80) & (options_schema.dte > 52)
+
+leg2.exit_filter = (options_schema.dte <= 52)
+
+sample_strategy.add_legs([leg1, leg2]);
+```
+
+We do the same for stocks: create a datahandler together with a list of the stocks we want in our inventory and their corresponding weights. In this case, we will hold `VOO`, `TUR` and `RSX`, with $0.4$, $0.1$ and $0.5$ weights respectively.
+
+
+```python
+stocks_data = TiingoData(SAMPLE_STOCK_DATA)
+stocks = [Stock('VOO', 0.4), Stock('TUR', 0.1), Stock('RSX', 0.5)]
+```
+
+We set our portfolio allocation, i.e. how much of our capital will be invested in stocks, options and cash. We'll allocate 50% of our capital to stocks and the rest to options.
+
+
+```python
+allocation = {'stocks': 0.5, 'options': 0.5, 'cash': 0.0}
+```
+
+Finally, we create the `Backtest` object.
+
+
+```python
+bt = Backtest(allocation, initial_capital=1_000_000)
+
bt.stocks = stocks
bt.stocks_data = stocks_data
-bt.options_data = options_data
-bt.options_strategy = strategy
+bt.options_strategy = sample_strategy
+bt.options_data = options_data
+```
+
+And run the backtest with a rebalancing period of one month.
+
+
+```python
bt.run(rebalance_freq=1)
+```
+
+ 0% [██████████████████████████████] 100% | ETA: 00:00:00
+ Total time elapsed: 00:00:00
+
+
+
+
+
+
+
+ |
+ leg_1 |
+ leg_2 |
+ totals |
+
+
+ |
+ contract |
+ underlying |
+ expiration |
+ type |
+ strike |
+ cost |
+ order |
+ contract |
+ underlying |
+ expiration |
+ type |
+ strike |
+ cost |
+ order |
+ cost |
+ qty |
+ date |
+
+
+
+
+ | 0 |
+ SPX170317C00300000 |
+ SPX |
+ 2017-03-17 |
+ call |
+ 300 |
+ 195010.0 |
+ Order.BTO |
+ SPX170317P00300000 |
+ SPX |
+ 2017-03-17 |
+ put |
+ 300 |
+ 5.0 |
+ Order.BTO |
+ 195015.0 |
+ 2.0 |
+ 2017-01-03 |
+
+
+ | 1 |
+ SPX170317C00300000 |
+ SPX |
+ 2017-03-17 |
+ call |
+ 300 |
+ -197060.0 |
+ Order.STC |
+ SPX170317P00300000 |
+ SPX |
+ 2017-03-17 |
+ put |
+ 300 |
+ -0.0 |
+ Order.STC |
+ -197060.0 |
+ 2.0 |
+ 2017-02-01 |
+
+
+ | 2 |
+ SPX170421C00500000 |
+ SPX |
+ 2017-04-21 |
+ call |
+ 500 |
+ 177260.0 |
+ Order.BTO |
+ SPX170421P01375000 |
+ SPX |
+ 2017-04-21 |
+ put |
+ 1375 |
+ 60.0 |
+ Order.BTO |
+ 177320.0 |
+ 2.0 |
+ 2017-02-01 |
+
+
+ | 3 |
+ SPX170421C00500000 |
+ SPX |
+ 2017-04-21 |
+ call |
+ 500 |
+ -188980.0 |
+ Order.STC |
+ SPX170421P01375000 |
+ SPX |
+ 2017-04-21 |
+ put |
+ 1375 |
+ -5.0 |
+ Order.STC |
+ -188985.0 |
+ 2.0 |
+ 2017-03-01 |
+
+
+ | 4 |
+ SPX170519C01000000 |
+ SPX |
+ 2017-05-19 |
+ call |
+ 1000 |
+ 138940.0 |
+ Order.BTO |
+ SPX170519P01650000 |
+ SPX |
+ 2017-05-19 |
+ put |
+ 1650 |
+ 100.0 |
+ Order.BTO |
+ 139040.0 |
+ 3.0 |
+ 2017-03-01 |
+
+
+ | 5 |
+ SPX170519C01000000 |
+ SPX |
+ 2017-05-19 |
+ call |
+ 1000 |
+ -135290.0 |
+ Order.STC |
+ SPX170519P01650000 |
+ SPX |
+ 2017-05-19 |
+ put |
+ 1650 |
+ -20.0 |
+ Order.STC |
+ -135310.0 |
+ 3.0 |
+ 2017-04-03 |
+
+
+
+
+
+
+
+The trade log (`bt.trade_log`) shows we executed 6 trades: we bought one call and one put on _2017-01-03_, _2017-02-01_ and _2017-03-01_, and exited those positions on _2017-02-01_, _2017-03-01_ and _2017-04-03_ respectively.
+
+The balance data structure shows how our positions evolved over time:
+- We started with $1000000 on _2017-01-02_
+- `total capital` is the sum of `cash`, `stocks capital` and `options capital`
+- `% change` shows the inter day change in `total capital`
+- `accumulated return` gives the compounded return in `total capital` since the start of the backtest
+
+
+```python
+bt.balance.head()
+```
+
+
+
+
+
+
+
+
+
+ |
+ total capital |
+ cash |
+ VOO |
+ TUR |
+ RSX |
+ options qty |
+ calls capital |
+ puts capital |
+ stocks qty |
+ VOO qty |
+ TUR qty |
+ RSX qty |
+ options capital |
+ stocks capital |
+ % change |
+ accumulated return |
+
+
+
+
+ | 2017-01-02 |
+ 1.000000e+06 |
+ 1000000.00000 |
+ NaN |
+ NaN |
+ NaN |
+ NaN |
+ NaN |
+ NaN |
+ NaN |
+ NaN |
+ NaN |
+ NaN |
+ 0.0 |
+ 0.000000 |
+ NaN |
+ NaN |
+
+
+ | 2017-01-03 |
+ 9.990300e+05 |
+ 110117.40592 |
+ 199872.763320 |
+ 49993.281167 |
+ 249986.549593 |
+ 2.0 |
+ 389060.0 |
+ 0.0 |
+ 16186.0 |
+ 1025.0 |
+ 1758.0 |
+ 13403.0 |
+ 389060.0 |
+ 499852.594080 |
+ -0.000970 |
+ 0.999030 |
+
+
+ | 2017-01-04 |
+ 1.004228e+06 |
+ 110117.40592 |
+ 201052.238851 |
+ 50072.862958 |
+ 251605.333911 |
+ 2.0 |
+ 391380.0 |
+ 0.0 |
+ 16186.0 |
+ 1025.0 |
+ 1758.0 |
+ 13403.0 |
+ 391380.0 |
+ 502730.435720 |
+ 0.005203 |
+ 1.004228 |
+
+
+ | 2017-01-05 |
+ 1.002706e+06 |
+ 110117.40592 |
+ 200897.553535 |
+ 49865.950301 |
+ 250564.686850 |
+ 2.0 |
+ 391260.0 |
+ 0.0 |
+ 16186.0 |
+ 1025.0 |
+ 1758.0 |
+ 13403.0 |
+ 391260.0 |
+ 501328.190686 |
+ -0.001516 |
+ 1.002706 |
+
+
+ | 2017-01-06 |
+ 1.003201e+06 |
+ 110117.40592 |
+ 201680.647945 |
+ 49372.543196 |
+ 248830.275081 |
+ 2.0 |
+ 393200.0 |
+ 0.0 |
+ 16186.0 |
+ 1025.0 |
+ 1758.0 |
+ 13403.0 |
+ 393200.0 |
+ 499883.466222 |
+ 0.000494 |
+ 1.003201 |
+
+
+
+
+
+
+Evolution of our total capital over time:
+
+
+```python
+bt.balance['total capital'].plot();
+```
+
+
+
+
+
+Evolution of our stock positions over time:
+
+
+```python
+bt.balance[[stock.symbol for stock in stocks]].plot();
+```
+
+
+
+
+
+More plots and statistics are available in the `backtester.statistics` module.
+
+### Other strategies
+
+The `Strategy` and `StrategyLeg` classes allow for more complex strategies; for instance, a [long strangle](https://www.investopedia.com/terms/s/strangle.asp) could be implemented like so:
+
+
+```python
+# Long strangle
+leg_1 = StrategyLeg('leg_1', options_schema, option_type=Type.PUT, direction=Direction.BUY)
+leg_1.entry_filter = (options_schema.underlying == 'SPX') & (options_schema.dte >= 60) & (options_schema.underlying_last <= 1.1 * options_schema.strike)
+leg_1.exit_filter = (options_schema.dte <= 30)
+
+leg_2 = StrategyLeg('leg_2', options_schema, option_type=Type.CALL, direction=Direction.BUY)
+leg_2.entry_filter = (options_schema.underlying == 'SPX') & (options_schema.dte >= 60) & (options_schema.underlying_last >= 0.9 * options_schema.strike)
+leg_2.exit_filter = (options_schema.dte <= 30)
+
+strategy = Strategy(options_schema)
+strategy.add_legs([leg_1, leg_2]);
```
You can explore more usage examples in the Jupyter [notebooks](backtester/examples/).
+
## Recommended reading
For complete novices in finance and economics, this [post](https://notamonadtutorial.com/how-to-earn-your-macroeconomics-and-finance-white-belt-as-a-software-developer-136e7454866f) gives a comprehensive introduction.
diff --git a/img/stock_positions.png b/img/stock_positions.png
new file mode 100644
index 0000000..a65bd41
Binary files /dev/null and b/img/stock_positions.png differ
diff --git a/img/total_capital.png b/img/total_capital.png
new file mode 100644
index 0000000..dd70092
Binary files /dev/null and b/img/total_capital.png differ