def match_orders(sec, buysell): """Match orders in cross""" # Get buy and sell lists b = Order.query(Order.security == sec, Order.buysell == 'Buy', Order.active == True, ancestor=sec.key).order(-Order.price, Order.timestamp) s = Order.query(Order.security == sec, Order.buysell == 'Sell', Order.active == True, ancestor=sec.key).order(Order.price, Order.timestamp) b = list(b) s = list(s) # Match orders until market uncrosses bn = 0 sn = 0 while(1): if bn + 1 > len(b): break if sn + 1 > len(s): break if b[bn].price >= s[sn].price: t = Trade() t.timestamp = datetime.utcnow() t.buy_user = b[bn].user t.sell_user = s[sn].user t.security = b[bn].security if buysell == "Buy": t.price = s[sn].price else: t.price = b[bn].price b[bn] = b[bn].key.get() s[sn] = s[sn].key.get() b_ptf = Portfolio.query(Portfolio.user == b[bn].user).get() s_ptf = Portfolio.query(Portfolio.user == s[sn].user).get() if b[bn].volume > s[sn].volume: t.volume = s[sn].volume b[bn].volume += -s[sn].volume s[sn].active = False b_ptf.points += s[sn].volume s_ptf.points += s[sn].volume b[bn].put() s[sn].put() sn += 1 elif b[bn].volume < s[sn].volume: t.volume = b[bn].volume s[sn].volume += -b[bn].volume b[bn].active = False b_ptf.points += b[bn].volume s_ptf.points += b[bn].volume b[bn].put() s[sn].put() bn += 1 elif b[bn].volume == s[sn].volume: t.volume = b[bn].volume b[bn].active = False s[sn].active = False b_ptf.points += b[bn].volume s_ptf.points += b[bn].volume b[bn].put() s[sn].put() bn += 1 sn += 1 b_ptf.put() s_ptf.put() t.put() flash(u'Trade %s successfully completed.' % t.key.id(), 'success') continue break
def CreateTrade(): """Creates a trade for the user.""" user_id = users.get_current_user().user_id() user_key = ndb.Key('Profile', user_id) current_user = user_key.get() prediction_key = ndb.Key(urlsafe=request.form['prediction_id']) prediction = prediction_key.get() if request.form['is_likelihood'] == 'true': user_id = users.get_current_user().user_id() user_key = ndb.Key('Profile', user_id) current_user = user_key.get() trade = calculate_trade_from_likelihood( float(request.form['likelihood']), prediction, current_user) print trade else: trade = Trade(prediction_id=prediction_key, user_id=user_key, direction=request.form['direction'], contract=request.form['contract'], quantity=float(request.form['quantity'])) verification_of_trade(trade) price = get_price_for_trade(prediction, trade) # TODO(goldhaber):replace flag new_ledger_record = False if trade.direction == 'BUY': if current_user.balance >= price: current_user.balance -= price # TODO(goldhaber): check results and/or better formatting current_user_portfolio = [ i for i in current_user.user_ledger if i.prediction_id == trade.prediction_id.urlsafe() ] if len(current_user_portfolio) == 0: ledger_records = LedgerRecords() ledger_records.prediction_id = trade.prediction_id.urlsafe() ledger_records.user_id = current_user.user_id if trade.contract == 'CONTRACT_ONE': ledger_records.contract_one = trade.quantity ledger_records.contract_two = 0.00 else: ledger_records.contract_two = trade.quantity ledger_records.contract_one = 0.00 current_user.user_ledger.append(ledger_records) new_ledger_record = True else: ledger_record_to_update = current_user_portfolio[0] if trade.contract == 'CONTRACT_ONE': ledger_record_to_update.contract_one += trade.quantity else: ledger_record_to_update.contract_two += trade.quantity if trade.contract == 'CONTRACT_ONE': prediction.contract_one += trade.quantity else: prediction.contract_two += trade.quantity else: # TODO(goldhaber): throw error return 'error' else: current_user_portfolio = [ i for i in current_user.user_ledger if i.prediction_id == trade.prediction_id.urlsafe() ] if (trade.contract == 'CONTRACT_ONE' and current_user_portfolio[0].contract_one >= trade.quantity ) or (trade.contract == 'CONTRACT_TWO' and current_user_portfolio[0].contract_two >= trade.quantity): ledger_record_to_update = current_user_portfolio[0] if trade.contract == 'CONTRACT_ONE': ledger_record_to_update.contract_one -= trade.quantity prediction.contract_one -= trade.quantity else: ledger_record_to_update.contract_two -= trade.quantity prediction.contract_two -= trade.quantity current_user.balance -= price else: return 'error' trade.put() if new_ledger_record: ledger_records.put() current_user.put() prediction.put() flash('You successfully predicted!') return redirect('/predictions/' + trade.prediction_id.urlsafe())