Esempio n. 1
0
//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
}
Esempio n. 2
0
func Parse(s string) (time.Duration, error) {

	var d time.Duration
	var p parser

	if s == "0" {
		return d, nil
	}
	if s[len(s)-1] == 's' {
		switch c := s[len(s)-2]; c {
		case 'n': //ns
			p = parsers[0]
		case 'µ': //µs
			p = parsers[1]
		case 'm': //ms
			p = parsers[2]
		default:
			if '0' <= c && c <= '9' { //s
				p = parsers[3]
			} else {
				return d, ErrMalformed
			}
		}
	} else {
		return d, ErrMalformed
	}

	sub := p.re.FindStringSubmatch(s)
	//	fmt.Println(len(sub), sub)
	switch len(sub) {
	case 5:
		i, _ := strconv.Atoi(sub[2])
		d += time.Duration(i) * time.Hour
		i, _ = strconv.Atoi(sub[3])
		d += time.Duration(i) * time.Minute

		f, err := decimal.NewFromString(sub[4])
		if err != nil {
			panic(err)
		}
		f = f.Mul(decimal.New(int64(p.unit), 0))
		d += time.Duration(f.IntPart())
	case 3:
		f, err := decimal.NewFromString(sub[2])
		if err != nil {
			panic(err)
		}
		f = f.Mul(decimal.New(int64(p.unit), 0))
		d += time.Duration(f.IntPart())
	default:
		return d, ErrMalformed
	}

	if sub[1] != "-" {
		return d, nil
	} else {
		return -d, nil
	}
}
Esempio n. 3
0
func AccountsUpdater(c *gin.Context) {
	acc_id, err := strconv.ParseInt(c.Param("accountId"), 10, 64)
	if err != nil {
		log.Fatal(err)
	}

	trans_id, err := strconv.ParseInt(c.PostForm("ID"), 10, 64)
	if err != nil {
		log.Printf("Invalid ID: %v - %v\n", trans_id, err)
		return
	}

	var account *Account
	for _, acc := range accounts {
		if acc.ID == acc_id {
			account = acc
			break
		}
	}

	var transaction Transaction
	for _, trans := range account.Transactions {
		if trans.ID == trans_id {
			transaction = trans
		}
	}

	transaction.Payee = c.PostForm("Payee")
	transaction.Memo = c.PostForm("Memo")
	debit, err := decimal.NewFromString(c.PostForm("Debit"))
	if err != nil {
		log.Printf("Invalid Debit %v\n", err)
	} else {
		transaction.Debit = debit
	}
	credit, err := decimal.NewFromString(c.PostForm("Credit"))
	if err != nil {
		log.Printf("Invalid Credit %v\n", err)
	} else {
		transaction.Credit = credit
	}

	for trans_key, trans := range account.Transactions {
		if trans.ID == trans_id {
			account.Transactions[trans_key] = transaction

			jsonResponse, err := json.Marshal(transaction)
			if err != nil {
				log.Printf("Json marshaling error: %v\n", err)
				return
			}
			c.JSON(http.StatusOK, jsonResponse)
		}
	}
}
Esempio n. 4
0
func Money(value interface{}, code string) (MoneyObject, error) {
	currency, found := CurrencyTypes[code]
	if !found {
		return MoneyObject{}, errors.New("Code not found.")
	}

	var money decimal.Decimal
	var moneyObject MoneyObject

	switch v := value.(type) {
	case string:
		m, err := decimal.NewFromString(v)
		if err != nil {
			return MoneyObject{}, err
		}
		money = m
	case float32:
		money = decimal.NewFromFloat(float64(v))
	case float64:
		money = decimal.NewFromFloat(v)
	case int:
		money = decimal.NewFromFloat(float64(v))
	default:
		return MoneyObject{}, errors.New("Value could not be translated.")
	}

	moneyObject.money = money
	moneyObject.currency = currency

	return moneyObject, nil
}
Esempio n. 5
0
func parseDecimal(lit string) (decimal.Decimal, error) {
	f, err := decimal.NewFromString(lit)
	if err != nil {
		return decimal.Zero, errors.New("Cannot parse recognized decimal: " + lit)
	}
	return f, nil
}
Esempio n. 6
0
func StringToDecimal(str string) decimal.Decimal {
	d, err := decimal.NewFromString(str)
	if err != nil {
		panic(err)
	}
	return d
}
Esempio n. 7
0
func TestTransactions(t *testing.T) {

	a := &Account{IsActive: true, CurrencyCode: "AUD"}

	credit10, _ := decimal.NewFromString("10.0")
	debit, _ := decimal.NewFromString("0.0")

	trans := Transaction{
		Credit:    credit10,
		Debit:     debit,
		IsCleared: true,
	}

	a.AddTransaction(trans)

	total := a.GetTotal()

	if total.String() != credit10.String() {
		t.Errorf("Total not right, expected %v got %v", credit10, a.GetTotal())
	}
	if a.GetClearedTotal().String() != credit10.String() {
		t.Error("Cleared Total not right")
	}

	credit, _ := decimal.NewFromString("0.0")
	debit, _ = decimal.NewFromString("5.0")

	trans.Credit = credit
	trans.Debit = debit
	trans.IsCleared = false
	a.AddTransaction(trans)

	if a.GetTotal().String() != debit.String() {
		t.Error("Total not right")
	}

	if a.GetClearedTotal().String() != credit10.String() {
		t.Error("Cleared total not right")
	}

	tr := a.GetTransactions()

	if len(tr) != 2 {
		t.Error("Number of transactions not right")
	}
	// log.Printf("%v\n", tr)
}
Esempio n. 8
0
func queryDecimal(fieldName string) decimal.Decimal {
	val, err := decimal.NewFromString(queryString(fieldName))
	if err != nil {
		panic(err)
	}

	return val
}
Esempio n. 9
0
// NewNum initializes a Num from a BasicLit. Kind will hold the unit
// the number portion is always treated as a float.
func NewNum(lit *ast.BasicLit) (*Num, error) {
	val := lit.Value
	// TODO: scanner should remove unit
	kind := lit.Kind
	val = strings.TrimSuffix(lit.Value, token.Tokens[kind])
	dec, err := decimal.NewFromString(val)
	return &Num{dec: dec, Unit: unitLookup(kind)}, err
}
Esempio n. 10
0
func (a *Account) ImportTransactions(r io.Reader) {

	csvr := csv.NewReader(r)
	csvr.LazyQuotes = true
	csvr.TrimLeadingSpace = true

	records, err := csvr.ReadAll()
	if err != nil {
		log.Println(err)
	}

	for k, record := range records {
		if k == 0 {
			continue
		}

		transDate, err := time.Parse("02/01/2006", record[1])
		if err != nil {
			log.Println(err)
		}

		cleared := true
		reconciled := false

		credit, err := decimal.NewFromString(record[4])
		if err != nil {
			log.Print(err)
		}
		debit, err := decimal.NewFromString(record[3])
		if err != nil {
			log.Print(err)
		}

		trans := Transaction{
			Credit:       credit,
			Debit:        debit,
			IsCleared:    cleared,
			IsReconciled: reconciled,
			Payee:        record[2],
			Date:         transDate,
		}
		a.AddTransaction(trans)
	}
}
Esempio n. 11
0
func TestCurrencyDivisionByZero(t *testing.T) {
	fromUSD, err := decimal.NewFromString("0")

	if err != nil {
		t.Fatal(err)
	}

	f, _ := fromUSD.Float64()

	if f != 0 {
		oneD.Div(fromUSD)
	}
}
Esempio n. 12
0
func (ex *Exchange) normalizeCurrencyData(yahooData *yahooCurrencyResponse) (map[Currency]ExchangeRate, error) {
	data := make(map[Currency]ExchangeRate)

	for _, res := range yahooData.List.Resources {
		sym := res.Resource.Fields.Symbol

		// exp EUR=X
		if len(sym) != 5 {
			return nil, ErrCurrencyLength
		}

		cur, err := ParseCurrency(sym[:3])

		if err != nil {
			if err == ErrCurrencyUnknown {
				continue
			}
			return nil, err
		}

		price := res.Resource.Fields.Price

		// extra check
		f, err := strconv.ParseFloat(price, 64)

		if err != nil {
			return nil, err
		}

		isZero := f == 0
		fromUSD, err := decimal.NewFromString(price)

		if err != nil {
			return nil, err
		}

		toUSD := fromUSD

		if !isZero {
			toUSD = oneD.Div(fromUSD)
		}

		toUSD = oneD.Div(fromUSD)
		data[cur] = ExchangeRate{
			FromUSD: fromUSD,
			ToUSD:   toUSD,
		}
	}

	return data, nil
}
Esempio n. 13
0
func NewTSPCoord(id string, origLat string, origLon string, mode string) (*TSPCoord, error) {
	intId, err := strconv.Atoi(id)
	if err != nil {
		return nil, err
	}
	decimalLat, err := decimal.NewFromString(origLat)
	if err != nil {
		return nil, err
	}
	decimalLon, err := decimal.NewFromString(origLon)
	if err != nil {
		return nil, err
	}
	tspCoord := &TSPCoord{Id: intId, OrigLat: origLat, OrigLon: origLon,
		Coord:      NewCoord(decimalLat, decimalLon),
		Duplicates: NewTSPCoordList(), CostTable: NewCostTable()}
	switch {
	case mode == "EUC_2D":
		tspCoord.fromEUC2D()
	}
	tspCoord.CoordHash = fmt.Sprintf("%s_%s", origLat, origLon)
	return tspCoord, nil
}
Esempio n. 14
0
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)
}
Esempio n. 15
0
func main() {

	account := bank.CreateAccount(1)
	account.Deposit(decimal.NewFromFloat(1000.50))

	reader := bufio.NewReader(os.Stdin)

	fmt.Println("Welcome to the Go ATM service!\n")

	for {

		fmt.Println("1. View current balance.")
		fmt.Println("2. Withdraw.")
		fmt.Println("3. Exit.")

		actionStr, _ := reader.ReadString('\n')
		action, _ := strconv.ParseInt(strings.TrimSpace(actionStr), 10, 32)

		switch action {
		case 1:
			fmt.Println(account.GetBalance().String())
		case 2:
			fmt.Println("\nWithdraw amount:")
			amountStr, _ := reader.ReadString('\n')
			amount, _ := decimal.NewFromString(strings.TrimSpace(amountStr))

			_, err := account.Withdraw(amount)

			if err != nil {
				fmt.Println(err)
			}

		case 3:
			os.Exit(0)
		}

	}

}
Esempio n. 16
0
// 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)
}
Esempio n. 17
0
func (s *SlackSession) handleMessage(User string, Channel string, msg *slack.Msg) {
	tx, err := s.Db.Begin()
	if err != nil {
		goto fail
	}
	defer tx.Rollback()

	// Check user type; ignore bots
	{
		if msg.SubType == "bot_message" {
			return
		}
		var is_bot bool
		if err = tx.QueryRow("select user_is_bot from users where user_id = $1 and team_id = $2",
			User, s.TeamID).Scan(&is_bot); err != nil {
			s.log.WithError(err).Warn("Failed to read row")
			goto fail
		}
		if is_bot {
			s.log.Debug("Ignoring message; from bot")
			return
		}
	}

	if match := rxProposal.FindStringSubmatch(msg.Text); match != nil {
		s.log.WithField("matchgroups", fmt.Sprintf("%#v", match)).Info("Saw proposal")
		topic := match[1]
		comment := match[2]

		_, err = tx.Exec(
			"INSERT INTO topics (team_id, topic_channel, topic_name, topic_comment) "+
				"VALUES ($1, $2, $3, nullif($4,''))",
			s.TeamID, Channel, topic, comment)
		if err != nil {
			// TODO: report error in channel
			s.log.WithError(err).Info("Failed to insert proposal")
			goto fail
		}
		pmp := slack.NewPostMessageParameters()
		pmp.AsUser = true
		//pmp.Username = s.rtm.GetInfo().User.Name
		_, _, err = s.rtm.PostMessage(Channel, fmt.Sprintf("Voting is now open on %s", topic), pmp)
		if err != nil {
			log.WithError(err).Info("Failed to post voting open message")
		}

	} else if match := rxVote.FindStringSubmatch(msg.Text); match != nil {
		var value decimal.Decimal
		topic := match[2]
		log := s.log.WithFields(log.Fields{
			"topic":    topic,
			"user":     User,
			"channel":  msg.Channel,
			"user_msg": msg.Text,
		})
		if value, err = decimal.NewFromString(match[1]); err != nil {
			log.WithError(err).Info("Failed to parse vote value")
			return
		}
		comment := match[3]

		_, err = tx.Exec(
			"INSERT INTO votes (team_id, topic_name, user_id, vote_value, vote_comment) "+
				"VALUES ($1, $2, $3, $4, nullif($5, '')) "+
				"ON CONFLICT (topic_name, team_id, user_id) "+
				"DO UPDATE SET (vote_value, vote_comment) = ($4, nullif($5, ''))",
			s.TeamID, topic, User, value, comment)
		if err != nil {
			log.WithError(err).Info("Failed to insert vote")
		}
		log.WithField("matchgroups", fmt.Sprintf("%#v", match)).Info("Saw vote")
	} else if match := s.rxAtMessage.FindStringSubmatch(msg.Text); match != nil {
		args, err := shlex.Split(match[1], true)
		pmp := slack.NewPostMessageParameters()
		pmp.AsUser = true
		pmp.EscapeText = false
		user_pfx := fmt.Sprintf("<@%s>: ", msg.User)
		if err != nil || len(args) < 1 {
			s.rtm.PostMessage(Channel, user_pfx+" Syntax error: %s"+err.Error(), pmp)
			return
		}
		switch strings.ToLower(args[0]) {
		case "howdy":
			s.rtm.PostMessage(Channel, user_pfx+" Howdy neighbor!", pmp)
		case "status":
			if len(args) < 2 {
				topics := []map[string]interface{}{}
				rows, err := tx.Query(
					"SELECT topic_name, COALESCE(topic_comment, ''), COUNT(user_id), SUM(vote_value) "+
						"FROM topics NATURAL LEFT JOIN (votes NATURAL JOIN users) "+
						"WHERE topic_open AND team_id = $1 AND topic_channel = $2 "+
						"GROUP BY topic_name, topic_channel, team_id, topic_comment",
					s.TeamID, Channel)
				if err != nil {
					log.WithError(err).Error("Failed to query topics")
					return
				}
				for rows.Next() {
					var (
						name, comment string
						count         int
						sum           decimal.Decimal
					)
					rows.Scan(&name, &comment, &count, &sum)
					topics = append(topics, map[string]interface{}{
						"name":    name,
						"comment": comment,
						"nvotes":  count,
						"total":   sum,
					})
				}
				buffer := &bytes.Buffer{}
				topicSummary.Execute(buffer, topics)
				s.rtm.PostMessage(Channel, buffer.String(), pmp)
			}

		default:
			s.rtm.PostMessage(Channel, fmt.Sprintf("%s You seem confused; you said `%#v`", user_pfx, args), pmp)
		}
	}
	tx.Commit()
	return
fail:
}

