Example #1
0
def index():
    """Show portfolio of stocks"""
    user = Users.query.get(session.get("user_id"))
    query = db.session.query(
        Records.symbol, Records.company_name,
        db.func.sum(Records.shares).label("shares")).group_by(
            Records.symbol,
            Records.company_name).filter(Records.user_id == user.id)
    info = [{}] * query.count()
    grand_total = user.cash
    for i, row in enumerate(query):
        try:
            info[i]['price'] = lookup(row.symbol)['price']
        except:
            info[i]['price'] = 1

        info[i]['symbol'] = row.symbol
        info[i]['company_name'] = row.company_name
        info[i]['shares'] = row.shares
        info[i]['value'] = round(row.shares * info[i]['price'], 2)
        grand_total += info[i]['value']

    return render_template("index.html",
                           cash=user.cash,
                           rows=info,
                           total=round(grand_total, 2))
Example #2
0
def buy():
    """Buy share of stock"""

    if request.method == "GET":
        return render_template("buy.html")

    # User reached route via POST (as by submitting a form via POST)
    shares = int(request.form.get("shares"))
    symbol = request.form.get("symbol")
    quote = lookup(symbol)

    if not quote:
        return apology("invalid symbol", 404)

    price = quote['price']
    value = round(shares * price, 2)
    user = Users.query.get(session.get("user_id"))

    if value > user.cash:
        return apology("You don't have enough cash", 406)

    record = Records(symbol=quote['symbol'],
                     company_name=quote['name'],
                     transact_type="buy",
                     shares=shares,
                     price=price,
                     user_id=user.id)
    user.cash -= value
    db.session.add(record)
    db.session.commit()

    flash("Bought")
    return redirect(url_for('index'))
Example #3
0
def getStockQuote():

    print("1) in route getStockQuote")

    # Query for currency exchange rate
    symbol = request.form.get("symbol")

    print(f"2) in route getStockQuote, symbol = {symbol}")

    stockDict = lookup(symbol)
    if not stockDict:
        #message = "You have requested an invalid stock symbol " + symbol + ".<br>Please try again."
        return jsonify({
            "success": False,
            "stockSymbol": symbol,
            "stockCompanyName": "",
            "stockLatestPrice": "",
            "title": ""
        })

    stockSymbol = stockDict["symbol"]
    stockCompanyName = stockDict["companyName"]
    stockLatestPrice = stockDict["latestPrice"]
    title = "Quote: Stock Symbol " + stockSymbol

    print(
        f"3) getStockQuote: done returning stock price {stockLatestPrice}, for company {stockCompanyName}"
    )
    return jsonify({
        "success": True,
        "stockSymbol": stockSymbol,
        "stockCompanyName": stockCompanyName,
        "stockLatestPrice": stockLatestPrice,
        "title": title
    })
Example #4
0
def quote(args=""):
    """Get stock quote."""
    if request.method == "GET":
        return render_template("getStockQuote.html", symbol=args)

    symbol = request.form.get("symbol")

    if not symbol:
        return messageAlert(Markup.escape("Stock symbol is required"), 403,
                            "error.png", "quote")

    stockDict = lookup(symbol)
    if not stockDict:
        message = "You have requested an invalid stock symbol " + symbol + ".<br>Please try again."
        return messageAlert(Markup.escape(message), 403, "error.png", "quote")

    stockSymbol = stockDict["symbol"]
    stockCompanyName = stockDict["companyName"]
    stockLatestPrice = stockDict["latestPrice"]
    title = "Quote: Stock Symbol " + stockSymbol

    return render_template('displayStockQuote.html',
                           symbol=stockSymbol,
                           stockSymbol=stockSymbol,
                           stockCompanyName=stockCompanyName,
                           stockLatestPrice=stockLatestPrice,
                           title=title)
Example #5
0
def quote():
    """Get stock quote."""
    if request.method == "GET":
        return render_template("quote.html")

    symbol = request.form.get("symbol")
    quote = lookup(symbol)
    if not quote:
        return apology("invalid symbol", 404)

    name = quote['name']
    price = quote['price']
    symbol = quote['symbol']
    return render_template("quoted.html",
                           name=name,
                           price=price,
                           symbol=symbol)
