Exemplo n.º 1
0
def handle_transactions():
    for currency in currencies:
        logging.info('Processing {} deposits'.format(currency))
        oldtransactions = CompletedOrder.query.filter().all()
        oldids = [x.transaction_id for x in oldtransactions]

        rpc = ServiceProxy(currencies[currency]['daemon'])
        transactions = [
            tx for tx in rpc.listtransactions() if tx['category'] == 'receive']
        newtransactions = []

        for tx in transactions:
            if tx['txid'] not in oldids:
                newtransactions.append(tx)
        for tx in newtransactions:
            addr = Address.query.filter(
                Address.address == str(
                    tx['address'])).first()
            if addr:
                logging.info(
                    "New Deposit! TXID: {} Amount: {} UserID: {}".format(
                        tx['txid'],
                        tx['amount'],
                        addr.user))
                adjustbalance(
                    currency, addr.user, int(
                        float(
                            tx['amount']) * currencies[currency]['multiplier']))
                co = CompletedOrder(
                    currency + "_" + currency,
                    "DEPOSIT",
                    float(
                        tx['amount']),
                    0,
                    addr.user,
                    is_deposit=True,
                    transaction_id=tx['txid'])
                db_session.add(co)

        logging.info('Processing {} withdrawals'.format(currency))
        withdrawals = CompletedOrder.query.filter(
            CompletedOrder.is_withdrawal).filter(
            CompletedOrder.withdrawal_complete == False).all()
        for withdrawal in withdrawals:
            # TODO: some proper error checking etc
            logging.info(
                "New Withdrawal! Amount: {}".format(
                    withdrawal.amount))
            sendaddr = withdrawal.withdrawal_address
            try:
                rpc.sendtoaddress(sendaddr, withdrawal.amount)
            except Exception as e:
                logging.warning(
                    "Error in executing withdrawal! ID: {} JSONRPC Error: {}".format(
                        withdrawal.id,
                        repr(
                            e.error)))
            withdrawal.withdrawal_complete = True
            db_session.add(withdrawal)
        db_session.commit()
Exemplo n.º 2
0
def handle_transactions():
    for currency in currencies:
        logging.info('Processing {} deposits'.format(currency))
        oldtransactions = CompletedOrder.query.filter().all()
        oldids = [x.transaction_id for x in oldtransactions]

        rpc = ServiceProxy(currencies[currency]['daemon'])
        transactions = [
            tx for tx in rpc.listtransactions() if tx['category'] == 'receive'
        ]
        newtransactions = []

        for tx in transactions:
            if tx['txid'] not in oldids:
                newtransactions.append(tx)
        for tx in newtransactions:
            addr = Address.query.filter(
                Address.address == str(tx['address'])).first()
            if addr:
                logging.info(
                    "New Deposit! TXID: {} Amount: {} UserID: {}".format(
                        tx['txid'], tx['amount'], addr.user))
                adjustbalance(
                    currency, addr.user,
                    int(
                        float(tx['amount']) *
                        currencies[currency]['multiplier']))
                co = CompletedOrder(currency + "_" + currency,
                                    "DEPOSIT",
                                    float(tx['amount']),
                                    0,
                                    addr.user,
                                    is_deposit=True,
                                    transaction_id=tx['txid'])
                db_session.add(co)

        logging.info('Processing {} withdrawals'.format(currency))
        withdrawals = CompletedOrder.query.filter(
            CompletedOrder.is_withdrawal).filter(
                CompletedOrder.withdrawal_complete == False).all()
        for withdrawal in withdrawals:
            # TODO: some proper error checking etc
            logging.info("New Withdrawal! Amount: {}".format(
                withdrawal.amount))
            sendaddr = withdrawal.withdrawal_address
            try:
                rpc.sendtoaddress(sendaddr, withdrawal.amount)
            except Exception as e:
                logging.warning(
                    "Error in executing withdrawal! ID: {} JSONRPC Error: {}".
                    format(withdrawal.id, repr(e.error)))
            withdrawal.withdrawal_complete = True
            db_session.add(withdrawal)
        db_session.commit()
Exemplo n.º 3
0
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()
Exemplo n.º 4
0
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()