first commit

This commit is contained in:
Francois Klieber committed 2021-06-06 20:25:14 +02:00
commit aa7869eb33
386 files changed
+69375

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
// overwrite config with test-config
var utils = require(__dirname + '/../core/util');
var testConfig = require(__dirname + '/test-config.json');
utils.setConfig(testConfig);
+104
View File
@@ -0,0 +1,104 @@
var chai = require('chai');
var expect = chai.expect;
var should = chai.should;
var sinon = require('sinon');
var _ = require('lodash');
var moment = require('moment');
var utils = require(__dirname + '/../core/util');
var dirs = utils.dirs();
var CandleBatcher = require(dirs.core + 'candleBatcher');
var candles = [
{id: 1, "start":moment("2015-02-14T23:57:00.000Z"),"open":257.19,"high":257.19,"low":257.18,"close":257.18,"vwp":257.18559990418294,"volume":0.97206065,"trades":2},
{id: 2, "start":moment("2015-02-14T23:58:00.000Z"),"open":257.02,"high":257.02,"low":256.98,"close":256.98,"vwp":257.0175849772836,"volume":4.1407478,"trades":2},
{id: 3, "start":moment("2015-02-14T23:59:00.000Z"),"open":256.85,"high":256.99,"low":256.85,"close":256.99,"vwp":256.9376998467,"volume":6,"trades":6},
{id: 4, "start":moment("2015-02-15T00:00:00.000Z"),"open":256.81,"high":256.82,"low":256.81,"close":256.82,"vwp":256.815,"volume":4,"trades":2},
{id: 5, "start":moment("2015-02-15T00:01:00.000Z"),"open":256.81,"high":257.02,"low":256.81,"close":257.01,"vwp":256.94666666666666,"volume":6,"trades":3},
{id: 6, "start":moment("2015-02-15T00:02:00.000Z"),"open":257.03,"high":257.03,"low":256.33,"close":256.33,"vwp":256.74257263558013,"volume":6.7551178,"trades":6},
{id: 7, "start":moment("2015-02-15T00:03:00.000Z"),"open":257.02,"high":257.47,"low":257.02,"close":257.47,"vwp":257.26466004728906,"volume":3.7384995300000003,"trades":3},
{id: 8, "start":moment("2015-02-15T00:04:00.000Z"),"open":257.47,"high":257.48,"low":257.37,"close":257.38,"vwp":257.4277429116875,"volume":8,"trades":6},
{id: 9, "start":moment("2015-02-15T00:05:00.000Z"),"open":257.38,"high":257.45,"low":257.38,"close":257.45,"vwp":257.3975644932184,"volume":7.97062564,"trades":4},
{id: 10, "start":moment("2015-02-15T00:06:00.000Z"),"open":257.46,"high":257.48,"low":257.46,"close":257.48,"vwp":257.47333333333336,"volume":7.5,"trades":4}
];
describe('core/candleBatcher', function() {
var cb;
it('should throw when not passed a number', function() {
expect(function() {
new CandleBatcher();
}).to.throw('candleSize is not a number');
});
it('should instantiate', function() {
cb = new CandleBatcher(2);
});
it('should throw when fed a candle', function() {
var candle = _.first(candles);
expect(
cb.write.bind(cb, candle)
).to.throw('candles is not an array');
});
it('should not emit an event when fed not enough candles', function() {
var candle = _.first(candles);
var spy = sinon.spy();
cb.on('candle', spy);
cb.write( [candle] );
expect(spy.called).to.be.false;
});
it('should not emit an event when not flushed', function() {
cb = new CandleBatcher(2);
var spy = sinon.spy();
cb.on('candle', spy);
cb.write( candles );
expect(spy.called).to.be.false;
});
it('should emit 5 events when fed 10 candles', function() {
cb = new CandleBatcher(2);
var spy = sinon.spy();
cb.on('candle', spy);
cb.write( candles );
cb.flush();
expect(spy.callCount).to.equal(5);
});
it('should correctly add two candles together', function() {
cb = new CandleBatcher(2);
var _candles = _.first(candles, 2);
var first = _.first(_candles);
var second = _.last(_candles);
var result = {
start: first.start,
open: first.open,
high: _.max([first.high, second.high]),
low: _.min([first.low, second.low]),
close: second.close,
volume: first.volume + second.volume,
vwp: (first.vwp * first.volume) + (second.vwp * second.volume),
trades: first.trades + second.trades
};
result.vwp /= result.volume;
var spy = sinon.spy();
cb.on('candle', spy);
cb.write( _candles );
cb.flush();
var cbResult = _.first(_.first(spy.args));
expect(cbResult).to.deep.equal(result);
expect(cbResult.id).to.equal(undefined);
});
});
+114
View File
@@ -0,0 +1,114 @@
// if you need to test Gekko against real mocked data
// uncomment the following:
// var fs = require('fs');
// var bitstamp = require('bitstamp');
// var bs = new bitstamp;
// bs.transactions('btcusd', (err, data) => {
// if(err)
// throw err;
// var json = JSON.stringify(data, null, 4);
// fs.writeFileSync('./data/bitstamp_trades.json', json);
// });
// return;
var chai = require('chai');
var expect = chai.expect;
var should = chai.should;
var sinon = require('sinon');
var proxyquire = require('proxyquire');
var _ = require('lodash');
var moment = require('moment');
var util = require(__dirname + '/../../core/util');
var config = util.getConfig();
var dirs = util.dirs();
var TRADES = require('./data/bitstamp_trades.json');
return; // TEMP
var FakeExchange = function() {};
FakeExchange.prototype = {
transactions: function(since, handler, descending) {
handler(
null,
TRADES
);
}
}
var transactionsSpy = sinon.spy(FakeExchange.prototype, 'transactions');
spoofer = {
bitstamp: FakeExchange
}
describe('exchanges/bitstamp', function() {
var Bitstamp = proxyquire(dirs.gekko + 'exchange/wrappers/bitstamp', spoofer);
var bs;
it('should instantiate', function() {
bs = new Bitstamp(config.watch);
});
it('should correctly fetch historical trades', function() {
bs.getTrades(null, _.noop, false);
expect(transactionsSpy.callCount).to.equal(1);
var args = transactionsSpy.lastCall.args;
expect(args.length).to.equal(2);
expect(args[0]).to.equal('btcusd');
});
it('should retry on exchange error', function() {
var ErrorFakeExchange = function() {};
ErrorFakeExchange.prototype = {
transactions: function(since, handler, descending) {
handler('Auth error');
}
}
spoofer = {
bitstamp: ErrorFakeExchange
}
var ErroringBitstamp = proxyquire(dirs.exchanges + 'bitstamp', spoofer);
var ebs = new ErroringBitstamp(config.watch);
ebs.retry = _.noop;
var retrySpy = sinon.spy(ebs, 'retry');
ebs.getTrades(null, _.noop)
expect(retrySpy.callCount).to.equal(1);
var args = retrySpy.lastCall.args;
expect(args[1].length).to.equal(2);
expect(args[1][0]).to.equal(null);
})
it('should correctly parse historical trades', function(done) {
var check = function(err, trades) {
expect(err).to.equal(null);
expect(trades.length).to.equal(TRADES.length);
var oldest = _.first(trades);
var OLDEST = _.last(TRADES);
expect(oldest.tid).to.equal(+OLDEST.tid);
expect(oldest.price).to.equal(+OLDEST.price);
expect(oldest.amount).to.equal(+OLDEST.amount);
expect(oldest.date).to.equal(OLDEST.date);
done();
}
bs.getTrades(null, check, false);
});
});
+947
View File
@@ -0,0 +1,947 @@
[
{
"date": "1476099635",
"tid": "12166560",
"price": "612.91000",
"type": "1",
"amount": "0.05563331"
},
{
"date": "1476099613",
"tid": "12166552",
"price": "614.20000",
"type": "0",
"amount": "0.65581425"
},
{
"date": "1476099574",
"tid": "12166551",
"price": "612.91000",
"type": "1",
"amount": "0.08348263"
},
{
"date": "1476099544",
"tid": "12166550",
"price": "614.20000",
"type": "0",
"amount": "0.05827100"
},
{
"date": "1476099523",
"tid": "12166548",
"price": "612.91000",
"type": "1",
"amount": "0.05563382"
},
{
"date": "1476099355",
"tid": "12166542",
"price": "614.20000",
"type": "0",
"amount": "0.81406708"
},
{
"date": "1476099246",
"tid": "12166541",
"price": "614.20000",
"type": "0",
"amount": "0.02000000"
},
{
"date": "1476099156",
"tid": "12166539",
"price": "614.20000",
"type": "0",
"amount": "0.39384817"
},
{
"date": "1476099154",
"tid": "12166538",
"price": "614.15000",
"type": "0",
"amount": "0.48832321"
},
{
"date": "1476099137",
"tid": "12166537",
"price": "614.15000",
"type": "0",
"amount": "0.02000000"
},
{
"date": "1476099099",
"tid": "12166534",
"price": "614.15000",
"type": "0",
"amount": "0.02300000"
},
{
"date": "1476099067",
"tid": "12166525",
"price": "614.15000",
"type": "0",
"amount": "0.07519000"
},
{
"date": "1476099058",
"tid": "12166524",
"price": "612.76000",
"type": "1",
"amount": "0.03708453"
},
{
"date": "1476099045",
"tid": "12166523",
"price": "614.15000",
"type": "0",
"amount": "0.06303310"
},
{
"date": "1476098972",
"tid": "12166519",
"price": "614.15000",
"type": "1",
"amount": "0.11617019"
},
{
"date": "1476098971",
"tid": "12166518",
"price": "614.20000",
"type": "0",
"amount": "0.02300000"
},
{
"date": "1476098943",
"tid": "12166517",
"price": "614.20000",
"type": "0",
"amount": "0.28252528"
},
{
"date": "1476098748",
"tid": "12166497",
"price": "614.20000",
"type": "0",
"amount": "0.07519000"
},
{
"date": "1476098707",
"tid": "12166490",
"price": "612.99000",
"type": "0",
"amount": "0.12971692"
},
{
"date": "1476098707",
"tid": "12166489",
"price": "612.99000",
"type": "0",
"amount": "0.06289098"
},
{
"date": "1476098616",
"tid": "12166487",
"price": "612.73000",
"type": "1",
"amount": "0.47650000"
},
{
"date": "1476098550",
"tid": "12166482",
"price": "612.99000",
"type": "0",
"amount": "0.04296970"
},
{
"date": "1476098544",
"tid": "12166480",
"price": "612.99000",
"type": "0",
"amount": "0.05113932"
},
{
"date": "1476098544",
"tid": "12166477",
"price": "612.99000",
"type": "0",
"amount": "0.09140786"
},
{
"date": "1476098538",
"tid": "12166474",
"price": "612.99000",
"type": "0",
"amount": "0.06517154"
},
{
"date": "1476098538",
"tid": "12166473",
"price": "612.99000",
"type": "0",
"amount": "0.07737564"
},
{
"date": "1476098532",
"tid": "12166470",
"price": "612.99000",
"type": "0",
"amount": "0.14254718"
},
{
"date": "1476098526",
"tid": "12166466",
"price": "612.99000",
"type": "0",
"amount": "0.14254718"
},
{
"date": "1476098488",
"tid": "12166463",
"price": "612.97000",
"type": "1",
"amount": "0.12971692"
},
{
"date": "1476098488",
"tid": "12166462",
"price": "612.97000",
"type": "1",
"amount": "0.15700000"
},
{
"date": "1476098488",
"tid": "12166461",
"price": "612.97000",
"type": "1",
"amount": "0.13047962"
},
{
"date": "1476098477",
"tid": "12166460",
"price": "614.20000",
"type": "0",
"amount": "0.02701517"
},
{
"date": "1476098476",
"tid": "12166458",
"price": "614.18000",
"type": "0",
"amount": "0.09610000"
},
{
"date": "1476098476",
"tid": "12166457",
"price": "614.18000",
"type": "0",
"amount": "0.15600000"
},
{
"date": "1476098476",
"tid": "12166456",
"price": "614.18000",
"type": "0",
"amount": "0.07639355"
},
{
"date": "1476098403",
"tid": "12166448",
"price": "614.18000",
"type": "0",
"amount": "0.04128385"
},
{
"date": "1476098403",
"tid": "12166447",
"price": "614.18000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476098403",
"tid": "12166446",
"price": "614.18000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476098403",
"tid": "12166445",
"price": "614.18000",
"type": "0",
"amount": "0.17900000"
},
{
"date": "1476098403",
"tid": "12166444",
"price": "614.18000",
"type": "0",
"amount": "0.41000000"
},
{
"date": "1476098403",
"tid": "12166443",
"price": "614.18000",
"type": "0",
"amount": "0.05371615"
},
{
"date": "1476098318",
"tid": "12166437",
"price": "612.97000",
"type": "1",
"amount": "0.01652038"
},
{
"date": "1476098176",
"tid": "12166429",
"price": "614.18000",
"type": "0",
"amount": "0.15665000"
},
{
"date": "1476098173",
"tid": "12166428",
"price": "612.78000",
"type": "1",
"amount": "0.11767740"
},
{
"date": "1476098173",
"tid": "12166427",
"price": "612.78000",
"type": "1",
"amount": "0.15600000"
},
{
"date": "1476098172",
"tid": "12166426",
"price": "612.79000",
"type": "1",
"amount": "0.09610000"
},
{
"date": "1476098104",
"tid": "12166421",
"price": "614.18000",
"type": "0",
"amount": "0.03001800"
},
{
"date": "1476098042",
"tid": "12166412",
"price": "614.18000",
"type": "0",
"amount": "0.01878000"
},
{
"date": "1476097969",
"tid": "12166408",
"price": "614.18000",
"type": "0",
"amount": "0.02000000"
},
{
"date": "1476097943",
"tid": "12166407",
"price": "614.18000",
"type": "0",
"amount": "0.12783585"
},
{
"date": "1476097943",
"tid": "12166406",
"price": "614.18000",
"type": "0",
"amount": "0.15900000"
},
{
"date": "1476097943",
"tid": "12166405",
"price": "614.18000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476097942",
"tid": "12166404",
"price": "614.18000",
"type": "0",
"amount": "0.49381415"
},
{
"date": "1476097814",
"tid": "12166401",
"price": "614.18000",
"type": "0",
"amount": "0.15080751"
},
{
"date": "1476097813",
"tid": "12166400",
"price": "614.18000",
"type": "0",
"amount": "0.23230000"
},
{
"date": "1476097811",
"tid": "12166399",
"price": "614.18000",
"type": "0",
"amount": "0.18140000"
},
{
"date": "1476097803",
"tid": "12166398",
"price": "612.95000",
"type": "1",
"amount": "0.16268000"
},
{
"date": "1476097643",
"tid": "12166387",
"price": "612.66000",
"type": "1",
"amount": "2.14279194"
},
{
"date": "1476097643",
"tid": "12166386",
"price": "612.99000",
"type": "1",
"amount": "2.30935500"
},
{
"date": "1476097643",
"tid": "12166385",
"price": "613.24000",
"type": "1",
"amount": "3.02659541"
},
{
"date": "1476097643",
"tid": "12166384",
"price": "613.26000",
"type": "1",
"amount": "1.05795023"
},
{
"date": "1476097642",
"tid": "12166383",
"price": "614.09000",
"type": "1",
"amount": "1.28080550"
},
{
"date": "1476097618",
"tid": "12166382",
"price": "614.20000",
"type": "0",
"amount": "0.91402550"
},
{
"date": "1476097617",
"tid": "12166381",
"price": "614.18000",
"type": "0",
"amount": "0.28027603"
},
{
"date": "1476097581",
"tid": "12166379",
"price": "614.18000",
"type": "0",
"amount": "0.27632529"
},
{
"date": "1476097567",
"tid": "12166378",
"price": "614.09000",
"type": "1",
"amount": "0.02178692"
},
{
"date": "1476097540",
"tid": "12166375",
"price": "614.09000",
"type": "0",
"amount": "0.15700000"
},
{
"date": "1476097540",
"tid": "12166373",
"price": "614.09000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476097540",
"tid": "12166372",
"price": "614.09000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476097540",
"tid": "12166370",
"price": "614.09000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476097540",
"tid": "12166369",
"price": "614.09000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476097539",
"tid": "12166368",
"price": "614.09000",
"type": "0",
"amount": "0.09484126"
},
{
"date": "1476097536",
"tid": "12166366",
"price": "614.09000",
"type": "0",
"amount": "0.06315874"
},
{
"date": "1476097536",
"tid": "12166365",
"price": "614.09000",
"type": "0",
"amount": "0.14600000"
},
{
"date": "1476097536",
"tid": "12166364",
"price": "614.09000",
"type": "0",
"amount": "0.41000000"
},
{
"date": "1476097536",
"tid": "12166363",
"price": "614.09000",
"type": "0",
"amount": "0.40600000"
},
{
"date": "1476097535",
"tid": "12166362",
"price": "614.09000",
"type": "0",
"amount": "0.40600000"
},
{
"date": "1476097535",
"tid": "12166361",
"price": "614.09000",
"type": "0",
"amount": "0.40600000"
},
{
"date": "1476097535",
"tid": "12166360",
"price": "614.09000",
"type": "0",
"amount": "0.40900000"
},
{
"date": "1476097535",
"tid": "12166359",
"price": "614.09000",
"type": "0",
"amount": "0.40600000"
},
{
"date": "1476097535",
"tid": "12166358",
"price": "614.09000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476097535",
"tid": "12166357",
"price": "614.09000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476097535",
"tid": "12166356",
"price": "614.09000",
"type": "0",
"amount": "0.15900000"
},
{
"date": "1476097534",
"tid": "12166355",
"price": "614.09000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476097534",
"tid": "12166354",
"price": "614.09000",
"type": "0",
"amount": "0.40600000"
},
{
"date": "1476097529",
"tid": "12166353",
"price": "613.32000",
"type": "1",
"amount": "2.90000000"
},
{
"date": "1476097503",
"tid": "12166350",
"price": "612.99000",
"type": "1",
"amount": "1.59260664"
},
{
"date": "1476097503",
"tid": "12166349",
"price": "613.06000",
"type": "1",
"amount": "0.14700000"
},
{
"date": "1476097502",
"tid": "12166348",
"price": "613.23000",
"type": "1",
"amount": "4.90000000"
},
{
"date": "1476097502",
"tid": "12166347",
"price": "613.43000",
"type": "1",
"amount": "0.15600000"
},
{
"date": "1476097502",
"tid": "12166346",
"price": "613.43000",
"type": "1",
"amount": "0.14700000"
},
{
"date": "1476097501",
"tid": "12166345",
"price": "613.55000",
"type": "1",
"amount": "0.15700000"
},
{
"date": "1476097501",
"tid": "12166344",
"price": "613.58000",
"type": "1",
"amount": "4.38220000"
},
{
"date": "1476097500",
"tid": "12166343",
"price": "614.11000",
"type": "1",
"amount": "0.48351110"
},
{
"date": "1476097492",
"tid": "12166342",
"price": "614.19000",
"type": "1",
"amount": "0.50000000"
},
{
"date": "1476097484",
"tid": "12166341",
"price": "614.20000",
"type": "1",
"amount": "31.92160000"
},
{
"date": "1476097484",
"tid": "12166340",
"price": "614.22000",
"type": "1",
"amount": "0.50000000"
},
{
"date": "1476097364",
"tid": "12166331",
"price": "614.20000",
"type": "1",
"amount": "1.95240650"
},
{
"date": "1476097364",
"tid": "12166330",
"price": "614.52000",
"type": "1",
"amount": "1.05521350"
},
{
"date": "1476097200",
"tid": "12166323",
"price": "614.76000",
"type": "0",
"amount": "0.08845994"
},
{
"date": "1476097171",
"tid": "12166321",
"price": "614.76000",
"type": "0",
"amount": "0.09385000"
},
{
"date": "1476097127",
"tid": "12166320",
"price": "614.38000",
"type": "1",
"amount": "0.02178327"
},
{
"date": "1476097028",
"tid": "12166312",
"price": "615.18000",
"type": "0",
"amount": "0.49433382"
},
{
"date": "1476097028",
"tid": "12166311",
"price": "615.18000",
"type": "0",
"amount": "0.28054507"
},
{
"date": "1476097027",
"tid": "12166310",
"price": "615.17000",
"type": "1",
"amount": "0.04000000"
},
{
"date": "1476096998",
"tid": "12166308",
"price": "614.11000",
"type": "1",
"amount": "0.01648890"
},
{
"date": "1476096994",
"tid": "12166307",
"price": "615.17000",
"type": "0",
"amount": "0.01732453"
},
{
"date": "1476096785",
"tid": "12166297",
"price": "614.15000",
"type": "0",
"amount": "4.36590263"
},
{
"date": "1476096782",
"tid": "12166295",
"price": "614.17000",
"type": "1",
"amount": "1.62632737"
},
{
"date": "1476096671",
"tid": "12166286",
"price": "615.18000",
"type": "0",
"amount": "0.77605625"
},
{
"date": "1476096671",
"tid": "12166285",
"price": "615.18000",
"type": "0",
"amount": "1.17641295"
},
{
"date": "1476096532",
"tid": "12166284",
"price": "615.18000",
"type": "0",
"amount": "0.45000000"
},
{
"date": "1476096518",
"tid": "12166283",
"price": "614.12000",
"type": "1",
"amount": "0.82273414"
},
{
"date": "1476096518",
"tid": "12166282",
"price": "614.60000",
"type": "1",
"amount": "0.39143007"
},
{
"date": "1476096475",
"tid": "12166281",
"price": "615.02000",
"type": "1",
"amount": "9.64860000"
},
{
"date": "1476096453",
"tid": "12166279",
"price": "614.99000",
"type": "1",
"amount": "4.12628026"
},
{
"date": "1476096450",
"tid": "12166278",
"price": "614.99000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476096450",
"tid": "12166277",
"price": "614.99000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476096450",
"tid": "12166276",
"price": "614.99000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476096450",
"tid": "12166275",
"price": "614.99000",
"type": "0",
"amount": "0.40900000"
},
{
"date": "1476096450",
"tid": "12166274",
"price": "614.99000",
"type": "0",
"amount": "0.30145000"
},
{
"date": "1476096370",
"tid": "12166265",
"price": "614.99000",
"type": "0",
"amount": "0.10655000"
},
{
"date": "1476096370",
"tid": "12166264",
"price": "614.99000",
"type": "0",
"amount": "0.05000000"
},
{
"date": "1476096292",
"tid": "12166258",
"price": "615.17000",
"type": "0",
"amount": "2.13738013"
},
{
"date": "1476096292",
"tid": "12166257",
"price": "614.97000",
"type": "0",
"amount": "0.86261987"
},
{
"date": "1476096172",
"tid": "12166241",
"price": "614.97000",
"type": "0",
"amount": "3.57370278"
},
{
"date": "1476096171",
"tid": "12166240",
"price": "614.91000",
"type": "0",
"amount": "2.98402000"
},
{
"date": "1476096171",
"tid": "12166239",
"price": "614.90000",
"type": "0",
"amount": "0.24000000"
},
{
"date": "1476096171",
"tid": "12166238",
"price": "614.84000",
"type": "0",
"amount": "0.34034948"
},
{
"date": "1476096170",
"tid": "12166237",
"price": "614.84000",
"type": "0",
"amount": "0.11200000"
},
{
"date": "1476096170",
"tid": "12166236",
"price": "614.84000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476096170",
"tid": "12166235",
"price": "614.84000",
"type": "0",
"amount": "0.15800000"
},
{
"date": "1476096170",
"tid": "12166234",
"price": "614.84000",
"type": "0",
"amount": "0.15700000"
},
{
"date": "1476096169",
"tid": "12166233",
"price": "614.84000",
"type": "0",
"amount": "0.40800000"
},
{
"date": "1476096154",
"tid": "12166232",
"price": "614.70000",
"type": "1",
"amount": "0.46887000"
}
]
+59
View File
@@ -0,0 +1,59 @@
var chai = require('chai');
var expect = chai.expect;
var should = chai.should;
var sinon = require('sinon');
var _ = require('lodash');
var util = require('../../core/util');
var dirs = util.dirs();
var INDICATOR_PATH = dirs.indicators;
// Fake input prices to verify all indicators
// are working correctly by comparing fresh
// calculated results to pre calculated results.
// Since there are is no CCI Indicator @ https://github.com/wuhkuh/talib,
// the precalculated results have been calculated with Excel :D
var high = [86, 85, 90, 95, 58, 71, 84, 98, 99, 100, 91, 95, 99, 96, 96, 90, 79, 72, 91, 81, 94, 87, 60, 93, 75, 94, 75, 93, 92, 92, 99, 99, 84, 91, 27, 67, 97, 92, 89];
var low = [1, 5, 14, 10, 20, 10, 1, 48, 64, 0, 0, 50, 15, 0, 4, 57, 1, 11, 9, 1, 1, 10, 25, 11, 16, 50, 7, 13, 74, 71, 59, 3, 1, 1, 0, 5, 1, 60, 6];
var close = [81, 24, 75, 21, 34, 25, 72, 92, 99, 2, 86, 80, 76, 8, 87, 75, 32, 65, 41, 9, 13, 26, 56, 28, 65, 58, 17, 90, 87, 86, 99, 3, 70, 1, 27, 9, 92, 68, 9];
describe('indicators/CCI', function() {
var CCI = require(INDICATOR_PATH + 'CCI');
//Had to limit the decimals because of rounding mistakes
var verified_cci8results = [0, 0, 0, 0, 0, 0, 0, 165.258216, 137.978495, -78.352249, 23.011844, 66.039216, 11.260054, -110.755556, 2.108795, 60.958054, -79.830149, -40.800225, -42.00627, -103.175918, -58.657244, -37.232704, 12.844037, 31.25, 101.960784, 187.096774, -82.539683, 114.047867, 147.875064, 101.075269, 88.888889, -108.039098, -43.914081, -87.872763, -113.138686, -68.525669, 43.243243, 82.481254, -29.942756];
var verified_cci10results = [0, 0, 0, 0, 0, 0, 0, 0, 0, -81.681682, 28.953557, 78.940028, 27.948194, -82.58317, 17.665798, 57.71725, -100.171969, -36.79078, -33.502538, -113.08642, -70.175439, -36.995092, 7.30897, -20.757021, 51.239669, 200, -99.574468, 134.51119, 166.021297, 117.174281, 100.395257, -94.147583, -33.202614, -101.396478, -115.00256, -71.976401, 27.092846, 53.157122, -49.211356];
var verified_cci12results = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91.97995, 35.138387, -86.288416, 30.06993, 67.713787, -85.863874, -44.274809, -51.105651, -102.536873, -68.659725, -49.02507, -14.705882, -21.217712, 42.461538, 122.124711, -94.10628, 146.91745, 197.464342, 135.599506, 111.925175, -80.55041, -23.476298, -99.837574, -126.229111, -84.671533, 30.350877, 58.954584, -61.147046];
it('should correctly calculate CCI with period 8', function() {
var cci = new CCI({ history: 8, constant: 0.015 });
_.each(close,function(p,i) {
cci.update({high: high[i], low: low[i] , close: close[i]});
//when i<history, cci.results returns false
if (typeof(cci.result) == 'boolean') cci.result = 0;
expect(cci.result.toFixed(6)).to.equal(verified_cci8results[i].toFixed(6));
});
});
it('should correctly calculate CCI with period 10', function() {
var cci = new CCI({ history: 10, constant: 0.015 });
_.each(close,function(p,i) {
cci.update({high: high[i], low: low[i] , close: close[i]});
if (typeof(cci.result) == 'boolean') cci.result = 0;
expect(cci.result.toFixed(6)).to.equal(verified_cci10results[i].toFixed(6));
})
});
it('should correctly calculate CCI with period 12', function() {
var cci = new CCI({ history: 12, constant: 0.015 });
_.each(close,function(p,i) {
cci.update({high: high[i], low: low[i] , close: close[i]});
if (typeof(cci.result) == 'boolean') cci.result = 0;
expect(cci.result.toFixed(6)).to.equal(verified_cci12results[i].toFixed(6));
})
});
});
+38
View File
@@ -0,0 +1,38 @@
var chai = require('chai');
var expect = chai.expect;
var should = chai.should;
var sinon = require('sinon');
var _ = require('lodash');
var util = require('../../core/util');
var dirs = util.dirs();
var INDICATOR_PATH = dirs.indicators;
// Fake input prices to verify all indicators
// are working correctly by comparing fresh
// calculated results to pre calculated results.
// The precalculated results are already compared
// to MS Excel results, more info here:
//
// https://github.com/askmike/gekko/issues/161
var prices = [81, 24, 75, 21, 34, 25, 72, 92, 99, 2, 86, 80, 76, 8, 87, 75, 32, 65, 41, 9, 13, 26, 56, 28, 65, 58, 17, 90, 87, 86, 99, 3, 70, 1, 27, 9, 92, 68, 9];
describe('indicators/DEMA', function() {
var DEMA = require(INDICATOR_PATH + 'DEMA');
var verified_dema10results = [81,62.157024793388416,65.1412471825695,49.61361928829999,42.570707415663364,34.597495090487996,44.47997295246192,58.6168391922143,71.4979863711489,48.963944850563,60.095241192962106,66.41965473810654,69.77997604557987,49.75572911767095,61.08641574881719,65.56112611350791,54.65374623818491,57.51231851211959,51.73955057939423,36.941596820151815,27.434153499662216,24.890025210750593,33.14097982029734,30.163817870645254,40.330715478873344,45.63811915119551,36.045947422710505,53.12735486322183,64.78921092296176,72.9995704035162,83.22304838955624,58.85287916072168,62.841348382387075,42.93804766689409,36.82301007497254,26.454331684513562,46.374329400503385,53.28360623846342,38.891184741941984];
it('should correctly calculate DEMA with weight 10', function() {
let dema = new DEMA({weight: 10});
_.each(prices, function(p, i) {
dema.update(p);
expect(dema.result).to.equal(verified_dema10results[i]);
});
});
});
+55
View File
@@ -0,0 +1,55 @@
var chai = require('chai');
var expect = chai.expect;
var should = chai.should;
var sinon = require('sinon');
var _ = require('lodash');
var util = require('../../core/util');
var dirs = util.dirs();
var INDICATOR_PATH = dirs.indicators;
// Fake input prices to verify all indicators
// are working correctly by comparing fresh
// calculated results to pre calculated results.
// The precalculated results are already compared
// to MS Excel results, more info here:
//
// https://github.com/askmike/gekko/issues/161
var prices = [81, 24, 75, 21, 34, 25, 72, 92, 99, 2, 86, 80, 76, 8, 87, 75, 32, 65, 41, 9, 13, 26, 56, 28, 65, 58, 17, 90, 87, 86, 99, 3, 70, 1, 27, 9, 92, 68, 9];
describe('indicators/EMA', function() {
var EMA = require(INDICATOR_PATH + 'EMA');
var verified_ema10results = [81,70.63636363636363,71.4297520661157,62.26070623591284,57.12239601120141,51.28196037280115,55.04887666865549,61.767262728899944,68.53685132364541,56.43924199207351,61.81392526624197,65.12048430874341,67.09857807079005,56.35338205791913,61.92549441102474,64.30267724538388,58.42946320076862,59.624106255174325,56.2379051178699,47.649195096439,41.349341442541004,38.55855208935173,41.72972443674232,39.233410902789174,43.91824528410023,46.47856432335473,41.118825355472055,50.00631165447713,56.73243680820856,62.053811933988825,68.77130067326358,56.81288236903384,59.21054012011859,48.626805552824294,44.69465908867441,38.204721072551784,47.985680877542364,51.62464799071648,43.874711992404386];
var verified_ema12results = [81,72.23076923076923,72.65680473372781,64.709604005462,59.98504954308323,54.602734228762735,57.27923665510693,62.620892554321244,68.2176783151949,58.030343189780304,62.33336731442949,65.05131080451726,66.73572452689922,57.69945921506857,62.20723472044264,64.17535245575915,59.2252982317962,60.11371388844294,57.173142520990176,49.761889825453224,44.10621446769119,41.320643011123316,43.57900562479665,41.182235528674084,44.84650698580115,46.87012129567789,42.27471801941975,49.61706909335518,55.368289232839,60.080860120094535,66.06842010161846,56.365586239831,58.46318835678008,49.62269784035237,46.14228278799047,40.42808543599194,48.36222613814702,51.383422116893634,44.86289563737154];
var verified_ema26results = [81,76.77777777777777,76.64609053497942,72.52415790275873,69.67051657662846,66.36158942280413,66.77924946555937,68.64745320885127,70.89579000819562,65.79239815573669,67.28925755160805,68.2307940292667,68.80629076783954,64.30212108133291,65.98344544567863,66.65133837562836,64.08457257002625,64.15238200928357,62.43739074933664,58.479065508645036,55.11024584133799,52.95393133457221,53.17956605052982,51.314413009749835,52.32816019421281,52.748296476122974,50.10027451492868,53.05580973604507,55.57019420004173,57.82425388892753,60.874309156414384,56.58732329297628,57.58085490090396,53.38968046379996,51.4348893183333,48.29156418364194,51.52922609596476,52.74928342218959,49.50859576128666];
it('should correctly calculate EMAs with weight 10', function() {
var ema = new EMA(10);
_.each(prices, function(p, i) {
ema.update(p);
expect(ema.result).to.equal(verified_ema10results[i]);
});
});
it('should correctly calculate EMAs with weight 12', function() {
var ema = new EMA(12);
_.each(prices, function(p, i) {
ema.update(p);
expect(ema.result).to.equal(verified_ema12results[i]);
});
});
it('should correctly calculate EMAs with weight 26', function() {
var ema = new EMA(26);
_.each(prices, function(p, i) {
ema.update(p);
expect(ema.result).to.equal(verified_ema26results[i]);
});
});
});
+100
View File
@@ -0,0 +1,100 @@
var chai = require('chai');
var expect = chai.expect;
var should = chai.should;
var sinon = require('sinon');
var _ = require('lodash');
var util = require('../../core/util');
var dirs = util.dirs();
var INDICATOR_PATH = dirs.indicators;
// Fake input prices to verify all indicators
// are working correctly by comparing fresh
// calculated results to pre calculated results.
// The precalculated results are already compared
// to MS Excel results, more info here:
//
// https://github.com/askmike/gekko/issues/161
var prices = [81, 24, 75, 21, 34, 25, 72, 92, 99, 2, 86, 80, 76, 8, 87, 75, 32, 65, 41, 9, 13, 26, 56, 28, 65, 58, 17, 90, 87, 86, 99, 3, 70, 1, 27, 9, 92, 68, 9];
describe('indicators/MACD', function() {
var MACD = require(INDICATOR_PATH + 'MACD');
var verified_macd12v26v9diff = [0,-4.547008547008545,-3.9892858012516115,-7.814553897296733,-9.68546703354523,-11.758855194041395,-9.500012810452446,-6.02656065453003,-2.678111693000716,-7.762054965956388,-4.955890237178558,-3.179483224749447,-2.070566240940323,-6.6026618662643415,-3.776210725235984,-2.4759859198692027,-4.859274338230051,-4.038668120840633,-5.264248228346467,-8.717175683191812,-11.004031373646804,-11.633288323448895,-9.600560425733171,-10.13217748107575,-7.4816532084116645,-5.8781751804450835,-7.825556495508927,-3.4387406426898934,-0.20190496720273643,2.256606231167005,5.1941109452040735,-0.2217370531452758,0.8823334558761218,-3.766982623447589,-5.29260653034283,-7.863478747649999,-3.166999957817737,-1.365861305295958,-4.64570012391512];
var verified_macd12v26v9signal = [0,-0.9094017094017091,-1.5253785277716898,-2.7832136016766986,-4.163664288050406,-5.6827024692486034,-6.446164537489373,-6.362243760897504,-5.625417347318147,-6.052744871045796,-5.833373944272349,-5.30259580036777,-4.65618988848228,-5.045484284038693,-4.791629572278152,-4.328500841796362,-4.4346555410831,-4.355458057034607,-4.537216091296979,-5.373208009675945,-6.499372682470117,-7.526155810665873,-7.941036733679333,-8.379264883158616,-8.199742548209226,-7.735429074656398,-7.753454558826904,-6.890511775599502,-5.55279041392015,-3.990911084902719,-2.153906678881361,-1.767472753734144,-1.2375115118120907,-1.7434057341391904,-2.4532458933799184,-3.535292464233935,-3.4616339629506956,-3.0424794314197485,-3.363123569918823];
var verified_macd12v26v9result = [0,-3.6376068376068362,-2.4639072734799217,-5.031340295620034,-5.521802745494824,-6.076152724792792,-3.053848272963074,0.33568310636747434,2.9473056543174314,-1.7093100949105917,0.8774837070937913,2.1231125756183227,2.585623647541957,-1.5571775822256484,1.0154188470421683,1.8525149219271597,-0.42461879714695083,0.3167899361939739,-0.7270321370494885,-3.3439676735158663,-4.504658691176687,-4.107132512783021,-1.6595236920538383,-1.7529125979171347,0.7180893397975616,1.8572538942113148,-0.07210193668202258,3.4517711329096086,5.350885446717413,6.247517316069724,7.3480176240854345,1.5457357005888681,2.1198449676882127,-2.0235768893083987,-2.839360636962912,-4.3281862834160645,0.2946340051329588,1.6766181261237905,-1.2825765539962966];
it('should correctly calculate MACD diffs with 12/26/9', function() {
var macd = new MACD({short: 12, long: 26, signal: 9});
_.each(prices, function(p, i) {
macd.update(p);
expect(macd.diff).to.equal(verified_macd12v26v9diff[i]);
});
});
it('should correctly calculate MACD signals with 12/26/9', function() {
var macd = new MACD({short: 12, long: 26, signal: 9});
_.each(prices, function(p, i) {
macd.update(p);
expect(macd.signal.result).to.equal(verified_macd12v26v9signal[i]);
});
});
it('should correctly calculate MACD results with 12/26/9', function() {
var macd = new MACD({short: 12, long: 26, signal: 9});
_.each(prices, function(p, i) {
macd.update(p);
expect(macd.result).to.equal(verified_macd12v26v9result[i]);
});
});
});
describe('indicators/PPO', function() {
var PPO = require(INDICATOR_PATH + 'PPO');
var verified_ppo12v26v9 = [0,-5.922297673383055,-5.204813152773915,-10.775104631720897,-13.901816018390623,-17.719369436924076,-14.22599518036208,-8.779001074074772,-3.7775327599722406,-11.79779911287454,-7.3650541223130555,-4.659894802610166,-3.0092688006197794,-10.268186733549467,-5.72296687408477,-3.714833010426942,-7.582596159036941,-6.295429716477546,-8.431243146403258,-14.906489369094212,-19.9673059077387,-21.968696242678835,-18.053100351760996,-19.745285752660987,-14.297565938958984,-11.143819939485432,-15.619787658403148,-6.481364924591247,-0.3633332042639952,3.9025254618963814,8.5325172756507,-0.3918493405267646,1.5323382353294481,-7.05563807597937,-10.289915270521151,-16.28333826120637,-6.14602662946988,-2.589345706109427,-9.383623293044062];
var verified_ppo12v26v9signal = [0,-1.184459534676611,-1.9885302582960718,-3.745845132981037,-5.777039310062954,-8.16550533543518,-9.37760330442056,-9.257882858351403,-8.161812838675571,-8.889010093515365,-8.584218899274903,-7.799354079941956,-6.8413370240775215,-7.526706965971911,-7.165958947594484,-6.475733760160976,-6.697106239936169,-6.616770935244445,-6.979665377476208,-8.565030175799809,-10.845485322187589,-13.07012750628584,-14.066722075380872,-15.202434810836897,-15.021461036461314,-14.245932817066137,-14.52070378533354,-12.912836013185082,-10.402935451400865,-7.541843268741416,-4.3269711598629925,-3.539946795995747,-2.5254897897307083,-3.431519446980441,-4.8031986116885825,-7.099226541592141,-6.908586559167689,-6.044738388556036,-6.712515369453642];
var verified_ppo12v26v9hist = [0,-4.737838138706444,-3.2162828944778434,-7.02925949873986,-8.12477670832767,-9.553864101488896,-4.84839187594152,0.47888178427663064,4.3842800787033305,-2.9087890193591743,1.2191647769618479,3.13945927733179,3.832068223457742,-2.7414797675775553,1.4429920735097133,2.760900749734034,-0.8854899191007712,0.32134121876689914,-1.4515777689270495,-6.341459193294403,-9.121820585551113,-8.898568736392996,-3.9863782763801243,-4.54285094182409,0.7238950975023304,3.102112877580705,-1.099083873069608,6.431471088593835,10.03960224713687,11.444368730637798,12.859488435513693,3.1480974554689825,4.057828025060156,-3.6241186289989296,-5.486716658832568,-9.18411171961423,0.762559929697809,3.455392682446609,-2.6711079235904203];
it('should correctly calculate PPOs with 12/26/9', function() {
var ppo = new PPO({short: 12, long: 26, signal: 9});
_.each(prices, function(p, i) {
ppo.update(p);
expect(ppo.result.ppo).to.equal(verified_ppo12v26v9[i]);
});
});
it('should correctly calculate PPO signals with 12/26/9', function() {
var ppo = new PPO({short: 12, long: 26, signal: 9});
_.each(prices, function(p, i) {
ppo.update(p);
expect(ppo.result.PPOsignal).to.equal(verified_ppo12v26v9signal[i]);
});
});
it('should correctly calculate PPO hists with 12/26/9', function() {
var ppo = new PPO({short: 12, long: 26, signal: 9});
_.each(prices, function(p, i) {
ppo.update(p);
expect(ppo.result.PPOhist).to.equal(verified_ppo12v26v9hist[i]);
});
});
});
xdescribe('indicators/DEMA', function() {
var DEMA = require(INDICATOR_PATH + 'DEMA');
xit('should correctly calculate DEMAs', function() {
// TODO!
});
});
+55
View File
@@ -0,0 +1,55 @@
var chai = require('chai');
var expect = chai.expect;
var should = chai.should;
var sinon = require('sinon');
var _ = require('lodash');
var util = require('../../core/util');
var dirs = util.dirs();
var INDICATOR_PATH = dirs.indicators;
// Fake input prices to verify all indicators
// are working correctly by comparing fresh
// calculated results to pre calculated results.
// The precalculated results are already compared
// to MS Excel results, more info here:
//
// https://github.com/askmike/gekko/issues/161
var prices = [81, 24, 75, 21, 34, 25, 72, 92, 99, 2, 86, 80, 76, 8, 87, 75, 32, 65, 41, 9, 13, 26, 56, 28, 65, 58, 17, 90, 87, 86, 99, 3, 70, 1, 27, 9, 92, 68, 9];
describe('indicators/PPO', function() {
var PPO = require(INDICATOR_PATH + 'PPO');
var verified_ppo12v26v9 = [0,-5.922297673383055,-5.204813152773915,-10.775104631720897,-13.901816018390623,-17.719369436924076,-14.22599518036208,-8.779001074074772,-3.7775327599722406,-11.79779911287454,-7.3650541223130555,-4.659894802610166,-3.0092688006197794,-10.268186733549467,-5.72296687408477,-3.714833010426942,-7.582596159036941,-6.295429716477546,-8.431243146403258,-14.906489369094212,-19.9673059077387,-21.968696242678835,-18.053100351760996,-19.745285752660987,-14.297565938958984,-11.143819939485432,-15.619787658403148,-6.481364924591247,-0.3633332042639952,3.9025254618963814,8.5325172756507,-0.3918493405267646,1.5323382353294481,-7.05563807597937,-10.289915270521151,-16.28333826120637,-6.14602662946988,-2.589345706109427,-9.383623293044062];
var verified_ppo12v26v9signal = [0,-1.184459534676611,-1.9885302582960718,-3.745845132981037,-5.777039310062954,-8.16550533543518,-9.37760330442056,-9.257882858351403,-8.161812838675571,-8.889010093515365,-8.584218899274903,-7.799354079941956,-6.8413370240775215,-7.526706965971911,-7.165958947594484,-6.475733760160976,-6.697106239936169,-6.616770935244445,-6.979665377476208,-8.565030175799809,-10.845485322187589,-13.07012750628584,-14.066722075380872,-15.202434810836897,-15.021461036461314,-14.245932817066137,-14.52070378533354,-12.912836013185082,-10.402935451400865,-7.541843268741416,-4.3269711598629925,-3.539946795995747,-2.5254897897307083,-3.431519446980441,-4.8031986116885825,-7.099226541592141,-6.908586559167689,-6.044738388556036,-6.712515369453642];
var verified_ppo12v26v9hist = [0,-4.737838138706444,-3.2162828944778434,-7.02925949873986,-8.12477670832767,-9.553864101488896,-4.84839187594152,0.47888178427663064,4.3842800787033305,-2.9087890193591743,1.2191647769618479,3.13945927733179,3.832068223457742,-2.7414797675775553,1.4429920735097133,2.760900749734034,-0.8854899191007712,0.32134121876689914,-1.4515777689270495,-6.341459193294403,-9.121820585551113,-8.898568736392996,-3.9863782763801243,-4.54285094182409,0.7238950975023304,3.102112877580705,-1.099083873069608,6.431471088593835,10.03960224713687,11.444368730637798,12.859488435513693,3.1480974554689825,4.057828025060156,-3.6241186289989296,-5.486716658832568,-9.18411171961423,0.762559929697809,3.455392682446609,-2.6711079235904203];
it('should correctly calculate PPOs with 12/26/9', function() {
var ppo = new PPO({short: 12, long: 26, signal: 9});
_.each(prices, function(p, i) {
ppo.update(p);
expect(ppo.result.ppo).to.equal(verified_ppo12v26v9[i]);
});
});
it('should correctly calculate PPO signals with 12/26/9', function() {
var ppo = new PPO({short: 12, long: 26, signal: 9});
_.each(prices, function(p, i) {
ppo.update(p);
expect(ppo.result.PPOsignal).to.equal(verified_ppo12v26v9signal[i]);
});
});
it('should correctly calculate PPO hists with 12/26/9', function() {
var ppo = new PPO({short: 12, long: 26, signal: 9});
_.each(prices, function(p, i) {
ppo.update(p);
expect(ppo.result.PPOhist).to.equal(verified_ppo12v26v9hist[i]);
});
});
});
+53
View File
@@ -0,0 +1,53 @@
var chai = require('chai');
var expect = chai.expect;
var should = chai.should;
var sinon = require('sinon');
var _ = require('lodash');
var util = require('../../core/util');
var dirs = util.dirs();
var INDICATOR_PATH = dirs.indicators;
// Fake input prices to verify all indicators
// are working correctly by comparing fresh
// calculated results to pre calculated results.
// The precalculated results are compared to the Talib repository at
// https://github.com/wuhkuh/talib
// (shameless plug, sorry guys ;))
var prices = [81, 24, 75, 21, 34, 25, 72, 92, 99, 2, 86, 80, 76, 8, 87, 75, 32, 65, 41, 9, 13, 26, 56, 28, 65, 58, 17, 90, 87, 86, 99, 3, 70, 1, 27, 9, 92, 68, 9];
describe('indicators/RSI', function() {
var RSI = require(INDICATOR_PATH + 'RSI');
var verified_rsi2results = [0, 0, 47.22222222222223, 23.611111111111114, 38.43283582089553, 30.294117647058826, 78.2967032967033, 86.31639722863741, 89.12844036697248, 13.311866264730071, 64.95013850415512, 59.85653017461453, 54.19016363132106, 12.8454188854557, 68.56748255340673, 57.41553886370404, 26.512530826658676, 59.75774345724092, 36.04149739852744, 17.51008036340795, 26.905774699598737, 58.00044863973779, 85.82728624443239, 38.371227493966536, 74.96090570884536, 61.21019495608749, 19.438903652597787, 76.51344601664712, 72.30324117451528, 69.74473974944168, 84.24228523539779, 10.429850167468388, 59.707866801087974, 27.99023519523047, 48.57675474701421, 34.80106793288934, 81.96579567492182, 57.78953245436237, 23.585658801479056];
var verified_rsi12results = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49.44320712694878, 42.432667245873155, 51.2017782300719, 49.94116787991835, 45.55663590860508, 49.284333951746184, 46.74501674557244, 43.4860123510052, 44.01823674189631, 45.82704797004994, 49.90209564896179, 46.351969981868436, 51.34208640997234, 50.37501845071388, 44.96351306736635, 54.464714123844956, 54.04642006918241, 53.895901697369816, 55.6476477612053, 42.60631369413207, 51.2964732419777, 43.83906729252931, 47.00600661743475, 45.08586375053323, 54.44633399991266, 51.6681674437389, 45.44886082103851];
var verified_rsi26results = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46.44444444444444, 50.61070579555701, 50.44298978067838, 50.385107396174675, 51.143071170125296, 45.77270174725033, 49.6130641968312, 46.115177339098764, 47.56394036014283, 46.660676933508505, 51.11283316502063, 49.861270146262456, 46.92369439491447];
it('should correctly calculate RSI with period 2', function() {
var rsi = new RSI({ interval: 2 });
_.each(prices, function(p, i) {
rsi.update({ close: p });
expect(rsi.result).to.equal(verified_rsi2results[i]);
});
});
it('should correctly calculate RSI with period 12', function() {
var rsi = new RSI({ interval: 12 });
_.each(prices, function(p, i) {
rsi.update({ close: p });
expect(rsi.result).to.equal(verified_rsi12results[i]);
});
});
it('should correctly calculate RSI with period 26', function() {
var rsi = new RSI({ interval: 26 });
_.each(prices, function(p, i) {
rsi.update({ close: p });
expect(rsi.result).to.equal(verified_rsi26results[i]);
});
});
});
+46
View File
@@ -0,0 +1,46 @@
var chai = require('chai');
var expect = chai.expect;
var should = chai.should;
var sinon = require('sinon');
var _ = require('lodash');
var util = require('../../core/util');
var dirs = util.dirs();
var INDICATOR_PATH = dirs.indicators;
var prices = [81, 24, 75, 21, 34, 25, 72, 92, 99, 2, 86, 80, 76, 8, 87, 75, 32, 65, 41, 9, 13, 26, 56, 28, 65, 58, 17, 90, 87, 86, 99, 3, 70, 1, 27, 9, 92, 68, 9];
describe('indicators/SMA', function() {
var SMA = require(INDICATOR_PATH + 'SMA');
var verified_SMA10results = [ 81, 52.5, 60, 50.25, 47, 43.333333333333336, 47.42857142857143, 53, 58.111111111111114, 52.5, 53, 58.6, 58.7, 57.4, 62.7, 67.7, 63.7, 61, 55.2, 55.9, 48.6, 43.2, 41.2, 43.2, 41, 39.3, 37.8, 40.3, 44.9, 52.6, 61.2, 58.9, 60.3, 57.6, 53.8, 48.9, 56.4, 54.2, 46.4 ];
var verified_SMA12results = [ 81, 52.5, 60, 50.25, 47, 43.333333333333336, 47.42857142857143, 53, 58.111111111111114, 52.5, 55.54545454545455, 57.583333333333336, 57.166666666666664, 55.833333333333336, 56.833333333333336, 61.333333333333336, 61.166666666666664, 64.5, 61.916666666666664, 55, 47.833333333333336, 49.833333333333336, 47.333333333333336, 43, 42.083333333333336, 46.25, 40.416666666666664, 41.666666666666664, 46.25, 48, 52.833333333333336, 52.333333333333336, 57.083333333333336, 55, 52.583333333333336, 51, 53.25, 54.083333333333336, 53.416666666666664 ];
var verified_SMA26results = [ 81, 52.5, 60, 50.25, 47, 43.333333333333336, 47.42857142857143, 53, 58.111111111111114, 52.5, 55.54545454545455, 57.583333333333336, 59, 55.357142857142854, 57.46666666666667, 58.5625, 57, 57.44444444444444, 56.578947368421055, 54.2, 52.23809523809524, 51.04545454545455, 51.26086956521739, 50.291666666666664, 50.88, 51.15384615384615, 48.69230769230769, 51.23076923076923, 51.69230769230769, 54.19230769230769, 56.69230769230769, 55.84615384615385, 55.76923076923077, 52.26923076923077, 49.5, 49.76923076923077, 50, 49.53846153846154, 46.96153846153846 ];
it('should correctly calculate SMAs with window length 10', function() {
var sma = new SMA(10);
_.each(prices, function(p, i) {
sma.update(p);
expect(sma.result).to.equal(verified_SMA10results[i]);
});
});
it('should correctly calculate SMAs with window length 12', function() {
var sma = new SMA(12);
_.each(prices, function(p, i) {
sma.update(p);
expect(sma.result).to.equal(verified_SMA12results[i]);
});
});
it('should correctly calculate SMAs with window length 26', function() {
var sma = new SMA(26);
_.each(prices, function(p, i) {
sma.update(p);
expect(sma.result).to.equal(verified_SMA26results[i]);
});
});
});
+53
View File
@@ -0,0 +1,53 @@
var chai = require('chai');
var expect = chai.expect;
var should = chai.should;
var sinon = require('sinon');
var _ = require('lodash');
var util = require('../../core/util');
var dirs = util.dirs();
var INDICATOR_PATH = dirs.indicators;
// Fake input prices to verify all indicators
// are working correctly by comparing fresh
// calculated results to pre calculated results.
// The precalculated results are compared to the Talib repository at
// https://github.com/wuhkuh/talib
// (shameless plug, sorry guys ;))
var prices = [81, 24, 75, 21, 34, 25, 72, 92, 99, 2, 86, 80, 76, 8, 87, 75, 32, 65, 41, 9, 13, 26, 56, 28, 65, 58, 17, 90, 87, 86, 99, 3, 70, 1, 27, 9, 92, 68, 9];
describe('indicators/SMMA', function() {
var SMMA = require(INDICATOR_PATH + 'SMMA');
var verified_smma2results = [0, 52.5, 63.75, 42.375, 38.1875, 31.59375, 51.796875, 71.8984375, 85.44921875, 43.724609375, 64.8623046875, 72.43115234375, 74.215576171875, 41.1077880859375, 64.05389404296875, 69.52694702148438, 50.76347351074219, 57.881736755371094, 49.44086837768555, 29.220434188842773, 21.110217094421387, 23.555108547210693, 39.77755427360535, 33.88877713680267, 49.44438856840134, 53.72219428420067, 35.361097142100334, 62.68054857105017, 74.84027428552508, 80.42013714276254, 89.71006857138127, 46.355034285690635, 58.17751714284532, 29.58875857142266, 28.29437928571133, 18.647189642855665, 55.32359482142783, 61.661797410713916, 35.33089870535696];
var verified_smma12results = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57.583333333333336, 59.118055555555564, 54.8582175925926, 57.53669945987655, 58.991974504886834, 56.74264329614626, 57.43075635480074, 56.061526658567345, 52.1397327703534, 48.878088372823946, 46.97158100842196, 47.72394925772013, 46.08028681957679, 47.656929584612065, 48.518852119227724, 45.89228110929208, 49.5679243501844, 52.687263987669034, 55.46332532202995, 59.09138154519412, 54.41709974976127, 55.7156747706145, 51.15603520639663, 49.14303227253024, 45.797779583152725, 49.64796461788999, 51.177300899732494, 47.66252582475479];
var verified_smma26results = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51.15384615384615, 49.84023668639053, 51.384842967683205, 52.75465669969539, 54.0333237497071, 55.76281129779529, 53.73347240172624, 54.35910807858292, 52.30683469094512, 51.33349489513954, 49.70528355301879, 51.33200341636422, 51.973080208042525, 50.32026943081012];
it('should correctly calculate SMMAs with weight 2', function() {
var smma = new SMMA(2);
_.each(prices, function(p, i) {
smma.update(p);
expect(smma.result).to.equal(verified_smma2results[i]);
});
});
it('should correctly calculate SMMAs with weight 12', function() {
var smma = new SMMA(12);
_.each(prices, function(p, i) {
smma.update(p);
expect(smma.result).to.equal(verified_smma12results[i]);
});
});
it('should correctly calculate SMMAs with weight 26', function() {
var smma = new SMMA(26);
_.each(prices, function(p, i) {
smma.update(p);
expect(smma.result).to.equal(verified_smma26results[i]);
});
});
});
+98
View File
@@ -0,0 +1,98 @@
var chai = require('chai');
var expect = chai.expect;
var should = chai.should;
var assert = chai.assert;
var sinon = require('sinon');
var proxyquire = require('proxyquire');
var _ = require('lodash');
var moment = require('moment');
var util = require(__dirname + '/../core/util');
var config = util.getConfig();
var dirs = util.dirs();
var providerName = config.watch.exchange.toLowerCase();
var providerPath = util.dirs().gekko + 'exchanges/' + providerName;
return; // TEMP
var mf;
var spoofer = {};
var TRADES = [
{ tid: 1, amount: 1, price: 100, date: 1475837937 },
{ tid: 2, amount: 1, price: 100, date: 1475837938 }
];
// stub the exchange
var FakeProvider = function() {};
var getTrades = function(since, handler, descending) {
handler(
null,
TRADES
);
}
FakeProvider.prototype = {
getTrades: getTrades
}
spoofer[providerPath] = FakeProvider;
var getTradesSpy = sinon.spy(FakeProvider.prototype, 'getTrades');
// stub the tradebatcher
var TradeBatcher = require(util.dirs().budfox + 'tradeBatcher');
var tradeBatcherSpy = sinon.spy(TradeBatcher.prototype, 'write');
spoofer[util.dirs().budfox + 'tradeBatcher'] = TradeBatcher;
var MarketFetcher = proxyquire(dirs.budfox + 'marketFetcher', spoofer);
describe('budfox/marketFetcher', function() {
it('should throw when not passed a config', function() {
expect(function() {
new MarketFetcher();
}).to.throw('TradeFetcher expects a config');
});
it('should instantiate', function() {
mf = new MarketFetcher(config);
});
it('should fetch with correct arguments', function() {
// mf.fetch should call the DataProvider like:
// provider.getTrades(since, callback, descending)
mf.fetch();
expect(getTradesSpy.callCount).to.equal(1);
var args = getTradesSpy.firstCall.args;
// test-config uses NO `tradingAdvisor`
var since = args[0];
expect(since).to.equal(undefined);
var handler = args[1];
assert.isFunction(handler);
var descending = args[2];
expect(descending).to.equal(false);
});
xit('should retry on error', function() {
// todo
});
it('should pass the data to the tradebatcher', function() {
mf.fetch();
expect(getTradesSpy.callCount).to.equal(2);
expect(tradeBatcherSpy.lastCall.args[0]).to.deep.equal(TRADES);
});
xit('should relay trades', function() {
// todo
});
});
View File
Whitespace-only changes.
+132
View File
@@ -0,0 +1,132 @@
{
"silent": true,
"watch": {
"exchange": "Bitstamp",
"currency": "USD",
"asset": "BTC"
},
"tradingAdvisor": {
"enabled": false
},
"trader": {
"enabled": false
},
"adviceLogger": {
"enabled": false
},
"profitSimulator": {
"enabled": false,
"reportInCurrency": true,
"simulationBalance": {
"asset": 1,
"currency": 100
},
"feeMaker": 0.15,
"feeTaker": 0.25,
"feeUsing": "maker",
"slippage": 0.05
},
"pushover": {
"enabled": false,
"sendPushoverOnStart": false,
"muteSoft": true,
"tag": "[GEKKO]",
"key": "",
"user": ""
},
"mailer": {
"enabled": false,
"sendMailOnStart": true,
"email": "",
"muteSoft": true,
"password": "",
"tag": "[GEKKO] ",
"server": "smtp.gmail.com",
"smtpauth": true,
"user": "",
"from": "",
"to": "",
"ssl": true,
"port": ""
},
"pushbullet": {
"enabled": false,
"sendMessageOnStart": true,
"key": "xxx",
"email": "[email protected]",
"tag": "[GEKKO]"
},
"ircbot": {
"enabled": false,
"emitUpdates": false,
"channel": "#your-channel",
"server": "irc.freenode.net",
"botName": "gekkobot"
},
"xmppbot": {
"enabled": false,
"emitUpdates": false,
"client_id": "jabber_id",
"client_pwd": "jabber_pw",
"client_host": "jabber_server",
"client_port": 5222,
"status_msg": "I'm online",
"receiver": "jabber_id_for_updates"
},
"campfire": {
"enabled": false,
"emitUpdates": false,
"nickname": "Gordon",
"roomId": null,
"apiKey": "",
"account": ""
},
"redisBeacon": {
"enabled": false,
"port": 6379,
"host": "127.0.0.1",
"channelPrefix": "",
"broadcast": [
"candle"
]
},
"candleWriter": {
"adapter": "sqlite",
"enabled": true
},
"adapters": {
"sqlite": {
"path": "plugins/sqlite",
"dataDirectory": "./history",
"version": 0.1,
"dependencies": [
{
"module": "sqlite3",
"version": "3.1.4"
}
]
},
"postgresql": {
"path": "plugins/postgresql",
"version": 0.1,
"connectionString": "postgres://user:pass@localhost:5432",
"dependencies": [
{
"module": "pg",
"version": "6.1.0"
}
]
}
},
"backtest": {
"adapter": "sqlite",
"daterange": "scan",
"batchSize": 50
},
"importer": {
"daterange": {
"from": "2015-09-09 12:00:00"
}
},
"I understand that Gekko only automates MY OWN trading strategies": false
}
+139
View File
@@ -0,0 +1,139 @@
var chai = require('chai');
var expect = chai.expect;
var should = chai.should;
var sinon = require('sinon');
var _ = require('lodash');
var moment = require('moment');
var utils = require(__dirname + '/../core/util');
var dirs = utils.dirs();
var TradeBatcher = require(dirs.budfox + 'tradeBatcher');
var trades_tid_1 = [
{tid: 1, price: 10, amount: 1, date: 1466115793},
{tid: 2, price: 10, amount: 1, date: 1466115794},
{tid: 3, price: 10, amount: 1, date: 1466115795}
];
var trades_tid_2 = [
{tid: 2, price: 10, amount: 1, date: 1466115794},
{tid: 3, price: 10, amount: 1, date: 1466115795},
{tid: 4, price: 10, amount: 1, date: 1466115796},
{tid: 5, price: 10, amount: 1, date: 1466115797}
];
var empty_trades = [
{tid: 2, price: 10, amount: 0, date: 1466115794},
{tid: 3, price: 10, amount: 0, date: 1466115795},
{tid: 4, price: 10, amount: 0, date: 1466115796},
{tid: 5, price: 10, amount: 0, date: 1466115797}
];
describe('budfox/tradeBatcher', function() {
var tb;
it('should throw when not passed a number', function() {
expect(function() {
new TradeBatcher()
}).to.throw('tid is not a string');
});
it('should instantiate', function() {
tb = new TradeBatcher('tid');
});
it('should throw when not fed an array', function() {
var trade = _.first(trades_tid_1);
expect(
tb.write.bind(tb, trade)
).to.throw('batch is not an array');
});
it('should emit an event when fed trades', function() {
tb = new TradeBatcher('tid');
var spy = sinon.spy();
tb.on('new batch', spy);
tb.write( trades_tid_1 );
expect(spy.callCount).to.equal(1);
});
it('should only emit once when fed the same trades twice', function() {
tb = new TradeBatcher('tid');
var spy = sinon.spy();
tb.on('new batch', spy);
tb.write( trades_tid_1 );
tb.write( trades_tid_1 );
expect(spy.callCount).to.equal(1);
});
it('should correctly set meta data', function() {
tb = new TradeBatcher('tid');
var spy = sinon.spy();
tb.on('new batch', spy);
tb.write( trades_tid_1 );
var transformedTrades = _.map(_.cloneDeep(trades_tid_1), function(trade) {
trade.date = moment.unix(trade.date).utc();
return trade;
});
var result = {
data: transformedTrades,
amount: _.size(transformedTrades),
start: _.first(transformedTrades).date,
end: _.last(transformedTrades).date,
first: _.first(transformedTrades),
last: _.last(transformedTrades)
}
var tbResult = _.first(_.first(spy.args));
expect(tbResult.amount).to.equal(result.amount);
expect(tbResult.start.unix()).to.equal(result.start.unix());
expect(tbResult.end.unix()).to.equal(result.end.unix());
expect(tbResult.data.length).to.equal(result.data.length);
_.each(tbResult.data, function(t, i) {
expect(tbResult.data[i].tid).to.equal(result.data[i].tid);
expect(tbResult.data[i].price).to.equal(result.data[i].price);
expect(tbResult.data[i].amount).to.equal(result.data[i].amount);
});
});
it('should correctly filter trades', function() {
tb = new TradeBatcher('tid');
var spy = sinon.spy();
tb.on('new batch', spy);
tb.write( trades_tid_1 );
tb.write( trades_tid_2 );
expect(spy.callCount).to.equal(2);
var tbResult = _.first(_.last(spy.args));
expect(tbResult.amount).to.equal(2);
expect(tbResult.start.unix()).to.equal(1466115796);
expect(tbResult.end.unix()).to.equal(1466115797);
expect(tbResult.data.length).to.equal(2);
});
// see @link
// https://github.com/askmike/gekko/issues/486
it('should filter out empty trades', function() {
tb = new TradeBatcher('tid');
var spy = sinon.spy();
tb.on('new batch', spy);
tb.write(empty_trades);
expect(spy.callCount).to.equal(0);
});
});
+181
View File
@@ -0,0 +1,181 @@
const chai = require('chai');
const expect = chai.expect;
const should = chai.should;
const sinon = require('sinon');
const _ = require('lodash');
const moment = require('moment');
const utils = require(__dirname + '/../../core/util');
const dirs = utils.dirs();
const TrailingStop = require(dirs.broker + 'triggers/trailingStop');
describe('exchange/triggers/trailingStop', () => {
let cb;
it('should instantiate a trailing stop loss trigger', () => {
expect(() => {
const ts = new TrailingStop({
trail: 10,
initialPrice: 100,
onTrigger: () => {}
})
}).to.not.throw()
})
it('should call onTrigger when the stop hits', () => {
const spy = sinon.spy();
const ts = new TrailingStop({
trail: 10,
initialPrice: 100,
onTrigger: spy
});
ts.updatePrice(50);
expect(spy.called).to.be.true;
});
it('should emit a trigger event when the stop hits', () => {
const spy = sinon.spy();
const ts = new TrailingStop({
trail: 10,
initialPrice: 100
});
ts.on('trigger', spy);
ts.updatePrice(50);
expect(spy.called).to.be.true;
});
it('should not trigger when the the price does not go down', () => {
const spy = sinon.spy();
const ts = new TrailingStop({
trail: 10,
initialPrice: 100,
onTrigger: spy
});
ts.updatePrice(100);
ts.updatePrice(101);
ts.updatePrice(102);
ts.updatePrice(103);
ts.updatePrice(104);
expect(spy.called).to.be.false;
});
it('should not trigger when the the price goes down but above the offset', () => {
const spy = sinon.spy();
const ts = new TrailingStop({
trail: 10,
initialPrice: 100,
onTrigger: spy
});
ts.updatePrice(99);
ts.updatePrice(98);
ts.updatePrice(97);
ts.updatePrice(96);
ts.updatePrice(95);
ts.updatePrice(94);
ts.updatePrice(93);
ts.updatePrice(92);
ts.updatePrice(91);
expect(spy.called).to.be.false;
});
it('should trigger when the the price equals the offset', () => {
const spy = sinon.spy();
const ts = new TrailingStop({
trail: 10,
initialPrice: 100,
onTrigger: spy
});
ts.updatePrice(99);
ts.updatePrice(98);
ts.updatePrice(92);
expect(spy.called).to.be.false;
ts.updatePrice(90);
expect(spy.called).to.be.true;
});
it('should trigger when the the price goes up and down', () => {
const spy = sinon.spy();
const ts = new TrailingStop({
trail: 10,
initialPrice: 100,
onTrigger: spy
});
ts.updatePrice(101);
ts.updatePrice(102);
ts.updatePrice(103);
ts.updatePrice(104);
ts.updatePrice(105);
expect(spy.called).to.be.false;
ts.updatePrice(95);
expect(spy.called).to.be.true;
});
it('should only trigger once', () => {
const spy = sinon.spy();
const ts = new TrailingStop({
trail: 10,
initialPrice: 100,
onTrigger: spy
});
ts.updatePrice(90);
expect(spy.called).to.be.true;
const spy2 = sinon.spy();
ts.on('trigger', spy2);
ts.updatePrice(80);
expect(spy2.called).to.be.false;
});
it('should not trigger when the the price swings above the trail', () => {
const spy = sinon.spy();
const ts = new TrailingStop({
trail: 10,
initialPrice: 100,
onTrigger: spy
});
ts.updatePrice(110);
ts.updatePrice(101);
ts.updatePrice(111);
ts.updatePrice(102);
ts.updatePrice(112);
ts.updatePrice(103);
ts.updatePrice(113);
ts.updatePrice(104);
expect(spy.called).to.be.false;
ts.updatePrice(103);
expect(spy.called).to.be.true;
});
});