Example #6
0
def sell():
    """Sell shares of stock"""
    if request.method == "GET":
        symbols = Records.query.with_entities(Records.symbol).\
                distinct().filter_by(user_id=session.get("user_id")).all()
        return render_template("sell.html", symbols=symbols)

    symbol = request.form.get("symbol")
    shares = int(request.form.get("shares"))

    record = db.session.query(db.func.sum(Records.shares).label("shares")).\
     group_by(Records.user_id).filter_by(symbol=symbol, user_id=session.get('user_id')).one()

    if shares > record.shares:
        return apology(
            f"You can only sell { record.shares } shares or less than", 400)

    quote = lookup(symbol)
    price = quote['price']
    value = round(shares * price, 2)

    user = Users.query.get(session.get('user_id'))
    user.cash += value

    record = Records(symbol=quote['symbol'],
                     company_name=quote['name'],
                     transact_type="sell",
                     shares=int('-' + str(shares)),
                     price=price,
                     user_id=user.id)

    db.session.add(record)
    db.session.commit()

    flash('Sold')
    return redirect(url_for('index'))
Example #7
0
def sell(args=""):
    """Sell shares of stock"""
    if request.method == "GET":
        return render_template("buyShares.html",
                               title="Sell Shares",
                               symbol=args,
                               action="sell")

    symbol = request.form.get("symbol")
    shares = request.form.get("shares")

    if not symbol:
        return messageAlert(Markup.escape("Stock symbol is required"), 403,
                            "error.png", "sell")

    if not shares:
        return messageAlert(Markup.escape("Number of shares is required"), 403,
                            "error.png", "sell", symbol)

    try:
        int(shares)
        shares = int(shares)
        isValidShares = True
    except ValueError:
        isValidShares = False

    if not isValidShares:
        return messageAlert(Markup.escape("Number of shares is an integer"),
                            403, "error.png", "sell", symbol)

    stockDict = lookup(symbol)
    if not stockDict:
        message = "You have requested an invalid stock symbol " + symbol + ".<br>Please try again."
        return messageAlert(Markup.escape(message), 403, "error.png", "sell")

    stockSymbol = stockDict["symbol"]
    stockCompanyName = stockDict["companyName"]
    stockLatestPrice = stockDict["latestPrice"]
    title = "Buy:  Stock Symbol " + stockSymbol

    # create a database connection
    #conn = create_connection(db)
    #conn.row_factory = sqlite3.Row

    conn = psycopg2.connect(host=os.environ.get('POSTGRESQL_HOST'),
                            database=os.environ.get('POSTGRESQL_DATABASE'),
                            user=os.environ.get('POSTGRESQL_USERNAME'),
                            password=os.environ.get('POSTGRESQL_PASSWORD'),
                            port=os.environ.get('POSTGRESQL_PORT'))

    with conn:
        isError = 0
        try:

            cur = conn.cursor()
            cur.execute("Select COALESCE(sum(shares),0) as accountShares from orders \
                         Where user_id='%s' \
                         And   symbol = upper(%s)"                                                  , \
                         (current_user.id,stockSymbol))

            rows = cur.fetchall()

            # Ensure record exists
            if len(rows) != 1:
                message = "You do not own any shares of " + stockCompanyName + " (" + stockSymbol + ").<br>Please try again."
                return messageAlert(Markup.escape(message), 403, "error.png",
                                    "sell", symbol)

            accountShares = rows[0][0]

            if shares > accountShares:
                message = "You own " + \
                           str(accountShares) + " shares of " + stockCompanyName + " (" + stockSymbol + ").<br>" + \
                           "You may not sell more shares (" + str(shares) + ") than you currently own."
                return messageAlert(Markup.escape(message), 403, "error.png",
                                    "sell", symbol)

            shares = shares * (-1)
            extendedPrice = stockLatestPrice * shares

            values = (current_user.id, "Sell", stockSymbol, stockCompanyName,
                      shares, stockLatestPrice, extendedPrice,
                      datetime.utcnow())

            sql = ''' INSERT INTO orders(user_id, transaction_type, symbol, company_name, shares, price, extended_price,order_date) VALUES(%s,%s,%s,%s,%s,%s,%s,%s) '''

            cur = conn.cursor()
            cur.execute(sql, values)
            id = cur.lastrowid

            cur = conn.cursor()
            cur.execute("Update users Set cash = cash - %s Where id=%s;",
                        (extendedPrice, current_user.id))

            conn.commit()

            # Redirect user to home page
            return redirect("/")

        except (Exception, psycopg2.Error) as error:
            isError = 1
            print("Error in route sell", error)

        if isError == 1:
            return messageAlert(
                Markup.escape(
                    "Sell Error: Error while connecting to PostgreSQL to sell an equity"
                ), 500, "error.png", "index")
