Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
vlitvak99 committed Aug 28, 2020
1 parent 1050fbb commit da5ca29
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 77 deletions.
68 changes: 34 additions & 34 deletions MyShareApi.py3
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#
# Author: Vlad Litvak
# Email: [email protected]
# Version: 4.2.7
# Since: 08.14.2020
# Version: 4.2.8
# Since: 08.27.2020
# --------------------------------------------------------------------------

from flask import Flask, Response, render_template
Expand Down Expand Up @@ -620,14 +620,14 @@ class Holdings(Resource):
if params["symbol"] is not None:
if not checkSymbolFormat(params["symbol"]) or not symbolExists(params["symbol"]):
return Response(json.dumps({ "error" : INVALID_SYMBOL_PARAM, "message" : "Invalid symbol" }), status=HTTP_BAD_REQUEST, mimetype="application/json")

if not symbolHeldByUser(params["symbol"], params["id"]):
return Response(json.dumps({ "symbol" : symbol.upper(), "shares" : 0, "currentPrice" : round(stock_info.get_live_price(symbol), 2), "avgCostPerShare" : None, "totalPrinciple" : 0.0, "marketValue" : 0.0, "valueIncrease" : 0.0, "lots" : [] }), status=HTTP_OK, mimetype="application/json")
return Response(json.dumps({ "symbol" : symbol.upper(), "shares" : 0, "currentPrice" : round(stock_info.get_live_price(symbol), 2), "avgCostPerShare" : None, "totalPrincipal" : 0.0, "marketValue" : 0.0, "valueIncrease" : 0.0, "lots" : [] }), status=HTTP_OK, mimetype="application/json")

symbolFilter = "AND Symbol = '{}'".format(params["symbol"].upper())

holdings = []
totalPrinciple = 0.0
totalPrincipal = 0.0
totalValueIncrease = 0.0
symbol = None
currentPrice = None
Expand All @@ -637,11 +637,11 @@ class Holdings(Resource):
buyPrice = None
buyDate = None
symbolShares = None
symbolPrinciple = None
symbolPrincipal = None

query = "SELECT Symbol, LotID, ShareID, BuyPrice, BuyDate FROM Holdings WHERE User = {} {}AND SellLotID IS NULL ORDER BY Symbol, BuyDate DESC, LotID;".format(params["id"], symbolFilter)
result = executeDatabaseQuery(query)

for row in result:
# for the first returned row, save the row's information
if symbol is None:
Expand All @@ -653,17 +653,17 @@ class Holdings(Resource):
buyPrice = round(float(row[3]), 2)
buyDate = row[4]
symbolShares = 1
symbolPrinciple = buyPrice
symbolPrincipal = buyPrice

# if the symbol is different than the current symbol, add the current lot to lots,
# then add lots to holdings, then save this row's information
elif symbol != row[0]:
lots.append({ "lotId" : lot, "buyPrice" : buyPrice, "buyDate" : buyDate, "valueIncrease": round((currentPrice - buyPrice) * len(shares), 2), "shares" : len(shares), "shareIds" : shares })
info = yfinance.Ticker(symbol)
info.info.update({ "currentPrice" : currentPrice })
holdings.append({ "symbol" : symbol, "shares" : symbolShares, "avgCostPerShare" : round(symbolPrinciple / symbolShares, 2), "principle" : round(symbolPrinciple, 2), "marketValue" : round(currentPrice * symbolShares, 2), "valueIncrease" : round((currentPrice * symbolShares) - symbolPrinciple, 2), "lots" : lots, "info" : info.info })
totalValueIncrease += round((currentPrice * symbolShares) - symbolPrinciple, 2)
totalPrinciple += round(symbolPrinciple, 2)
holdings.append({ "symbol" : symbol, "shares" : symbolShares, "avgCostPerShare" : round(symbolPrincipal / symbolShares, 2), "principal" : round(symbolPrincipal, 2), "marketValue" : round(currentPrice * symbolShares, 2), "valueIncrease" : round((currentPrice * symbolShares) - symbolPrincipal, 2), "lots" : lots, "info" : info.info })
totalValueIncrease += round((currentPrice * symbolShares) - symbolPrincipal, 2)
totalPrincipal += round(symbolPrincipal, 2)
symbol = row[0]
currentPrice = round(stock_info.get_live_price(symbol), 2)
lot = int(row[1])
Expand All @@ -672,8 +672,8 @@ class Holdings(Resource):
buyPrice = round(float(row[3]), 2)
buyDate = row[4]
symbolShares = 1
symbolPrinciple = buyPrice
symbolPrincipal = buyPrice