/* Sample message
var foo = &slack.MessageEvent{Msg: slack.Msg{
	Type:      "message",
	Channel:   "C0KGNAP7A",
	User:      "******",
	Text:      "More testage",
	Timestamp: "1454444512.000011",
	IsStarred: false, PinnedTo: []string(nil),
	Attachments: []slack.Attachment(nil), Edited: (*slack.Edited)(nil),
	SubType: "", Hidden: false,
	DeletedTimestamp: "",
	EventTimestamp:   "", BotID: "", Username: "", Icons: (*slack.Icon)(nil),
	Inviter: "", Topic: "", Purpose: "", Name: "", OldName: "", Members: []string(nil),
	File: (*slack.File)(nil), Upload: false, Comment: (*slack.Comment)(nil),
	ItemType: "", ReplyTo: 0, Team: "T06RWKEF3"}}
*/

func (s *SlackSession) updateUser(user slack.User) {
	tx, err := s.Db.Begin()
	if err != nil {
		goto fail
	}
	defer tx.Rollback()
	if _, err = tx.Exec(
		"INSERT INTO users (team_id, user_id, user_name, user_is_bot) VALUES ($3, $2, $1, $4) "+
			"ON CONFLICT (team_id, user_id) DO UPDATE SET (user_name, user_is_bot) = ($1, $4)",
		user.Name, user.ID, s.TeamID, user.IsBot); err != nil {

		goto fail
	}
	if err = tx.Commit(); err != nil {
		goto fail
	}
	return

fail:
	if err != nil {
		s.log.WithError(err).WithField("user", user.ID).Error("Failed to refresh user in db")
	}

}