Example #8
0
def index():
    """Show portfolio of stocks"""
    # create a database connection

    conn = psycopg2.connect(host=os.environ.get('POSTGRESQL_HOST'),
                            database=os.environ.get('POSTGRESQL_DATABASE'),
                            user=os.environ.get('POSTGRESQL_USERNAME'),
                            password=os.environ.get('POSTGRESQL_PASSWORD'),
                            port=os.environ.get('POSTGRESQL_PORT'))

    #conn = create_connection(db)
    #conn.row_factory = sqlite3.Row

    with conn:
        isError = 0
        try:
            cur = conn.cursor()
            print(f"executing query to get cash")
            # Query database for username
            cur.execute(
                "SELECT id, username, hash, cash, mobile,comments FROM users WHERE id = '%s';",
                (current_user.id, ))

            rows = cur.fetchall()

            # Ensure record exists
            if len(rows) != 1:
                return messageAlert(
                    Markup.escape("Portfolio Error: User does not exist"), 500,
                    "error.png", "login")

            #cash = rows[0]["cash"]
            cash = rows[0][3]
            accountTotal = cash
            print(f"Account total is {accountTotal}")
        except (Exception, psycopg2.Error) as error:
            isError = 1
            print("Error while connecting to PostgreSQL for query to get cash",
                  error)

        if isError == 1:
            # if(conn):
            #    cur.close()
            #     conn.close()
            #     cur = None
            #     conn = None
            #     print("1) index:  PostgreSQL connection is closed")
            return messageAlert(
                Markup.escape(
                    "Portfolio Error: Error while connecting to PostgreSQL for query to get cash"
                ), 500, "error.png", "index")

        isError = 0
        try:
            cur = conn.cursor()
            cur.execute("SELECT symbol, sum(shares) as shares from orders \
                         WHERE user_id = '%s' \
                         group by symbol \
                         having sum(shares) > 0 \
                         order by symbol"                                         , \
                          (current_user.id,))

            rows = cur.fetchall()

            idx = -1
            allStocks = []
            for row in rows:

                idx += 1
                # shares = rows[idx][1]
                stockDict = lookup(rows[idx][0])

                if not stockDict:
                    return messageAlert(
                        Markup.escape(
                            "Portfolio Error: Invalid stock symbol " +
                            str(idx) + " " + rows[idx]["symbol"]), 500,
                        "error.png", "quote")

                # The tuple is constructed as (Symbol, company_name, Shares, Price, TOTAL)
                stockTuple = ()
                stockSymbol = stockDict["symbol"]
                stockCompanyName = stockDict["companyName"]

                shares = rows[idx][1]

                stockLatestPrice = stockDict["latestPrice"]
                formattedLatestPrice = "${:,.2f}".format(stockLatestPrice)

                stockTotalPrice = stockLatestPrice * shares
                formattedTotalPrice = "${:,.2f}".format(stockTotalPrice)

                stockTuple = (stockSymbol, stockCompanyName, shares,
                              formattedLatestPrice, formattedTotalPrice)
                allStocks.append(stockTuple)

                accountTotal = accountTotal + stockTotalPrice

                # if(conn):
                #     cur.close()
                #     conn.close()
                #     cur = None
                #     conn = None
                #     print("2) index:  PostgreSQL connection is closed")

            return render_template("portfolio.html",
                                   title="Portfolio",
                                   cash=cash,
                                   allStocks=allStocks,
                                   accountTotal=accountTotal)

        except (Exception, psycopg2.Error) as error:
            isError = 1
            print(
                "Error while connecting to PostgreSQL for query to get stock transactions",
                error)

        # if(conn):
        #     cur.close()
        #     conn.close()
        #     cur = None
        #     conn = None
        #     print("3) index:  PostgreSQL connection is closed")

        if isError == 1:
            return messageAlert(
                Markup.escape(
                    "Portfolio Error: Error while connecting to PostgreSQL for query to get stock transactions"
                ), 500, "error.png", "index")
