Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge #15

Merged
merged 28 commits into from
Aug 28, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0a47199
Updated Path to UIconfig.js file in setup instructions.
ACregan Jul 9, 2018
61a5cf9
Merge pull request #2346 from askmike/develop
askmike Jul 21, 2018
f936339
v0.6.5 (#2428)
askmike Aug 10, 2018
97a9b6d
Disconnect child processes, fix #2457
eusorov Aug 22, 2018
e12eea0
make sure the balance & exposure always gets reset after sync
askmike Aug 22, 2018
47f4a49
bundle current version ws dep, fix #2476
askmike Aug 24, 2018
1f0ee10
init trailing stop
askmike Aug 11, 2018
d238016
add tests for trailing stop
askmike Aug 11, 2018
41107a6
[TEST] also check spy pre trigger
askmike Aug 11, 2018
48a3ab9
[TEST] stop should only trigger once
askmike Aug 11, 2018
90a13a6
[TEST] check whether the trailing stop trails up
askmike Aug 11, 2018
0ba7ba1
init strategy stop API
askmike Aug 11, 2018
11fc34f
init paper trader stop implementation
askmike Aug 11, 2018
8de1c83
[DOCS] add trigger events
askmike Aug 13, 2018
cf495ff
add trigger event subscriptions
askmike Aug 13, 2018
e7da592
implement triggerCreated & triggerAborted in paper trader
askmike Aug 13, 2018
25698c8
implement triggerFired event
askmike Aug 13, 2018
1b8a707
rewire stop prop into trigger & init paper trader glue
askmike Aug 14, 2018
5484ebb
[TEST] price swings around trail
askmike Aug 14, 2018
2e0b4e2
[DOCS] cleanup tmp copy/paste
askmike Aug 14, 2018
a7038a7
mv triggers into gekko broker
askmike Aug 15, 2018
7a26284
[GB] init real trader trigger glue
askmike Aug 15, 2018
a63d927
only create trigger after init trade is completed
askmike Aug 16, 2018
331ceeb
[GB] rewire live trigger to init exec price
askmike Aug 17, 2018
a418c4a
make sure we only move the trail up
askmike Aug 27, 2018
5a798fb
when empty data returns, loader never finishes and never get killed
Aug 23, 2018
f27b3ce
v0.6.6
askmike Aug 27, 2018
95d1873
Merge branch 'stable' into develop
askmike Aug 27, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[GB] init real trader trigger glue
  • Loading branch information
askmike committed Aug 27, 2018
commit 7a26284ef4d60e3c6542bfc78a4d21f4cf6832c2
12 changes: 12 additions & 0 deletions exchange/gekkoBroker.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ const errors = require('./exchangeErrors');
const Portfolio = require('./portfolioManager');
// const Market = require('./market');
const orders = require('./orders');
const Trigger = require('./trigger');
const exchangeUtils = require('./exchangeUtils');
const bindAll = exchangeUtils.bindAll;
const isValidOrder = exchangeUtils.isValidOrder;



class Broker {
constructor(config) {
this.config = config;
Expand Down Expand Up @@ -157,6 +160,15 @@ class Broker {

return order;
}

createTrigger({type, onTrigger, props}) {
return new Trigger({
api: this.api,
type,
props,
onTrigger
});
}
}

module.exports = Broker;
84 changes: 84 additions & 0 deletions exchange/trigger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// wraps around a low level trigger and feeds
// it live market data.

const _ = require('lodash');

const exchangeUtils = require('./exchangeUtils');
const bindAll = exchangeUtils.bindAll;

const triggers = require('./triggers');

// @param api: a gekko broker wrapper instance
// @param type: type of trigger to wrap
// @param props: properties to feed to trigger
class Trigger {
constructor({api, type, props, onTrigger}) {
this.onTrigger = onTrigger;
this.api = api;
this.props = props;
this.type = type;

this.isLive = true;

// note: we stay on the safe side and trigger
// as soon as the bid goes below trail.
this.tickerProp = 'bid';

if(!_.has(triggers, type)) {
throw new Error('Gekko Broker does not know trigger ' + type);
}

this.CHECK_INTERVAL = this.api.interval * 10;

bindAll(this);

this.api.getTicker(this.init);
}

init(err, ticker) {
if(err) {
return console.log('[GB/trigger] failed to init ticker:', err);
}

this.trigger = new triggers[this.type]({
initialPrice: ticker[this.tickerProp],
onTrigger: this.propogateTrigger,
...this.props
})

this.scheduleFetch();
}

scheduleFetch() {
setTimeout(this.fetch, this.CHECK_INTERVAL);
}

fetch() {
if(!this.isLive) {
return;
}
this.api.getTicker(this.processTicker)
}

processTicker(err, ticker) {
if(!this.isLive) {
return;
}

if(err) {
return console.log('[GB/trigger] failed to fetch ticker:', err);
}

this.price = ticker[this.tickerProp];

this.trigger.updatePrice(this.price);
this.scheduleFetch();
}

propogateTrigger() {
this.isLive = false;
this.onTrigger();
}
}

module.exports = Trigger;
3 changes: 3 additions & 0 deletions exchange/triggers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const trailingStop = require('./trailingStop');

module.exports = { trailingStop };
7 changes: 1 addition & 6 deletions plugins/paperTrader/paperTrader.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,7 @@ PaperTrader.prototype.processAdvice = function(advice) {
PaperTrader.prototype.createTrigger = function(advice) {
const trigger = advice.trigger;

if(trigger.type === 'trailingStop') {

if(trigger.trailPercentage && !trigger.trailValue) {
trigger.trailValue = trigger.trailPercentage / 100 * this.price;
log.info('[PaperTrader] Trailing stop trail value specified as percentage, setting to:', trigger.trailValue, this.currency);
}
if(trigger && trigger.type === 'trailingStop') {

if(!trigger.trailValue) {
return log.warn(`[Papertrader] ignoring trailing stop without trail value`);
Expand Down
57 changes: 56 additions & 1 deletion plugins/trader/trader.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const dirs = util.dirs();
const moment = require('moment');

const log = require(dirs.core + 'log');
const Broker = require(dirs.gekko + '/exchange/gekkoBroker');
const Broker = require(dirs.broker + '/gekkoBroker');

require(dirs.gekko + '/exchange/dependencyCheck');

Expand All @@ -20,6 +20,7 @@ const Trader = function(next) {
}

this.propogatedTrades = 0;
this.propogatedTriggers = 0;

try {
this.broker = new Broker(this.brokerConfig);
Expand Down Expand Up @@ -180,6 +181,34 @@ Trader.prototype.processAdvice = function(advice) {
});
}

const trigger = advice.trigger;

if(trigger && trigger.type === 'trailingStop') {
const triggerId = 'trigger-' + (++this.propogatedTriggers);

this.deferredEmit('triggerCreated', {
id: triggerId,
at: advice.date,
initialPrice: this.price,
type: 'trialingStop',
proprties: {
trail: trigger.trailValue
}
});

this.activeStopTrigger = {
id: triggerId,
adviceId: advice.id,
instance: this.broker.createTrigger({
type: trigger.type,
onTrigger: this.onStopTrigger,
props: {
trail: trigger.trailValue,
}
})
}
}

amount = this.portfolio.currency / this.price * 0.95;

log.info(
Expand All @@ -202,6 +231,16 @@ Trader.prototype.processAdvice = function(advice) {
});
}

// clean up potential old stop trigger
if(this.activeStopTrigger) {
this.deferredEmit('triggerAborted', {
id: this.activeStopTrigger.id,
date: advice.date
});

delete this.activeStopTrigger;
}

amount = this.portfolio.asset;

log.info(
Expand Down Expand Up @@ -320,6 +359,22 @@ Trader.prototype.createOrder = function(side, amount, advice, id) {
});
}

Trader.prototype.onStopTrigger = function() {
this.deferredEmit('triggerFired', {
id: this.activeStopTrigger.id,
date: moment()
});

const adviceMock = {
recommendation: 'short',
id: this.activeStopTrigger.adviceId
}

delete this.activeStopTrigger;

this.processAdvice(adviceMock);
}

Trader.prototype.cancelOrder = function(id, advice, next) {

if(!this.order) {
Expand Down
6 changes: 6 additions & 0 deletions plugins/tradingAdvisor/baseTradingMethod.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,14 @@ Base.prototype.advice = function(newDirection) {
'As such the stop is ignored'
);
} else {

// the trigger is implemented in a trader
trigger = newDirection.trigger;

if(trigger.trailPercentage && !trigger.trailValue) {
trigger.trailValue = (1 - (trigger.trailPercentage / 100)) * this.candle.close;
log.info('[StratRunner] Trailing stop trail value specified as percentage, setting to:', trigger.trailValue);
}
}
}

Expand Down