Skip to content
This repository has been archived by the owner on Feb 15, 2022. It is now read-only.

Still getting buy delayed errors.. 'Placing Order' #365

Closed
ghost opened this issue Jul 7, 2017 · 2 comments
Closed

Still getting buy delayed errors.. 'Placing Order' #365

ghost opened this issue Jul 7, 2017 · 2 comments

Comments

@ghost
Copy link

ghost commented Jul 7, 2017

[root@www zenbot0]# ./zenbot.sh buy --order_type=maker --order_adjust_time=300 --debug --markup_pct=-0.2500 poloniex.XBC-BTC
warning: mongodb not accessible. some features (such as backfilling/simulation) may be disabled.
placing order...

2017-07-07 16:46:55 - buy delayed: +0.0% of funds (0.00000000 BTC) on hold
placing order...

2017-07-07 16:47:01 - buy delayed: +0.0% of funds (0.00000000 BTC) on hold
placing order...
placing order...
- buy delayed: +0.0% of funds (0.00000000 BTC) on hold
2017-07-07 16:47:12 - buy delayed: +0.0% of funds (0.00000000 BTC) on hold
placing order...

2017-07-07 16:47:18 - buy delayed: +0.0% of funds (0.00000000 BTC) on hold
placing order...

2017-07-07 16:47:23 - buy delayed: +0.0% of funds (0.00000000 BTC) on hold
placing order...

2017-07-07 16:47:28 - buy delayed: +0.0% of funds (0.00000000 BTC) on hold
placing order...

2017-07-07 16:47:33 - buy delayed: +0.0% of funds (0.00000000 BTC) on hold
placing order...
placing order...

2017-07-07 16:47:39 - buy delayed: +0.0% of funds (0.00000000 BTC) on hold


I think this is somewhere in the maker/taker function. and in --markup_pct

If not a timeout issue through poloniex.

@ghost
Copy link
Author

ghost commented Jul 7, 2017

OK I think I might have fixed this
Here's my codes:
cointrader.py

import json
import requests
import re
import unicodedata
import subprocess
import os
import sqlite3
import time
from decimal import *

flag = "undefined"

##Main App Loop
while True:
	##DB Refresh
	os.remove('/example.db')
	print("File Removed!")
	conn = sqlite3.connect('/example.db')
	c = conn.cursor()
	c.execute('''CREATE TABLE gains (ke4,pct1,dips,dips1)''')
	wjdata = requests.get('https://poloniex.com/public?command=returnTicker&period=60').json()
	##Load Initial Data
	for key in wjdata:
		if re.match(r'BTC_+', key):
			ke1=key.replace('_', '-')
			ke2=ke1.replace('BTC-', '')
			ke3='-BTC'
			ke9=ke2+ke3
			pct=(wjdata[key]['last'])
			pct0=Decimal(pct)
			pct1=format(pct0, 'f')
			print(ke9)
			print(pct1)
			dips='undefined'
			dips1='undefined'
			c.execute("INSERT INTO gains VALUES (?, ?, ?, ?);", (ke9, pct1, dips, dips1))
			conn.commit()
	print('Waiting some time for comparison...')
	#time.sleep(600)
	wjdata = requests.get('https://poloniex.com/public?command=returnTicker&period=60').json()
	##Load the second Data
	for key in wjdata:
		if re.match(r'BTC_+', key):
			ke1=key.replace('_', '-')
			ke2=ke1.replace('BTC-', '')
			ke3='-BTC'
			ke4=ke2+ke3
			pct2=(wjdata[key]['last'])
			pct3=Decimal(pct2)
			dips=format(pct3, 'f')
			print(ke4)
			print(dips)
			c.execute('UPDATE gains SET dips = ? WHERE ke4 = ?;', (dips, ke4))
			conn.commit()
	for row in c.execute('SELECT ke4, (dips-pct1) as diff FROM gains ORDER BY diff DESC LIMIT 1;'):
			print(row)
			row=str(tuple(row))
			ro1=row.replace("u", '')
			ro2=ro1.replace("'", '')
			ro3=ro2.replace('(', '')
			ro4=ro3.replace(')', '')
			ro5=ro4.replace(",", '')
			s = ro5
			s=re.sub('\d', '', s)
			ros=s.replace(".", '')
	if flag == ros:
			print(ros)
			print(flag)
			print ('Current Profitable Coin Is The Same!')
	else:
			print(ros)
			print(flag)
			sell=subprocess.call('./zenbot.sh sell --order_adjust_time=20000 --debug  poloniex.'+flag,shell=True)
	##Doublecheck the data
			for key in wjdata:
				if re.match(r'BTC_+', key):
					ke1=key.replace('_', '-')
					ke2=ke1.replace('BTC-', '')
					ke3='-BTC'
					ke4=ke2+ke3
					pct2=(wjdata[key]['last'])
					pct3=Decimal(pct2)
					dips1=format(pct3, 'f')
					print(ke4)
					print(dips1)
					c.execute('UPDATE gains SET dips1 = ? WHERE ke4 = ?;', (dips1, ke4))
					conn.commit()
			for row in c.execute('SELECT ke4, (dips1-pct1) as diff FROM gains ORDER BY diff DESC LIMIT 1;'):
					print(row)
					row=str(tuple(row))
					ro1=row.replace("u", '')
					ro2=ro1.replace("'", '')
					ro3=ro2.replace('(', '')
					ro4=ro3.replace(')', '')
					ro5=ro4.replace(",", '')
					s = ro5
					s=re.sub('\d', '', s)
					ros=s.replace(".", '')
					time.sleep(10)
					buy=subprocess.call('./zenbot.sh buy --order_adjust_time=20000 --debug  poloniex.'+ros,shell=True)
	flag=ros

