a

Execute your trading strategy with Honey Framework and Bitfinex terminal



Execute your trading strategy with Honey Framework and Bitfinex terminal

Recently we learned how the backtest of a strategy can work with Bitfinex Terminal data feeds. Basically, data feeds are free Dazaar feeds shared through P2P technology similar to BitTorrent. But unlike BitTorrent, data can be cryptographically verified and can be streamed. We can request images from a dataset right in the middle or decide to just follow a live feed with the latest additions. Of course, downloading the entire data is also possible.

In this article, we’ll use the data streamed to Bitfinex Terminal to execute a live strategy. For demonstration purposes, the generated trading signals are sent to the Bitfinex Websocket API. In practice, however, we can do anything with them. Even if you want to turn on a coffee machine with a Raspberry Pi every time your strategy is negotiated, you can!

For our tutorial, we are using a popular strategy, the EMA cross strategy. It issues a trading signal when two EMA indicators cross. The EMA Cross strategy is included as one of the examples in the bfx-hf-strategy library.

Let’s start

To get started, we need to install the required dependencies:

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

We also need to create a file, which will contain the code we write, let’s call it exec-strategy.js:

touch exec-strategy.js

We can now load the required dependencies. Readers of our backtesting tutorial will notice a few similarities:

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

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

We also load and initialize the Bitfinex Websocket client. For this to work, you need to replace the placeholders with your credentials:

const { WSv2 } = require('bitfinex-api-node')
const { Order } = require('bfx-api-node-models')

const apiKey = 'SECRET'
const apiSecret="SECRETSECRET"
const ws = new WSv2({
  apiKey,
  apiSecret
})

Next, we initialize our strategy:

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

const strat = EMAStrategy(market)

And initialize Dazaar:

const dmarket = dazaar('dbs/terminal-live') // stores received data in `dbs/terminal-live`

With wget we can extract the Dazaar card for the data stream we want to consume. An overview of the data feeds can be found here.

wget https://raw.githubusercontent.com/bitfinexcom/bitfinex-terminal/master/cards/free/candles/bitfinex.terminal.btcusd.candles.json

This map is loaded in Dazaar and the terms of use are accepted by loading them into Dazaar after reading them:

const card = require('./bitfinex.terminal.btcusd.candles.json')
const buyer = dmarket.buy(card, { sparse: true, terms })

And if Dazaar issues a feed event, we configure Hyperbee and call a function called runStrategy:

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

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

  runStrategy(db)
})

So far, most of our setup is similar to the one we used for the backtests in the last article. We must now define the function runStrategy, which allows us to do something with the trading signals of our strategy:

async function runStrategy (db) {

}

Function runStrategy will set up the logic that executes our strategy on each candle received. First, we open the Websocket to the Bitfinex API.

await ws.open()
await ws.auth()

We have also set up the data flow. We call execDazaar with our strategy, the defined market and the Hyperbee database. As options, we switch to submitOrder, a custom function we’ll write about in a moment. submitOrder will be called for each trading signal emitted by our strategy. the simulateFill The option allows us not to wait for the order to be fully filled by the exchange, which is useful for our tutorial. The integrated submitOrder-function in Honey Framework also submits commands through WebSocket and waits for a command to be executed before continuing. In production, you might want to use the built-in one, depending on your strategy and use case. We also seed the state of the strategy, we use a count of 120 candles.

const { exec, stream } = await execDazaar(strat, market, db, {
  submitOrder,
  simulateFill: true,
  includeTrades: false,
  seedCandleCount: 120
})

execDazaar returns a stream and a function called exec. We call exec on each entry sent in the stream:

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

Our function runStrategy is now complete, here is the full function:

async function runStrategy (db) {
  await ws.open()
  await ws.auth()

  const { exec, stream } = await execDazaar(strat, market, db, {
    submitOrder,
    simulateFill: true,
    includeTrades: false,
    seedCandleCount: 10
  })

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

It remains to define the function submitOrder. For each signal emitted by our EMA Cross strategy, submitOrder is called with the current status of the policy and the order data. In our case, we take the order data and send it to Bitfinex. We are writing a simplified version of the

async function submitOrder (strategyState = {}, order = {}) {
  const _o = {
    cid: Date.now(),
    ...order
  }

  console.log('submitting order', _o)

  const o = new Order(_o, ws)
  o.registerListeners()

  o.on('update', () => {
    console.log(`order updated: ${o.serialize()}`)
  })

  const res = await o.submit()
  return res
}

To start everything, you have to connect to the network, which will trigger a feed Event:

swarm(buyer)

When we run the file now, it will take the last 120 candles and pre-boot our strategy algorithm with it. Then it will follow the live stream of new incoming candles and execute our strategy on them. In the event that a trading signal is generated, it is submitted to the Bitfinex API. You can find the complete file that we wrote in this article here.

And that’s all! In this article, we have learned how to adopt a Honey Framework strategy, feed the Bitfinex terminal data, and submit the trading signals for trading. With the help of custom submitOrder functions, we can create personalized functionalities on which our trading strategy acts. We hope you enjoyed the article.

PS: Bitfinex is recruiting! ?



Source link

Leave a Comment