# if only the lot is different than the current lot, add the current lot to lots,
# then save this this lot
elif lot != int(row[1]):
Expand All @@ -683,27 +683,27 @@ class Holdings(Resource):
buyPrice = round(float(row[3]), 2)
buyDate = row[4]
symbolShares += 1
symbolPrinciple += buyPrice
symbolPrincipal += buyPrice

# otherwise, add this share to shares
else:
symbolShares += 1
symbolPrinciple += buyPrice
symbolPrincipal += buyPrice
shares.append(int(row[2]))

# add the saved information from the last returned row to lots and holdings
if symbol is not None:
lots.append({ "lotId" : lot, "buyPrice" : buyPrice, "buyDate" : buyDate, "valueIncrease": round((currentPrice - buyPrice) * len(shares), 2), "shares" : len(shares), "shareIds" : shares })
info = yfinance.Ticker(symbol)
info.info.update({ "currentPrice" : currentPrice })
holdings.append({ "symbol" : symbol, "shares" : symbolShares, "avgCostPerShare" : round(symbolPrinciple / symbolShares, 2), "principle" : round(symbolPrinciple, 2), "marketValue" : round(currentPrice * symbolShares, 2), "valueIncrease" : round((currentPrice * symbolShares) - symbolPrinciple, 2), "lots" : lots, "info" : info.info })
totalValueIncrease += round((currentPrice * symbolShares) - symbolPrinciple, 2)
totalPrinciple += round(symbolPrinciple, 2)
holdings.append({ "symbol" : symbol, "shares" : symbolShares, "avgCostPerShare" : round(symbolPrincipal / symbolShares, 2), "principal" : round(symbolPrincipal, 2), "marketValue" : round(currentPrice * symbolShares, 2), "valueIncrease" : round((currentPrice * symbolShares) - symbolPrincipal, 2), "lots" : lots, "info" : info.info })
totalValueIncrease += round((currentPrice * symbolShares) - symbolPrincipal, 2)
totalPrincipal += round(symbolPrincipal, 2)

if params["symbol"] is not None:
return Response(json.dumps(holdings[0]), status=HTTP_OK, mimetype="application/json")

return Response(json.dumps({ "id" : int(params["id"]), "totalPrinciple" : round(totalPrinciple, 2), "marketValue": round(totalPrinciple + totalValueIncrease, 2), "totalValueIncrease" : totalValueIncrease, "holdings" : holdings }), status=HTTP_OK, mimetype="application/json")
return Response(json.dumps({ "id" : int(params["id"]), "totalPrincipal" : round(totalPrincipal, 2), "marketValue": round(totalPrincipal + totalValueIncrease, 2), "totalValueIncrease" : totalValueIncrease, "holdings" : holdings }), status=HTTP_OK, mimetype="application/json")


# /myshare/user/lots
Expand Down Expand Up @@ -745,7 +745,7 @@ class Lots(Resource):
lots = []
totalProfitFromSelling = 0.0
totalValueIncrease = 0.0
totalPrinciple = 0.0
totalPrincipal = 0.0
lot = None
symbol = None
buyPrice = None
Expand All @@ -756,9 +756,9 @@ class Lots(Resource):
sellLot = None
sold = None
profitFromSelling = None

query = "SELECT LotID, Symbol, ShareID, BuyPrice, BuyDate, SellLotID, SellPrice, SellDate FROM Holdings WHERE {}User = {} ORDER BY BuyDate DESC, LotID, SellDate DESC, SellLotID;".format(lotFilter, params["id"])

result = executeDatabaseQuery(query)
for row in result:
# for the first returned row, save the row's information
Expand All @@ -776,7 +776,7 @@ class Lots(Resource):
if row[5] is None:
holding.append(int(row[2]))

