def getvolume(instrument): """ Returns open orders from redis orderbook. """ #TODO: add some error checking in here completed_book = instrument+"/completed" orders = redis.zrange(completed_book,0,-1,withscores=True) quote_volume = 0.0 base_volume = 0.0 for order in orders: # I *REALLY* should not be doing this every time I go though, but it's temporary # Note this is evaluated before gethigh and getlow when the front page is displayed so those values should be correct as well due to clean in up here if not redis.exists(order[0]): redis.zrem(completed_book,order[0]) continue quote_volume += float(redis.hget(order[0],'quote_currency_amount')) base_volume += float(redis.hget(order[0],'base_currency_amount')) return {"quote_currency_volume":quote_volume, "base_currency_volume":base_volume}
def fill_order(): """ Typical limit order book implementation, handles orders in Redis and writes exchange history to SQL. """ orderid = redis.blpop("order_queue")[1] order = redis.hgetall(orderid) print("FILLING ORDER: " + str(order)) ordertype = order["ordertype"] # do this here, the canceled order hashes dont have all the info that # normal ones do if ordertype == "cancel": old_order_id = order['old_order_id'] if redis.exists(old_order_id): old_order = redis.hgetall(old_order_id) redis.delete(old_order_id) cUID = old_order['uid'] ramount = int(old_order["amount"]) instrument = old_order["instrument"] price = float(old_order["price"]) redis.lrem("order_queue", old_order_id) redis.srem(str(cUID) + "/orders", old_order_id) if old_order['ordertype'] == 'buy': redis.zrem(old_order['instrument'] + "/bid", old_order_id) adjustbalance( instrument.split("_")[1], cUID, ramount * price, price) elif old_order['ordertype'] == 'sell': redis.zrem(old_order['instrument'] + "/ask", old_order_id) adjustbalance(instrument.split("_")[0], cUID, ramount, price) return ramount = int(order["amount"]) instrument = order["instrument"] base_currency = instrument.split("_")[0] quote_currency = instrument.split("_")[1] bidtable = instrument + "/bid" asktable = instrument + "/ask" completedlist = instrument + "/completed" price = float(order["price"]) uid = order["uid"] if ordertype == 'buy': lowesthash = redis.zrange(asktable, 0, 0) # search ask table to see if there are any orders that are at or below # this price lowestprice = 0.0 norders = redis.zcard(asktable) if norders > 0: lowestprice = redis.zscore(asktable, lowesthash[0]) amount_to_buy = 0 if lowestprice > price or norders < 1: # if there are none, add straight to the orderbook redis.zadd(bidtable, orderid, price) else: orders = redis.zrangebyscore(asktable, 0, price) # Go through as many valid orders as needed for current in orders: camt = int(redis.hget(current, "amount")) cUID = redis.hget(current, "uid") if ramount < camt: # Adjust their amount amount_to_buy = ramount ramount = 0 redis.hset(current, "amount", camt - amount_to_buy) amount_to_credit = price * ramount adjustbalance( quote_currency, cUID, price * amount_to_buy, price) else: # Our order is bigger than theirs, we can remove them from # the books amount_to_buy += camt ramount -= camt redis.delete(current) redis.zrem(asktable, current) redis.srem(str(cUID) + "/orders", current) adjustbalance(quote_currency, cUID, price * camt, price) co = CompletedOrder( instrument, 'sell', amount_to_buy, price, cUID) db_session.add(co) completedtxredis = generate_password_hash( current + str(random.random())) redis.hmset( completedtxredis, { 'price': price, 'quote_currency_amount': price * amount_to_buy / config.get_multiplier(quote_currency), 'base_currency_amount': amount_to_buy / config.get_multiplier(base_currency)}) # redis.expire(completedtxredis,86400) # 24 * 60 * 60 redis.zadd(completedlist, completedtxredis, price) if ramount == 0: redis.srem(str(uid) + "/orders", orderid) # TODO: Write a completed transaction to SQL?? break if ramount != 0: redis.zadd(bidtable, orderid, price) redis.hset(orderid, "amount", ramount) if(amount_to_buy != 0): # TODO: Write a completed transaction to SQL adjustbalance(base_currency, uid, amount_to_buy, price) co = CompletedOrder(instrument, 'buy', amount_to_buy, price, uid) db_session.add(co) elif ordertype == 'sell': # search bid table to see if there are are at or above this price highesthash = redis.zrange(bidtable, -1, -1) norders = redis.zcard(bidtable) highestprice = 0 if norders > 0: highestprice = redis.zscore( bidtable, highesthash[0]) # unsure why, but this workaround is needed for now if norders < 1 or highestprice < price: # if not add straight to the books redis.zadd(asktable, orderid, price) else: orders = redis.zrangebyscore(bidtable, price, '+inf')[::-1] amount_to_credit = 0 for current in orders: camt = int(redis.hget(current, "amount")) cUID = redis.hget(current, "uid") if ramount < camt: amount_to_credit += ramount amount_to_sell = ramount ramount = 0 redis.hset(current, "amount", camt - amount_to_sell) amount_to_credit += ramount adjustbalance(base_currency, cUID, amount_to_sell, price) else: amount_to_credit += camt amount_to_sell = camt ramount -= camt redis.delete(current) redis.zrem(bidtable, current) redis.srem(str(cUID) + "/orders", current) adjustbalance(base_currency, cUID, amount_to_sell, price) co = CompletedOrder( instrument, 'buy', amount_to_sell, price, cUID) db_session.add(co) completedtxredis = generate_password_hash( current + str(random.random())) redis.hmset( completedtxredis, { 'price': price, 'quote_currency_amount': price * amount_to_sell / config.get_multiplier(quote_currency), 'base_currency_amount': amount_to_sell / config.get_multiplier(base_currency)}) # redis.expire(completedtxredis,86400) # 24 * 60 * 60 redis.zadd(completedlist, completedtxredis, price) if ramount == 0: # TODO: Write a completed transaction to SQL redis.srem(str(uid) + "/orders", orderid) break if(ramount != 0): redis.zadd(asktable, orderid, price) redis.hset(orderid, "amount", ramount) if(amount_to_credit != 0): # TODO: Write a completed transaction to SQL adjustbalance( quote_currency, uid, amount_to_credit * price, price) co = CompletedOrder( instrument, 'sell', amount_to_credit * price, price, uid) db_session.add(co) else: pass # TODO: throw an error, not a buy or sell # db_session.add(b) db_session.commit()
def fill_order(): """ Typical limit order book implementation, handles orders in Redis and writes exchange history to SQL. """ orderid = redis.blpop("order_queue")[1] order = redis.hgetall(orderid) ordertype = order["ordertype"] # do this here, the canceled order hashes dont have all the info that normal ones do if ordertype == "cancel": old_order_id = order['old_order_id'] if redis.exists(old_order_id): old_order = redis.hgetall(old_order_id) redis.delete(old_order_id) cUID = old_order['uid'] ramount = int(old_order["amount"]) instrument = old_order["instrument"] price = float(old_order["price"]) redis.lrem("order_queue",old_order_id) redis.srem(str(cUID)+"/orders",old_order_id) if old_order['ordertype'] == 'buy': redis.zrem(old_order['instrument']+"/bid",old_order_id) adjustbalance(instrument.split("_")[1],cUID,ramount*price,price) elif old_order['ordertype'] == 'sell': redis.zrem(old_order['instrument']+"/ask",old_order_id) adjustbalance(instrument.split("_")[0],cUID,ramount,price) return ramount = int(order["amount"]) instrument = order["instrument"] base_currency = instrument.split("_")[0] quote_currency = instrument.split("_")[1] bidtable = instrument + "/bid" asktable = instrument + "/ask" completedlist = instrument + "/completed" price = float(order["price"]) uid = order["uid"] if ordertype == 'buy': lowesthash = redis.zrange(asktable,0,0) #search ask table to see if there are any orders that are at or below this price lowestprice = 0.0 norders = redis.zcard(asktable) if norders > 0: lowestprice = redis.zscore(asktable,lowesthash[0]) amount_to_buy = 0.0 if lowestprice > price or norders < 1: # if there are none, add straight to the orderbook redis.zadd(bidtable,orderid, price) else: orders = redis.zrangebyscore(asktable, 0, price) # Go through as many valid orders as needed for current in orders: camt = int(redis.hget(current,"amount")) cUID = redis.hget(current,"uid") if ramount < camt: # Adjust their amount amount_to_buy = ramount ramount = 0 redis.hset(current, "amount",camt-amount_to_buy) amount_to_credit = price*ramount adjustbalance(quote_currency,cUID,price*amount_to_buy,price) else: # Our order is bigger than theirs, we can remove them from the books amount_to_buy += camt ramount -= camt redis.delete(current) redis.zrem(asktable,current) redis.srem(str(cUID)+"/orders",current) adjustbalance(quote_currency,cUID,price*camt,price) co = CompletedOrder(instrument, 'sell', amount_to_buy, price, cUID) db_session.add(co) completedtxredis = generate_password_hash(current + str(random.random())) redis.hmset(completedtxredis,{'price':price,'quote_currency_amount':price*amount_to_buy/config.get_multiplier(quote_currency), 'base_currency_amount':amount_to_buy/config.get_multiplier(base_currency)}) #redis.expire(completedtxredis,86400) # 24 * 60 * 60 redis.zadd(completedlist,completedtxredis, price) if ramount == 0: redis.srem(str(uid)+"/orders",orderid) #TODO: Write a completed transaction to SQL?? break if ramount != 0: redis.zadd(bidtable,orderid, price) redis.hset(orderid,"amount",ramount) if(amount_to_buy != 0): #TODO: Write a completed transaction to SQL adjustbalance(base_currency,uid,amount_to_buy,price) co = CompletedOrder(instrument, 'buy', amount_to_buy, price, uid) db_session.add(co) elif ordertype == 'sell': #search bid table to see if there are are at or above this price highesthash = redis.zrange(bidtable,-1,-1) norders = redis.zcard(bidtable) highestprice = 0 if norders > 0: highestprice = redis.zscore(bidtable,highesthash[0]) #unsure why, but this workaround is needed for now if norders < 1 or highestprice < price: # if not add straight to the books redis.zadd(asktable,orderid,price) else: orders = redis.zrangebyscore(bidtable,price,'+inf')[::-1] amount_to_credit = 0 for current in orders: camt = int(redis.hget(current,"amount")) cUID = redis.hget(current,"uid") if ramount < camt: amount_to_credit += ramount amount_to_sell = ramount ramount = 0 redis.hset(current, "amount",camt-amount_to_sell) amount_to_credit += ramount adjustbalance(base_currency,cUID,amount_to_sell,price) else: amount_to_credit += camt amount_to_sell = camt ramount -= camt redis.delete(current) redis.zrem(bidtable,current) redis.srem(str(cUID)+"/orders",current) adjustbalance(base_currency,cUID,amount_to_sell,price) co = CompletedOrder(instrument, 'buy', amount_to_sell, price, cUID) db_session.add(co) completedtxredis = generate_password_hash(current + str(random.random())) redis.hmset(completedtxredis,{'price':price,'quote_currency_amount':price*amount_to_sell/config.get_multiplier(quote_currency), 'base_currency_amount':amount_to_sell/config.get_multiplier(base_currency)}) #redis.expire(completedtxredis,86400) # 24 * 60 * 60 redis.zadd(completedlist,completedtxredis, price) if ramount == 0: #TODO: Write a completed transaction to SQL redis.srem(str(uid)+"/orders",orderid) break if(ramount != 0): redis.zadd(asktable,orderid,price) redis.hset(orderid,"amount",ramount) if(amount_to_credit != 0): #TODO: Write a completed transaction to SQL adjustbalance(quote_currency,uid,amount_to_credit*price,price) co = CompletedOrder(instrument, 'sell', amount_to_credit*price, price, uid) db_session.add(co) else: pass #TODO: throw an error, not a buy or sell #db_session.add(b) db_session.commit()