Backtest your trading strategies with Bitfinex Terminal & Honey Framework

I show You how To Make Huge Profits In A Short Time With Cryptos!

Backtest your trading strategies with Bitfinex Terminal & Honey Framework

Honey Framework provides easy ways to create and backtest trading strategies. Today we take a look at how you can backtest your trading strategies with Bitfinex Terminal data and Node.js. Bitfinex Terminal was launched with the needs of algo traders in mind – a fast and reliable way to sync and share historical data. We will take a trading strategy, EMA Crossover, and backtest it on historical candle data.

We will backtest 5 minute candles from the BTCUSD trading data. This data is, like in a blockchain, stored in a Merkle tree and can be verified cryptographically. The data is shared over a peer-to-peer (P2P) network and can be streamed live. This means the backtest can start to run while we retrieve data and resume downloads after a connection reset for us. All of these features make Terminal a great choice for sharing trading data and trading signals.

The Bitfinex terminal supports Dazaar cards, which is an easy way to access data streams. Each data stream has a unique identifier, which is cryptographically verified, similar to a Bitcoin address. The Dazaar card contains a description of the content and the feed ID. Think of it as a torrent file, but for real-time encrypted data streams.

Let’s try

To get started, we install the required dependencies:

npm install dazaar hyperbee bitfinex-terminal-key-encoding bfx-hf-util bfx-hf-backtest 
  bfx-hf-strategy bitfinex-terminal-terms-of-use

We also need to create a file; Let’s say backtest.js. We can now start writing our code.

To see the results of our backtest on the console, we need to enable debug output:

process.env.DEBUG = process.env.DEBUG || 'bfx:*'

The EMA-Cross strategy that we apply today is one of the example strategies included in the Honey Framework. We load this strategy with our other dependencies. The Bitfinex Terminal Terms of Service depend on it – we will need to load them into Dazaar after reading and acknowledging them:

const dazaar = require('dazaar')
const swarm = require('dazaar/swarm')
const Hyperbee = require('hyperbee')
const keyEncoding = require('bitfinex-terminal-key-encoding')

const HFBT = require('bfx-hf-backtest')
const { SYMBOLS, TIME_FRAMES } = require('bfx-hf-util')
const EMAStrategy = require('bfx-hf-strategy/examples/ema_cross')

const terms = require('bitfinex-terminal-terms-of-use')

We also set up a little helper function to give us the time exactly 24 hours in the past:

const get24HoursAgo = (date) => {
  const res = date.getTime() - (1 * 86400 * 1000)

  return new Date(res)
}

For backtesting, we need to define the market we are testing and pass it on to the EMA strategy:

const market = {
  symbol: SYMBOLS.BTC_USD,
  tf: TIME_FRAMES.FIVE_MINUTES
}

const strat = EMAStrategy(market)

Then we can initialize Dazaar:

const dmarket = dazaar('dbs/terminal-backtest')

With the above command, Dazaar will create a local database in dbs/terminal-backtest. All of our data will be stored in this folder, so if you want to start over you can just delete it.

As next step, we download the Dazaar card for BTCUSD from https://raw.githubusercontent.com/bitfinexcom/bitfinex-terminal/master/cards/bitfinex.terminal.btcusd.candles.json and load it:

wget https://raw.githubusercontent.com/bitfinexcom/bitfinex-terminal/master/cards/free/candles/bitfinex.terminal.btcusd.candles.json
const card = require('./bitfinex.terminal.btcusd.candles.json')

Dazaar also supports paid feeds, for example to sell trading signals of a successful strategy, but Bitfinex terminal data is free. Our map is loaded in Dazaar. We activate the sparse mode, with the sparse mode set, it will only download the data requested from us. We also load the Terms of Service we need above, after reading and agreeing to them:

const buyer = dmarket.buy(card, { sparse: true, terms })

If we wanted to download a full copy of all the background candles, we would set sparse at false.

Once the data is ready, Dazaar will issue a feed Event. Once this is issued, we can configure Hyperbee on top of the Dazaar feed. Hyperbee provides us with a B-Tree structure for easy querying of data. For Terminal, we use a special key encoding module, which makes it easier to query the data. We have already loaded the key encoding module with const keyEncoding = require('bitfinex-terminal-key-encoding'). Once the Hyperbee database is set up, we can call runTest and work with the database:

buyer.on('feed', function () {
  console.log('got feed')

  const db = new Hyperbee(buyer.feed, {
    keyEncoding,
    valueEncoding: 'json'
  })

  runTest(db)
})

The last part of our backtest is the actual test. To do this, you have to define the function runTest:

async function runTest (db) {

}

Inside the function runTest we need to set the time frame we want to use for our test. For the start of the period, we use the helper feature that we created at the start of our tutorial. The value for to indicates the current time:

 const from = get24HoursAgo(new Date())
 const to = new Date()

With our strategy and the market, we pass on the lead time definitions to HFBT.execStream. It returns a function called exec and a function called onEnd:

  const { exec, onEnd } = await HFBT.execStream(strat, market, {
    from,
    to
  })

Function exec will be applied to every element of the stream, but we need to start the stream first. We will do our test on 5m candles. To get all the data within this 24 hour period, we use our variables from and to in the respective fields lte (less than equal) and gte (greater than equal):

  const stream = db.createReadStream({
    gte: { candle: TIME_FRAMES.FIVE_MINUTES, timestamp: from },
    lte: { candle: TIME_FRAMES.FIVE_MINUTES, timestamp: to }
  })

With the help of an asynchronous iterator, we call exec on each input and store the result in btState:

  let btState
  for await (const data of stream) {
    const { key, value } = data
    btState = await exec(key, value)
  }

Then once the iterator gives us no more results, we call the function onEnd, which will print our results to the console:

  await onEnd(btState)

Here is the whole function runTest:

async function runTest (db) {
  const from = get24HoursAgo(new Date())
  const to = new Date()

  const { exec, onEnd } = await HFBT.execStream(strat, market, {
    from,
    to
  })

  const stream = db.createReadStream({
    gte: { candle: TIME_FRAMES.FIVE_MINUTES, timestamp: from },
    lte: { candle: TIME_FRAMES.FIVE_MINUTES, timestamp: to }
  })

  let btState
  for await (const data of stream) {
    const { key, value } = data
    btState = await exec(key, value)
  }

  await onEnd(btState)
}

After completing the function runTest, we’re almost done. To get started, you have to go online:

swarm(buyer)

Here is the complete code in one file for our backtest.

Now when we run our file we get the output printed to the console:

As you can see, we would have suffered a loss with this strategy during the period of 9/6/2020 3:18:58 PM to 9/7/2020 3:18:58 PM when this article was written.

Conclusion

In this article, we took a look at how backtesting a Honey Framework trading strategy works with Bitfinex Terminal. We were able to create a backtest in less than 70 lines of code with a simple and reliable way to sync large amounts of data. Everything was working on top of Dazaar, which can also be used to sell trading signals. One of our next posts will cover exactly this topic, so stay tuned!



Source link

Leave a Reply

Your email address will not be published.