135 lines
3.9 KiB
JavaScript
135 lines
3.9 KiB
JavaScript
// log trade performance results
|
|
|
|
const _ = require('lodash');
|
|
const moment = require('moment');
|
|
const humanizeDuration = require('humanize-duration');
|
|
|
|
const util = require('../../core/util.js');
|
|
const dirs = util.dirs();
|
|
const mode = util.gekkoMode();
|
|
const log = require(dirs.core + 'log');
|
|
|
|
const Logger = function(watchConfig) {
|
|
this.currency = watchConfig.currency;
|
|
this.asset = watchConfig.asset;
|
|
|
|
this.roundtrips = [];
|
|
}
|
|
|
|
Logger.prototype.round = function(amount) {
|
|
return amount.toFixed(8);
|
|
}
|
|
|
|
// used for:
|
|
// - realtime logging (per advice)
|
|
// - backtest logging (on finalize)
|
|
Logger.prototype.logReport = function(trade, report) {
|
|
// ignore the trade
|
|
|
|
var start = this.round(report.startBalance);
|
|
var current = this.round(report.balance);
|
|
|
|
log.info(`(PROFIT REPORT) original balance:\t\t ${start} ${this.currency}`);
|
|
log.info(`(PROFIT REPORT) current balance:\t\t ${current} ${this.currency}`);
|
|
log.info(
|
|
`(PROFIT REPORT) profit:\t\t\t\t ${this.round(report.profit)} ${this.currency}`,
|
|
`(${this.round(report.relativeProfit)}%)`
|
|
);
|
|
}
|
|
|
|
Logger.prototype.logRoundtripHeading = function() {
|
|
log.info('(ROUNDTRIP)', 'entry date (UTC) \texit date (UTC) \texposed duration\tP&L \tprofit');
|
|
}
|
|
|
|
Logger.prototype.logRoundtrip = function(rt) {
|
|
const display = [
|
|
rt.entryAt.utc().format('YYYY-MM-DD HH:mm'),
|
|
rt.exitAt.utc().format('YYYY-MM-DD HH:mm'),
|
|
(moment.duration(rt.duration).humanize() + " ").slice(0, 16),
|
|
rt.pnl.toFixed(2),
|
|
rt.profit.toFixed(2)
|
|
];
|
|
|
|
log.info('(ROUNDTRIP)', display.join('\t'));
|
|
}
|
|
|
|
if(mode === 'backtest') {
|
|
// we only want to log a summarized one line report, like:
|
|
// 2016-12-19 20:12:00: Paper trader simulated a BUY 0.000 USDT => 1.098 BTC
|
|
Logger.prototype.handleTrade = function(trade) {
|
|
if(trade.action !== 'sell' && trade.action !== 'buy')
|
|
return;
|
|
|
|
var at = trade.date.format('YYYY-MM-DD HH:mm:ss');
|
|
|
|
|
|
if(trade.action === 'sell')
|
|
|
|
log.info(
|
|
`${at}: Paper trader simulated a SELL`,
|
|
`\t${this.round(trade.portfolio.currency)}`,
|
|
`${this.currency} <= ${this.round(trade.portfolio.asset)}`,
|
|
`${this.asset}`
|
|
);
|
|
|
|
else if(trade.action === 'buy')
|
|
|
|
log.info(
|
|
`${at}: Paper trader simulated a BUY`,
|
|
`\t${this.round(trade.portfolio.currency)}`,
|
|
`${this.currency}\t=> ${this.round(trade.portfolio.asset)}`,
|
|
`${this.asset}`
|
|
);
|
|
}
|
|
|
|
Logger.prototype.finalize = function(report) {
|
|
|
|
log.info();
|
|
log.info('(ROUNDTRIP) REPORT:');
|
|
|
|
this.logRoundtripHeading();
|
|
_.each(this.roundtrips, this.logRoundtrip, this);
|
|
|
|
log.info()
|
|
log.info(`(PROFIT REPORT) start time:\t\t\t ${report.startTime}`);
|
|
log.info(`(PROFIT REPORT) end time:\t\t\t ${report.endTime}`);
|
|
log.info(`(PROFIT REPORT) timespan:\t\t\t ${report.timespan}`);
|
|
log.info(`(PROFIT REPORT) exposure:\t\t\t ${report.exposure}`);
|
|
log.info();
|
|
log.info(`(PROFIT REPORT) start price:\t\t\t ${report.startPrice} ${this.currency}`);
|
|
log.info(`(PROFIT REPORT) end price:\t\t\t ${report.endPrice} ${this.currency}`);
|
|
log.info(`(PROFIT REPORT) Market:\t\t\t\t ${this.round(report.market)}%`);
|
|
log.info();
|
|
log.info(`(PROFIT REPORT) amount of trades:\t\t ${report.trades}`);
|
|
|
|
this.logReport(null, report);
|
|
|
|
log.info(
|
|
`(PROFIT REPORT) simulated yearly profit:\t ${report.yearlyProfit}`,
|
|
`${this.currency} (${report.relativeYearlyProfit}%)`
|
|
);
|
|
|
|
log.info(`(PROFIT REPORT) sharpe ratio:\t\t\t ${report.sharpe}`);
|
|
log.info(`(PROFIT REPORT) expected downside:\t\t ${report.downside}`);
|
|
log.info(`(PROFIT REPORT) ratio roundtrips:\t\t ${report.ratioRoundTrips}%`);
|
|
}
|
|
|
|
Logger.prototype.handleRoundtrip = function(rt) {
|
|
this.roundtrips.push(rt);
|
|
}
|
|
|
|
} else if(mode === 'realtime') {
|
|
Logger.prototype.handleTrade = Logger.prototype.logReport;
|
|
|
|
Logger.prototype.handleRoundtrip = function(rt) {
|
|
this.logRoundtripHeading();
|
|
this.logRoundtrip(rt);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = Logger;
|