Skip to content
This repository has been archived by the owner on Jun 27, 2018. It is now read-only.

Commit

Permalink
Merge branch 'carlos8f-master'
Browse files Browse the repository at this point in the history
* carlos8f-master:
  Add extension point in dev doc (DeviaVir#395)
  Removed trailing comma from dependencies. (DeviaVir#398)
  Updated name of renamed srsi_macd strategy (DeviaVir#400)
  Quadriga CX now supports LTC trading, adding to products (DeviaVir#392)
  - Bitfinex and Kraken API throw the "post only" error only on checkOrder(), check for it in engine.js (DeviaVir#391)
  Windows support (DeviaVir#387)
  setRawMode is not supported on some remote consoles (no tty) (DeviaVir#380)
  Fixes for Quadriga CX trading (DeviaVir#386)
  Only do last sell in simExit when there have been trades (DeviaVir#383)
  • Loading branch information
Christian Alvarez authored and Christian Alvarez committed Jul 27, 2017
2 parents bebadf2 + 0708ad2 commit dd9a757
Show file tree
Hide file tree
Showing 12 changed files with 513 additions and 60 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Zenbot is a command-line cryptocurrency trading bot using Node.js and MongoDB. I

## Quick-start

### 1. Requirements: Linux or OSX or Docker, [Node.js](https://nodejs.org/) and [MongoDB](https://www.mongodb.com/).
### 1. Requirements: Windows, Linux or OSX or Docker, [Node.js](https://nodejs.org/) and [MongoDB](https://www.mongodb.com/).

### 2. Install zenbot 4:

Expand Down Expand Up @@ -95,6 +95,12 @@ docker-compose build
docker-compose up (-d if you don't want to see the log)
```

If you are running windows use the following command

```
docker-compose --file=docker-compose-windows.yml up
```

If you wish to run commands (e.g. backfills, list-selectors), you can run this separate command after a successful `docker-compose up -d`:

```
Expand Down
14 changes: 8 additions & 6 deletions commands/sim.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,14 @@ module.exports = function container (get, set, clear) {
})
var options_json = JSON.stringify(options, null, 2)
output_lines.push(options_json)
s.my_trades.push({
price: s.period.close,
size: s.balance.asset,
type: 'sell',
time: s.period.time
})
if (s.my_trades.length) {
s.my_trades.push({
price: s.period.close,
size: s.balance.asset,
type: 'sell',
time: s.period.time
})
}
s.balance.currency = n(s.balance.currency).add(n(s.period.close).multiply(s.balance.asset)).format('0.00000000')
s.balance.asset = 0
s.lookback.unshift(s.period)
Expand Down
27 changes: 17 additions & 10 deletions commands/trade.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ module.exports = function container (get, set, clear) {
var periods = get('db.periods')

console.log('fetching pre-roll data:')
var backfiller = spawn(path.resolve(__dirname, '..', 'zenbot.sh'), ['backfill', so.selector, '--days', days])
var zenbot_cmd = process.platform === 'win32' ? 'zenbot.bat' : 'zenbot.sh'; // Use 'win32' for 64 bit windows too
var backfiller = spawn(path.resolve(__dirname, '..', zenbot_cmd), ['backfill', so.selector, '--days', days])
backfiller.stdout.pipe(process.stdout)
backfiller.stderr.pipe(process.stderr)
backfiller.on('exit', function (code) {
Expand Down Expand Up @@ -152,28 +153,34 @@ module.exports = function container (get, set, clear) {
forwardScan()
setInterval(forwardScan, c.poll_trades)
readline.emitKeypressEvents(process.stdin)
process.stdin.setRawMode(true)
if (process.stdin.setRawMode) {process.stdin.setRawMode(true)
process.stdin.on('keypress', function (key, info) {
if (key === 'b' && !info.ctrl) {
if (key === 'b' && !info.ctrl ) {
engine.executeSignal('buy')
} else if (key === 'B' && !info.ctrl) {
}
else if (key === 'B' && !info.ctrl) {
engine.executeSignal('buy', null, null, false, true)
} else if (key === 's' && !info.ctrl) {
}
else if (key === 's' && !info.ctrl) {
engine.executeSignal('sell')
} else if (key === 'S' && !info.ctrl) {
}
else if (key === 'S' && !info.ctrl) {
engine.executeSignal('sell', null, null, false, true)
} else if ((key === 'c' || key === 'C') && !info.ctrl) {
}
else if ((key === 'c' || key === 'C') && !info.ctrl) {
delete s.buy_order
delete s.sell_order
} else if ((key === 'm' || key === 'M') && !info.ctrl) {
}
else if ((key === 'm' || key === 'M') && !info.ctrl) {
so.manual = !so.manual
console.log('\nmanual mode: ' + (so.manual ? 'ON' : 'OFF') + '\n')
} else if (info.name === 'c' && info.ctrl) {

}else if (info.name === 'c' && info.ctrl) {
// @todo: cancel open orders before exit
console.log()
process.exit()
}
})
})}
})
})
return
Expand Down
21 changes: 21 additions & 0 deletions docker-compose-windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
server:
build: .
volumes:
- .:/app
- /app/node_modules
links:
- mongodb
command: ./zenbot.sh trade --paper
restart: always

mongodb:
image: mongo:latest
volumes_from:
- mongodb-data
command: mongod --smallfiles

mongodb-data:
image: mongo:latest
volumes:
- /data/db
command: "true"
2 changes: 1 addition & 1 deletion docs/developers.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ getQuote: function (opts, cb)
```
Called from:
- https://github.com/carlos8f/zenbot/blob/master/lib/engine.js
- https://github.com/carlos8f/zenbot/blob/master/commands/buyjs
- https://github.com/carlos8f/zenbot/blob/master/commands/buy.js
- https://github.com/carlos8f/zenbot/blob/master/commands/sell.js

Input:
Expand Down
74 changes: 43 additions & 31 deletions extensions/exchanges/quadriga/exchange.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ module.exports = function container (get, set, clear) {
name: 'quadriga',
historyScan: 'backward',
makerFee: 0.5,
takerFee: 0.5,

getProducts: function () {
return require('./products.json')
Expand All @@ -63,22 +64,24 @@ module.exports = function container (get, set, clear) {
}

var client = publicClient()
client.api('transactions', args, function (err, trades) {
client.api('transactions', args, function (err, body) {
if (!shownWarnings) {
console.log('please note: the quadriga api does not support backfilling (trade/paper only).')
console.log('please note: make sure to set the period to 1h')
console.log('please note: the quadriga api does not support backfilling.')
console.log('please note: periods should be set to 1h or less.');
shownWarnings = true
}

if (err) return retry('getTrades', func_args, err)
if (trades.error) return retry('getTrades', func_args, trades.error)
if (body.error) return retry('getTrades', func_args, trades.error)

var trades = trades.map(function (trade) {
var trades = body.filter(t => {
return (typeof opts.from === 'undefined') ? true : (moment.unix(t.date).valueOf() > opts.from)
}).reverse().map(function (trade) {
return {
trade_id: trade.tid,
time: moment.unix(trade.date).valueOf(),
size: trade.amount,
price: trade.price,
size: Number(trade.amount),
price: Number(trade.price),
side: trade.side
}
})
Expand All @@ -101,11 +104,11 @@ module.exports = function container (get, set, clear) {
currency: 0
}

balance.currency = wallet[currency + '_balance']
balance.asset = wallet[asset + '_balance']
balance.currency = Number(wallet[currency + '_balance']);
balance.asset = Number(wallet[asset + '_balance']);

balance.currency_hold = wallet[currency + '_reserved']
balance.asset_hold = wallet[asset + '_reserved']
balance.currency_hold = Number(wallet[currency + '_reserved'])
balance.asset_hold = Number(wallet[asset + '_reserved'])
cb(null, balance)
})
},
Expand All @@ -123,8 +126,8 @@ module.exports = function container (get, set, clear) {
if (quote.error) return retry('getQuote', func_args, quote.error)

var r = {
bid: quote.bid,
ask: quote.ask
bid: Number(quote.bid),
ask: Number(quote.ask)
}

cb(null, r)
Expand Down Expand Up @@ -160,15 +163,18 @@ module.exports = function container (get, set, clear) {
var order = {
id: null,
status: 'open',
price: opts.price,
size: opts.size,
price: Number(opts.price),
size: Number(opts.size),
created_at: new Date().getTime(),
filled_size: '0',
filled_size: 0,
ordertype: opts.order_type
}

if (err) return cb(err)
if (body.error) return cb(body.error.message)
if (body.error) {
//console.log(`API Error: ${body.error.message}`);
return cb(body.error)
}

if (opts.order_type === 'taker') {
order.status = 'done'
Expand All @@ -179,15 +185,15 @@ module.exports = function container (get, set, clear) {
var price_total = 0.0
var order_count = body.orders_matched.length
for (var idx = 0; idx < order_count; idx++) {
asset_total = asset_total + body.orders_matched[idx].amount
price_total = price_total + (body.orders_matched[idx].amount * body.orders_matched[idx].price)
asset_total = asset_total + Number(body.orders_matched[idx].amount)
price_total = price_total + (Number(body.orders_matched[idx].amount) * Number(body.orders_matched[idx].price))
}

order.price = price_total / asset_total
order.size = asset_total
} else {
order.price = body.price
order.size = body.amount
order.price = Number(body.price)
order.size = Number(body.amount)
}
}

Expand All @@ -212,15 +218,18 @@ module.exports = function container (get, set, clear) {
var order = {
id: null,
status: 'open',
price: opts.price,
size: opts.size,
price: Number(opts.price),
size: Number(opts.size),
created_at: new Date().getTime(),
filled_size: '0',
filled_size: 0,
ordertype: opts.order_type
}

if (err) return cb(err)
if (body.error) return cb(body.error.message)
if (body.error) {
//console.log(`API Error: ${body.error.message}`);
return cb(body.error)
}

if (opts.order_type === 'taker') {
order.status = 'done'
Expand All @@ -231,15 +240,15 @@ module.exports = function container (get, set, clear) {
var price_total = 0.0
var order_count = body.orders_matched.length
for (var idx = 0; idx < order_count; idx++) {
asset_total = asset_total + body.orders_matched[idx].amount
price_total = price_total + (body.orders_matched[idx].amount * body.orders_matched[idx].price)
asset_total = asset_total + Number(body.orders_matched[idx].amount)
price_total = price_total + (Number(body.orders_matched[idx].amount) * body.orders_matched[idx].price)
}

order.price = price_total / asset_total
order.size = asset_total
} else {
order.price = body.price
order.size = body.amount
order.price = Number(body.price)
order.size = Number(body.amount)
}
}

Expand All @@ -258,12 +267,15 @@ module.exports = function container (get, set, clear) {
var client = authedClient()
client.api('lookup_order', params, function (err, body) {
if (err) return cb(err)
if (body.error) return cb(body.error.message)
if (body.error) {
//console.log(`API Error: ${body.error.message}`);
return cb(body.error)
}

if (body.status === 2) {
order.status = 'done'
order.done_at = new Date().getTime()
order.filled_size = body.amount
order.filled_size = Number(body.amount)
return cb(null, order)
}
cb(null, order)
Expand Down
Loading

0 comments on commit dd9a757

Please sign in to comment.