# otherwise initialize a sell lot and add this share to its shareIds
# otherwise initialize a sell lot and add this share to its shareIds
else:
sellLot = { "sellLotId" : int(row[5]), "sellPrice" : round(float(row[6]), 2), "sellDate" : row[7], "shareIds" : [int(row[2])] }
sold += 1
Expand All @@ -795,7 +795,7 @@ class Lots(Resource):
sharesHolding = len(holding)
valueIncrease = round((currentPrice - buyPrice) * sharesHolding, 2)
totalValueIncrease += valueIncrease
totalPrinciple += round(buyPrice * sharesHolding, 2)
totalPrincipal += round(buyPrice * sharesHolding, 2)
totalProfitFromSelling += profitFromSelling
lots.append({ "lotId" : lot, "symbol" : symbol, "buyPrice" : buyPrice, "buyDate" : buyDate, "currentPrice" : currentPrice, "profitFromSelling" : round(profitFromSelling, 2), "holdingValueIncrease" : valueIncrease, "sharesHolding" : sharesHolding, "holding" : holding, "sharesSold" : sold, "sellLots" : sellLots })
lot = int(row[0])
Expand All @@ -811,8 +811,8 @@ class Lots(Resource):
# if this share was not sold, add it to the holdings array
if row[5] is None:
holding.append(int(row[2]))
# otherwise initialize a sell lot and add this share to its shareIds

# otherwise initialize a sell lot and add this share to its shareIds
else:
sellLot = { "sellLotId" : int(row[5]), "sellPrice" : round(float(row[6]), 2), "sellDate" : row[7], "shareIds" : [int(row[2])] }
sold += 1
Expand Down Expand Up @@ -841,14 +841,14 @@ class Lots(Resource):
sellLot.update({ "shares" : sellLotShares, "profit" : sellLotProfit } )
sellLots.append(sellLot)
sellLot = { "sellLotId" : int(row[5]), "sellPrice" : round(float(row[6]), 2), "sellDate" : row[7], "shareIds" : [int(row[2])] }

# otherwise if there is a saved sell lot and this share is from that lot,
# add this share to the lot's shareIds
else:
sellLot["shareIds"].append(int(row[2]))
sold += 1

# otherwise initialize a sell lot and add this share to its shareIds
# otherwise initialize a sell lot and add this share to its shareIds
else:
sellLot = { "sellLotId" : int(row[5]), "sellPrice" : round(float(row[6]), 2), "sellDate" : row[7], "shareIds" : [int(row[2])] }
sold += 1
Expand All @@ -867,14 +867,14 @@ class Lots(Resource):
sharesHolding = len(holding)
valueIncrease = round((currentPrice - buyPrice) * sharesHolding, 2)
totalValueIncrease += valueIncrease
totalPrinciple += round(buyPrice * sharesHolding, 2)
totalPrincipal += round(buyPrice * sharesHolding, 2)
totalProfitFromSelling += profitFromSelling
lots.append({ "lotId" : lot, "symbol" : symbol, "buyPrice" : buyPrice, "buyDate" : buyDate, "currentPrice" : currentPrice, "profitFromSelling" : round(profitFromSelling, 2), "holdingValueIncrease" : valueIncrease, "sharesHolding" : sharesHolding, "holding" : holding, "sharesSold" : sold, "sellLots" : sellLots })

if params["lotId"] is not None:
return Response(json.dumps(lots[0]), status=HTTP_OK, mimetype="application/json")

return Response(json.dumps({ "id" : int(params["id"]), "currentPrinciple" : totalPrinciple, "totalValueIncrease" : round(totalValueIncrease, 2), "totalProfitFromSelling": round(totalProfitFromSelling, 2), "lots" : lots }), status=HTTP_OK, mimetype="application/json")
return Response(json.dumps({ "id" : int(params["id"]), "currentPrincipal" : totalPrincipal, "totalValueIncrease" : round(totalValueIncrease, 2), "totalProfitFromSelling": round(totalProfitFromSelling, 2), "lots" : lots }), status=HTTP_OK, mimetype="application/json")


# add a new lot for a user
Expand Down Expand Up @@ -1223,7 +1223,7 @@ class SellLots(Resource):

query = "SELECT Symbol, SellLotID, ShareID, BuyPrice, BuyDate, SellPrice, SellDate, LotID FROM Holdings WHERE User = {} AND SellLotID {} ORDER BY SellDate DESC, SellLotID, BuyDate, LotID;".format(params["id"], sellLotFilter)
result = executeDatabaseQuery(query)

for row in result:
# for the first returned row, save the row's information
if symbol is None:
Expand Down
Binary file modified demos/Holdings.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified demos/Lots.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions static/css/list.css
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ input[type=text]::placeholder {
color: white;
}

