Skip to content

Commit

Permalink
[Fix] : Add min networth for short sell and fix email id (#355)
Browse files Browse the repository at this point in the history
* [Fix] : Add min actual for short sell and fix email id

* [Fix] : Remove password log in register and login

* Update submodule

* Reset go.sum file

* Fix unlock stock
  • Loading branch information
PranavShriram authored Apr 2, 2021
1 parent 65a3642 commit a0a25fe
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 14 deletions.
2 changes: 1 addition & 1 deletion frontend
2 changes: 1 addition & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -217,4 +217,4 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
2 changes: 1 addition & 1 deletion models/PasswordReset.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func PasswordReset(email string) (string, error) {
%s`, templates.HtmlPasswordResetTemplateHead, tempPass, templates.HtmlPasswordResetTemplateTail)
plainContent := fmt.Sprintf(templates.PlainPasswordResetTemplate, tempPass)

err = utils.SendEmail("noreply@dalalstreet.com", "Password Reset", email, plainContent, htmlContent)
err = utils.SendEmail("noreply@dalal.pragyan.org", "Password Reset", email, plainContent, htmlContent)

if err != nil {
l.Errorf("Error while sending password reset email to player %s", err)
Expand Down
2 changes: 1 addition & 1 deletion models/Registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func ResendVerificationEmail(email string) error {
%s
%s`, templates.HtmlEmailVerificationTemplateHead, verificationURL, templates.HtmlEmailVerificationTemplateTail)
plainContent := fmt.Sprintf(templates.PlainEmailVerificationTemplate, verificationURL)
if err := utils.SendEmail("noreply@dalalstreet.com", "Account Verification", email, plainContent, htmlContent); err != nil {
if err := utils.SendEmail("noreply@dalal.pragyan.org", "Account Verification", email, plainContent, htmlContent); err != nil {
l.Errorf("Error while sending verification email to player %s", err)
return err
}
Expand Down
74 changes: 66 additions & 8 deletions models/User.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ func Login(email, password string) (User, error) {
var l = logger.WithFields(logrus.Fields{
"method": "Login",
"param_email": email,
"param_password": password,
})

l.Infof("Attempting to login user")
Expand Down Expand Up @@ -219,7 +218,6 @@ func RegisterUser(email, password, fullName, referralCode string) error {
var l = logger.WithFields(logrus.Fields{
"method": "Register",
"param_email": email,
"param_password": password,
})
l.Debugf("Attempting to register user")

Expand Down Expand Up @@ -293,7 +291,7 @@ func RegisterUser(email, password, fullName, referralCode string) error {
%s
%s`, templates.HtmlEmailVerificationTemplateHead, verificationURL, templates.HtmlEmailVerificationTemplateTail)
plainContent := fmt.Sprintf(templates.PlainEmailVerificationTemplate, verificationURL)
err = utils.SendEmail("noreply@dalalstreet.com", "Account Verification", email, plainContent, htmlContent)
err = utils.SendEmail("noreply@dalal.pragyan.org", "Account Verification", email, plainContent, htmlContent)
if err != nil {
l.Errorf("Error while sending verification email to player %s", err)
return err
Expand Down Expand Up @@ -423,7 +421,6 @@ func postLoginToPragyan(email, password string) (pragyanUser, error) {
var l = logger.WithFields(logrus.Fields{
"method": "postLoginToPragyan",
"param_email": email,
"param_name": password,
})

form := url.Values{
Expand Down Expand Up @@ -607,6 +604,18 @@ func (e NotEnoughStocksError) Error() string {
return fmt.Sprintf("Not have enough stocks to place this order. Current maximum Ask size: %d stocks", e.currentAllowedQty)
}

// NotEnoughActualWorth is generated when an Ask's StockQuantity is such that
// deducting those many stocks will mean that with the current stock worth
// multiplied by number of stocks being short sold is more than the cash in
// hand and stock worth of the user
type NotEnoughActualWorthError struct {
actualWorth int64
}

func (e NotEnoughActualWorthError) Error() string {
return fmt.Sprintf("Not have actual networh to place this order. Cash in hand plus stock worth should be atleast: %d", e.actualWorth)
}

// NotEnoughCashError is generated when a Bid's StockQuantity*Price is such that
// deducting so much cash from the user will leave him with less than
// MINIMUM_CASH_LIMIT
Expand Down Expand Up @@ -964,22 +973,71 @@ func PlaceAskOrder(userId uint32, ask *Ask) (uint32, error) {
}

l.Debugf("Check2: Passed.")



var shortSellMin = numStocksLeft*int64(ask.Price)
var stockWorth int64 = 0

db := getDB()

sql := "Select stockId, sum(stockQuantity) as stockQuantity from Transactions where userId=? group by stockId"
rows, err := db.Raw(sql, userId).Rows()
if err != nil {
l.Error(err)
return 0, err
}
defer rows.Close()

stocksOwned := make(map[uint32]int64)
for rows.Next() {
var stockId uint32
var stockQty int64
rows.Scan(&stockId, &stockQty)

stocksOwned[stockId] = stockQty
}


// Find Stock worth of user
for id, number := range stocksOwned{
allStocks.m[id].RLock()
stockWorth = stockWorth + int64(allStocks.m[id].stock.CurrentPrice)*number
allStocks.m[id].RUnlock()
}

//Actual worth of user includes only
//Stock worth and cash
//Does not include reserved cash and stocks
var actualWorth = int64(user.Cash) + stockWorth

l.Debugf("Check3: Current stocks: %d. Stocks after trade: %d. User Actual Worth(Cash in hand + Stock Worth) %d", numStocks, numStocksLeft, user.Total)

//Check if networth of user is more than the number of stocks
//which are short sold
if numStocksLeft < 0 && -(actualWorth) > shortSellMin {
l.Debugf("Check3: Failed. Not enough actual worth to short sell.")
return 0, NotEnoughActualWorthError{-shortSellMin}
}

l.Debugf("Check3: Passed.")

orderPrice := getOrderFeePrice(ask.Price, ask.StockId, ask.OrderType)
orderFee := getOrderFee(ask.StockQuantity, orderPrice)
cashLeft := int64(user.Cash) - int64(orderFee)

l.Debugf("Check3: User has %d cash currently. Will be left with %d cash after trade.", user.Cash, cashLeft)
l.Debugf("Check4: User has %d cash currently. Will be left with %d cash after trade.", user.Cash, cashLeft)

if cashLeft < MINIMUM_CASH_LIMIT {
l.Debugf("Check3: Failed. Not enough cash.")
l.Debugf("Check4: Failed. Not enough cash.")
return 0, NotEnoughCashError{}
}

l.Debugf("Check3: Passed. Creating Ask.")
l.Debugf("Check4: Passed. Creating Ask.")

oldCash := user.Cash

db := getDB()
db = getDB()
tx := db.Begin()

var errorHelper = func(format string, args ...interface{}) (uint32, error) {
Expand Down
4 changes: 2 additions & 2 deletions models/User_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ func Test_PlaceAskOrder(t *testing.T) {

transactions := []*Transaction{
makeTrans(2, 1, FromExchangeTransaction, 0, 10, 200, 0, 2000),
makeTrans(2, 1, FromExchangeTransaction, 0, -10, 200, 0, 2000),
makeTrans(2, 1, FromExchangeTransaction, 0, -10, 200, 0, 2000),
makeTrans(2, 1, FromExchangeTransaction, 0, 10, 200, 0, 2000),
makeTrans(2, 1, FromExchangeTransaction, 0, 10, 200, 0, 2000),
}

testcases := []struct {
Expand Down

0 comments on commit a0a25fe

Please sign in to comment.