//绝对值转成浮点数 func toFloat64(d decimal.Decimal) float64 { result, ok := d.Float64() if !ok { // TODO } return result }
func (c *Converter) genConvert(value decimal.Decimal, from, to Currency, at *time.Time) (decimal.Decimal, error) { var t time.Time if at == nil { t = time.Now().UTC() } else { t = *at } var usd decimal.Decimal if from == USD { usd = value } else { fromRate, err := c.ex.Get(t, from) if err != nil { return decimal.Zero, err } usd = value.Mul(fromRate.ToUSD) } if to == USD { return usd, nil } toRate, err := c.ex.Get(t, to) if err != nil { return decimal.Zero, err } return usd.Mul(toRate.FromUSD), nil }
//Decode is the inverse operation of Encode. //Decode returns latitude, longitude, and whether or not they are both represented precisely as float64 types. func Decode(bucket int64) (float64, float64, bool) { var latitudeUnshifted, longitudeUnshifted decimal.Decimal var latitude, longitude float64 var err error var exact bool bucketString := strconv.FormatInt(bucket, 10) for len(bucketString) < 18 { bucketString = "0" + bucketString } latString, lonString := unzip(bucketString) latString = latString[0:3] + "." + latString[3:] lonString = lonString[0:3] + "." + lonString[3:] latitudeUnshifted, err = decimal.NewFromString(latString) longitudeUnshifted, err = decimal.NewFromString(lonString) if err != nil { fmt.Errorf("Error creating decimal from string") } latitudeUnshifted = latitudeUnshifted.Sub(decimal.NewFromFloat(90.0)) longitudeUnshifted = longitudeUnshifted.Sub(decimal.NewFromFloat(180.0)) latitude, exact = latitudeUnshifted.Float64() longitude, exact = longitudeUnshifted.Float64() return latitude, longitude, exact }
func DecimalToString(res decimal.Decimal, min int32, max int32) string { if res.Cmp(decimal.New(10, min)) <= 0 || res.Cmp(decimal.New(10, max)) >= 0 { f, _ := res.Float64() return strconv.FormatFloat(f, 'G', -1, 64) } return res.String() }
func (sc *salaryCalculator) Calculate(grossSalary, dependentsQty decimal.Decimal) Salary { inss := sc.inss.Calculate(grossSalary) dependents := sc.depedents.Calculate(dependentsQty) irrfBase := grossSalary.Sub(inss).Sub(dependents) irrf := sc.irrf.Calculate(irrfBase) netSalary := grossSalary.Sub(inss).Sub(irrf) return Salary{ GrossSalary: grossSalary, INSS: inss, Dependents: dependents, IRRF: irrf, NetSalary: netSalary, } }
func (irrf *IRRF) Calculate(grossSalary decimal.Decimal) decimal.Decimal { for _, irrfInterval := range irrf.irrfRange { if grossSalary.Cmp(irrfInterval.Lower) >= 0 && grossSalary.Cmp(irrfInterval.Upper) <= 0 { return grossSalary.Mul(irrfInterval.Aliquot).Sub(irrfInterval.Deduction) } } lastIRRFInterval := irrf.irrfRange[len(irrf.irrfRange)-1] return grossSalary.Mul(lastIRRFInterval.Aliquot).Sub(lastIRRFInterval.Deduction) }
func (ex *CaVirtex) PlaceOrder(mode OrderMode, amount decimal.Decimal, price decimal.Decimal, base, counter string) (status, id string, err error) { textMode := "sell" if mode == ORDER_BUY { textMode = "buy" } resp, err := ex.AuthenticatedPost("order", map[string]string{ "currencypair": fmt.Sprintf("%s%s", base, counter), "mode": textMode, "amount": amount.String(), "price": price.String(), }) if err != nil { return "", "", err } result := struct { Status string Message string ApiRate int Order struct { Status string ID int } }{} cnt, err := ioutil.ReadAll(resp.Body) if err != nil { return "", "", err } err = json.Unmarshal(cnt, &result) if err != nil { return "", "", err } if result.Status != "ok" { return "", "", fmt.Errorf("status=%s: %s", result.Status, result.Message) } return result.Order.Status, fmt.Sprintf("%d", result.Order.ID), nil }
// Use github.com/shopspring/decimal as real-world database/sql custom type // to test against. func TestConnQueryDatabaseSQLDriverValuer(t *testing.T) { t.Parallel() conn := mustConnect(t, *defaultConnConfig) defer closeConn(t, conn) expected, err := decimal.NewFromString("1234.567") if err != nil { t.Fatal(err) } var num decimal.Decimal err = conn.QueryRow("select $1::decimal", expected).Scan(&num) if err != nil { t.Fatalf("Scan failed: %v", err) } if !num.Equals(expected) { t.Errorf("Expected num to be %v, but it was %v", expected, num) } ensureConnValid(t, conn) }
func Quote(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) StockId := vars["symbol"] UserId := vars["id"] TransId := r.Header.Get("X-TransNo") if TransId == "" { TransId = "0" } //Audit UserCommand Guid := getNewGuid() CommandEvent := UserCommandEvent{ EventType: "UserCommandEvent", Guid: Guid.String(), OccuredAt: time.Now(), TransactionId: TransId, UserId: UserId, Service: "Command", Server: "B134", Command: "QUOTE", StockSymbol: StockId, Funds: "", } SendRabbitMessage(CommandEvent, CommandEvent.EventType) //Check Stock Symbol if len(StockId) == 0 || len(StockId) > 3 { writeResponse(w, http.StatusBadRequest, "Symbol is Not Valid") return } //Get Stock Price var strPrice string strPrice, _ = getStockPrice(TransId, "false", UserId, StockId, Guid.String()) //Verify Return Price var price decimal.Decimal price, err := decimal.NewFromString(strPrice) if err != nil { writeResponse(w, http.StatusBadRequest, "Quote Return: "+err.Error()) return } //Success var Output string = "The Quote For UserId " + UserId + " and StockId " + StockId + " returned " + price.String() writeResponse(w, http.StatusOK, Output) }
func (inss *INSS) Calculate(grossSalary decimal.Decimal) decimal.Decimal { for _, inssInterval := range inss.inssRange { if grossSalary.Cmp(inssInterval.Lower) >= 0 && grossSalary.Cmp(inssInterval.Upper) <= 0 { return grossSalary.Mul(inssInterval.Aliquot) } } lastINSSInterval := inss.inssRange[len(inss.inssRange)-1] return lastINSSInterval.Upper.Mul(lastINSSInterval.Aliquot) }
func Sell(w http.ResponseWriter, r *http.Request) { zero, _ := decimal.NewFromString("0") type sell_struct struct { Amount string Symbol string } type return_struct struct { Error bool SaleId int Price string NumShares int64 Expiration time.Duration } vars := mux.Vars(r) UserId := vars["id"] TransId := r.Header.Get("X-TransNo") if TransId == "" { TransId = "0" } //Decode Body decoder := json.NewDecoder(r.Body) var t sell_struct err := decoder.Decode(&t) //Audit UserCommand Guid := getNewGuid() OccuredAt := time.Now() CommandEvent := UserCommandEvent{ EventType: "UserCommandEvent", Guid: Guid.String(), OccuredAt: OccuredAt, TransactionId: TransId, UserId: UserId, Service: "Command", Server: Hostname, Command: "SELL", StockSymbol: t.Symbol, Funds: t.Amount, } SendRabbitMessage(CommandEvent, CommandEvent.EventType) if err != nil { writeResponse(w, http.StatusBadRequest, err.Error()) return } //get User Account Information db, id, found, _ := getDatabaseUserId(UserId) if found == false { writeResponse(w, http.StatusOK, "User Account Does Not Exist") return } //Check amount AmountDec, err := decimal.NewFromString(t.Amount) if err != nil { writeResponse(w, http.StatusBadRequest, err.Error()) return } if AmountDec.Cmp(zero) != 1 { writeResponse(w, http.StatusBadRequest, "Amount to sell is not a valid number") return } //Check Stock Symbol StockId := t.Symbol if len(StockId) == 0 || len(StockId) > 3 { writeResponse(w, http.StatusBadRequest, "Symbol is Not Valid") return } //Get and Verify Quote var strPrice string var strExpiration string strPrice, strExpiration = getStockPrice(TransId, "true", UserId, StockId, Guid.String()) var quotePrice decimal.Decimal quotePrice, err = decimal.NewFromString(strPrice) if err != nil { writeResponse(w, http.StatusBadRequest, err.Error()) return } if quotePrice.Cmp(zero) != 1 { writeResponse(w, http.StatusBadRequest, "Quote is not a valid number") return } //Verify Expiration Time ExpirationTime, err := time.Parse("2006-01-02 15:04:05 -0700 MST", strExpiration) if err != nil { writeResponse(w, http.StatusOK, "Expiration Conversion Error") return } //Calculate Amount to Sell toSell := (AmountDec.Div(quotePrice)).IntPart() if toSell < 1 { writeResponse(w, http.StatusOK, "Can't Sell less than 1 Stock") return } strSell := strconv.Itoa(int(toSell)) //Create Pending Sale var SaleId int rows, err := db.Query(addPendingSale, id, t.Symbol, strSell, strPrice, time.Now(), ExpirationTime) defer rows.Close() if err != nil { writeResponse(w, http.StatusBadRequest, "Add pending Sale; "+err.Error()) return } TimeToExpiration := (ExpirationTime.Sub(time.Now())) / time.Millisecond rows.Next() err = rows.Scan(&SaleId) //Build Response rtnStruct := return_struct{false, SaleId, strPrice, toSell, TimeToExpiration} strRtnStruct, err := json.Marshal(rtnStruct) //success writeResponse(w, http.StatusOK, string(strRtnStruct)) return }
func (a *Account) GetFormattedAmount(amount decimal.Decimal) string { return amount.StringFixed(a.DecimalPlaces) }
func handleConnection(conn net.Conn) { var found bool var QuoteItem QuoteCacheItem if err != nil { // do stuff return } status := make([]byte, 100) _, err = conn.Read(status) if err != nil { // do stuff println("ERROR READ: " + err.Error()) return } status = bytes.Trim(status, "\x00") inputs := strings.Split(string(status), ",") var price decimal.Decimal _, err := strconv.ParseBool(strings.ToLower(inputs[0])) APIUserId := inputs[1] stockSymbol := inputs[2] TransId := "1" GGuid := getNewGuid() Guid := GGuid.String() if len(inputs) > 3 { TransId = inputs[3] Guid = inputs[4] } QuoteItem, found = memCache[stockSymbol] if found { if QuoteItem.Expiration.After(time.Now()) { fmt.Fprintf(conn, string(QuoteItem.Value)+","+QuoteItem.Expiration.String()) conn.Close() hit = hit + 1 return } else { found = false } } miss = miss + 1 if !found { messages := make(chan string) var returned bool = false num_threads := 0 go func() { for returned == false { num_threads = num_threads + 1 go func() { sendString := stockSymbol + "," + APIUserId + "\n" addr, err := net.ResolveTCPAddr("tcp", "quoteserve.seng.uvic.ca:"+quotePort) if err != nil { return } qconn, err := net.DialTCP("tcp", nil, addr) if err != nil { //error println("ERROR qconn: " + err.Error()) return } defer qconn.Close() _, err = fmt.Fprintf(qconn, sendString) if err != nil { failOnError(err, "Error with fprintf") } response := make([]byte, 100) _, err = qconn.Read(response) returned = true messages <- string(response) }() time.Sleep(time.Duration(thread_wait) * time.Millisecond) } }() QuoteReturn := <-messages ParsedQuoteReturn := strings.Split(QuoteReturn, ",") price, err = decimal.NewFromString(ParsedQuoteReturn[0]) if err != nil { //error println("ERROR PARSING") } backoff := 50 + rand.Intn(5) QuoteExpiration := time.Now().Add(time.Duration(backoff) * time.Second) _, err = conn.Write([]byte(price.String() + "," + QuoteExpiration.String())) conn.Close() stockSymbol = ParsedQuoteReturn[1] ReturnUserId := ParsedQuoteReturn[2] msTimeStamp, err := msToTime(ParsedQuoteReturn[3]) if err != nil { //error } cryptoKey := stripCtlAndExtFromUTF8(ParsedQuoteReturn[4]) cryptoKey = strings.TrimSpace(cryptoKey) if ReturnUserId != APIUserId { // system error } QuoteEvent := QuoteServerEvent{ EventType: "QuoteServerEvent", Guid: Guid, OccuredAt: time.Now(), TransactionId: TransId, UserId: APIUserId, Service: "QUOTE", Server: "QuoteCache", Price: price.String(), StockSymbol: stockSymbol, QuoteServerTime: msTimeStamp, Cryptokey: cryptoKey, } SendRabbitMessage(QuoteEvent, QuoteEvent.EventType) tmpQuoteItem := QuoteCacheItem{ Expiration: QuoteExpiration, Value: price.String(), } memCache[stockSymbol] = tmpQuoteItem if err != nil { // system error } for i := 0; i < num_threads-1; i++ { <-messages } close(messages) return } }
func MultiplyDecimalWithoutNew(decimalStartFloat, decimalFactor decimal.Decimal) (calculated decimal.Decimal) { calculated = decimalStartFloat.Mul(decimalFactor) return }
func newton(z, x decimal.Decimal) decimal.Decimal { return z.Sub(z.Mul(z).Sub(x).Div(Const2.Mul(z))) }
func AddDecimalWithoutNew(decimalStartFloat, decimalFactor decimal.Decimal) (calculated decimal.Decimal) { calculated = decimalStartFloat.Add(decimalFactor) return }
func (f fakeCalculator) Calculate(d decimal.Decimal) decimal.Decimal { return d.Mul(rebatePercentage) }
func ConvertToDecimalBinary(f func(float64, float64) float64, a decimal.Decimal, b decimal.Decimal) decimal.Decimal { aFloat, _ := a.Float64() bFloat, _ := b.Float64() return decimal.NewFromFloat(f(aFloat, bFloat)) }
// isPositiveDecimal checks if the decimal is positive func isNegativeDecimal(amount decimal.Decimal) bool { return amount.Cmp(decimal.NewFromFloat(0)) < 0 }
func UpdateSale(w http.ResponseWriter, r *http.Request) { zero, _ := decimal.NewFromString("0") vars := mux.Vars(r) UserId := vars["id"] TransId := vars["PurchaseId"] //get User Account Information db, uid, found, _ := getDatabaseUserId(UserId) if found == false { writeResponse(w, http.StatusOK, "User Account Does Not Exist") return } Guid := getNewGuid() //Find last Sell Command LatestPendingrows, err := db.Query(getLatestPendingSale, uid) defer LatestPendingrows.Close() if err != nil { writeResponse(w, http.StatusOK, "Error Getting Last Sale: "+err.Error()) return } var id string var stock string var num_shares int var share_price string var requested_at time.Time var expires_at time.Time found = false for LatestPendingrows.Next() { found = true err = LatestPendingrows.Scan(&id, &uid, &stock, &num_shares, &share_price, &requested_at, &expires_at) } if found == false { writeResponse(w, http.StatusOK, "No Recent Sell Commands") return } strOldPrice := strings.TrimPrefix(share_price, "$") strOldPrice = strings.Replace(strOldPrice, ",", "", -1) OldPrice, err := decimal.NewFromString(strOldPrice) if err != nil { writeResponse(w, http.StatusBadRequest, err.Error()+strOldPrice) return } //Get and Verify Quote var strPrice string strPrice, _ = getStockPrice(TransId, "true", UserId, stock, Guid.String()) var quotePrice decimal.Decimal quotePrice, err = decimal.NewFromString(strPrice) if err != nil { writeResponse(w, http.StatusBadRequest, err.Error()) return } if quotePrice.Cmp(zero) != 1 { writeResponse(w, http.StatusBadRequest, "Quote is not a valid number") return } totalAmount := decimal.New(int64(num_shares), 0).Mul(OldPrice) newShareNum := totalAmount.Div(quotePrice).IntPart() diffShares := int(newShareNum) - num_shares _, err = db.Exec(updateSale, TransId, int(newShareNum), strPrice, int(diffShares), time.Now().Add(time.Duration(60)*time.Second)) if err != nil { writeResponse(w, http.StatusBadRequest, "Unable to update Sale") return } type return_struct struct { Error bool SaleId string Price string NumShares int64 Expiration time.Duration } //Build Response rtnStruct := return_struct{false, id, strPrice, newShareNum, -1} strRtnStruct, err := json.Marshal(rtnStruct) writeResponse(w, http.StatusOK, string(strRtnStruct)) return }
func Buy(w http.ResponseWriter, r *http.Request) { zero, _ := decimal.NewFromString("0") type buy_struct struct { Amount string Symbol string } type return_struct struct { Error bool SaleId int Price string NumShares int64 Expiration time.Duration } vars := mux.Vars(r) UserId := vars["id"] TransId := r.Header.Get("X-TransNo") if TransId == "" { TransId = "0" } decoder := json.NewDecoder(r.Body) var t buy_struct err := decoder.Decode(&t) //Audit UserCommand Guid := getNewGuid() CommandEvent := UserCommandEvent{ EventType: "UserCommandEvent", Guid: Guid.String(), OccuredAt: time.Now(), TransactionId: TransId, UserId: UserId, Service: "Command", Server: Hostname, Command: "BUY", StockSymbol: t.Symbol, Funds: t.Amount, } SendRabbitMessage(CommandEvent, CommandEvent.EventType) //Decode Request Body if err != nil { writeResponse(w, http.StatusBadRequest, "Request Body Is Invalid") return } //Validate Request Body AmountDec, err := decimal.NewFromString(t.Amount) if err != nil { writeResponse(w, http.StatusBadRequest, "Request Body Is Invalid") return } //Validate amount to buy if AmountDec.Cmp(zero) != 1 { writeResponse(w, http.StatusBadRequest, "Amount to buy is not a valid number") return } StockId := t.Symbol //Validate Stock Symbol if len(StockId) == 0 || len(StockId) > 3 { writeResponse(w, http.StatusBadRequest, "Symbol is Not Valid") return } //Get and Validate Quote var strPrice string var strExpiration string strPrice, strExpiration = getStockPrice(TransId, "true", UserId, StockId, Guid.String()) var quotePrice decimal.Decimal quotePrice, err = decimal.NewFromString(strPrice) if err != nil { writeResponse(w, http.StatusInternalServerError, "Quote Return is not Valid") return } if quotePrice.Cmp(zero) != 1 { writeResponse(w, http.StatusBadRequest, "Amount to buy is not a valid number: "+quotePrice.String()) return } //Verify Expiration Time ExpirationTime, err := time.Parse("2006-01-02 15:04:05 -0700 MST", strExpiration) if err != nil { writeResponse(w, http.StatusOK, "Expiration Conversion Error") return } //Check If User Exists db, uid, found, _ := getDatabaseUserId(UserId) if found == false { writeResponse(w, http.StatusBadRequest, "User Does Not Exist") return } //Calculate Stock To Buy toBuy := (AmountDec.Div(quotePrice)).IntPart() //Validate Buy Amount if toBuy < 1 { writeResponse(w, http.StatusBadRequest, "Cannot Buy less than 1 stock") return } strBuy := strconv.Itoa(int(toBuy)) //Add Pending Purchase for Amount var PurchaseId int rows, err := db.Query(addPendingPurchase, uid, t.Symbol, strBuy, strPrice, time.Now(), ExpirationTime) defer rows.Close() if err != nil { writeResponse(w, http.StatusInternalServerError, "Failed to Create Purchase") return } rows.Next() err = rows.Scan(&PurchaseId) if err != nil { writeResponse(w, http.StatusBadRequest, "Sale Id Request Failed") return } TimeToExpiration := (ExpirationTime.Sub(time.Now())) / time.Millisecond //Build Response rtnStruct := return_struct{false, PurchaseId, strPrice, toBuy, TimeToExpiration} strRtnStruct, err := json.Marshal(rtnStruct) //success writeResponse(w, http.StatusOK, string(strRtnStruct)) return }
func PerformBuyTrigger(w http.ResponseWriter, r *http.Request) { zero, _ := decimal.NewFromString("0") vars := mux.Vars(r) UserId := vars["id"] StockId := vars["symbol"] TransId := r.Header.Get("X-TransNo") if TransId == "" { TransId = "0" } type trigger_struct struct { TriggerId string } decoder := json.NewDecoder(r.Body) var t trigger_struct err := decoder.Decode(&t) if err != nil { } Guid := getNewGuid() //Check If User Exists db, uid, found, _ := getDatabaseUserId(UserId) if !found { //error return } //Get A Quote var strPrice string strPrice, _ = getStockPrice(TransId, "false", UserId, StockId, Guid.String()) var quotePrice decimal.Decimal quotePrice, err = decimal.NewFromString(strPrice) if err != nil { //writeResponse(w, http.StatusInternalServerError, "Quote Return is not Valid") return } if quotePrice.Cmp(zero) != 1 { Error := ErrorEvent{ EventType: "ErrorEvent", Guid: Guid.String(), OccuredAt: time.Now(), TransactionId: TransId, UserId: UserId, Service: "API", Server: Hostname, Command: "ADD", StockSymbol: "", Funds: strPrice, FileName: "", ErrorMessage: "Quote is not greater than 0", } SendRabbitMessage(Error, Error.EventType) //writeResponse(w, http.StatusBadRequest, "Amount to buy is not a valid number") return } //Get Trigger Information rows, err := db.Query(getTriggerById, t.TriggerId) defer rows.Close() if err != nil { //error return } var id int var stock string var trigger_type string var trigger_price string var num_shares int var created_at time.Time found = false for rows.Next() { found = true err = rows.Scan(&id, &uid, &stock, &trigger_type, &trigger_price, &num_shares, &created_at) } if err != nil { //error return } if !found { //error return } trigger_price = strings.Trim(trigger_price, "$") trigger_price = strings.Replace(trigger_price, ",", "", -1) trigger_priceDec, err := decimal.NewFromString(trigger_price) if quotePrice.Cmp(trigger_priceDec) != -1 { //error return } //Commit trigger at price _, err = db.Exec(performBuyTrigger, id, strPrice) if err != nil { //error return } }
func (dep *Dependent) Calculate(quantity decimal.Decimal) decimal.Decimal { return quantity.Mul(dep.deduction) }