def CANCEL_SET_BUY(self, cmd: Command):

        resp = self._database.GetUser(cmd.UserId)
        if resp.error is not None:
            return self.error(cmd, "The user does not exist.")

        # TODO:// Cancel Triggers and Unreserve money...
        trig: Trigger = self._database.CancelTrigger(cmd.UserId,
                                                     cmd.StockSymbol, "BUY")

        if trig.error is not None:
            return self.error(cmd, "No buy trigger to cancel.")

        resp = self._database.UnreserveMoney(cmd.UserId, trig.Amount)

        if resp.error is not None:
            logging.error(resp.error)
            return self.error(cmd, "Internal server error.")

        _executor.submit(
            self._audit.AccountTransaction,
            *(
                cmd.Amount,
                trig.Amount,
                "unreserve",
                cmd.TransactionID,
            ))

        return Response(Success=True, Stock=cmd.StockSymbol)
    def CANCEL_SET_SELL(self, cmd: Command):
        user = self._database.GetUser(cmd.UserId)
        if user.error is not None:
            return self.error(cmd, "The user does not exist.")

        trig: Trigger = self._database.CancelTrigger(cmd.UserId,
                                                     cmd.StockSymbol, "SELL")
        if trig.error is not None:
            return self.error(cmd, "No sell trigger to cancel")

        resp = self._database.UnreserveShares(cmd.UserId, cmd.StockSymbol,
                                              trig.Shares)
        if resp.error is not None:
            logging.error(resp.error)
            return self.error(cmd, "Internal error occured.")

        _executor.submit(
            self._audit.AccountTransaction,
            *(
                cmd.UserId,
                trig.Amount,
                "unreserve",
                cmd.TransactionID,
            ))
        return Response(Success=True)
    def SET_SELL_AMOUNT(self, cmd: Command):
        resp = self._database.GetUser(cmd.UserId)
        if resp.error is not None:
            return self.error(cmd, "The user does not exist.")

        reserved = self._database.GetReservedShares(cmd.UserId,
                                                    cmd.StockSymbol)

        if resp.error is not None or resp.user == {} \
          or resp.user is None or resp.user.stock == {}\
          or resp.user.stock is None:
            return self.error(
                cmd, "The user " + str(cmd.UserId) + " does not exist.")
        elif cmd.StockSymbol not in resp.user.stock.keys():
            return self.error(
                cmd,
                "The user " + str(cmd.UserId) + " does not own any stocks.")
        elif reserved < 0 or resp.user.stock[cmd.StockSymbol]["real"] == 0:
            return self.error(cmd,
                              "User does not own any shares for that stock")

        real_stocks = resp.user.stock[cmd.StockSymbol]["real"] - reserved
        if real_stocks <= 0:
            return self.error(cmd, "The user does not have any stocks.")

        quote = self._cache.GetQuote(cmd.StockSymbol, cmd.UserId,
                                     cmd.TransactionID)
        if quote.error is not None:
            return self.error(cmd, "Failed to get quote for that stock.")

        reserved_shares = cmd.Amount // quote.Quote
        if reserved_shares > real_stocks:
            reserved_shares = real_stocks

        trigger = Trigger(UserId=cmd.UserId,
                          Type="SELL",
                          TransactionID=cmd.TransactionID,
                          Shares=reserved_shares,
                          Stock=cmd.StockSymbol,
                          Amount=cmd.Amount,
                          When=0)

        # TODO:// Set the trigger...
        resp = self._database.AddNewTrigger(trigger)
        if resp.error is not None:
            return self.error(cmd, "Failed to set sell amount.")
        self._database.ReserveShares(cmd.UserId, cmd.StockSymbol,
                                     reserved_shares)
        _executor.submit(self._audit.AccountTransaction, (
            cmd.UserId,
            cmd.Amount,
            "reserve",
            cmd.TransactionID,
        ))
        return Response(Success=True)
    def ADD(self, cmd: Command):
        resp = self._database.AddUserMoney(userId=cmd.UserId,
                                           amount=cmd.Amount)
        if resp.error is not None:
            return self.error(cmd,
                              "Failed to create and/or add money to account")
        _executor.submit(self._audit.AccountTransaction,
                         *(
                             cmd.UserId,
                             cmd.Amount,
                             "add",
                             cmd.TransactionID,
                         ))

        return Response(Success=True)
