Skip to content

Commit

Permalink
market 结算
Browse files Browse the repository at this point in the history
  • Loading branch information
Your Name committed Oct 13, 2023
1 parent c3128d1 commit e89aa9b
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 146 deletions.
27 changes: 10 additions & 17 deletions cmd/haobase/assets/transfer_assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,29 @@ import (
"fmt"
"strings"

"github.com/sirupsen/logrus"
"xorm.io/xorm"
)

func Transfer(db *xorm.Session, enable_transaction bool, from, to string, symbol string, amount string, business_id string, behavior OpBehavior) (success bool, err error) {
return transfer(db, enable_transaction, from, to, symbol, amount, business_id, behavior)
func Transfer(db *xorm.Session, from, to string, symbol string, amount string, business_id string, behavior OpBehavior) (success bool, err error) {
return transfer(db, from, to, symbol, amount, business_id, behavior)
}

func SysRecharge(to string, symbol string, amount string, business_id string) (success bool, err error) {
db := db_engine.NewSession()
defer db.Close()

return transfer(db, true, UserRoot, to, symbol, amount, "", Behavior_Recharge)
db.Begin()
success, err = transfer(db, UserRoot, to, symbol, amount, "", Behavior_Recharge)
if err != nil {
db.Rollback()
}
db.Commit()
return success, err
}

func transfer(db *xorm.Session, enable_transaction bool, from, to string, symbol string, amount string, business_id string, behavior OpBehavior) (success bool, err error) {
func transfer(db *xorm.Session, from, to string, symbol string, amount string, business_id string, behavior OpBehavior) (success bool, err error) {
symbol = strings.ToLower(symbol)

if enable_transaction {
db.Begin()
defer func() {
if err != nil {
logrus.Error(err)
db.Rollback()
} else {
db.Commit()
}
}()
}

if from == to {
return false, fmt.Errorf("invalid to")
}
Expand Down
21 changes: 5 additions & 16 deletions cmd/haobase/assets/unfreeze_assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,15 @@ import (
"xorm.io/xorm"
)

func UnfreezeAssets(db *xorm.Session, enable_transaction bool, user_id string, business_id, unfreeze_amount string) (success bool, err error) {
return unfreezeAssets(db, enable_transaction, user_id, business_id, unfreeze_amount)
func UnfreezeAssets(db *xorm.Session, user_id string, business_id, unfreeze_amount string) (success bool, err error) {
return unfreezeAssets(db, user_id, business_id, unfreeze_amount)
}

func UnfreezeAllAssets(db *xorm.Session, enable_transaction bool, user_id string, business_id string) (success bool, err error) {
return unfreezeAssets(db, enable_transaction, user_id, business_id, "0")
func UnfreezeAllAssets(db *xorm.Session, user_id string, business_id string) (success bool, err error) {
return unfreezeAssets(db, user_id, business_id, "0")
}

func unfreezeAssets(db *xorm.Session, enable_transaction bool, user_id string, business_id, unfreeze_amount string) (success bool, err error) {
if enable_transaction {
db.Begin()
defer func() {
if err != nil {
db.Rollback()
} else {
db.Commit()
}
}()
}

func unfreezeAssets(db *xorm.Session, user_id string, business_id, unfreeze_amount string) (success bool, err error) {
if check_number_lt_zero(unfreeze_amount) {
return false, fmt.Errorf("unfreeze amount should be >= 0")
}
Expand Down
68 changes: 48 additions & 20 deletions cmd/haobase/clearing/clearing_flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type clean struct {
trading_varieties *symbols.TradingVarieties
ask orders.Order
bid orders.Order
raw trading_engine.TradeResult
tlog trading_engine.TradeResult
tradelog orders.TradeLog
err error
}
Expand All @@ -31,7 +31,7 @@ func newClean(raw trading_engine.TradeResult) {
trading_varieties: symbols.NewTradingVarieties(raw.Symbol),
ask: orders.Order{},
bid: orders.Order{},
raw: raw,
tlog: raw,
}

item.flow()
Expand All @@ -57,11 +57,11 @@ func (c *clean) flow() {
}

func (c *clean) check_order() error {
_, err := c.db.Table(orders.GetOrderTableName(c.raw.Symbol)).Where("order_id=?", c.raw.AskOrderId).ForUpdate().Get(&c.ask)
_, err := c.db.Table(orders.GetOrderTableName(c.tlog.Symbol)).Where("order_id=?", c.tlog.AskOrderId).ForUpdate().Get(&c.ask)
if err != nil {
return err
}
_, err = c.db.Table(orders.GetOrderTableName(c.raw.Symbol)).Where("order_id=?", c.raw.BidOrderId).ForUpdate().Get(&c.bid)
_, err = c.db.Table(orders.GetOrderTableName(c.tlog.Symbol)).Where("order_id=?", c.tlog.BidOrderId).ForUpdate().Get(&c.bid)
if err != nil {
return err
}
Expand All @@ -77,17 +77,17 @@ func (c *clean) check_order() error {
}

func (c *clean) trade_log() error {
amount := c.raw.TradePrice.Mul(c.raw.TradeQuantity)
amount := c.tlog.TradePrice.Mul(c.tlog.TradeQuantity)
c.tradelog = orders.TradeLog{
Symbol: c.raw.Symbol,
Symbol: c.tlog.Symbol,
TradeId: generate_trading_id(c.ask.OrderId, c.bid.OrderId),
Ask: c.ask.OrderId,
Bid: c.bid.OrderId,
// TradeBy: "",
AskUid: c.ask.UserId,
BidUid: c.bid.UserId,
Price: c.raw.TradePrice.String(),
Quantity: c.raw.TradeQuantity.String(),
Price: c.tlog.TradePrice.String(),
Quantity: c.tlog.TradeQuantity.String(),
Amount: amount.String(),
AskFeeRate: c.ask.FeeRate,
AskFee: amount.Mul(utils.D(c.ask.FeeRate)).String(),
Expand All @@ -108,12 +108,11 @@ func (c *clean) update_order(side trading_engine.OrderSide) error {
order.Fee = utils.D(order.Fee).Add(utils.D(c.tradelog.BidFee)).String()
}

order.Symbol = c.raw.Symbol
order.FinishedQty = utils.D(order.FinishedQty).Add(c.raw.TradeQuantity).String()
order.TradeAmount = utils.D(order.TradeAmount).Add(utils.D(c.tradelog.Amount)).String()
order.AvgPrice = utils.D(order.TradeAmount).Div(utils.D(order.FinishedQty)).String()
order.Symbol = c.tlog.Symbol
order.FinishedQty = utils.D(order.FinishedQty).Add(c.tlog.TradeQuantity).String()
order.FinishedAmount = utils.D(order.FinishedAmount).Add(utils.D(c.tradelog.Amount)).String()
order.AvgPrice = utils.D(order.FinishedAmount).Div(utils.D(order.FinishedQty)).String()

//todo 一些必要的边界值检查
if order.OrderType == trading_engine.OrderTypeLimit {
be := utils.D(order.FinishedQty).Cmp(utils.D(order.Quantity))
if be > 0 {
Expand All @@ -139,41 +138,70 @@ func (c *clean) update_order(side trading_engine.OrderSide) error {
return err
}
}
}
//todo 市价单结算
} else {
//市价单结算
if utils.D(order.Quantity).Equal(utils.D(order.FinishedQty)) || utils.D(order.Amount).Equal(utils.D(order.FinishedAmount)) {
order.Status = orders.OrderStatusDone
}

if c.tlog.Last {
order.Status = orders.OrderStatusDone
}

_, err := c.db.Table(order.TableName()).Where("order_id=?", order.OrderId).AllCols().Update(order)
if err != nil {
return err
}
}
return nil
}

func (c *clean) transfer() error {
//给买家结算交易物品
_, err := assets.UnfreezeAssets(c.db, false, c.ask.UserId, c.ask.OrderId, c.raw.TradeQuantity.String())
_, err := assets.UnfreezeAssets(c.db, c.ask.UserId, c.ask.OrderId, c.tlog.TradeQuantity.String())
if err != nil {
return err
}
_, err = assets.Transfer(c.db, false, c.ask.UserId, c.bid.UserId, c.trading_varieties.Target.Symbol, c.raw.TradeQuantity.String(), c.tradelog.TradeId, assets.Behavior_Trade)
_, err = assets.Transfer(c.db, c.ask.UserId, c.bid.UserId, c.trading_varieties.Target.Symbol, c.tlog.TradeQuantity.String(), c.tradelog.TradeId, assets.Behavior_Trade)
if err != nil {
return err
}

//卖家结算本位币
amount := utils.D(c.tradelog.Amount).Add(utils.D(c.tradelog.BidFee))
_, err = assets.UnfreezeAssets(c.db, false, c.bid.UserId, c.bid.OrderId, amount.String())
_, err = assets.UnfreezeAssets(c.db, c.bid.UserId, c.bid.OrderId, amount.String())
if err != nil {
return err
}

//扣除fee
fee := utils.D(c.tradelog.BidFee).Add(utils.D(c.tradelog.AskFee))
_, err = assets.Transfer(c.db, false, c.bid.UserId, c.ask.UserId, c.trading_varieties.Standard.Symbol, amount.Sub(fee).String(), c.tradelog.TradeId, assets.Behavior_Trade)
_, err = assets.Transfer(c.db, c.bid.UserId, c.ask.UserId, c.trading_varieties.Standard.Symbol, amount.Sub(fee).String(), c.tradelog.TradeId, assets.Behavior_Trade)
if err != nil {
return err
}

//手续费收入到一个全局的账号里
_, err = assets.Transfer(c.db, false, c.bid.UserId, assets.UserSystemFee, c.trading_varieties.Standard.Symbol, fee.String(), c.tradelog.TradeId, assets.Behavior_Trade)
_, err = assets.Transfer(c.db, c.bid.UserId, assets.UserSystemFee, c.trading_varieties.Standard.Symbol, fee.String(), c.tradelog.TradeId, assets.Behavior_Trade)
if err != nil {
return err
}

//市价单解除全部冻结
if c.tlog.Last {
if c.ask.OrderType == trading_engine.OrderTypeMarket {
_, err = assets.UnfreezeAllAssets(c.db, c.ask.UserId, c.ask.OrderId)
if err != nil {
return err
}
}
if c.bid.OrderType == trading_engine.OrderTypeMarket {
_, err = assets.UnfreezeAllAssets(c.db, c.bid.UserId, c.bid.OrderId)
if err != nil {
return err
}
}
}

return nil
}
42 changes: 40 additions & 2 deletions cmd/haobase/clearing/clearing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ func TestLimitOrder(t *testing.T) {
initdb(t)
Convey("限价单完全成交结算测试", t, func() {
initAssets(t)
// defer cleanOrders(t)
// defer cleanAssets(t)
defer cleanOrders(t)
defer cleanAssets(t)

sell, err := orders.NewLimitOrder(sellUser, testSymbol, trading_engine.OrderSideSell, "1.00", "1")
So(err, ShouldBeNil)
Expand Down Expand Up @@ -122,3 +122,41 @@ func TestLimitOrder(t *testing.T) {

})
}

func TestMarket(t *testing.T) {
initdb(t)
Convey("市价买指定的数量", t, func() {
initAssets(t)
// defer cleanOrders(t)
// defer cleanAssets(t)

s1, err := orders.NewLimitOrder(sellUser, testSymbol, trading_engine.OrderSideSell, "1.00", "1")
So(err, ShouldBeNil)

s2, _ := orders.NewLimitOrder(sellUser, testSymbol, trading_engine.OrderSideSell, "2.00", "1")

buy, err := orders.NewMarketOrderByQty(buyUser, testSymbol, trading_engine.OrderSideBuy, "3")
So(err, ShouldBeNil)

result1 := trading_engine.TradeResult{
Symbol: testSymbol,
AskOrderId: s1.OrderId,
BidOrderId: buy.OrderId,
TradePrice: utils.D("1.00"),
TradeQuantity: utils.D("1"),
TradeTime: time.Now().UnixNano(),
}
result2 := trading_engine.TradeResult{
Symbol: testSymbol,
AskOrderId: s2.OrderId,
BidOrderId: buy.OrderId,
TradePrice: utils.D("2.00"),
TradeQuantity: utils.D("1"),
TradeTime: time.Now().UnixNano(),
Last: true,
}

newClean(result1)
newClean(result2)
})
}
3 changes: 1 addition & 2 deletions cmd/haobase/orders/cancel_order.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,9 @@ func cancel_order(symbol, order_id string) (order *Order, err error) {
}

//解除订单冻结金额
_, err = assets.UnfreezeAllAssets(db, false, order.UserId, order.OrderId)
_, err = assets.UnfreezeAllAssets(db, order.UserId, order.OrderId)
if err != nil {
return nil, err
}

return order, nil
}
29 changes: 15 additions & 14 deletions cmd/haobase/orders/limit_order.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,21 @@ func limit_order(user_id string, symbol string, side trading_engine.OrderSide, p
//todo 检查交易对限制

neworder := Order{
OrderId: generate_order_id_by_side(side),
Symbol: symbol,
OrderSide: side,
OrderType: trading_engine.OrderTypeLimit,
UserId: user_id,
Price: price,
AvgPrice: "0",
Quantity: qty,
Amount: "0",
FinishedQty: "0",
FeeRate: string(varieties.FeeRate),
Fee: "0",
TradeAmount: "0",
Status: OrderStatusNew,
OrderId: generate_order_id_by_side(side),
Symbol: symbol,
OrderSide: side,
OrderType: trading_engine.OrderTypeLimit,
UserId: user_id,
Price: price,
AvgPrice: "0",
Quantity: qty,
Amount: "0",
FinishedQty: "0",
FeeRate: string(varieties.FeeRate),
FreezeAmount: "0",
Fee: "0",
FinishedAmount: "0",
Status: OrderStatusNew,
}

db := assets.DB().NewSession()
Expand Down
Loading

0 comments on commit e89aa9b

Please sign in to comment.