Ejemplo n.º 1
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!")
Ejemplo n.º 2
0
def tradehistory(currency, uid):
    if not is_logged_in(session):
        return home_page("ltc_btc",
                         danger="Please log in to perform that action.")
    orders = CompletedOrder.query.filter(CompletedOrder.user == uid).filter(
        CompletedOrder.base_currency == str(currency)).all()
    orders2 = []
    for o in orders:
        if o.is_deposit:
            orders2.append([
                "DEPOSIT", o.order_type, o.price,
                str(o.amount) + " " + str(o.base_currency).upper()
            ])
        elif o.is_withdrawal:
            orders2.append([
                "WITHDRAWAL", o.order_type, o.price,
                str(o.amount) + " " + str(o.base_currency).upper()
            ])
        else:
            orders2.append([
                o.currency_pair, o.order_type,
                (str(o.price) + " " + o.quote_currency + "/" +
                 o.base_currency).upper(),
                str(float(o.amount) / config.get_multiplier(currency)) + " " +
                str(o.base_currency).upper()
            ])
    return orders2
Ejemplo n.º 3
0
 def getbalance(c, uid):
     return "{:.4f}".format(
         check_balance(
             c,
             uid) /
         float(
             config.get_multiplier(c)))
Ejemplo n.º 4
0
def withdraw(currency): 
    if not is_logged_in(session):
        return home_page("ltc_btc",danger="Please log in to perform that action.")
    if not config.is_valid_currency(currency):
        return account_page(danger="Invalid Currency!")
    if request.method == 'GET':
        return account_page(withdraw=currency)
    elif request.method == 'POST':
        if 'amount' not in request.form or 'address' not in request.form:
            return account_page(danger="Please enter an address and an amount!") #TODO: change this error
        try:
            total = float(request.form['amount'])
        except:
            return account_page(danger="Invalid amount!")
        if check_balance(currency,session['userid']) < int(total * config.get_multiplier(currency)) or total < 0:
            return account_page(danger="Balance too low to execute withdrawal!")
        #TODO: add valid address checking
        adjustbalance(currency,session['userid'],-1 * int(total * config.get_multiplier(currency)))
        co = CompletedOrder(currency + "_" + currency, "WITHDRAWAL", total, 0, session['userid'], is_withdrawal=True, withdrawal_address=request.form['address'])
        db_session.add(co)
        db_session.commit()
        return account_page(success="Deposit to " + request.form['address'] + " completed!")
Ejemplo n.º 5
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!")
Ejemplo n.º 6
0
def openorders(uid):
    if not is_logged_in(session):
        return home_page("ltc_btc",
                         danger="Please log in to perform that action.")
    orders = redis.smembers(str(uid) + "/orders")
    r = []
    for o in orders:
        c = redis.hgetall(o)
        base_currency = c['instrument'][0:c['instrument'].find("_")]
        quote_currency = c['instrument'][c['instrument'].find("_") + 1:]
        instrument = (base_currency + "/" + quote_currency).upper()
        r.append([
            instrument, c['ordertype'], c['price'] + " " + instrument,
            str(float(c['amount']) / config.get_multiplier(base_currency)) +
            " " + base_currency.upper(), o
        ])
    return r
Ejemplo n.º 7
0
def openorders(uid):
    if not is_logged_in(session):
        return home_page(
            "ltc_btc",
            danger="Please log in to perform that action.")
    orders = redis.smembers(str(uid) + "/orders")
    r = []
    for o in orders:
        c = redis.hgetall(o)
        base_currency = c['instrument'][0:c['instrument'].find("_")]
        quote_currency = c['instrument'][c['instrument'].find("_") + 1:]
        instrument = (base_currency + "/" + quote_currency).upper()
        r.append([instrument, c['ordertype'], c['price'] +
                  " " +
                  instrument, str(float(c['amount']) /
                                  config.get_multiplier(base_currency)) +
                  " " +
                  base_currency.upper(), o])
    return r
Ejemplo n.º 8
0
def getjsonorders(instrument,t):
    """ Returns open orders from redis orderbook. """
    orders = []
    if config.is_valid_instrument(instrument):
        if t == "bid":
            bids = redis.zrange(instrument+"/bid",0,-1,withscores=True)
            for bid in bids:
                orders.append({"price":bid[1], "amount":redis.hget(bid[0],"amount")})
        else:
            asks = redis.zrange(instrument+"/ask",0,-1,withscores=True)
            for ask in asks:
                orders.append({"price":ask[1], "amount":redis.hget(ask[0],"amount")})
        #So prices are not quoted in satoshis
        #TODO: move this client side?
        for order in orders:
            order['amount'] = float(order['amount'])/config.get_multiplier(instrument.split("_")[0])
    else:
        orders.append("Invalid trade pair!")
    jo = json.dumps(orders)
    return Response(jo,  mimetype='application/json')
Ejemplo n.º 9
0
def getjsonorders(instrument,t):
    """ Returns open orders from redis orderbook. """
    orders = []
    if config.is_valid_instrument(instrument):
        if t == "bid":
            bids = redis.zrange(instrument+"/bid",0,-1,withscores=True)
            for bid in bids:
                orders.append({"price":bid[1], "amount":redis.hget(bid[0],"amount")})
        else:
            asks = redis.zrange(instrument+"/ask",0,-1,withscores=True)
            for ask in asks:
                orders.append({"price":ask[1], "amount":redis.hget(ask[0],"amount")})
        #So prices are not quoted in satoshis
        #TODO: move this client side?
        for order in orders:
            order['amount'] = float(order['amount'])/config.get_multiplier(instrument.split("_")[0])
    else:
        orders.append("Invalid trade pair!")
    jo = json.dumps(orders)
    return Response(jo,  mimetype='application/json')
Ejemplo n.º 10
0
def tradehistory(currency, uid):
    if not is_logged_in(session):
        return home_page("ltc_btc",danger="Please log in to perform that action.")
    orders = CompletedOrder.query.filter(CompletedOrder.user == uid).filter(CompletedOrder.base_currency==str(currency)).all()
    orders2 = []
    for o in orders:
        if o.is_deposit:
            orders2.append(["DEPOSIT",  o.order_type, o.price, str(o.amount) + " " + str(o.base_currency).upper()])
        elif o.is_withdrawal:
            orders2.append(["WITHDRAWAL",  o.order_type, o.price, str(o.amount) + " " + str(o.base_currency).upper()])
        else:
            orders2.append([o.currency_pair,  o.order_type, (str(o.price) + " " + o.quote_currency + "/" + o.base_currency).upper(), str(float(o.amount)/config.get_multiplier(currency))+ " " + str(o.base_currency).upper()])
    return orders2
Ejemplo n.º 11
0
 def getbalance(c, uid):
     return "{:.4f}".format(check_balance(c, uid)/float(config.get_multiplier(c)))
Ejemplo n.º 12
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()
Ejemplo n.º 13
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()
Ejemplo n.º 14
0
 def getbalance(c, uid):
     return check_balance(c, uid)/config.get_multiplier(c)