gcx/backend/services/trading-service/internal/domain/entity/trade.go

69 lines
1.8 KiB
Go

package entity
import (
"fmt"
"time"
"github.com/genex/trading-service/internal/domain/vo"
)
const (
// TakerFeeRate is the fee rate charged to the taker (0.5%).
TakerFeeRate = 0.005
// MakerFeeRate is the fee rate charged to the maker (0.1%).
MakerFeeRate = 0.001
)
// Trade represents an executed trade between a buyer and seller.
type Trade struct {
ID string `json:"id"`
CouponID string `json:"couponId"`
BuyOrderID string `json:"buyOrderId"`
SellOrderID string `json:"sellOrderId"`
BuyerID string `json:"buyerId"`
SellerID string `json:"sellerId"`
Price vo.Price `json:"price"`
Quantity int `json:"quantity"`
BuyerFee float64 `json:"buyerFee"`
SellerFee float64 `json:"sellerFee"`
CreatedAt time.Time `json:"createdAt"`
}
// NewTrade creates a new Trade from matched orders.
func NewTrade(id string, buyOrder, sellOrder *Order, price vo.Price, matchQty int) (*Trade, error) {
if id == "" {
return nil, fmt.Errorf("trade ID cannot be empty")
}
if matchQty <= 0 {
return nil, fmt.Errorf("trade quantity must be positive")
}
notional := price.Multiply(matchQty)
takerFee := notional * TakerFeeRate
makerFee := notional * MakerFeeRate
return &Trade{
ID: id,
CouponID: buyOrder.CouponID,
BuyOrderID: buyOrder.ID,
SellOrderID: sellOrder.ID,
BuyerID: buyOrder.UserID,
SellerID: sellOrder.UserID,
Price: price,
Quantity: matchQty,
BuyerFee: takerFee,
SellerFee: makerFee,
CreatedAt: time.Now(),
}, nil
}
// Notional returns the total value of the trade (price * quantity).
func (t *Trade) Notional() float64 {
return t.Price.Multiply(t.Quantity)
}
// TotalFees returns the sum of buyer and seller fees.
func (t *Trade) TotalFees() float64 {
return t.BuyerFee + t.SellerFee
}