There are multiple libraries that you can use to backtest a strategy in Python. However, I often use Backtrader because it is a nice open-source framework that allows me to quickly test historical data, optimize strategies, and create visual plots. Backtrader comes across as being really flexible and quite easy to use – which makes it a reasonable choice, especially for beginner algorithmic traders.

In this learning session, I will demonstrate how you can write your own simple backtrader strategy in Python.

### Step 1: Important Libraries

The first step is to import important libraries to load some of the functionality that we are going to need (so we don’t have to write this functionality from scratch). These libraries include backtrader, backtrader analyzers (for monitoring our strategy), matplotlib (for plotting results), and datetime (for working with dates).

```import backtrader as bt
import matplotlib
from datetime import datetime
```

### Step 2: Create Strategy (Class)

The next step is to create an empty class for our strategy.

```class MaCrossStrategy(bt.Strategy):
```

You then need to define (at least two) functions for your strategy. One function will initialize the strategy while the other one will specify logic for orders (i.e. when your engine should enter and exit positions).

Strategy initialization function

Note: in this demonstration, I used a moving average strategy where I can store crossover signals.

```    def __init__(self):
ma_fast = bt.ind.SMA(period = 10)
ma_slow = bt.ind.SMA(period = 50)

self.crossover = bt.ind.CrossOver(ma_fast, ma_slow)

```

Logic function

In this demonstration, I created a function with a pretty basic logic implemented via conditional (if) statements.

Logic: If you are not in position then you see a bullish crossover then you enter a long position then if you are in position and you see bullish crossover you close position.

```    def next(self):
if not self.position:
if self.crossover > 0:
elif self.crossover < 0:
self.close()

```

### Step 3: Create Engine

Backtrader’s Cerebro engine gathers all inputs (Data Feeds), actors (Strategies), spectators (Observers), critics (Analyzers), and documenters to execute backtesting, return results, measure performance, and provide plotting facilities.

Here’s a one-liner to instantiate your Cerebro engine.

```cerebro = bt.Cerebro()
```

The next step is to get data (using feeds such as Yahoo Finance) for the Cerebro engine you have created. Keep in mind that you also need to specify parameters such as the period of time over which you want to obtain data for the data.

```data = bt.feeds.YahooFinanceData(dataname = 'AAPL', fromdate = datetime(2010, 1, 1), todate = datetime(2020, 1, 1))

```

Now that you already have loaded the data, it’s time to add the strategy that you created in the second step above to your engine.

```cerebro.addstrategy(MaCrossStrategy)
```

Note: we could run our strategy at this juncture but I prefer we add a few more useful things (below) so we make the most out of it.

#### → Set Initial Capital (beginning balance)

This can be done using the cash function.

```cerebro.broker.setcash(1000000.0)
```

#### → Change Position Size

You may change the way the engine sizes your position. By default, it only trades about one share but there’s a Celebro function to change it to the desired size.

```cerebro.addsizer(bt.sizers.PercentSizer, percents = 10)
```

Backtrader has a variety of analyzers that you may use without having to create your own. In this example, I used SharpeRatio, Transactions, and TradeAnalyzer.

```cerebro.addanalyzer(btanalyzers.SharpeRatio, _name = "sharpe")

```

### Step 4: Run Engine and Assess Performance

The final step is to get the results of our backtesting and then call the analyzers to assess for performance.

Here is the code to accomplish this final bit of your first backtrader strategy.

```back = cerebro.run()		  #collect results of backtesting
cerebro.broker.getvalue()	 #get an interval of your basic capital
back.analyzers.sharpe.get_analysis()	 #get the first element of your #backtesting and call SharpeRatio analyzer
back.analyzers.trans.get_analysis() 	 #get the first element of your #backtesting and call Transactions analyzer
```

Note: you get a lot of useful information from this analysis plus you can also try other analyzers already available in Backtrader (check documentation).

Cerebro also has a plot function that you can use to quickly plot basic information about your strategy and performance.

```cerebro.plot()
``` Here’s the aggregate/combined code snippet.

```import backtrader as bt
import matplotlib
from datetime import datetime

class MaCrossStrategy(bt.Strategy):

def __init__(self):
ma_fast = bt.ind.SMA(period = 10)
ma_slow = bt.ind.SMA(period = 50)

self.crossover = bt.ind.CrossOver(ma_fast, ma_slow)

def next(self):
if not self.position:
if self.crossover > 0:
elif self.crossover < 0:
self.close()

cerebro = bt.Cerebro()

data = bt.feeds.YahooFinanceData(dataname = 'AAPL', fromdate = datetime(2010, 1, 1), todate = datetime(2020, 1, 1))

cerebro.broker.setcash(1000000.0)

back = cerebro.run()

cerebro.broker.getvalue()

back.analyzers.sharpe.get_analysis()

back.analyzers.trans.get_analysis()