Closed ghost closed 7 years ago
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
}
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.
I think this is somewhere in the maker/taker function. and in --markup_pct
If not a timeout issue through poloniex.