.lotprinciple {
.lotprincipal {
font-size: 25px;
float: right;
margin-top: 10px;
Expand All @@ -134,7 +134,7 @@ input[type=text]::placeholder {
color: white;
}

.portfolioprinciple {
.portfolioprincipal {
font-size: 18px;
float: left;
margin-top: 10px;
Expand Down
40 changes: 20 additions & 20 deletions static/js/holdings.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @author Vlad Litvak
* @since 08.14.2020
* @since 08.27.2020
*/

// goes to home page if no user is logged in
Expand Down Expand Up @@ -141,26 +141,26 @@ function loadUserMenuAndHoldings() {
if (response.status === 200) {
response.json().then(function(data) {
// verify user has holdings
if(data.holdings.length != 0 || data.totalPrinciple != 0 || data.marketValue != 0) {
if(data.holdings.length != 0 || data.totalPrincipal != 0 || data.marketValue != 0) {
// get existing display areas
let totalMarketValueDiv = document.getElementById("marketvalue");
let totalPrincipleDiv = document.getElementById("principle");
let totalPrincipalDiv = document.getElementById("principal");
let totalChangeDiv = document.getElementById("change");

// color the market value and total change displays based on whether it's increased
totalMarketValueDiv.style.color = "#24A292";
totalChangeDiv.style.color = "#24A292";
if(data.marketValue < data.totalPrinciple) {
if(data.marketValue < data.totalPrincipal) {
totalMarketValueDiv.style.color = "#FF3200";
totalChangeDiv.style.color = "#FF3200";
}

// calculate percent change
let percentChange = (data.totalValueIncrease / data.totalPrinciple) * 100;
let percentChange = (data.totalValueIncrease / data.totalPrincipal) * 100;

// display the total market value and total principle
// display the total market value and total principal
totalMarketValueDiv.innerHTML = dollar.format(data.marketValue);
totalPrincipleDiv.innerHTML = dollar.format(data.totalPrinciple);
totalPrincipalDiv.innerHTML = dollar.format(data.totalPrincipal);

// display the total change
if(percentChange < 0) totalChangeDiv.innerHTML = changeInDollars.format(data.totalValueIncrease) + " | " + percentChange.toFixed(2) + "%";
Expand All @@ -171,7 +171,7 @@ function loadUserMenuAndHoldings() {

// create a div for each holding and add it to the display area
for(var holding of data.holdings) {
let percentChange = (holding.valueIncrease / holding.principle) * 100;
let percentChange = (holding.valueIncrease / holding.principal) * 100;

let holdingDiv = document.createElement("div");
holdingDiv.classList.add("listitem");
Expand Down Expand Up @@ -248,10 +248,10 @@ function loadUserMenuAndHoldings() {
clearDiv.style.clear = "both";
infoDiv.appendChild(clearDiv);

let principleDiv = document.createElement("div");
principleDiv.classList.add("leftinfo");
principleDiv.innerHTML = "Principle:&nbsp;&nbsp;<span style='color:white;'>" + dollar.format(holding.principle) + "</span>";
infoDiv.appendChild(principleDiv);
let principalDiv = document.createElement("div");
principalDiv.classList.add("leftinfo");
principalDiv.innerHTML = "Principal:&nbsp;&nbsp;<span style='color:white;'>" + dollar.format(holding.principal) + "</span>";
infoDiv.appendChild(principalDiv);

let dayGainDiv = document.createElement("div");
dayGainDiv.classList.add("rightinfo");
Expand Down Expand Up @@ -305,10 +305,10 @@ function loadUserMenuAndHoldings() {
sharesHeader.innerHTML = "Shares";
tableHeader.appendChild(sharesHeader);

let principleHeader = document.createElement("th");
principleHeader.style.textAlign = "right";
principleHeader.innerHTML = "Principle";
tableHeader.appendChild(principleHeader);
let principalHeader = document.createElement("th");
principalHeader.style.textAlign = "right";
principalHeader.innerHTML = "Principal";
tableHeader.appendChild(principalHeader);

let gainHeader = document.createElement("th");
gainHeader.style.textAlign = "right";
Expand Down Expand Up @@ -337,10 +337,10 @@ function loadUserMenuAndHoldings() {
sharesValue.innerHTML = lot.shares;
lotRow.appendChild(sharesValue);

let principleValue = document.createElement("td");
principleValue.style.textAlign = "right";
principleValue.innerHTML = dollar.format(lot.shares * lot.buyPrice);
lotRow.appendChild(principleValue);
let principalValue = document.createElement("td");
principalValue.style.textAlign = "right";
principalValue.innerHTML = dollar.format(lot.shares * lot.buyPrice);
lotRow.appendChild(principalValue);

let percentGain = (((lot.valueIncrease / lot.shares) / lot.buyPrice) * 100).toFixed(2);
let gainValue = document.createElement("td");
Expand Down
10 changes: 5 additions & 5 deletions static/js/lot.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @author Vlad Litvak
* @since 08.14.2020
* @since 08.27.2020
*/

// goes to home page if no user is logged in
Expand Down Expand Up @@ -191,10 +191,10 @@ function loadUserMenuAndLot() {
lotDateDiv.innerHTML = data.buyDate;
headerDiv.appendChild(lotDateDiv);

let lotPrincipleDiv = document.createElement("div");
lotPrincipleDiv.classList.add("lotprinciple");
lotPrincipleDiv.innerHTML = dollar.format(data.buyPrice * (data.sharesSold + data.sharesHolding));
headerDiv.appendChild(lotPrincipleDiv);
let lotPrincipalDiv = document.createElement("div");
lotPrincipalDiv.classList.add("lotprincipal");
lotPrincipalDiv.innerHTML = dollar.format(data.buyPrice * (data.sharesSold + data.sharesHolding));
headerDiv.appendChild(lotPrincipalDiv);

clearDiv = document.createElement("div");
clearDiv.style.clear = "both";
Expand Down
18 changes: 9 additions & 9 deletions static/js/lots.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @author Vlad Litvak
* @since 08.14.2020
* @since 08.27.2020
*/

// goes to home page if no user is logged in
Expand Down Expand Up @@ -141,9 +141,9 @@ function loadUserMenuAndLots() {
if (response.status === 200) {
response.json().then(function(data) {
// verify user has lots
if(data.lots.length != 0 || data.currentPrinciple != 0 || data.totalValueIncrease != 0 || data.totalProfitFromSelling != 0) {
if(data.lots.length != 0 || data.currentPrincipal != 0 || data.totalValueIncrease != 0 || data.totalProfitFromSelling != 0) {
// get existing display areas
let currentPrincipleDiv = document.getElementById("principle");
let currentPrincipalDiv = document.getElementById("principal");
let valueIncreaseDiv = document.getElementById("valueincrease");
let profitFromSellingDiv = document.getElementById("profit");

Expand All @@ -155,8 +155,8 @@ function loadUserMenuAndLots() {
if(data.totalProfitFromSelling < 0) profitFromSellingDiv.style.color = "#FF3200";
else profitFromSellingDiv.style.color = "#24A292";

// display the current principle, total value increase, and total profit from selling
currentPrincipleDiv.innerHTML = dollar.format(data.currentPrinciple);
// display the current principal, total value increase, and total profit from selling
currentPrincipalDiv.innerHTML = dollar.format(data.currentPrincipal);
valueIncreaseDiv.innerHTML = changeInDollars.format(data.totalValueIncrease);
profitFromSellingDiv.innerHTML = changeInDollars.format(data.totalProfitFromSelling);

Expand Down Expand Up @@ -223,10 +223,10 @@ function loadUserMenuAndLots() {
lotDateDiv.innerHTML = lot.buyDate;
headerDiv.appendChild(lotDateDiv);

let lotPrincipleDiv = document.createElement("div");
lotPrincipleDiv.classList.add("lotprinciple");
lotPrincipleDiv.innerHTML = dollar.format(lot.buyPrice * (lot.sharesSold + lot.sharesHolding));
headerDiv.appendChild(lotPrincipleDiv);
let lotPrincipalDiv = document.createElement("div");
lotPrincipalDiv.classList.add("lotprincipal");
lotPrincipalDiv.innerHTML = dollar.format(lot.buyPrice * (lot.sharesSold + lot.sharesHolding));
headerDiv.appendChild(lotPrincipalDiv);

clearDiv = document.createElement("div");
clearDiv.style.clear = "both";
Expand Down
Loading

0 comments on commit da5ca29

Please sign in to comment.