예제 #1
0
파일: e_data.go 프로젝트: dzyk/dcoin-go
func (c *Controller) EData() (string, error) {

	c.w.Header().Set("Access-Control-Allow-Origin", "*")

	// сколько всего продается DC
	eOrders, err := c.GetAll(`SELECT sell_currency_id, sum(amount) as amount FROM e_orders  WHERE sell_currency_id < 1000 AND empty_time = 0 GROUP BY sell_currency_id`, 100)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	values := ""
	for _, data := range eOrders {
		values += utils.ClearNull(data["amount"], 0) + ` d` + c.CurrencyList[utils.StrToInt64(data["sell_currency_id"])] + `, `
	}
	if len(values) > 0 {
		values = values[:len(values)-2]
	}
	ps, err := c.Single(`SELECT value FROM e_config WHERE name = 'ps'`).String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	jsonData, err := json.Marshal(map[string]string{"values": values, "ps": ps})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return string(jsonData), nil

}
예제 #2
0
파일: e_withdraw.go 프로젝트: dzyk/dcoin-go
func (c *Controller) EWithdraw() (string, error) {

	if c.SessUserId == 0 {
		return "", errors.New(c.Lang["sign_up_please"])
	}

	c.r.ParseForm()
	currencyId := utils.StrToInt64(c.r.FormValue("currency_id"))
	if !utils.CheckInputData(c.r.FormValue("amount"), "amount") {
		return "", fmt.Errorf("incorrect amount")
	}
	method := c.r.FormValue("method")
	if !utils.CheckInputData(method, "method") {
		return "", fmt.Errorf("incorrect method")
	}
	account := c.r.FormValue("account")
	if !utils.CheckInputData(account, "account") {
		return "", fmt.Errorf("incorrect account")
	}
	amount := utils.StrToFloat64(c.r.FormValue("amount"))

	curTime := utils.Time()

	// нужно проверить, есть ли нужная сумма на счету юзера
	userAmount := utils.EUserAmountAndProfit(c.SessUserId, currencyId)
	if userAmount < amount {
		return "", fmt.Errorf("%s (%f<%f)", c.Lang["not_enough_money"], userAmount, amount)
	}
	if method != "Dcoin" && currencyId < 1000 {
		return "", fmt.Errorf("incorrect method")
	}

	err := userLock(c.SessUserId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	err = c.ExecSql(`UPDATE e_wallets SET amount = ?, last_update = ? WHERE user_id = ? AND currency_id = ?`, userAmount-amount, curTime, c.SessUserId, currencyId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	var commission float64
	if method == "Dcoin" {
		commission = utils.StrToFloat64(c.EConfig["dc_commission"])
	} else if method == "Perfect-money" {
		commission = utils.StrToFloat64(c.EConfig["pm_commission"])
	}
	wdAmount := utils.ClearNull(utils.Float64ToStr(amount*(1-commission/100)), 2)

	err = c.ExecSql(`INSERT INTO e_withdraw (open_time, user_id, currency_id, account, amount, wd_amount, method) VALUES (?, ?, ?, ?, ?, ?, ?)`, curTime, c.SessUserId, currencyId, account, amount, wdAmount, method)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	userUnlock(c.SessUserId)

	return utils.JsonAnswer(c.Lang["request_is_created"], "success").String(), nil
}
예제 #3
0
파일: index_e.go 프로젝트: dzyk/dcoin-go
func (c *Controller) getMyWallets() ([]map[string]string, error) {
	var myWallets []map[string]string
	eCurrency, err := c.GetAll(`SELECT name as currency_name, id FROM e_currency ORDER BY sort_id ASC`, -1)
	if err != nil {
		return myWallets, utils.ErrInfo(err)
	}
	for _, data := range eCurrency {
		wallet, err := c.OneRow("SELECT * FROM e_wallets WHERE user_id  =  ? AND currency_id  =  ?", c.SessUserId, data["id"]).String()
		if err != nil {
			return myWallets, utils.ErrInfo(err)
		}
		if len(wallet) > 0 {
			amount := utils.StrToFloat64(wallet["amount"])
			profit, err := utils.DB.CalcProfitGen(utils.StrToInt64(wallet["currency_id"]), amount, 0, utils.StrToInt64(wallet["last_update"]), utils.Time(), "wallet")
			if err != nil {
				return myWallets, utils.ErrInfo(err)
			}
			myWallets = append(myWallets, map[string]string{"amount": utils.ClearNull(utils.Float64ToStr(amount+profit), 2), "currency_name": data["currency_name"], "last_update": wallet["last_update"]})
		}
	}

	return myWallets, nil
}
예제 #4
0
파일: e_main.go 프로젝트: dzyk/dcoin-go
func (c *Controller) EMain() (string, error) {

	var err error

	dcCurrencyId := utils.StrToInt64(c.Parameters["dc_currency_id"])
	currencyId := utils.StrToInt64(c.Parameters["currency_id"])
	if dcCurrencyId == 0 {
		dcCurrencyId = 72
	}
	if currencyId == 0 {
		currencyId = 1001
	}

	// все валюты, с которыми работаем
	currencyList, err := utils.EGetCurrencyList()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	log.Debug("%v", currencyList)

	// работаем только с теми валютами, которые есть у нас в списке
	if len(currencyList[dcCurrencyId]) == 0 || len(currencyList[currencyId]) == 0 {
		return "", utils.ErrInfo("incorrect currency")
	}

	// пары валют для меню
	currencyListPair, err := eGetCurrencyPair()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	dcCurrency := currencyList[dcCurrencyId]
	currency := currencyList[currencyId]

	// история сделок
	var tradeHistory []map[string]string

	rows, err := c.Query(c.FormatQuery(`
			SELECT sell_currency_id, sell_rate, amount, time
			FROM e_trade
			WHERE ((sell_currency_id = ? AND buy_currency_id = ?) OR (sell_currency_id = ? AND buy_currency_id = ?)) AND main = 1
			ORDER BY time DESC
			LIMIT 40
			`), dcCurrencyId, currencyId, currencyId, dcCurrencyId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	for rows.Next() {
		var sellCurrencyId, eTime int64
		var sellRate, amount float64
		err = rows.Scan(&sellCurrencyId, &sellRate, &amount, &eTime)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		var eType string
		var eAmount float64
		var eTotal float64
		if sellCurrencyId == dcCurrencyId {
			eType = "sell"
			sellRate = 1 / sellRate
			eAmount = amount
			eTotal = amount * sellRate
		} else {
			eType = "buy"
			eAmount = amount * (1 / sellRate)
			eTotal = amount
		}
		t := time.Unix(eTime, 0)
		tradeHistory = append(tradeHistory, map[string]string{"Time": t.Format(c.TimeFormat), "Type": eType, "SellRate": utils.ClearNull(utils.Float64ToStr(sellRate), 4), "Amount": utils.ClearNull(utils.Float64ToStr(eAmount), 4), "Total": utils.ClearNull(utils.Float64ToStr(eTotal), 4)})
	}

	// активные ордеры на продажу
	var orders eOrders
	rows, err = c.Query(c.FormatQuery(`
			SELECT sell_rate, amount
			FROM e_orders
			WHERE (sell_currency_id = ? AND buy_currency_id = ?) AND
						empty_time = 0 AND
						del_time = 0 AND
						amount > 0
			ORDER BY sell_rate DESC
			LIMIT 100
			`), dcCurrencyId, currencyId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	// мин. цена покупки
	var buyMin float64
	for rows.Next() {
		var sellRate, amount float64
		err = rows.Scan(&sellRate, &amount)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if orders.Sell == nil {
			orders.Sell = make(map[float64]float64)
		}
		sellRate = utils.ClearNullFloat64(1/sellRate, 6)
		orders.Sell[sellRate] = utils.ClearNullFloat64(orders.Sell[sellRate]+amount, 6)
		if buyMin == 0 {
			buyMin = sellRate
		} else if sellRate < buyMin {
			buyMin = sellRate
		}
	}

	keys := []float64{}
	for k := range orders.Sell {
		keys = append(keys, k)
	}
	sort.Float64s(keys)
	var eOrdersSell []map[string]float64
	for _, k := range keys {
		eOrdersSell = append(eOrdersSell, map[string]float64{"sell_rate": k, "amount": orders.Sell[k]})
	}

	// активные ордеры на покупку
	rows, err = c.Query(c.FormatQuery(`
			SELECT sell_rate, amount
			FROM e_orders
			WHERE (sell_currency_id = ? AND buy_currency_id = ?) AND
					empty_time = 0 AND
					del_time = 0 AND
					amount > 0
			ORDER BY sell_rate ASC
			LIMIT 100
			`), currencyId, dcCurrencyId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	// мин. цена продажи
	var sellMax float64
	for rows.Next() {
		var sellRate, amount float64
		err = rows.Scan(&sellRate, &amount)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if orders.Buy == nil {
			orders.Buy = make(map[float64]float64)
		}
		sellRate = utils.ClearNullFloat64(sellRate, 6)
		orders.Buy[sellRate] = utils.ClearNullFloat64(orders.Buy[sellRate]+amount*(1/sellRate), 6)
		if sellMax == 0 {
			sellMax = sellRate
		} else if sellRate < sellMax {
			sellMax = sellRate
		}
	}
	var keysR sort.Float64Slice
	for k := range orders.Buy {
		keysR = append(keysR, k)
	}
	sort.Sort(sort.Reverse(keysR))
	var eOrdersBuy []map[string]float64
	for _, k := range keysR {
		eOrdersBuy = append(eOrdersBuy, map[string]float64{"sell_rate": k, "amount": orders.Buy[k]})
	}

	// комиссия
	commission := c.EConfig["commission"]
	commissionText := strings.Replace(c.Lang["commission_text"], "[commission]", commission, -1)

	// кол-во юзеров
	members, err := c.Single(`SELECT count(*) FROM e_users`).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	TemplateStr, err := makeTemplate("e_main", "eMain", &eMainPage{
		Lang:             c.Lang,
		Commission:       commission,
		Members:          members,
		SellMax:          sellMax,
		BuyMin:           buyMin,
		EOrdersSell:      eOrdersSell,
		EOrdersBuy:       eOrdersBuy,
		DcCurrency:       dcCurrency,
		Currency:         currency,
		DcCurrencyId:     dcCurrencyId,
		UserId:           c.SessUserId,
		TradeHistory:     tradeHistory,
		CurrencyId:       currencyId,
		CommissionText:   commissionText,
		CurrencyListPair: currencyListPair,
		CurrencyList:     currencyList})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
예제 #5
0
파일: common.go 프로젝트: dzyk/dcoin-go
func NewForexOrder(userId int64, amount, sellRate float64, sellCurrencyId, buyCurrencyId int64, orderType string, eCommission float64) error {
	log.Debug("userId: %v / amount: %v / sellRate: %v / sellCurrencyId: %v / buyCurrencyId: %v / orderType: %v ", userId, amount, sellRate, sellCurrencyId, buyCurrencyId, orderType)
	curTime := utils.Time()
	err := userLock(userId)
	if err != nil {
		return utils.ErrInfo(err)
	}
	commission := utils.StrToFloat64(utils.ClearNull(utils.Float64ToStr(amount*(eCommission/100)), 6))
	newAmount := utils.StrToFloat64(utils.ClearNull(utils.Float64ToStr(amount-commission), 6))
	if newAmount < commission {
		commission = 0
		newAmount = amount
	}
	log.Debug("newAmount: %v / commission: %v ", newAmount, commission)
	if commission > 0 {
		userAmount := utils.EUserAmountAndProfit(1, sellCurrencyId)
		newAmount_ := userAmount + commission
		// наисляем комиссию системе
		err = utils.UpdEWallet(1, sellCurrencyId, utils.Time(), newAmount_, true)
		if err != nil {
			return utils.ErrInfo(err)
		}
		// и сразу вычитаем комиссию с кошелька юзера
		userAmount = utils.EUserAmountAndProfit(userId, sellCurrencyId)
		err = utils.DB.ExecSql("UPDATE e_wallets SET amount = ?, last_update = ? WHERE user_id = ? AND currency_id = ?", userAmount-commission, utils.Time(), userId, sellCurrencyId)
		if err != nil {
			return utils.ErrInfo(err)
		}
	}
	// обратный курс. нужен для поиска по ордерам
	reverseRate := utils.StrToFloat64(utils.ClearNull(utils.Float64ToStr(1/sellRate), 6))
	log.Debug("sellRate %v", sellRate)
	log.Debug("reverseRate %v", reverseRate)

	var totalBuyAmount, totalSellAmount float64
	if orderType == "buy" {
		totalBuyAmount = newAmount * reverseRate
	} else {
		totalSellAmount = newAmount
	}

	var debit float64
	var prevUserId int64
	// берем из БД только те ордеры, которые удовлетворяют нашим требованиям
	rows, err := utils.DB.Query(utils.DB.FormatQuery(`
				SELECT id, user_id, amount, sell_rate, buy_currency_id, sell_currency_id
				FROM e_orders
				WHERE buy_currency_id = ? AND
							 sell_rate >= ? AND
							 sell_currency_id = ?  AND
							 del_time = 0 AND
							 empty_time = 0
				ORDER BY sell_rate DESC
				`), sellCurrencyId, reverseRate, buyCurrencyId)
	if err != nil {
		return utils.ErrInfo(err)
	}
	defer rows.Close()
	for rows.Next() {
		var rowId, rowUserId, rowBuyCurrencyId, rowSellCurrencyId int64
		var rowAmount, rowSellRate float64
		err = rows.Scan(&rowId, &rowUserId, &rowAmount, &rowSellRate, &rowBuyCurrencyId, &rowSellCurrencyId)
		if err != nil {
			return utils.ErrInfo(err)
		}
		log.Debug("rowId: %v / rowUserId: %v / rowAmount: %v / rowSellRate: %v / rowBuyCurrencyId: %v / rowSellCurrencyId: %v", rowId, rowUserId, rowAmount, rowSellRate, rowBuyCurrencyId, rowSellCurrencyId)

		// чтобы ордеры одного и тоже юзера не вызывали стопор, пропускаем все его оредера
		if rowUserId == prevUserId {
			continue
		}
		// блокируем юзера, чей ордер взяли, кроме самого себя
		if rowUserId != userId {
			lockErr := userLock(rowUserId)
			if lockErr != nil {
				log.Error("%v", utils.ErrInfo(err))
				prevUserId = rowUserId
				continue
			}
		}
		if orderType == "buy" {
			// удовлетворит ли данный ордер наш запрос целиком
			if rowAmount >= totalBuyAmount {
				debit = totalBuyAmount
				log.Debug("order ENDED")
			} else {
				debit = rowAmount
			}
		} else {
			// удовлетворит ли данный ордер наш запрос целиком
			if rowAmount/rowSellRate >= totalSellAmount {
				debit = totalSellAmount * rowSellRate
			} else {
				debit = rowAmount
			}
		}
		log.Debug("totalBuyAmount: %v / debit: %v", totalBuyAmount, debit)
		if rowAmount-debit < 0.01 { // ордер опустошили
			err = utils.DB.ExecSql("UPDATE e_orders SET amount = 0, empty_time = ? WHERE id = ?", curTime, rowId)
			if err != nil {
				return utils.ErrInfo(err)
			}
		} else {
			// вычитаем забранную сумму из ордера
			err = utils.DB.ExecSql("UPDATE e_orders SET amount = amount - ? WHERE id = ?", debit, rowId)
			if err != nil {
				return utils.ErrInfo(err)
			}
		}
		mySellRate := utils.ClearNull(utils.Float64ToStr(1/rowSellRate), 6)
		myAmount := debit * utils.StrToFloat64(mySellRate)
		eTradeSellCurrencyId := sellCurrencyId
		eTradeBuyCurrencyId := buyCurrencyId

		// для истории сделок
		err = utils.DB.ExecSql("INSERT INTO e_trade ( user_id, sell_currency_id, sell_rate, amount, buy_currency_id, time, main ) VALUES ( ?, ?, ?, ?, ?, ?, 1 )", userId, eTradeSellCurrencyId, mySellRate, myAmount, eTradeBuyCurrencyId, curTime)
		if err != nil {
			return utils.ErrInfo(err)
		}

		// тот, чей ордер обрабатываем
		err = utils.DB.ExecSql("INSERT INTO e_trade ( user_id, sell_currency_id, sell_rate, amount, buy_currency_id, time ) VALUES ( ?, ?, ?, ?, ?, ? )", rowUserId, eTradeBuyCurrencyId, rowSellRate, debit, eTradeSellCurrencyId, curTime)
		if err != nil {
			return utils.ErrInfo(err)
		}

		// ==== Продавец валюты (тот, чей ордер обработали) ====
		// сколько продавец данного ордера продал валюты
		sellerSellAmount := debit

		// сколько продавец получил buy_currency_id с продажи суммы $seller_sell_amount по его курсу
		sellerBuyAmount := sellerSellAmount * (1 / rowSellRate)

		// начисляем валюту, которую продавец получил (R)
		userAmount := utils.EUserAmountAndProfit(rowUserId, rowBuyCurrencyId)
		newAmount_ := userAmount + sellerBuyAmount
		err = utils.UpdEWallet(rowUserId, rowBuyCurrencyId, utils.Time(), newAmount_, true)
		if err != nil {
			return utils.ErrInfo(err)
		}

		// ====== Покупатель валюты (наш юзер) ======

		// списываем валюту, которую мы продали (R)
		userAmount = utils.EUserAmountAndProfit(userId, rowBuyCurrencyId)
		newAmount_ = userAmount - sellerBuyAmount
		err = utils.UpdEWallet(userId, rowBuyCurrencyId, utils.Time(), newAmount_, true)
		if err != nil {
			return utils.ErrInfo(err)
		}

		// начисляем валюту, которую мы получили (U)
		userAmount = utils.EUserAmountAndProfit(userId, rowSellCurrencyId)
		newAmount_ = userAmount + sellerSellAmount
		err = utils.UpdEWallet(userId, rowSellCurrencyId, utils.Time(), newAmount_, true)
		if err != nil {
			return utils.ErrInfo(err)
		}

		if orderType == "buy" {
			totalBuyAmount -= rowAmount
			if totalBuyAmount <= 0 {
				userUnlock(rowUserId)
				log.Debug("total_buy_amount == 0 break")
				break // проход по ордерам прекращаем, т.к. наш запрос удовлетворен
			}
		} else {
			totalSellAmount -= rowAmount / rowSellRate
			if totalSellAmount <= 0 {
				userUnlock(rowUserId)
				log.Debug("total_sell_amount == 0 break")
				break // проход по ордерам прекращаем, т.к. наш запрос удовлетворен
			}
		}
		if rowUserId != userId {
			userUnlock(rowUserId)
		}
	}

	log.Debug("totalBuyAmount: %v / orderType: %v / sellRate: %v / reverseRate: %v", totalBuyAmount, orderType, sellRate, reverseRate)

	// если после прохода по всем имеющимся ордерам мы не набрали нужную сумму, то создаем свой ордер
	if totalBuyAmount > 0 || totalSellAmount > 0 {
		var newOrderAmount float64
		if orderType == "buy" {
			newOrderAmount = totalBuyAmount * sellRate
		} else {
			newOrderAmount = totalSellAmount
		}
		log.Debug("newOrderAmount: %v", newOrderAmount)
		if newOrderAmount >= 0.000001 {
			err = utils.DB.ExecSql("INSERT INTO e_orders ( time, user_id, sell_currency_id, sell_rate, begin_amount, amount, buy_currency_id ) VALUES ( ?, ?, ?, ?, ?, ?, ? )", curTime, userId, sellCurrencyId, sellRate, newOrderAmount, newOrderAmount, buyCurrencyId)
			if err != nil {
				return utils.ErrInfo(err)
			}

			// вычитаем с баланса сумму созданного ордера
			userAmount := utils.EUserAmountAndProfit(userId, sellCurrencyId)
			err = utils.DB.ExecSql("UPDATE e_wallets SET amount = ?, last_update = ? WHERE user_id = ? AND currency_id = ?", userAmount-newOrderAmount, utils.Time(), userId, sellCurrencyId)
			if err != nil {
				return utils.ErrInfo(err)
			}
		}
	}

	userUnlock(userId)

	return nil
}