Exemple #1
0
def cancelorder(old_order_id):
    if not is_logged_in(session):
        return home_page("ltc_btc",danger="Please log in to perform that action.")
    uid = session['userid']
    if old_order_id not in redis.smembers(str(uid)+"/orders"):
        return home_page("ltc_btc",danger="Unable to cancel the specified order!")    
    orderid = generate_password_hash(str(random.random()))
    redis.hmset(orderid, {"ordertype":'cancel', "uid":uid, 'old_order_id':old_order_id})
    redis.rpush("order_queue",orderid)
    return home_page("ltc_btc", dismissable="Cancelled order!")
Exemple #2
0
def cancelorder(old_order_id):
    if not is_logged_in(session):
        return home_page("ltc_btc",danger="Please log in to perform that action.")
    uid = session['userid']
    if old_order_id not in redis.smembers(str(uid)+"/orders"):
        return home_page("ltc_btc",danger="Unable to cancel the specified order!")    
    orderid = generate_password_hash(str(random.random()))
    redis.hmset(orderid, {"ordertype":'cancel', "uid":uid, 'old_order_id':old_order_id})
    redis.rpush("order_queue",orderid)
    return home_page("ltc_btc", dismissable="Cancelled order!")
Exemple #3
0
def addorder():

    """ Checks balance and essential stuff, generates an order ID then adds order to a redis queue. """
    instrument = request.form['currency_pair']
    if not is_logged_in(session):
        return home_page(instrument, danger="Please log in to perform that action.")
    
    #They shouldn't be able to modify the trade pair, if it isnt valid either I messed up somewhere or they are trying to do something wrong
    if not config.is_valid_instrument(instrument):
        return home_page("ltc_btc", danger="Unknown Error, contact the administrator!") 

    base_currency = request.form['currency_pair'].split("_")[0]
    quote_currency = request.form['currency_pair'].split("_")[1]
    try:
        rprice = Decimal(request.form['price'])
        ramount = string_to_currency_unit(request.form['amount'], config.get_multiplier(base_currency))
        print(ramount)
    except Exception as e:
        print(e)
        return home_page(instrument, danger="Please enter numerical values for price and amount!") 
    if ramount < 1: #TODO: find a good amount for this
        return home_page(instrument, danger="Transaction amount too low!") 
    if rprice <= 0:
        return home_page(instrument, danger="Price must be greater than 0!") 

    getcontext().prec = 6
    whole, dec = ExtendedContext.divmod(rprice*ramount/config.get_multiplier(base_currency), Decimal(1))
    total = int(whole * config.get_multiplier(base_currency) + dec * config.get_multiplier(base_currency)) 
    print("total: " + str(total))
    uid = session['userid']

    orderid = generate_password_hash(str(random.random()))
    instrument = request.form['currency_pair']
    bidtable = instrument + "/bid"
    asktable = instrument + "/ask"

    if request.form['ordertype'] == 'buy': 
        currency = quote_currency
        if check_balance(currency,session['userid']) < total:
            return home_page(instrument, danger="Balance too low to execute order!")
        else:
            adjustbalance(currency,session['userid'],-1 * total)
    elif request.form['ordertype'] == 'sell':
        currency = base_currency
        if check_balance(currency, uid) < ramount:
            return home_page(instrument, danger="Balance too low to execute order!")
        else:
            adjustbalance(currency, uid, -1 * ramount)
    else:
        return home_page(instrument, danger="Unknown Error, contact the administrator!") #invalid order type, they must have been messing around
    redis.hmset(orderid, {"ordertype":request.form['ordertype'],"instrument":request.form['currency_pair'],"amount":ramount, "uid":uid,"price":rprice})
    redis.rpush("order_queue",orderid)
    redis.sadd(str(uid)+"/orders", orderid)
    return home_page(instrument, dismissable="Order placed successfully!")
Exemple #4
0
def addorder():
    """ Checks balance and essential stuff, generates an order ID then adds order to a redis queue. """
    instrument = request.form['currency_pair']
    if not is_logged_in(session):
        return home_page(instrument, danger="Please log in to perform that action.")
    
    #They shouldn't be able to modify the trade pair, if it isnt valid either I messed up somewhere or they are trying to do something wrong
    if not config.is_valid_instrument(instrument):
        return home_page("ltc_btc", danger="Unknown Error, contact the administrator!") 

    base_currency = request.form['currency_pair'].split("_")[0]
    quote_currency = request.form['currency_pair'].split("_")[1]
    try:
        rprice = float(request.form['price'])
        ramount = int(float(request.form['amount'])* config.get_multiplier(base_currency))
    except:
        return home_page(instrument, danger="Please enter numerical values for price and amount!") 
    if ramount < 1: #TODO: find a good amount for this
        return home_page(instrument, danger="Transaction amount too low!") 
    if rprice <= 0:
        return home_page(instrument, danger="Price must be greater than 0!") 

    total = int(rprice * ramount)
    uid = session['userid']

    orderid = generate_password_hash(str(random.random()))
    instrument = request.form['currency_pair']
    bidtable = instrument + "/bid"
    asktable = instrument + "/ask"

    if request.form['ordertype'] == 'buy': 
        currency = quote_currency
        if check_balance(currency,session['userid']) < total:
            return home_page(instrument, danger="Balance too low to execute order!")
        else:
            adjustbalance(currency,session['userid'],-1 * total)
    elif request.form['ordertype'] == 'sell':
        currency = base_currency
        if check_balance(currency, uid) < ramount:
            return home_page(instrument, danger="Balance too low to execute order!")
        else:
            adjustbalance(currency, uid, -1 * ramount)
    else:
        return home_page(instrument, danger="Unknown Error, contact the administrator!") #invalid order type, they must have been messing around
    redis.hmset(orderid, {"ordertype":request.form['ordertype'],"instrument":request.form['currency_pair'],"amount":ramount, "uid":uid,"price":rprice})
    redis.rpush("order_queue",orderid)
    redis.sadd(str(uid)+"/orders", orderid)
    return home_page(instrument, dismissable="Order placed successfully!")
Exemple #5
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()
Exemple #6
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()