1bug修复

This commit is contained in:
2025-05-19 09:47:49 +08:00
parent 44ba8bfbf1
commit 7b50873de3
7 changed files with 179 additions and 11 deletions

View File

@ -295,7 +295,7 @@ func (req LineAddPreOrderReq) Valid() error {
return errors.New("主单减仓数量百分比不能为空")
}
if req.ReducePriceRatio.IsZero() || req.ReducePriceRatio.Cmp(decimal.NewFromInt(100)) >= 0 {
if req.PricePattern != "mixture" && (req.ReducePriceRatio.IsZero() || req.ReducePriceRatio.Cmp(decimal.NewFromInt(100)) >= 0) {
return errors.New("主单减仓价格百分比错误")
}
@ -447,7 +447,7 @@ func (req LineBatchAddPreOrderReq) CheckParams() error {
return errors.New("主单减仓数量百分比不能为空")
}
if req.ReducePriceRatio.Cmp(decimal.Zero) <= 0 || req.ReducePriceRatio.Cmp(decimal.NewFromInt(100)) >= 0 {
if req.PricePattern != "mixture" && (req.ReducePriceRatio.Cmp(decimal.Zero) <= 0 || req.ReducePriceRatio.Cmp(decimal.NewFromInt(100)) >= 0) {
return errors.New("主单减仓价格百分比错误")
}

View File

@ -592,6 +592,7 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, apiUserIds []int
preOrderStatus := models.LinePreOrderStatus{}
preOrderStatus.OrderSn = AddOrder.OrderSn
mainPrice := utility.StringToDecimal(AddOrder.Price)
//订单配置信息
preOrderExts := make([]models.LinePreOrderExt, 0)
@ -606,6 +607,12 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, apiUserIds []int
TpTpPriceRatio: req.ProfitTpTpPriceRatio,
TpSlPriceRatio: req.ProfitTpSlPriceRatio,
}
if req.PricePattern == "mixture" {
defultExt.TakeProfitRatio = mainPrice.Div(utility.StrToDecimal(req.Profit)).Sub(decimal.NewFromInt(1)).Abs().Mul(decimal.NewFromInt(100)).Truncate(2)
defultExt.StopLossRatio = mainPrice.Div(req.StopLoss).Sub(decimal.NewFromInt(1)).Abs().Mul(decimal.NewFromInt(100)).Truncate(2)
}
//减仓单
defultExt2 := models.LinePreOrderExt{
AddType: 2,
@ -617,17 +624,12 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, apiUserIds []int
TakeProfitNumRatio: decimal.NewFromInt(100), //减仓止盈默认100%
StopLossRatio: req.ReduceStopLossRatio,
}
mainPrice := utility.StringToDecimal(AddOrder.Price)
mainAmount := utility.SafeDiv(buyPrice, mainPrice)
defultExt.TotalAfter = utility.StrToDecimal(AddOrder.Num).Truncate(int32(tradeSet.AmountDigit))
defultExt2.TotalBefore = defultExt.TotalAfter
default2NumPercent := utility.SafeDiv(decimal.NewFromInt(100).Sub(req.ReduceNumRatio), decimal.NewFromInt(100))
defultExt2.TotalAfter = mainAmount.Mul(default2NumPercent).Truncate(int32(tradeSet.AmountDigit))
defultExt2.ReTakeRatio = utility.SafeDiv(req.ReducePriceRatio, default2NumPercent).Truncate(2)
preOrderExts = append(preOrderExts, defultExt)
preOrderExts = append(preOrderExts, defultExt2)
calculateResp := dto.CalculateBreakEvenRatioResp{}
mainParam := dto.CalculateBreakEevenRatioReq{
@ -643,15 +645,22 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, apiUserIds []int
AddPositionVal: req.ReduceNumRatio,
}
if req.PricePattern == "mixture" {
mainParam.LossEndPercent = mainPrice.Div(req.ReducePriceRatio).Sub(decimal.NewFromInt(1)).Abs().Mul(decimal.NewFromInt(100)).Truncate(2)
defultExt2.PriceRatio = mainParam.LossEndPercent
}
//计算减仓后
mainParam.LossEndPercent = req.ReducePriceRatio
defultExt2.ReTakeRatio = utility.SafeDiv(mainParam.LossEndPercent, default2NumPercent).Truncate(2)
mainParam.RemainingQuantity = mainAmount
e.CalculateBreakEvenRatio(&mainParam, &calculateResp, tradeSet)
mainParam.RemainingQuantity = calculateResp.RemainingQuantity //mainAmount.Mul(decimal.NewFromInt(100).Sub(req.ReduceNumRatio).Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit))
mainParam.TotalLossAmountU = calculateResp.TotalLossAmountU //buyPrice.Mul(req.ReducePriceRatio.Div(decimal.NewFromInt(100)).Truncate(4)).Truncate(int32(tradeSet.PriceDigit))
req.ReduceReTakeProfitRatio = calculateResp.Ratio
mainParam.LossBeginPercent = req.ReducePriceRatio
mainParam.LossBeginPercent = mainParam.LossEndPercent
// defultExt.ReTakeRatio = calculateResp.Ratio
preOrderExts = append(preOrderExts, defultExt)
preOrderExts = append(preOrderExts, defultExt2)
for index, addPosition := range req.Ext {
ext := models.LinePreOrderExt{
@ -1069,6 +1078,8 @@ func makeFuturesTakeAndReduce(preOrder *models.LinePreOrder, ext models.LinePreO
mainId = preOrder.MainId
}
fmt.Println("take", ext.TakeProfitRatio.String())
fmt.Println("boo", ext.TakeProfitRatio.Cmp(decimal.Zero))
if ext.TakeProfitRatio.Cmp(decimal.Zero) > 0 {
// 止盈单
profitOrder := models.LinePreOrder{}
@ -2237,15 +2248,18 @@ func (e *LinePreOrder) GenerateOrder(req *dto.LineAddPreOrderReq) error {
AddPositionVal: req.ReduceNumRatio,
}
if req.PricePattern == "mixture" {
mainParam.LossEndPercent = price.Div(req.ReducePriceRatio).Sub(decimal.NewFromInt(1)).Abs().Mul(decimal.NewFromInt(100)).Truncate(2)
}
//计算减仓后
mainParam.LossEndPercent = req.ReducePriceRatio
mainParam.RemainingQuantity = mainAmount
mainParam.AddType = 2
e.CalculateBreakEvenRatio(&mainParam, &calculateResp, tradeSet)
mainParam.RemainingQuantity = calculateResp.RemainingQuantity
mainParam.TotalLossAmountU = calculateResp.TotalLossAmountU
req.ReduceReTakeProfitRatio = calculateResp.Ratio
lossBeginPercent = req.ReducePriceRatio
lossBeginPercent = mainParam.LossEndPercent
//顺序排序
sort.Slice(req.Ext, func(i, j int) bool {

67
app/jobs/account_job.go Normal file
View File

@ -0,0 +1,67 @@
package jobs
import (
binancedto "go-admin/models/binancedto"
"go-admin/services/binanceservice"
DbModels "go-admin/app/admin/models"
"github.com/go-admin-team/go-admin-core/logger"
"github.com/shopspring/decimal"
)
type BinanceSpotAccountJob struct{}
type BinanceFuturesAccountJob struct{}
// 币安账户划转
func (t BinanceSpotAccountJob) Exec(arg interface{}) error {
db := getDefaultDb()
req := binancedto.BinanceTransfer{
Type: "MAIN_UMFUTURE",
Asset: "USDT",
Amount: decimal.NewFromFloat(0.1),
FromSymbol: "USDT",
ToSymbol: "USDT",
}
var apis []DbModels.LineApiUser
if err := db.Model(&DbModels.LineApiUser{}).Where("open_status = 1").Find(&apis).Error; err != nil {
return err
}
for _, apiUserInfo := range apis {
err := binanceservice.TradeAmount(db, &req, apiUserInfo)
if err != nil {
logger.Errorf("现货划转合约失败, err: %s", err)
}
}
return nil
}
// 币安账户划转
func (t BinanceFuturesAccountJob) Exec(arg interface{}) error {
db := getDefaultDb()
req := binancedto.BinanceTransfer{
Type: "UMFUTURE_MAIN",
Asset: "USDT",
Amount: decimal.NewFromFloat(0.1),
FromSymbol: "USDT",
ToSymbol: "USDT",
}
var apis []DbModels.LineApiUser
if err := db.Model(&DbModels.LineApiUser{}).Where("open_status = 1").Find(&apis).Error; err != nil {
return err
}
for _, apiUserInfo := range apis {
err := binanceservice.TradeAmount(db, &req, apiUserInfo)
if err != nil {
logger.Errorf("合约划转现货失败, err: %s", err)
}
}
return nil
}

View File

@ -0,0 +1,34 @@
package jobs
import (
"go-admin/common/helper"
"testing"
"github.com/go-admin-team/go-admin-core/sdk"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func TestAccountJob(t *testing.T) {
dsn := "root:123456@tcp(127.0.0.1:3306)/go_exchange_single?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
sdk.Runtime.SetDb("default", db)
helper.InitDefaultRedis("127.0.0.1:6379", "", 2)
helper.InitLockRedisConn("127.0.0.1:6379", "", "2")
accountJob := BinanceSpotAccountJob{}
accountJob.Exec(nil)
}
func TestFutureAccountJob(t *testing.T) {
dsn := "root:123456@tcp(127.0.0.1:3306)/go_exchange_single?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
sdk.Runtime.SetDb("default", db)
helper.InitDefaultRedis("127.0.0.1:6379", "", 2)
helper.InitLockRedisConn("127.0.0.1:6379", "", "2")
accountJob := BinanceFuturesAccountJob{}
accountJob.Exec(nil)
}

View File

@ -39,6 +39,8 @@ func InitJob() {
"MemberRenwalOrderExpirationJob": MemberRenwalOrderExpirationJob{}, //会员续费订单过期处理
"TrxQueryJobs": TrxQueryJobs{}, //订单支付监听
"StrategyJob": StrategyJob{}, //下单策略触发
"BinanceSpotAccountJob": BinanceSpotAccountJob{}, //币安现货划转
"BinanceFuturesAccountJob": BinanceFuturesAccountJob{}, //币安合约划转
}
}

View File

@ -0,0 +1,11 @@
package binancedto
import "github.com/shopspring/decimal"
type BinanceTransfer struct {
Type string `json:"type" content:"枚举 MAIN_UMFUTURE-现货到u合约"`
Asset string `json:"asset" content:"币种"`
Amount decimal.Decimal `json:"amount" content:"数量"`
FromSymbol string `json:"fromSymbol" content:"转出币种"`
ToSymbol string `json:"toSymbol" content:"转入币种"`
}

View File

@ -640,3 +640,43 @@ func GetSpotUProperty(apiUserInfo DbModels.LineApiUser, data *dto.LineUserProper
return nil
}
// 万象划转
func TradeAmount(db *gorm.DB, req *binancedto.BinanceTransfer, apiUserInfo DbModels.LineApiUser) error {
url := "/sapi/v1/asset/transfer"
client := GetClient(&apiUserInfo)
params := map[string]string{
"type": req.Type,
"asset": req.Asset,
"amount": req.Amount.String(),
"fromSymbol": req.FromSymbol,
"toSymbol": req.ToSymbol,
"recvWindow": "10000",
}
_, code, err := client.SendSpotAuth(url, "POST", params)
if err != nil || code != 200 {
log.Error("万向划转失败 参数:", params)
log.Error("万向划转失败 code:", code)
log.Error("万向划转失败 err:", err)
dataMap := make(map[string]interface{})
if err.Error() != "" {
if err := sonic.Unmarshal([]byte(err.Error()), &dataMap); err != nil {
return fmt.Errorf("api_id:%d 万向划转失败:%+v", apiUserInfo.Id, err.Error())
}
}
code, ok := dataMap["code"]
if ok {
return fmt.Errorf("api_id:%d 万向划转失败:%s", apiUserInfo.Id, ErrorMaps[code.(float64)])
}
if strings.Contains(err.Error(), "Unknown order sent.") {
return fmt.Errorf("api_id:%d 万向划转失败:%+v", apiUserInfo.Id, ErrorMaps[-2011])
}
return fmt.Errorf("api_id:%d 万向划转失败:%+v", apiUserInfo.Id, err.Error())
}
return nil
}