Bitfinex Honey Framework Backtesting Tools for Node.JS
This repo provides an interface for executing backtests using either offline data, or a bfx-hf-data-server
instance for historical Bitfinex market data.
Features
- Offline backtest execution with user-supplied trade & candle data
- Online backtest execution with data from
bfx-hf-data-server
- Simulates trades within a candle if none are provided
Installation
npm i --save bfx-hf-backtest
Quickstart
const HFS = require('bfx-hf-strategy')
const HFBT = require('bfx-hf-backtest')
const Strategy = ...
const candles = []
const candleKey = HFS.candleMarketDataKey({
symbol: SYMBOLS.BTC_USD,
tf: TIME_FRAMES.ONE_HOUR
})
HFBT.execOffline(strat, {
trades: {},
candles: {
[candleKey]: candles,
}
}).then((btState) => {
const { trades = [] } = btState
})
Docs
Refer to docs/exec.md
for JSDoc-generated API documentation, and the examples/
folder for executable examples.
Examples
Offline Backtests
To execute a backtest of a trading strategy using historical data, the execOffline
method is provided which will run the strategy against each trade & candle in-order by timestamp:
const HFS = require('bfx-hf-strategy')
const HFBT = require('bfx-hf-backtest')
const EMAStrategy = require('bfx-hf-strategy/examples/ema_cross')
const { Candle } = require('bfx-api-node-models')
const { SYMBOLS, TIME_FRAMES } = require('bfx-hf-util')
const rawCandleData = require('./btc_candle_data.json')
const market = {
symbol: SYMBOLS.BTC_USD,
tf: TIME_FRAMES.ONE_HOUR
}
const candleKey = HFS.candleMarketDataKey(market)
const strat = EMAStrategy(market)
const candles = rawCandleData
.sort((a, b) => a[0] - b[0])
.map(c => ({
...(new Candle(c).toJS()),
...market
}))
const run = async () => {
await HFBT.execOffline(strat, {
trades: {},
candles: {
[candleKey]: candles,
}
})
}
try {
run()
} catch (e) {
console.error(e)
}
Online Backtests
Online backtests are executed a running bfx-hf-data-server
instance, which will automatically synchronize historical data as needed and pass it to the backtesting logic:
const HFBT = require('bfx-hf-backtest')
const EMAStrategy = require('bfx-hf-strategy/examples/ema_cross')
const { SYMBOLS, TIME_FRAMES } = require('bfx-hf-util')
const now = Date.now()
const market = {
symbol: SYMBOLS.XMR_USD,
tf: TIME_FRAMES.ONE_MINUTE
}
const strat = EMAStrategy(market)
const run = async () => {
await HFBT.execOnline([strat], {
exchange: 'bitfinex',
from: now - (2 * 24 * 60 * 60 * 1000),
to: now,
trades: true,
candles: true,
...market
})
}
try {
run()
} catch (e) {
console.error(e)
}
Bitfinex Terminal Data
Bitfinex Terminal data can be used to run a strategy. There is also a full blog article on this.
examples/
const strat = EMAStrategy(market)
const from = get24HoursAgo(new Date())
const to = new Date()
const { exec, onEnd } = await HFBT.execStream(strat, market, {
from,
to
})
let btState
const stream = db.createReadStream({
gte: { candle: '5m', timestamp: from },
lte: { candle: '5m', timestamp: to }
})
for await (const data of stream) {
const { key, value } = data
btState = await exec(key, value)
}
await onEnd(btState)
For the full blog article, visit the Bitfinex Terminal repo
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request