conf-sample.js

// Order execution rules:

// avoid trading at a slippage above this pct
c.max_slippage_pct = 5
// buy with this % of currency balance (WARNING : sim won't work properly if you set this value to 100) 
c.buy_pct = 100
// sell with this % of asset balance (WARNING : sim won't work properly if you set this value to 100)
c.sell_pct = 100
// ms to adjust non-filled order after
c.order_adjust_time = 20000
// avoid selling at a loss below this pct
c.max_sell_loss_pct = 25
// ms to poll order status
c.order_poll_time = 30000
// ms to wait for settlement (after an order cancel) not sure if this works at all
c.wait_for_settlement = 10000
// % to mark up or down price for orders -0.2 moves them quick
c.markup_pct = 0.0
// become a market taker (high fees) or a market maker (low fees) only maker is supported on poloniex
c.order_type = 'maker'

// Misc options:

// default # days for backfill and sim commands
c.days = 14
// ms to poll new trades at
c.poll_trades = 30000
// amount of currency to start simulations with
c.currency_capital = 1000
// amount of asset to start simulations with
c.asset_capital = 0
// for sim, reverse time at the end of the graph, normalizing buy/hold to 0
c.symmetrical = false
// number of periods to calculate RSI at
c.rsi_periods = 14
// period to record balances for stats
c.balance_snapshot_period = '15m'
// avg. amount of slippage to apply to sim trades
c.avg_slippage_pct = 0.045

var c = module.exports = {}

// mongo configuration
c.mongo = {}
c.mongo.host = process.env.MONGODB_PORT_27017_TCP_ADDR || 'localhost'
c.mongo.port = 27017
c.mongo.db = 'zenbot4'
c.mongo.username = null
c.mongo.password = null
// when using mongodb replication, i.e. when running a mongodb cluster, you can define your replication set here; when you are not using replication (most of the users), just set it to `null` (default).
c.mongo.replicaSet = null

// default selector. only used if omitting [selector] argument from a command.
c.selector = 'poloniex.BTC-USD'
// name of default trade strategy
c.strategy = 'trend_ema'

// Exchange API keys:

// to enable GDAX trading, enter your API credentials:
c.gdax = {}
c.gdax.key = 'YOUR-API-KEY'
c.gdax.b64secret = 'YOUR-BASE64-SECRET'
c.gdax.passphrase = 'YOUR-PASSPHRASE'

// to enable Poloniex trading, enter your API credentials:
c.poloniex = {}
c.poloniex.key = ''
c.poloniex.secret = ''
// please note: poloniex does not support market orders via the API only maker really works well

// to enable Kraken trading, enter your API credentials:
c.kraken = {}
c.kraken.key = 'YOUR-API-KEY'
c.kraken.secret = 'YOUR-SECRET'
// Please read API TOS on https://www.kraken.com/u/settings/api
c.kraken.tosagree = 'disagree'

// to enable Bittrex trading, enter your API credentials:
c.bittrex = {}
c.bittrex.key = 'YOUR-API-KEY'
c.bittrex.secret = 'YOUR-SECRET'
// make sure to give your API key access to only: "Trade Limit" and "Read Info",
// please note that this might change in the future.
// please note that bittrex API is limited, you cannot use backfills or sims (paper/live trading only)