Example #9
0
def buy(args=""):
    """Buy shares of stock"""
    if request.method == "GET":
        return render_template("buyShares.html",
                               title="Buy Shares",
                               symbol=args,
                               action="buy")

    symbol = request.form.get("symbol")
    shares = request.form.get("shares")

    if not symbol:
        return messageAlert(Markup.escape("Stock symbol is required"), 403,
                            "error.png", "buy")

    if not shares:
        return messageAlert(Markup.escape("Number of shares is required"), 403,
                            "error.png", "buy", symbol)

    try:
        int(shares)
        shares = int(shares)
        isValidShares = True
    except ValueError:
        isValidShares = False

    if not isValidShares:
        return messageAlert(Markup.escape("Number of shares is an integer"),
                            403, "error.png", "buy", symbol)

    stockDict = lookup(symbol)
    if not stockDict:
        message = "You have requested an invalid stock symbol " + symbol + ".<br>Please try again."
        return messageAlert(Markup.escape(message), 403, "error.png", "buy",
                            symbol)

    stockSymbol = stockDict["symbol"]
    stockCompanyName = stockDict["companyName"]
    stockLatestPrice = stockDict["latestPrice"]
    title = "Buy:  Stock Symbol " + stockSymbol
    extendedPrice = stockLatestPrice * shares

    # create a database connection
    # conn = create_connection(db)
    # conn.row_factory = sqlite3.Row

    conn = psycopg2.connect(host=os.environ.get('POSTGRESQL_HOST'),
                            database=os.environ.get('POSTGRESQL_DATABASE'),
                            user=os.environ.get('POSTGRESQL_USERNAME'),
                            password=os.environ.get('POSTGRESQL_PASSWORD'),
                            port=os.environ.get('POSTGRESQL_PORT'))

    with conn:
        isError = 0
        try:
            cur = conn.cursor()
            # Query database for username
            cur.execute(
                "SELECT id, username, hash, cash, mobile,comments FROM users WHERE id = '%s';",
                (current_user.id, ))

            rows = cur.fetchall()

            # Ensure record exists
            if len(rows) != 1:
                return messageAlert(
                    Markup.escape("Portfolio Error: User does not exist"), 500,
                    "error.png", "login")

            cash = rows[0][3]

            if cash < extendedPrice:
                message = "You do not have sufficient funds (" + "${:,.2f}".format(cash) + ")<br>to buy " + \
                          str(shares) + " shares of " + stockCompanyName + "(" + stockSymbol + ") at " + \
                          "${:,.2f}".format(stockLatestPrice) + " a share<br>for a net price of " + "${:,.2f}".format(extendedPrice) + "."
                return messageAlert(Markup.escape(message), 403, "error.png",
                                    "buy", symbol)

            values = (current_user.id, "Buy", stockSymbol, stockCompanyName,
                      shares, stockLatestPrice, extendedPrice,
                      datetime.utcnow())

            sql = ''' INSERT INTO orders(user_id, transaction_type, symbol, company_name, shares, price, extended_price, order_date) VALUES(%s,%s,%s,%s,%s,%s,%s,%s) '''

            cur = conn.cursor()
            cur.execute(sql, values)
            id = cur.lastrowid

            cur = conn.cursor()
            cur.execute("Update users Set cash = cash - %s Where id=%s;",
                        (extendedPrice, current_user.id))

            conn.commit()

            # if(conn):
            #     cur.close()
            #     conn.close()
            #     cur = None
            #     conn = None
            #     print("1) buy:  PostgreSQL connection is closed")

            # Redirect user to home page
            return redirect("/")

        except (Exception, psycopg2.Error) as error:
            isError = 1
            print("Error in route Buy", error)

        # if(conn):
        #     cur.close()
        #     conn.close()
        #     cur = None
        #     conn = None
        #     print("2) buy:  PostgreSQL connection is closed")

        if isError == 1:
            return messageAlert(
                Markup.escape(
                    "Buy Error: Error while connecting to PostgreSQL to buy a stock"
                ), 500, "error.png", "index")