Commits

Nik Cubrilovic committed f7840c4

0.0.4d1

Comments (0)

Files changed (5)

 
  will generate a blank config file at `cex.cnf`. Edit the file and fill in `username`, `key` and `secret`
 
+## Example Config
+
+````
+    [auth]
+    username = user
+    apikey = key
+    secret = secret
+
 ## Usage
 
  see
-0.0.2d1
+0.0.5d1
 import sys
 import os
 
-VERSION = (0, 0, 4, 'dev', 1)
+VERSION = (0, 0, 5, 'dev', 1)
 
 __clsname__ = 'cexbot'
 __author__ = 'Nik Cubrilovic <nikcub@gmail.com>'
 #!/usr/bin/env python
 """
-	cexbot.cexapi
+  cexbot.cexapi
 """
 
 import requests
 
 class CexAPI(object):
 
-	CEX_API_BASE = 'https://cex.io/api'
-
-	# format is (URI, private, required params)
-	api_methods = {
-		'ticker': ('/ticker/GHS/BTC', False, None),
-		'book': ('/order_book/GHS/BTC', False, None),
-		'history': ('/trade_history/GHS/BTC', False, None),
-		'balance': ('/balance/', True),
-		'orders': ('/open_orders/GHS/BTC', True),
-		'cancel_order': ('/cancel_order/', True, ('id')),
-		'place_order': ('/place_order/GHS/BTC', True, ('type', 'amount', 'price')),
-	}
-
-	access_token = {'username': None, 'apikey': None, 'secret': None}
-
-	headers = {
-		'User-Agent' : 'bot-cex.io-',
-		}
-
-	def __init__(self, username, apikey, secret):
-		if not username or not apikey or not secret:
-			logging.error("Need username, apikey and secret")
-		self.access_token['username'] = username
-		self.access_token['apikey'] = apikey
-		self.access_token['secret'] = secret
-
-	def get_params(self):
-		nonce = int(time())
-		message = str(nonce) + self.access_token['username'] + self.access_token['apikey']
-		sig = hmac.new(self.access_token['secret'], msg=message, digestmod=hashlib.sha256).hexdigest().upper()
-		return {'key': self.access_token['apikey'], 'signature': sig, 'nonce': nonce}
-
-	def get_headers(self):
-		headers = self.headers
-		# @TODO add headers
-		return headers
-
-	def req(self, meth, extras={}):
-		if not meth in self.api_methods:
-			logging.error("Error: No method %s" % (meth))
-			return False
-		req_method = self.api_methods[meth]
-		req_uri = self.CEX_API_BASE + req_method[0]
-		try:
-			if req_method[1]:
-				params = self.get_params()
-				params.update(extras)
-				r = requests.post(req_uri, headers=self.headers, data=params)
-			else:
-				r = requests.post(req_uri, headers=self.headers)
-		except requests.exceptions.ConnectionError, e:
-			logging.error("Error: connection")
-			return false
-		if r.headers['Content-Type'] != 'text/json' or not r.text:
-			logging.error("Request error (%s)" % r.text[:200])
-			return False
-		try:
-			c = json.loads(r.text)
-			if 'error' in c:
-				logging.error("API: %s" % c['error'])
-				return False
-		except ValueError:
-			logging.error("Content loading error")
-			return False
-		return c
-
-	def get_balance(self):
-		try:
-			br = self.req('balance')
-			if br:
-				return br['BTC']['available']
-		except KeyError:
-			return False
-
-	def buy_market(self, amount):
-		pass
-
-	def place_order(self, amount, price, typ='buy'):
-		extras = {
-			'type': typ,
-			'amount': amount,
-			'price': price
-		}
-		r = self.req('place_order', extras)
-		if 'id' in r:
-			return r['id']
-		logging.error("Order error")
-		return False
-
-	def buy_balance(self, balance_threshold=0.0001):
-		balance = self.get_balance()
-		if not balance:
-			return False
-		if balance < balance_threshold:
-			return False
-		price = self.get_market_quote()
-		if not price:
-			return False
-		price = float(price)
-		balance = float(balance)
-		amount = balance / price
-		order_total = amount * price
-		if amount > 0.0001:
-			logging.info("Buy %s at %s for total balance %s (of %s)" % (amount, price, order_total, balance))
-			e = self.place_order(amount, price)
-			logging.info("Order Id: %s" % e)
-
-	def get_market_quote(self):
-		# @todo check the quantity here
-		try:
-			ask = self.req('book')['asks'][0][0]
-			return ask
-		except Exception:
-			return False
+  CEX_API_BASE = 'https://cex.io/api'
+
+  # format is (URI, private, required params)
+  api_methods = {
+    'ticker': ('/ticker/GHS/BTC', False, None),
+    'book': ('/order_book/GHS/BTC', False, None),
+    'history': ('/trade_history/GHS/BTC', False, None),
+    'balance': ('/balance/', True),
+    'orders': ('/open_orders/GHS/BTC', True),
+    'cancel_order': ('/cancel_order/', True, ('id')),
+    'place_order': ('/place_order/GHS/BTC', True, ('type', 'amount', 'price')),
+  }
+
+  access_token = {'username': None, 'apikey': None, 'secret': None}
+
+  headers = {
+    'User-Agent' : 'bot-cex.io-',
+    }
+
+  def __init__(self, username, apikey, secret):
+    if not username or not apikey or not secret:
+      logging.error("Need username, apikey and secret")
+    self.access_token['username'] = username
+    self.access_token['apikey'] = apikey
+    self.access_token['secret'] = secret
+
+  def get_params(self):
+    nonce = int(time())
+    message = str(nonce) + self.access_token['username'] + self.access_token['apikey']
+    sig = hmac.new(self.access_token['secret'], msg=message, digestmod=hashlib.sha256).hexdigest().upper()
+    return {'key': self.access_token['apikey'], 'signature': sig, 'nonce': nonce}
+
+  def get_headers(self):
+    headers = self.headers
+    # @TODO add headers
+    return headers
+
+  def req(self, meth, extras={}):
+    if not meth in self.api_methods:
+      logging.error("Error: No method %s" % (meth))
+      return False
+    req_method = self.api_methods[meth]
+    req_uri = self.CEX_API_BASE + req_method[0]
+    try:
+      if req_method[1]:
+        params = self.get_params()
+        params.update(extras)
+        r = requests.post(req_uri, headers=self.headers, data=params)
+      else:
+        r = requests.post(req_uri, headers=self.headers)
+    except requests.exceptions.ConnectionError, e:
+      logging.error("Error: connection")
+      return false
+    if r.headers['Content-Type'] != 'text/json' or not r.text:
+      logging.error("Request error (%s)" % r.text[:200])
+      return False
+    try:
+      c = json.loads(r.text)
+      if 'error' in c:
+        logging.error("API: %s" % c['error'])
+        return False
+    except ValueError:
+      logging.error("Content loading error")
+      return False
+    return c
+
+  def get_balance(self):
+    try:
+      br = self.req('balance')
+      if br:
+        return br['BTC']['available']
+    except KeyError:
+      return False
+
+  def buy_market(self, amount):
+    pass
+
+  def place_order(self, amount, price, typ='buy'):
+    extras = {
+      'type': typ,
+      'amount': amount,
+      'price': price
+    }
+    r = self.req('place_order', extras)
+    if 'id' in r:
+      return r['id']
+    logging.error("Order error")
+    return False
+
+  def buy_balance(self, balance_threshold=0.0001):
+    balance = self.get_balance()
+    if not balance:
+      return False
+    if balance < balance_threshold:
+      logging.debug("Balance %s less then threshold %s" % (balance, balance_threshold))
+      return False
+    price = self.get_market_quote()
+    if not price:
+      logging.debug('orice error')
+      return False
+    price = float(price)
+    balance = float(balance)
+    amount = balance / price
+    order_total = amount * price
+    if amount > 0.0001:
+      logging.info("Buy %s at %s for total balance %s (of %s)" % (amount, price, order_total, balance))
+      e = self.place_order(amount, price)
+      logging.info("Order Id: %s" % e)
+
+  def get_market(self):
+    try:
+      quotes = self.req('book')
+      if quotes:
+        for q in quotes[:5]:
+          print q
+    except Exception:
+      return False
+
+  def get_market_quote(self):
+    # @todo check the quantity here
+    try:
+      ask = self.req('book')
+      if ask:
+        return ask['asks'][0][0]
+    except Exception:
+      return False
 

