Coder Social home page Coder Social logo

bfx-hf-strategy's Introduction

HF Trading Strategy Module

Build Status

This repo serves as a framework for creating trading bots/strategies on the Bitfinex platform. It consists of a set of order methods and an architecture compatible with bfx-hf-data-server and bfx-hf-backtest for backtests on historical candle/trade data, which can be transitioned seamlessly to trading on the live markets.

Strategies written using this framework must define a set of update methods, called on each tick (with either a trade or a candle), along with a set of indicators which are automatically updated on each tick. The indicators are made available to the strategy methods, and can be queried to direct trading behavior.

Defining a Strategy

The define method is provided to construct a trading strategy from a set of indicators & update methods. Strategies created with it can be used with bfx-hf-backtest or with the exec method to run on the live market. An example strategy follows below:

const { SYMBOLS, TIME_FRAMES } = require('bfx-hf-util')
const { EMA } = require('bfx-hf-indicators')

HFS.define({
  id: 'ema_cross',
  name: 'ema_cross',
  symbol: SYMBOLS.BTC_USD,
  tf: TIME_FRAMES.ONE_MINUTE,

  indicators: {
    emaL: new EMA([100]),
    emaS: new EMA([20])
  },

  onEnter: require('./on_enter'),
  onUpdateLong: require('./on_update_long'),
  onUpdateShort: require('./on_update_short')
})

The above strategy defines two EMA indicators, emaL and emaS, with periods of 100 and 20 respectively, and 3 update methods; In total, 5 update methods are available:

  • onEnter - called when no position is open
  • onUpdateLong - called when a long position is open
  • onUpdateShort - called when a short position is open
  • onUpdate - called when any position is open
  • onPriceUpdate - called on every tick

Update Handlers

All update handlers must be asynchronous, and receive the same arguments of (state = {}, update = {}). The update has the following fields:

  • type - 'candle' or 'trade', indicating which fields are available
  • mts - timestamp, in ms
  • price - candle or trade price (depends on candlePrice strategy setting)
  • for candles, open, high, low, close, and vol are provided

Update handlers must return the next state object after performing any actions, or the current state object if no modifications were made.

The state object can be queried for historical candle data, indicators & indicator values, open positions, and previous strategy trades. Various helpers are provided to query this data; for an example, see the EMA cross example onEnter handler below:

const _get = require('lodash/get')
const HFS = require('bfx-hf-strategy')

module.exports = async (state = {}, update = {}) => {
  const { price, mts } = update
  const i = HFS.indicators(state)
  const iv = HFS.indicatorValues(state)
  const { emaS } = i // full indicator object
  const l = iv.emaL
  const s = iv.emaS

  // Note that the default strategy symbol is used if no symbol is specified
  if (emaS.crossed(l)) {
    if (s > l) {
      return HFS.openLongPositionMarket(state, {
        mtsCreate: mts,
        amount: 1,
        price
      })
    } else {
      return HFS.openShortPositionMarket(state, {
        mtsCreate: mts,
        amount: 1,
        price
      })
    }
  }

  return state
}

Managing Positions

Within the update handlers, several async helpers are available to open/update/close positions:

  • openLongPositionMarket(state, args = {})
  • openLongPositionLimit(state, args = {})
  • openLongPosition(state, args = {})
  • openShortPositionMarket(state, args = {})
  • openShortPositionLimit(state, args = {})
  • openShortPosition(state, args = {})
  • openPosition(state, args = {})
  • updateLongPositionMarket(state, args = {})
  • updateLongPositionLimit(state, args = {})
  • updateLongPosition(state, args = {})
  • updateShortPositionMarket(state, args = {})
  • updateShortPositionLimit(state, args = {})
  • updateShortPosition(state, args = {})
  • updatePosition(state, args = {})
  • closePositionMarket(state, args = {})
  • closePositionLimit(state, args = {})
  • closePosition(state, args = {})

The price and mtsCreate timestamp must both be provided to all update handlers, even those operating with MARKET orders, in order to record the price and timestamp during backtests. If these are not provided, backtests run via bfx-hf-backtest will fail.

Executing on Live Markets

To run a strategy against the live marketplace, attach a WSv2 instance from bitfinex-api-node to the strategy object on ws and call the exec method to bind the Bitfinex API listeners to the various strategy update methods:

const debug = require('debug')('bfx:hf:strategy:example:exec')
const HFS = require('bfx-hf-strategy')
const { SYMBOLS, TIME_FRAMES } = require('bfx-hf-util')
const { Manager } = require('bfx-api-node-core')
const WDPlugin = require('bfx-api-node-plugin-wd')
const S = require('./some/strategy')

const m = new Manager({
  plugins: [WDPlugin({ // automatically reconnect if the connection drops
    packetWDDelay: 30000,
  })],

  apiKey: '...',
  apiSecret: '...',
  transform: true,
})

const run = async () => {
  const strat = await S({ /* strategy arguments */ })

  m.onWS('open', {}, (state = {}) => {
    debug('open')
  })

  m.onceWS('event:auth:success', {}, async (authEvent, ws) => {
    debug('authenticated')
    debug('executing strategy...')

    strat.ws = ws // attach websocket

    await HFS.exec(strat, m, {
      symbol: SYMBOLS.ETH_USD,
      tf: TIME_FRAMES.ONE_MINUTE,
      includeTrades: true,
    })
  })

  debug('opening socket...')

  m.openWS()
}

try {
  run()
} catch (err) {
  debug('error: %s', err)
}

bfx-hf-strategy's People

Contributors

f3rno avatar prdn avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.