Crypto Quant: programmatic trading of BTC using Binance and Backtrader — Part 2 of 3 PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Crypto Quant: programmatic trading of BTC using Binance and Backtrader — Part 2 of 3


Crypto Quant: programmatic trading of BTC using Binance and Backtrader — Part 2 of 3 PlatoBlockchain Data Intelligence. Vertical Search. Ai.

In this part we want to install Backtrader and backtest some trading models against the Binance data we gathered in the prior section.

There are numerous articles and videos on Backtrader and its setup. This popular Python library facilitates the Quant work of backtesting trading strategies with historical data, answering the quintessential question “how profitable would it have been to trade using given BUY/SELL strategies”. This feels like mathematical alchemy at first but one has to remember that historical data is, well, historical! A trading strategy that worked yesterday is unlikely to work today… but we’ll get back to that shortly.

Backtrader (‘bt’) installation instructions are here. Note: there are known issues with mapplotlib versions above 3.2.0 so beware about that.

Quickstart guide is a worthwhile read, find it here.

RSI

What we will be trying with Backtrader here is backtesting an RSI (Relative Strength Indicator) trading strategy on historical crypto data (for BTC) from earlier in the year.

The RSI momentum indicator is explained here. It measures relative oversold and overbought conditions for a given trading asset and a parameter of ‘period’ which is the # of ticks (trading intervals) backwards.

The period parameter defaults to 14, so if the interval is minutes then the formula will include 14 interval ticks of data. As we’ll explore next, each technical indicator has parameters which are our way of ‘tuning’ to market conditions; these parameters have a huge impact on the profitability of any given indicator within a strategy.

Backtest.py

Our backtest setup: backtest.py is shared here. This will provide the backtest structure for our backtest run, to be defined next. This is a fairly standard ‘bt’ setup. Let’s review some of this code, note that there are plenty of examples and video tutorials online on Python backtest to learn from.

Here in the class definition we establish parameters for our RSI strategy.

  • verbose: if we want to output log data during the backtest
  • maperiod: moving average period, the # of ticks to consider
  • quantity: the # of shares to buy/sell
  • upper: the upper threshold of the indicator for overbought
  • lower: the lower threshold of the indicator for oversold
  • stopLoss: the stop loss setting for selling

The next() function in a Backtrader strategy class is what happens after each interval ‘tick’ of data. Here is buy() or sell() according to the data, in this case the RSI indicator and our thresholds.

Here we define the runbacktest() function which will be called by our code. The aforementioned RSI strategy function is added to the cerebro instance.

All fairly standard Backtrader stuff. Let’s see how to run this against our data.

Backtesting our data

Be sure to get data (using the last section’s steps) for Jan 1 to Jan 2 2021, this will be in a file named: BTCUSDT-20210101–20210102–1m.csv with 1440 CSV lines, one for each minute of the day.

Here is the code and output for this one day’s worth of minute-by-minute trading day for Bitcoin (BTC):

Taking a closer look:

The parameters are simple, we want to analyze one day of trading, using the RSI indicator with a period of 12 ticks, no stop-loss and default limits of 70,30 for the overbought and oversold triggers.

Jan 1 bt results with standard RSI indicator strategy

The last line of output summarizes the results of this backtest:

/BTCUSDT-20210101-20210102-1m.csv, RSI (Pd 12) (SL 0.0%) (U70 L30) Net $777.78 (0.78%) WL 18/7 SQN 1.76

RSI period 12, 0 (No) stop-loss, (U)pper limit of 70 (L)ower limit of 30, net profit (in one day) of $777.78 with 18 winning trades and 7 losing trades.

The last figure is SQN, a ‘System Quality Number’ (SQN) which is designed to assist traders in determining the strengths, desirability, quality of a trading system. A good quality strategy is seen as one that is both tradeable and efficient.*

The following SQN values suggest the following “qualities” :

  • 1.6–1.9 Below average
  • 2.0–2.4 Average
  • 2.5–2.9 Good
  • 3.0–5.0 Excellent
  • 5.1–6.9 Superb
  • 7.0 — Holy Grail

The SQN formula :

SquareRoot(NumberTrades) * Average(TradesProfit) / StdDev(TradesProfit)

Normally we would insist on at least 30 trades for this metric to be statistically significant but we’ll ignore that for now as we are testing out our backtest with a short period of time.

You can zoom into sections of the plot, for example:

Here we see a buy signal (green up-arrow) as the RSI value dips below 30 and then a profitable sell signal as and profit marker (blue circle) as RSI reaches above 70. See the values for RSI in the right-lower corner.

Profit (in one day) of $777.78 with 18 winning trades and 7 losing trades is quite good, particular for a trading day of relatively shallow action (+1.42%). Imagine what we could achieve on a bullish day with high volume!

Model parameters

You get run get_data for different days and analyze these separately. Notice how different RSI parameters have an impact on profitability from one day to the next.

Case in point, the same day of BTC trading but with an RSI period of 20 rather than 12, win-loss of 2/3 and a net profit of -$21.51 (including trading fees). That’s a big difference from the last backtest!

You can also experiment with different RSI limits (other than the default 70/30) and stop-loss parameters. Stop-loss is an automatic sell order once the price goes below some level relative to the executed buy order. As the name implies, this can serve to “stop a loss” after getting into a position in volatility.

Stop-Loss

The way we’ve setup stop-loss here is as follows:

  • 0 : no stop-loss setup, wait for the indicator to trigger a sell order
  • 0.00x : stop-loss at a % value below purchase price, 0.001 is 0.1% under
  • -0.0x : trailing stop-loss will follow the trade as the price goes up, 0.01 is a trailing stop-loss 1% below purchase price

This stop-loss is an important parameter for each trade and can have a significant import, not surprisingly, on performance. For more on stop-loss strategies see here.

Here in our backtest.py is where we set this up using backtrader:

Here is the same run as we just analyzed but with a 0.1% trailing stop-loss

Net profit of $383.67 with 12 wins and 12 losses, much better than the loss we had prior. The you can see in the plot that the trailing stop-loss protected many of the trades from slipping into losses as the indicator waiting for a sell (overbought) signal.

Within a single indicator, in this setup then, we have many different possible permutations:

  • a period range between 10 and 30 intervals (20 variants)
  • a stop-loss setting (let’s imagine 5 different practical variants)
  • a threshold for overbought/oversold (let’s imagine 5 variants for now)

That would be 20x5x5, or 500 different variations for each day. To examine these one-by-one by hand would be ridiculous and yet we want to know which parameters were most profitable and of the highest trading quality and which were not.

Quant alchemy!

This brings us to our next step in this Crypto Quant exploration. We can brute-force determine the most profitable and highest quality trading strategy parameters for a given period of trading and then see how these carry forward.

Source: https://medium.com/@gk_/crypto-quant-programmatic-trading-of-btc-using-binance-and-backtrader-part-2-of-3-d8af44c93e2b?source=rss——-8—————–cryptocurrency

Time Stamp:

More from Medium