181 lines
3.6 KiB
JavaScript
181 lines
3.6 KiB
JavaScript
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;
|
|
});
|
|
|
|
}); |