Closed vincentbollaert closed 7 years ago
someone fix it here https://github.com/rferro/plnx/issues/2 but i cant implement it
sorry too late it's mine it works
var Poloniex = require('poloniex.js')
, path = require('path')
, moment = require('moment')
, n = require('numbro')
, colors = require('colors')
module.exports = function container (get, set, clear) {
var c = get('conf')
var public_client, public_client2, authed_client
function publicClient (product_id) {
if (!public_client) public_client = new Poloniex(c.poloniex.key, c.poloniex.secret)
return public_client
}
function authedClient () {
if (!authed_client) {
if (!c.poloniex || !c.poloniex.key || c.poloniex.key === 'YOUR-API-KEY') {
throw new Error('please configure your Poloniex credentials in conf.js')
}
authed_client = new Poloniex(c.poloniex.key, c.poloniex.secret)
}
return authed_client
}
function joinProduct (product_id) {
return product_id.split('-')[1] + '_' + product_id.split('-')[0]
}
function retry (method, args) {
if (method !== 'getTrades') {
console.error(('\nPoloniex API is down! unable to call ' + method + ', retrying in 10s').red)
}
setTimeout(function () {
exchange[method].apply(exchange, args)
}, 10000)
}
var orders = {}
var lock = false
var exchange = {
name: 'poloniex',
historyScan: 'backward',
makerFee: 0.15,
takerFee: 0.25,
getProducts: function () {
return require('./products.json')
},
getTrades: function (opts, cb) {
//console.error('getTrades')
var func_args = [].slice.call(arguments)
if (lock) {
// console.log('locked from getTrades')
return retry('getTrades', func_args)
}
//console.log('getTrades')
lock = true
var client = publicClient()
var args = {
currencyPair: joinProduct(opts.product_id)
}
if (opts.from) {
args.start = opts.from
}
if (opts.to) {
args.end = opts.to
}
if (args.start && !args.end) {
// add 2 hours
args.end = args.start + 7200
}
else if (args.end && !args.start) {
// subtract 2 hours
args.start = args.end - 7200
}
client._public('returnTradeHistory', args, function (err, body) {
lock = false
//console.log('finish getTrades')
if (err) return cb(err)
//console.error('getTrades returnTradeHistory')
if (typeof body === 'string') {
return retry('getTrades', func_args)
}
if (!body.map) {
console.error('\getTrades odd result:')
console.error(body)
return retry('getTrades', func_args)
}
var trades = body.map(function (trade) {
return {
trade_id: trade.tradeID,
time: moment.utc(trade.date).valueOf(),
size: Number(trade.amount),
price: Number(trade.rate),
side: trade.type
}
})
cb(null, trades)
})
},
getBalance: function (opts, cb) {
var args = [].slice.call(arguments)
var client = authedClient()
if(lock){
// console.error('locked from getBalance')
return retry('getBalance', args)
}
lock = true
//console.log('getBalance')
client.returnCompleteBalances(function (err, body) {
lock = false
//console.log('finish getBalance')
if (err) return cb(err)
//console.error('getBalance returnCompleteBalances')
var balance = {asset: 0, currency: 0}
if (typeof body === 'string') {
return retry('getBalance', args)
}
if (body.error) {
console.error('\ggetBalance error:')
console.error(body)
return retry('getBalance', args)
}
if (body[opts.currency]) {
balance.currency = n(body[opts.currency].available).add(body[opts.currency].onOrders).format('0.00000000')
balance.currency_hold = body[opts.currency].onOrders
}
if (body[opts.asset]) {
balance.asset = n(body[opts.asset].available).add(body[opts.asset].onOrders).format('0.00000000')
balance.asset_hold = body[opts.asset].onOrders
}
cb(null, balance)
})
},
getQuote: function (opts, cb) {
//console.error('getQuote')
var args = [].slice.call(arguments)
var client = publicClient()
var product_id = joinProduct(opts.product_id)
client.getTicker(function (err, body) {
if (err) return cb(err)
//console.error('getQuote getTicker')
if (typeof body === 'string') {
return retry('getQuote', args)
}
if (body.error) {
console.error('\ggetQuote error:')
console.error(body)
return retry('getQuote', args)
}
var quote = body[product_id]
if (!quote) return cb(new Error('no quote for ' + product_id))
if (quote.isFrozen == '1') console.error('\nwarning: product ' + product_id + ' is frozen')
cb(null, {
bid: quote.highestBid,
ask: quote.lowestAsk,
})
})
},
cancelOrder: function (opts, cb) {
//console.error('cancelOrder')
var args = [].slice.call(arguments)
var client = authedClient()
client._private('cancelOrder', {orderNumber: opts.order_id}, function (err, result) {
//console.error('cancelOrder2')
if (typeof result === 'string') {
return retry('cancelOrder', args)
}
if (!err && !result.success) {
// sometimes the order gets cancelled on the server side for some reason and we get this. ignore that case...
if (result.error !== 'Invalid order number, or you are not the person who placed the order.') {
err = new Error('unable to cancel order')
err.body = result
}
}
cb(err)
})
},
trade: function (type, opts, cb) {
//console.error('trade')
var args = [].slice.call(arguments)
if(lock)
{
return retry('trade', args)
}
lock = true
var client = authedClient()
var params = {
currencyPair: joinProduct(opts.product_id),
rate: opts.price,
amount: opts.size,
postOnly: opts.post_only === false ? '0' : '1'
}
client._private(type, params, function (err, result) {
//console.error('trade2')
lock = false
if (typeof result === 'string') {
return retry('trade', args)
}
var order = {
id: result ? result.orderNumber : null,
status: 'open',
price: opts.price,
size: opts.size,
post_only: !!opts.post_only,
created_at: new Date().getTime(),
filled_size: '0'
}
if (result && result.error === 'Unable to place post-only order at this price.') {
order.status = 'rejected'
order.reject_reason = 'post only'
return cb(null, order)
}
else if (result && result.error && result.error.match(/^Not enough/)) {
order.status = 'rejected'
order.reject_reason = 'balance'
return cb(null, order)
}
if (!err && result.error) {
err = new Error('unable to ' + type)
err.body = result
}
if (err) return cb(err)
orders['~' + result.orderNumber] = order
cb(null, order)
})
},
buy: function (opts, cb) {
exchange.trade('buy', opts, cb)
},
sell: function (opts, cb) {
exchange.trade('sell', opts, cb)
},
getOrder: function (opts, cb) {
//console.error('getOrder')
var args = [].slice.call(arguments)
var order = orders['~' + opts.order_id]
if (!order) return cb(new Error('order not found in cache'))
var client = authedClient()
var params = {
currencyPair: joinProduct(opts.product_id)
}
client._private('returnOpenOrders', params, function (err, body) {
if (err) return cb(err)
//console.error('returnOpenOrders')
if (typeof body === 'string' || !body) {
return retry('getOrder', args)
}
var active = false
if (!body.forEach) {
console.error('\nreturnOpenOrders odd result:')
console.error(body)
}
else {
body.forEach(function (api_order) {
if (api_order.orderNumber == opts.order_id) active = true
})
}
if (!active) {
order.status = 'done'
order.done_at = new Date().getTime()
return cb(null, order)
}
client.returnOrderTrades(opts.order_id, function (err, body) {
//console.error('returnOrderTrades')
if (typeof body === 'string' || !body) {
return retry('getOrder', args)
}
if (err || body.error || !body.forEach) return cb(null, order)
order.filled_size = '0'
body.forEach(function (trade) {
order.filled_size = n(order.filled_size).add(trade.amount).format('0.00000000')
})
if (n(order.filled_size).value() == n(order.size).value()) {
order.status = 'done'
order.done_at = new Date().getTime()
}
cb(null, order)
})
})
},
// return the property used for range querying.
getCursor: function (trade) {
return Math.floor((trade.time || trade) / 1000)
}
}
return exchange
}
no rly bug, only api down
Poloniex API is down! unable to call getBalance, retrying in 10s
Poloniex API is down! unable to call getBalance, retrying in 10s
and again returnOpenOrders odd result: { error: 'Nonce must be greater than 149756185095800. You provided 149756185068600.' }
Api down is not bug. Maybe the reason is your request is frequent. My code is for avoiding noce error from requesting multiple api at the same time.
My code is not occured since few days before.
and it didnt cancel the orders http://prntscr.com/fk9slg
so right now, but is useless
Are you play with the date of you pc? I do a few days ago and make the bot crazy with nonce error! The solution was make a new poloniex key.
works, i set my server time 2min. above the real time... no Nonce must be greater than anymore but still Poloniex API is down! unable to call getBalance, retrying in 10s is there any way to add 2 ore more apikeys?
@crack00r It is really no help in advancing your computers time. the only factor the exchange care about is that the nonce has a higher value than the previous one. The most important factor is to have a stable clock. You can achieve that by using NTP, but that might not help if you have an unstable computer.
Other reasons:
due to the asyncronous nature of a node program, an old nonce can slip through
I made some test... that is the problem... the program make 2 even 3 calls to poloniex whitout wait for the first to be resolved.
Fixed by adding --lock and installing NTP on centos and set to sync every minute with --period=1m But this does not fix my nonce issue!!!!!
THE EDIT in exchange.js:
var orders = {}
var lock = false
var exchange = {
name: 'poloniex',
historyScan: 'backward',
makerFee: 0.15,
takerFee: 0.25,
getProducts: function () {
return require('./products.json')
},
getTrades: function (opts, cb) {
//console.error('getTrades')
var func_args = [].slice.call(arguments)
if (lock) {
// console.log('locked from getTrades')
return retry('getTrades', func_args)
}
//console.log('getTrades')
lock = true
var client = publicClient()
var args = {
currencyPair: joinProduct(opts.product_id)
}
if (opts.from) {
args.start = opts.from
}
if (opts.to) {
args.end = opts.to
}
if (args.start && !args.end) {
// add 2 hours
args.end = args.start + 7200
}
else if (args.end && !args.start) {
// subtract 2 hours
args.start = args.end - 7200
}
client._public('returnTradeHistory', args, function (err, body) {
lock = false
You also need to do this instead of running docker, use separate configs for each instance for different coins and API keys. I run 5.
./zenbot.sh trade --conf=/zenbot0/conf0.js --period=1m --buy_pct=100 --sell_pct=100 --lock
./zenbot.sh trade --conf=/zenbot0/conf1.js --period=1m --buy_pct=100 --sell_pct=100 --lock
./zenbot.sh trade --conf=/zenbot0/conf2.js --period=1m --buy_pct=100 --sell_pct=100 --lock
./zenbot.sh trade --conf=/zenbot0/conf3.js --period=1m --buy_pct=100 --sell_pct=100 --lock
./zenbot.sh trade --conf=/zenbot0/conf4.js --period=1m --buy_pct=100 --sell_pct=100 --lock
But this is still giving the getbalance nonce error? Adjusting the time correctly using ntp seems to help.
Also setting period to 3m seems to help even more.
I guess poloniex has some type of IP-based flood protection.
I have no idea.. Still getting the nonce issue. But atleast now it's only the nonce issue.
UPDATE:
I read somewhere that nonce is a generated with time, and for some reason poloniex takes 30 seconds to s send market data so I set my clock 30 seconds ahead about and did get some better results.
Had following problem with kraken:
Kraken API warning - unable to call trade (Error: Kraken API returned error: API:Invalid nonce), retrying in 0.15s
Increased the nonce window at Kraken API key settings to 360. No problems right now. I think the request takes to long to process and run into this timeout.
With Kraken - check status page https://status.kraken.com/ 👎
Update: It's no as often as before but still there. Very often if connection to Kraken had a problem Kraken API warning - unable to call getTrades (Connection between Cloudflare CDN and api.kraken.com failed), retrying in 0.15s Kraken API warning - unable to call trade (Error: Kraken API returned error: API:Invalid nonce), retrying in 0.15s
Looks like a Kraken issue, closing this side of the equation.
While making its 1st purchase on poloniex.BCN-BTC