Example #5
0
	def GetQuote(self, symbol, userId, tid):
		logging.debug("Getting Quote: " + str(symbol))
		# Get a line of text from the user
		fromUser = str(symbol) + ", " + str(userId) + "\n"
		if not self._mock:
			# Connect the socket
			# Send the user's query
			self._quote_server_conn.send(fromUser)
			# Read and print up to 1k of data.
			data = self._quote_server_conn.recv(1024)
			quote, sym, userid, timestamp, cryptokey = data.split(",")
		else:
			quote, sym, userid, timestamp, cryptokey = (12.55, symbol, userId, time.time(), "<<<MY_CRYPTOKEY>>>")
			_executor.submit(self._audit.QuoteServer, args=(quote, tid,))

		return QuoteData(UserId=userid, Symbol=symbol, Quote=float(quote), Timestamp=timestamp, Cryptokey=cryptokey)
    def SET_BUY_AMOUNT(self, cmd: Command):
        resp = self._database.GetUser(cmd.UserId)
        if resp.error is not None or resp.user is None or resp.user.Reserved is None:
            return self.error(cmd, "The user does not exist.")

        user_reserved = resp.user.Reserved
        user_balance = resp.user.Balance
        if user_balance - user_reserved < cmd.Amount:
            return self.error(cmd, "Not enough funds.")

        # Skipping getting a quote here, hope we can later...

        trigger = Trigger(UserId=cmd.UserId,
                          Stock=cmd.StockSymbol,
                          TransactionID=cmd.TransactionID,
                          Type="BUY",
                          Amount=cmd.Amount,
                          When=0)

        reserved = self._database.ReserveMoney(cmd.UserId, cmd.Amount)
        if reserved.error is not None:
            return self.error(cmd,
                              "Failed to reserve even though we should have.")

        # TODO:// Set Trigger and unreserve money if fails...
        trig = self._database.AddNewTrigger(trigger)
        if trig.error is not None:
            self._database.UnreserveMoney(cmd.UserId, cmd.Amount)
            return self.error(cmd, "Failed to set trigger in DB.")

        _executor.submit(
            self._audit.AccountTransaction,
            *(
                cmd.UserId,
                cmd.Amount,
                "reserve",
                cmd.TransactionID,
            ))
        return Response(Success=True)
    def COMMIT_SELL(self, cmd: Command):
        sell: PendingTxn = self._database.PopPendingTxn(cmd.UserId, "SELL")
        if sell.error is None:
            return self.error(cmd, "There are no pending transactions.")

        resp: DBResponse = self._database.ProcessTxn(sell, True)
        if resp.error is not None:
            return self.error(
                cmd, "User no longer has the correct number of shares.")

        _executor.submit(self._audit.AccountTransaction,
                         *(
                             cmd.UserId,
                             cmd.Amount,
                             "add",
                             cmd.TransactionID,
                         ))

        # TODO:// Log into database?... (trying to just write to file, see how it works)

        return Response(Success=True,
                        Stock=sell.Stock,
                        Shares=sell.Shares,
                        Received=sell.Price)
    def COMMIT_BUY(self, cmd: Command):
        buy = self._database.PopPendingTxn(cmd.UserId, "BUY")
        if buy is None:
            return self.error(cmd, "There are no pending transactions.")

        resp: DBResponse = self._database.ProcessTxn(buy, True)
        if resp.error is not None:
            return self.error(cmd, "User can no longer afford this purchase.")

        log = _executor.submit(
            self._audit.AccountTransaction,
            *(
                cmd.UserId,
                buy.Reserved,
                "remove",
                cmd.TransactionID,
            ))
        # TODO:// Log to database.
        log.result()

        return Response(Success=True,
                        Stock=buy.Stock,
                        Shares=buy.Shares,
                        Paid=buy.Price)