func (s *SlackSession) updateTeam(team *slack.Team) {
	tx, err := s.Db.Begin()
	if err != nil {
		goto fail
	}
	defer tx.Rollback()
	if _, err = tx.Exec("UPDATE teams SET (team_name) = ($1) WHERE team_id = $2", team.Name, team.ID); err != nil {
		goto fail
	}
	if err = tx.Commit(); err != nil {
		goto fail
	}
	return

fail:
	if err != nil {
		s.log.WithError(err).Error("Failed to refresh team in db")
	}

}
Esempio n. 18
0
// ParseAmount parses `in` into an Amount value
func ParseAmount(in string) (ret Amount, err error) {
	dec, err := decimal.NewFromString(in)
	ret = Amount{dec}
	return
}
Esempio n. 19
0
func init() {
	Const1K, _ = decimal.NewFromString("1000")
	ConstNegative1K, _ = decimal.NewFromString("-1000")
}
Esempio n. 20
0
// DecodeDecimal decodes a transit big decimal into decimal.Decimal.
func DecodeDecimal(d Decoder, x interface{}) (interface{}, error) {
	s := x.(string)
	return decimal.NewFromString((s))
}
Esempio n. 21
0
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
	}
}
Esempio n. 22
0
// ConvertStringAt converts the decimal value (represented as a string) to the
// given currency using the exchange rate from the date specificied.
func (c *Converter) ConvertStringAt(value string, from, to Currency, at time.Time) (decimal.Decimal, error) {
	v, _ := decimal.NewFromString(value)
	return c.genConvert(v, from, to, &at)
}
Esempio n. 23
0
// ConvertString converts the decimal value (represented as a string) to the
// given currency.
func (c *Converter) ConvertString(value string, from, to Currency) (decimal.Decimal, error) {
	v, _ := decimal.NewFromString(value)
	return c.genConvert(v, from, to, nil)
}
Esempio n. 24
0
func Add(w http.ResponseWriter, r *http.Request) {
	zero, _ := decimal.NewFromString("0")

	type add_struct struct {
		Amount string
	}

	type return_struct struct {
		Error  bool
		Amount string
		UserId string
	}
	vars := mux.Vars(r)
	UserId := vars["id"]
	TransId := r.Header.Get("X-TransNo")
	if TransId == "" {
		TransId = "0"
	}
	decoder := json.NewDecoder(r.Body)
	var t add_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:       "ADD",
		StockSymbol:   "",
		Funds:         t.Amount,
	}
	SendRabbitMessage(CommandEvent, CommandEvent.EventType)
	if err != nil {
		writeResponse(w, http.StatusBadRequest, err.Error())
		return
	}

	AmountDec, err := decimal.NewFromString(t.Amount)
	if err != nil {
		writeResponse(w, http.StatusBadRequest, err.Error())
		return
	}

	//Get user id from Database
	db := getDatabasePointerForUser(UserId)

	//Amount to add is invalid
	if AmountDec.Cmp(zero) != 1 {
		writeResponse(w, http.StatusBadRequest, "Amount to add is not a valid number")
		return
	}

	_, err = db.Exec(addOrCreateUser, UserId, t.Amount, time.Now())
	//Failed to Create Account
	if err != nil {
		writeResponse(w, http.StatusBadRequest, err.Error())
		return
	}

	//Build Response
	rtnStruct := return_struct{false, t.Amount, UserId}
	strRtnStruct, err := json.Marshal(rtnStruct)

	//Success
	writeResponse(w, http.StatusOK, string(strRtnStruct))
	return
}
Esempio n. 25
0
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
}
Esempio n. 26
0
func CreateSellTrigger(w http.ResponseWriter, r *http.Request) {
	type trigger_struct struct {
		Amount string
		Price  string
	}

	vars := mux.Vars(r)
	UserId := vars["id"]
	Symbol := vars["symbol"]
	TransId := r.Header.Get("X-TransNo")
	if TransId == "" {
		TransId = "0"
	}

	decoder := json.NewDecoder(r.Body)
	var t trigger_struct
	err := decoder.Decode(&t)

	//Audit UserCommand
	Guid := getNewGuid()
	OccuredAt := time.Now()

	if t.Amount == "" && t.Price == "" {
		CommandEvent := UserCommandEvent{
			EventType:     "UserCommandEvent",
			Guid:          Guid.String(),
			OccuredAt:     OccuredAt,
			TransactionId: TransId,
			UserId:        UserId,
			Service:       "Command",
			Server:        Hostname,
			Command:       "SET_BUY_AMOUNT",
			StockSymbol:   Symbol,
			Funds:         "",
		}
		SendRabbitMessage(CommandEvent, CommandEvent.EventType)
		writeResponse(w, http.StatusBadRequest, "Invalid Request Body")
		return
	}

	if t.Amount != "" {
		CommandEvent := UserCommandEvent{
			EventType:     "UserCommandEvent",
			Guid:          Guid.String(),
			OccuredAt:     OccuredAt,
			TransactionId: TransId,
			UserId:        UserId,
			Service:       "Command",
			Server:        Hostname,
			Command:       "SET_SELL_AMOUNT",
			StockSymbol:   Symbol,
			Funds:         "",
		}
		SendRabbitMessage(CommandEvent, CommandEvent.EventType)

		if err != nil {
			writeResponse(w, http.StatusBadRequest, "Invalid Request Body")
			return
		}

		db, uid, found, _ := getDatabaseUserId(UserId)
		if !found {
			writeResponse(w, http.StatusBadRequest, "User Account Does Not Exist")
			return
		}

		_, err := decimal.NewFromString(t.Amount)
		if err != nil {
			writeResponse(w, http.StatusBadRequest, "Amount Is Not A Valid Number")
			return
		}

		_, err = db.Exec(addSellTrigger, uid, Symbol, t.Amount, time.Now())
		if err != nil {
			writeResponse(w, http.StatusBadRequest, "addSellTrigger: "+err.Error())
			return
		}

		//success
		writeResponse(w, http.StatusOK, "Sell Trigger Created")
		return
	} else {
		CommandEvent := UserCommandEvent{
			EventType:     "UserCommandEvent",
			Guid:          Guid.String(),
			OccuredAt:     OccuredAt,
			TransactionId: TransId,
			UserId:        UserId,
			Service:       "Command",
			Server:        Hostname,
			Command:       "SET_SELL_TRIGGER",
			StockSymbol:   Symbol,
			Funds:         "",
		}
		SendRabbitMessage(CommandEvent, CommandEvent.EventType)

		if err != nil {
			writeResponse(w, http.StatusBadRequest, "Invalid Request Body")
			return
		}

		db, uid, found, _ := getDatabaseUserId(UserId)
		if !found {
			writeResponse(w, http.StatusBadRequest, "User Account Not Found")
			return
		}

		_, err := decimal.NewFromString(t.Price)
		if err != nil {
			writeResponse(w, http.StatusBadRequest, "Price Is Not A Valid Number")
			return
		}

		getPendingTriggerRows, err := db.Query(getPendingTriggerId, uid, Symbol, "sell")
		defer getPendingTriggerRows.Close()
		if err != nil {
			writeResponse(w, http.StatusBadRequest, "getPendingTriggerId: "+err.Error())
			return
		}

		var id int
		found = false
		for getPendingTriggerRows.Next() {
			found = true
			err = getPendingTriggerRows.Scan(&id)
		}
		if found == false {
			writeResponse(w, http.StatusBadRequest, "No recent SET_SELL_AMOUNT commands Issued")
			return
		}

		_, err = db.Exec(setSellTrigger, id, uid, t.Price, time.Now())
		if err != nil {
			writeResponse(w, http.StatusBadRequest, "setSellTrigger: "+err.Error())
			return
		}

		//Send Trigger Message
		Trigger := TriggerEvent{
			TriggerType:   "sell",
			UserId:        UserId,
			TransactionId: TransId,
			UpdatedAt:     time.Now(),
		}
		SendRabbitMessage(Trigger, "sell")

		//success
		writeResponse(w, http.StatusOK, "Sell Trigger Set")
		return
	}
}
Esempio n. 27
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
}
Esempio n. 28
0
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
}
Esempio n. 29
0
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
	}
}
Esempio n. 30
0
func (d *FIXDecimal) Read(bytes []byte) (err error) {
	d.Decimal, err = decimal.NewFromString(string(bytes))
	return
}