cexbot/command_utils.py

   if args.task == 'initdb':
     return dbi.initdb()
 
+  if args.task == 'getmarket':
+    return ac.get_market()
+
+  if args.task == 'getprice':
+    return ac.get_market_quote()
+
+  if args.task == 'order':
+    amount = args.amount
+    price = args.price
+    r = ac.place_order(amount, price)
+    logging.info("Ordered: %s" % r)
+
   if args.task == 'updatequotes':
+    logging.info('Running updatequotes')
     ticker_timer = ReqTimer(2, cx.update_ticker)
     ticker_timer.start()
 
   if args.task == 'buybalance':
-    balance_timer = ReqTimer(60 * 5, ac.buy_balance)
+    logging.info('Running buybalance')
+    balance_timer = ReqTimer(30, ac.buy_balance)
     balance_timer.start()
 
   # @TODO __import__
   # parser.add_argument('-o', dest='logfile', type=str, help='output log file')
   parser.add_argument('-v', dest='verbose', action='store_true', help='verbose output')
   parser.add_argument('-d', dest='debug', action='store_true', help='debug output')
+  parser.add_argument('-p', dest='price', action='store_true', help='price')
+  parser.add_argument('-a', dest='amount', action='store_true', help='amount')
   # parser.add_argument('-p', dest='proxy', type=str, default='tor', help='proxy to use')
-  # parser.add_argument('-t', dest='threads', type=int, default=25, help='number of threads')
+  # parser.add_argument('-t', dest='threads', type=int, default=1, help='number of threads')
   return parser.parse_args()
 
 def cl_error(msg=""):