UNPKG

crypto-backtest

Version:

Backtesting on market data imported from crypto exchange

108 lines 4.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BacktestBase = void 0; class BacktestBase { constructor(options) { this.candles = []; this.initialBalance = 0; this.stoplossLevel = 0; // доля от цены открытия, на которую рыночная цена может упасть this.fee = 0; // доля this.trades = []; this.roundtrips = []; this.maxLosingSeriesLength = 0; this.maxDrawDown = 0; this.currencyBalance = 0; this.assetBalance = 0; this.stoplossPrice = 0; Object.assign(this, options); } calculateRountrips() { let roundtrip = null; let peak = this.initialBalance; let losingLength = 0; this.trades.forEach((trade) => { // если открытого нет, тогда сначала создать // предполагается что трейды чередуются, открывающий и закрывающий if (!roundtrip) { roundtrip = { begin: trade.time, openPrice: trade.price, openAmount: trade.amount + trade.fee, fee: trade.fee, }; } else { roundtrip.end = trade.time; roundtrip.closePrice = trade.price; roundtrip.closeAmount = trade.amount - trade.fee; roundtrip.fee = roundtrip.fee + trade.fee; roundtrip.profit = roundtrip.closeAmount - roundtrip.openAmount; peak = Math.max(peak, roundtrip.closeAmount); if (roundtrip.profit > 0) { losingLength = 0; } else { this.maxLosingSeriesLength = Math.max(this.maxLosingSeriesLength, ++losingLength); this.maxDrawDown = Math.max(this.maxDrawDown, 1 - roundtrip.closeAmount / peak); } this.roundtrips.push(roundtrip); roundtrip = null; } }); } candleHandler(candle, index, candles) { const { time, close: price } = candle; // всегда закрывается трейдом или стоп-лосс if ((index === candles.length - 1 || price < this.stoplossPrice) && this.assetBalance > 0) { this.sell(time, price); } else { const advice = this.advices.find((a) => a.time === time); if (advice) { const { side } = advice; if (side === "buy" && this.currencyBalance > 0) { this.buy(time, price); } else if (side === "sell" && this.assetBalance > 0) { this.sell(time, price); } } } } buy(time, price) { this.stoplossPrice = price * this.stoplossLevel; const fee = this.currencyBalance * this.fee; const amount = this.currencyBalance - fee; const quantity = amount / price; const trade = { time, side: "buy", quantity, price, amount, fee, }; this.currencyBalance = 0; this.assetBalance = quantity; this.trades.push(trade); } sell(time, price) { const quantity = this.assetBalance; const amount = quantity * price; const fee = amount * this.fee; const trade = { time, side: "sell", quantity, price, amount, fee, }; this.assetBalance = 0; this.currencyBalance = amount - fee; this.trades.push(trade); } } exports.BacktestBase = BacktestBase; //# sourceMappingURL=BacktestBase.js.map