1bug修复
This commit is contained in:
@ -295,7 +295,7 @@ func (req LineAddPreOrderReq) Valid() error {
|
|||||||
return errors.New("主单减仓数量百分比不能为空")
|
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("主单减仓价格百分比错误")
|
return errors.New("主单减仓价格百分比错误")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,7 +447,7 @@ func (req LineBatchAddPreOrderReq) CheckParams() error {
|
|||||||
return errors.New("主单减仓数量百分比不能为空")
|
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("主单减仓价格百分比错误")
|
return errors.New("主单减仓价格百分比错误")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -592,6 +592,7 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, apiUserIds []int
|
|||||||
|
|
||||||
preOrderStatus := models.LinePreOrderStatus{}
|
preOrderStatus := models.LinePreOrderStatus{}
|
||||||
preOrderStatus.OrderSn = AddOrder.OrderSn
|
preOrderStatus.OrderSn = AddOrder.OrderSn
|
||||||
|
mainPrice := utility.StringToDecimal(AddOrder.Price)
|
||||||
|
|
||||||
//订单配置信息
|
//订单配置信息
|
||||||
preOrderExts := make([]models.LinePreOrderExt, 0)
|
preOrderExts := make([]models.LinePreOrderExt, 0)
|
||||||
@ -606,6 +607,12 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, apiUserIds []int
|
|||||||
TpTpPriceRatio: req.ProfitTpTpPriceRatio,
|
TpTpPriceRatio: req.ProfitTpTpPriceRatio,
|
||||||
TpSlPriceRatio: req.ProfitTpSlPriceRatio,
|
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{
|
defultExt2 := models.LinePreOrderExt{
|
||||||
AddType: 2,
|
AddType: 2,
|
||||||
@ -617,17 +624,12 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, apiUserIds []int
|
|||||||
TakeProfitNumRatio: decimal.NewFromInt(100), //减仓止盈默认100%
|
TakeProfitNumRatio: decimal.NewFromInt(100), //减仓止盈默认100%
|
||||||
StopLossRatio: req.ReduceStopLossRatio,
|
StopLossRatio: req.ReduceStopLossRatio,
|
||||||
}
|
}
|
||||||
mainPrice := utility.StringToDecimal(AddOrder.Price)
|
|
||||||
mainAmount := utility.SafeDiv(buyPrice, mainPrice)
|
mainAmount := utility.SafeDiv(buyPrice, mainPrice)
|
||||||
defultExt.TotalAfter = utility.StrToDecimal(AddOrder.Num).Truncate(int32(tradeSet.AmountDigit))
|
defultExt.TotalAfter = utility.StrToDecimal(AddOrder.Num).Truncate(int32(tradeSet.AmountDigit))
|
||||||
defultExt2.TotalBefore = defultExt.TotalAfter
|
defultExt2.TotalBefore = defultExt.TotalAfter
|
||||||
|
|
||||||
default2NumPercent := utility.SafeDiv(decimal.NewFromInt(100).Sub(req.ReduceNumRatio), decimal.NewFromInt(100))
|
default2NumPercent := utility.SafeDiv(decimal.NewFromInt(100).Sub(req.ReduceNumRatio), decimal.NewFromInt(100))
|
||||||
defultExt2.TotalAfter = mainAmount.Mul(default2NumPercent).Truncate(int32(tradeSet.AmountDigit))
|
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{}
|
calculateResp := dto.CalculateBreakEvenRatioResp{}
|
||||||
mainParam := dto.CalculateBreakEevenRatioReq{
|
mainParam := dto.CalculateBreakEevenRatioReq{
|
||||||
@ -643,15 +645,22 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, apiUserIds []int
|
|||||||
AddPositionVal: req.ReduceNumRatio,
|
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
|
mainParam.RemainingQuantity = mainAmount
|
||||||
e.CalculateBreakEvenRatio(&mainParam, &calculateResp, tradeSet)
|
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.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))
|
mainParam.TotalLossAmountU = calculateResp.TotalLossAmountU //buyPrice.Mul(req.ReducePriceRatio.Div(decimal.NewFromInt(100)).Truncate(4)).Truncate(int32(tradeSet.PriceDigit))
|
||||||
req.ReduceReTakeProfitRatio = calculateResp.Ratio
|
req.ReduceReTakeProfitRatio = calculateResp.Ratio
|
||||||
mainParam.LossBeginPercent = req.ReducePriceRatio
|
mainParam.LossBeginPercent = mainParam.LossEndPercent
|
||||||
// defultExt.ReTakeRatio = calculateResp.Ratio
|
// defultExt.ReTakeRatio = calculateResp.Ratio
|
||||||
|
preOrderExts = append(preOrderExts, defultExt)
|
||||||
|
preOrderExts = append(preOrderExts, defultExt2)
|
||||||
|
|
||||||
for index, addPosition := range req.Ext {
|
for index, addPosition := range req.Ext {
|
||||||
ext := models.LinePreOrderExt{
|
ext := models.LinePreOrderExt{
|
||||||
@ -1069,6 +1078,8 @@ func makeFuturesTakeAndReduce(preOrder *models.LinePreOrder, ext models.LinePreO
|
|||||||
mainId = preOrder.MainId
|
mainId = preOrder.MainId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Println("take", ext.TakeProfitRatio.String())
|
||||||
|
fmt.Println("boo", ext.TakeProfitRatio.Cmp(decimal.Zero))
|
||||||
if ext.TakeProfitRatio.Cmp(decimal.Zero) > 0 {
|
if ext.TakeProfitRatio.Cmp(decimal.Zero) > 0 {
|
||||||
// 止盈单
|
// 止盈单
|
||||||
profitOrder := models.LinePreOrder{}
|
profitOrder := models.LinePreOrder{}
|
||||||
@ -2237,15 +2248,18 @@ func (e *LinePreOrder) GenerateOrder(req *dto.LineAddPreOrderReq) error {
|
|||||||
AddPositionVal: req.ReduceNumRatio,
|
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.RemainingQuantity = mainAmount
|
||||||
mainParam.AddType = 2
|
mainParam.AddType = 2
|
||||||
e.CalculateBreakEvenRatio(&mainParam, &calculateResp, tradeSet)
|
e.CalculateBreakEvenRatio(&mainParam, &calculateResp, tradeSet)
|
||||||
mainParam.RemainingQuantity = calculateResp.RemainingQuantity
|
mainParam.RemainingQuantity = calculateResp.RemainingQuantity
|
||||||
mainParam.TotalLossAmountU = calculateResp.TotalLossAmountU
|
mainParam.TotalLossAmountU = calculateResp.TotalLossAmountU
|
||||||
req.ReduceReTakeProfitRatio = calculateResp.Ratio
|
req.ReduceReTakeProfitRatio = calculateResp.Ratio
|
||||||
lossBeginPercent = req.ReducePriceRatio
|
lossBeginPercent = mainParam.LossEndPercent
|
||||||
|
|
||||||
//顺序排序
|
//顺序排序
|
||||||
sort.Slice(req.Ext, func(i, j int) bool {
|
sort.Slice(req.Ext, func(i, j int) bool {
|
||||||
|
|||||||
67
app/jobs/account_job.go
Normal file
67
app/jobs/account_job.go
Normal 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
|
||||||
|
}
|
||||||
34
app/jobs/account_job_test.go
Normal file
34
app/jobs/account_job_test.go
Normal 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)
|
||||||
|
}
|
||||||
@ -39,6 +39,8 @@ func InitJob() {
|
|||||||
"MemberRenwalOrderExpirationJob": MemberRenwalOrderExpirationJob{}, //会员续费订单过期处理
|
"MemberRenwalOrderExpirationJob": MemberRenwalOrderExpirationJob{}, //会员续费订单过期处理
|
||||||
"TrxQueryJobs": TrxQueryJobs{}, //订单支付监听
|
"TrxQueryJobs": TrxQueryJobs{}, //订单支付监听
|
||||||
"StrategyJob": StrategyJob{}, //下单策略触发
|
"StrategyJob": StrategyJob{}, //下单策略触发
|
||||||
|
"BinanceSpotAccountJob": BinanceSpotAccountJob{}, //币安现货划转
|
||||||
|
"BinanceFuturesAccountJob": BinanceFuturesAccountJob{}, //币安合约划转
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
models/binancedto/account.go
Normal file
11
models/binancedto/account.go
Normal 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:"转入币种"`
|
||||||
|
}
|
||||||
@ -640,3 +640,43 @@ func GetSpotUProperty(apiUserInfo DbModels.LineApiUser, data *dto.LineUserProper
|
|||||||
|
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user