// to enable Bitfinex trading, enter your API credentials:
c.bitfinex = {}
c.bitfinex.key = 'YOUR-API-KEY'
c.bitfinex.secret = 'YOUR-SECRET'
// May use 'exchange' or 'trading' wallet balances. However margin trading may not work...read the API documentation.
c.bitfinex.wallet = 'exchange'

// to enable Bitfinex trading, enter your API credentials:
c.bitstamp = {}
c.bitstamp.key = ''
c.bitstamp.secret = ''
// A client ID is required on Bitstamp
c.bitstamp.client_id = 'YOUR-CLIENT-ID'

// to enable QuadrigaCX tranding, enter your API credentials:
c.quadriga = {}
c.quadriga.key = 'YOUR-API-KEY';

// this is the manual secret key entered by editing the API access
// and NOT the md5 hash you see in the summary
c.quadriga.secret = 'YOUR-SECRET';

// replace with the client id used at login, as a string, not number
c.quadriga.client_id = 'YOUR-CLIENT-ID';

// Optional stop-order triggers:

// sell if price drops below this % of bought price (0 to disable)
c.sell_stop_pct = 0
// buy if price surges above this % of sold price (0 to disable)
c.buy_stop_pct = 0
// enable trailing sell stop when reaching this % profit (0 to disable)
c.profit_stop_enable_pct = 0
// maintain a trailing stop this % below the high-water mark of profit
c.profit_stop_pct = 1

// Order execution rules:

// avoid trading at a slippage above this pct
c.max_slippage_pct = 5
// buy with this % of currency balance (WARNING : sim won't work properly if you set this value to 100) 
c.buy_pct = 100
// sell with this % of asset balance (WARNING : sim won't work properly if you set this value to 100)
c.sell_pct = 100
// ms to adjust non-filled order after
c.order_adjust_time = 20000
// avoid selling at a loss below this pct
c.max_sell_loss_pct = 25
// ms to poll order status
c.order_poll_time = 30000
// ms to wait for settlement (after an order cancel) not sure if this works at all
c.wait_for_settlement = 10000
// % to mark up or down price for orders -0.2 moves them quick
c.markup_pct = 0.0
// become a market taker (high fees) or a market maker (low fees) only maker is supported on poloniex
c.order_type = 'maker'

// Misc options:

// default # days for backfill and sim commands
c.days = 14
// ms to poll new trades at
c.poll_trades = 30000
// amount of currency to start simulations with
c.currency_capital = 1000
// amount of asset to start simulations with
c.asset_capital = 0
// for sim, reverse time at the end of the graph, normalizing buy/hold to 0
c.symmetrical = false
// number of periods to calculate RSI at
c.rsi_periods = 14
// period to record balances for stats
c.balance_snapshot_period = '15m'
// avg. amount of slippage to apply to sim trades
c.avg_slippage_pct = 0.045

exchange.js

//      console.error(('\nPoloniex API is down! unable to call ' + method + ', retrying in 10s').red)
    }
//    setTimeout(function () {
//      exchange[method].apply(exchange, args)
//    }, 10000)
  }

        var active = false
        if (!body.forEach) {
          active = true
          console.error('\nreturnOpenOrders odd result:')
          console.error(body)
        }
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, 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 exchange = {
    name: 'poloniex',
    historyScan: 'backward',
    makerFee: 0.15,
    takerFee: 0.25,

    getProducts: function () {
      return require('./products.json')
    },

    getTrades: function (opts, cb) {
      var func_args = [].slice.call(arguments)
      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) {
        if (err) return cb(err)
        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()
      client.returnCompleteBalances(function (err, body) {
        if (err) return cb(err)
        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) {
      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)
        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) {
      var args = [].slice.call(arguments)
      var client = authedClient()
      client._private('cancelOrder', {orderNumber: opts.order_id}, function (err, result) {
        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) {
      var args = [].slice.call(arguments)
      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) {
        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) {
      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)
        if (typeof body === 'string' || !body) {
          return retry('getOrder', args)
        }
        var active = false
        if (!body.forEach) {
          active = true
          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) {
          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
}

@ghost
Copy link
Author

ghost commented Jul 8, 2017

Got my buy orders stable at 2 minutes now.

What happens is: c.order_adjust_time = 5000 or 10000 is too low and will cancel the order too much.

The second part gets rid of the timeout issue that tricks the bot into thinking that the order has completed.

This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

0 participants