This commit is contained in:
2025-02-18 09:59:51 +08:00
parent eb2455f967
commit 08a7da607f
9 changed files with 420 additions and 548 deletions

View File

@ -606,7 +606,7 @@ func (e LinePreOrder) QueryAiCoinPrice(c *gin.Context) {
// 计算回本盈利比例
func (e LinePreOrder) CalculateBreakEevenRatio(c *gin.Context) {
s := service.LinePreOrder{}
req := dto.CalculateBreakEevenRatioReq{}
req := dto.LineAddPreOrderReq{}
err := e.MakeContext(c).
MakeOrm().
@ -619,12 +619,12 @@ func (e LinePreOrder) CalculateBreakEevenRatio(c *gin.Context) {
return
}
data := dto.CalculateBreakEvenRatioResp{}
err = s.CalculateBreakEvenRatio(&req, &data)
// data := dto.CalculateBreakEvenRatioResp{}
_, err = s.GenerateOrder(&req)
if err != nil {
e.Error(500, err, err.Error())
return
}
e.OK(data, "操作成功")
e.OK(req, "操作成功")
}

View File

@ -12,6 +12,7 @@ type LinePreOrderExt struct {
MainOrderId int `json:"mainOrderId" gorm:"type:bigint;comment:主单id"`
OrderId int `json:"orderId" gorm:"type:bigint;comment:订单id"`
TakeProfitRatio decimal.Decimal `json:"takeProfitRatio" gorm:"type:decimal(10,2);comment:止盈百分比"`
ReTakeRatio decimal.Decimal `json:"reTakeRatio" gorm:"type:decimal(10,2);comment:亏损回本止盈百分比"`
ReduceOrderType string `json:"reduceOrderType" gorm:"type:varchar(20);comment:减仓类型 LIMIT-限价 MARKET-市价"`
ReducePriceRatio decimal.Decimal `json:"reducePriceRatio" gorm:"type:decimal(10,2);comment:减仓价格百分比"`
ReduceNumRatio decimal.Decimal `json:"reduceNumRatio" gorm:"type:decimal(10,2);comment:减仓数量百分比"`
@ -21,6 +22,9 @@ type LinePreOrderExt struct {
AddPositionPriceRatio decimal.Decimal `json:"addPositionPriceRatio" gorm:"type:decimal(10,2);comment:加仓价格百分比"`
AddPositionType int `json:"addPositionType" gorm:"type:int;comment:加仓类型 1-百分比 2-实际金额"`
AddPositionVal decimal.Decimal `json:"addPositionVal" gorm:"type:decimal(10,2);comment:加仓值"`
ReduceReTakeRatio decimal.Decimal `json:"reduceReTakeRatio" gorm:"type:decimal(10,2);comment:减仓后亏损回本止盈百分比"`
TotalAfterAdding decimal.Decimal `json:"totalAfterAdding" gorm:"-"` //加仓后总数
TotalAfterReducing decimal.Decimal `json:"totalAfterReducing" gorm:"-"` //减仓后总数
models.ModelTime
models.ControlBy
}

View File

@ -38,7 +38,7 @@ func registerLinePreOrderRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTM
r.POST("clearUnTriggered", actions.PermissionAction(), api.ClearUnTriggered) // 清除待触发的交易对
r.POST("aiCoinPrice", actions.PermissionAction(), api.QueryAiCoinPrice) //获取aiCoin买入点
r.GET("/calculate", api.CalculateBreakEevenRatio) //计算亏损后止盈百分比
r.POST("/calculate", api.CalculateBreakEevenRatio) //计算亏损后止盈百分比
}
}

View File

@ -191,18 +191,20 @@ type LineAddPreOrderReq struct {
Price string `json:"price"` //下单价百分比
Profit string `json:"profit"` //止盈价
// StopPrice string `json:"stop_price"` //止损价
PriceType string `json:"price_type"` //价格类型
SaveTemplate string `json:"save_template"` //是否保存模板
TemplateName string `json:"template_name"` //模板名字
SymbolType int `json:"symbol_type"` //交易对类型 1-现货 2-合约
CoverType int `json:"cover_type"` //对冲类型 0=无对冲 1= 现货对合约 2=合约对合约 3 合约对现货
ExpireHour int `json:"expire_hour"` // 过期时间 单位小时
MainOrderType string `json:"main_order_type"` //主单类型:限价(LIMIT)或市价(MARKET)
ReducePriceRatio decimal.Decimal `json:"reduce_price"` //主单减仓价格百分比
ReduceNumRatio decimal.Decimal `json:"reduce_num"` //主单减仓数量百分比
ReduceTakeProfitRatio decimal.Decimal `json:"reduce_take_profit"` //主单减仓后止盈价百分比
ReduceStopLossRatio decimal.Decimal `json:"reduce_stop_price"` //主单减仓后止损价百分比
Ext []LineAddPreOrderExtReq `json:"ext"` //拓展字段
PriceType string `json:"price_type"` //价格类型
SaveTemplate string `json:"save_template"` //是否保存模板
TemplateName string `json:"template_name"` //模板名字
SymbolType int `json:"symbol_type"` //交易对类型 1-现货 2-合约
CoverType int `json:"cover_type"` //对冲类型 0=无对冲 1= 现货对合约 2=合约对合约 3 合约对现货
ExpireHour int `json:"expire_hour"` // 过期时间 单位小时
MainOrderType string `json:"main_order_type"` //主单类型:限价(LIMIT)或市价(MARKET)
ReducePriceRatio decimal.Decimal `json:"reduce_price"` //主单减仓价格百分比
ReduceNumRatio decimal.Decimal `json:"reduce_num"` //主单减仓数量百分比
ReduceTakeProfitRatio decimal.Decimal `json:"reduce_take_profit"` //主单减仓后止盈价百分比
ReduceStopLossRatio decimal.Decimal `json:"reduce_stop_price"` //主单减仓后止损价百分比
ReduceReTakeProfitRatio decimal.Decimal `json:"reTakeProfitRatio" comment:"减仓后亏损回本止盈百分比"`
Ext []LineAddPreOrderExtReq `json:"ext"` //拓展字段
}
func (req LineAddPreOrderReq) CheckParams() error {
@ -232,6 +234,11 @@ func (req LineAddPreOrderReq) CheckParams() error {
return nil
}
type LineTreeOrder struct {
models.LinePreOrder
Childs []models.LinePreOrder `json:"childs"`
}
// LineBatchAddPreOrderReq 批量添加订单请求参数
type LineBatchAddPreOrderReq struct {
ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type

View File

@ -37,15 +37,17 @@ func (m *LinePreOrderExtGetPageReq) GetNeedSearch() interface{} {
}
type LineAddPreOrderExtReq struct {
TakeProfitRatio decimal.Decimal `json:"takeProfitRatio" comment:"止盈百分比"`
ReducePriceRatio decimal.Decimal `json:"reducePriceRatio" comment:"减仓价格百分比"`
ReduceNumRatio decimal.Decimal `json:"reduceNumRatio" comment:"减仓数量百分比"`
ReduceTakeProfitRatio decimal.Decimal `json:"reduceTakeProfitRatio" comment:"减仓后止盈百分比"`
ReduceStopLossRatio decimal.Decimal `json:"reduceStopLossRatio" comment:"减仓后止百分比"`
AddPositionPriceRatio decimal.Decimal `json:"addPositionPriceRatio" comment:"加仓价格百分比"`
AddPositionOrderType string `json:"addPositionOrderType" comment:"加仓订单类型 LIMIT-限价 MARKET-市价"`
AddPositionType int `json:"addPositionType" comment:"加仓类型 1-百分比 2-实际金额"`
AddPositionVal decimal.Decimal `json:"addPositionVal" comment:"加仓"`
TakeProfitRatio decimal.Decimal `json:"takeProfitRatio" comment:"止盈百分比"`
ReTakeProfitRatio decimal.Decimal `json:"reTakeProfitRatio" comment:"亏损回本止盈百分比"`
ReducePriceRatio decimal.Decimal `json:"reducePriceRatio" comment:"减仓价格百分比"`
ReduceNumRatio decimal.Decimal `json:"reduceNumRatio" comment:"减仓数量百分比"`
ReduceTakeProfitRatio decimal.Decimal `json:"reduceTakeProfitRatio" comment:"减仓后止百分比"`
ReduceStopLossRatio decimal.Decimal `json:"reduceStopLossRatio" comment:"减仓后止损百分比"`
ReduceReTakeProfitRatio decimal.Decimal `json:"reduceReTakeProfitRatio" comment:"减仓后回本止盈百分比"`
AddPositionPriceRatio decimal.Decimal `json:"addPositionPriceRatio" comment:"加仓价格百分比"`
AddPositionOrderType string `json:"addPositionOrderType" comment:"加仓订单类型 LIMIT-限价 MARKET-市价"`
AddPositionType int `json:"addPositionType" comment:"加仓类型 1-百分比 2-实际金额"`
AddPositionVal decimal.Decimal `json:"addPositionVal" comment:"加仓值"`
}
type LinePreOrderExtInsertReq struct {

View File

@ -347,11 +347,13 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
AddOrder.ExpireTime = time.Now().Add(time.Duration(req.ExpireHour) * time.Hour) //过期时间
AddOrder.MainOrderType = req.MainOrderType
AddOrder.Site = req.Site
AddOrder.SignPrice = tickerPrice.String()
if req.PricePattern == "percentage" {
AddOrder.Rate = req.Price
orderPrice, _ := decimal.NewFromString(req.Price) //下单价百分比 10%
priceRate := orderPrice.Div(decimal.NewFromInt(100)) //下单价除100 =0.1
AddOrder.SignPrice = tickerPrice.String()
if strings.ToUpper(req.Site) == "BUY" { //购买方向
//实际下单价格
truncate := tickerPrice.Mul(decimal.NewFromInt(1).Sub(priceRate)).Truncate(int32(tradeSet.PriceDigit))
@ -363,11 +365,10 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
} else { //实际价格下单
AddOrder.Price = utility.StringToDecimal(req.Price).Truncate(int32(tradeSet.PriceDigit)).String()
AddOrder.SignPrice = req.Price
AddOrder.SignPriceType = req.PricePattern
AddOrder.Rate = "0"
}
buyPrice, _ := decimal.NewFromString(req.BuyPrice) //购买多少U
buyPrice := utility.StrToDecimal(req.BuyPrice) //购买多少U
var symbolInfo models.LineSymbol
e.Orm.Model(&models.LineSymbol{}).Where("type = ? AND symbol = ?", req.SymbolType, req.Symbol).Find(&symbolInfo)
//计算购买数量 判断是否是否是U本位
@ -426,9 +427,31 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
ReduceTakeProfitRatio: req.ReduceTakeProfitRatio,
ReduceStopLossRatio: req.ReduceStopLossRatio,
}
mainPrice := utility.StringToDecimal(AddOrder.Price)
mainAmount := buyPrice.Div(mainPrice)
defultExt.TotalAfterReducing = mainAmount.Mul(decimal.NewFromInt(100).Sub(req.ReduceNumRatio)).Div(decimal.NewFromInt(100)).Truncate(int32(tradeSet.AmountDigit))
preOrderExts = append(preOrderExts, defultExt)
for _, addPosition := range req.Ext {
calculateResp := dto.CalculateBreakEvenRatioResp{}
mainParam := dto.CalculateBreakEevenRatioReq{
Price: mainPrice,
ExchangeType: req.ExchangeType,
Symbol: req.Symbol,
SymbolType: req.SymbolType,
BuyPrice: buyPrice,
LossBeginPercent: decimal.Zero,
LossEndPercent: req.ReducePriceRatio,
AddPositionType: 2,
AddPositionVal: decimal.Zero,
ReducePercent: req.ReduceNumRatio,
}
//计算减仓后
mainParam.LossBeginPercent = req.ReducePriceRatio
mainParam.RemainingQuantity = mainAmount.Mul(decimal.NewFromInt(100).Sub(req.ReduceNumRatio).Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit))
mainParam.TotalLossAmountU = buyPrice.Mul(req.ReducePriceRatio.Div(decimal.NewFromInt(100)).Truncate(4)).Truncate(int32(tradeSet.PriceDigit))
for index, addPosition := range req.Ext {
ext := models.LinePreOrderExt{
TakeProfitRatio: addPosition.TakeProfitRatio,
ReducePriceRatio: addPosition.ReducePriceRatio,
@ -441,6 +464,30 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
AddPositionVal: addPosition.AddPositionVal,
}
mainParam.LossEndPercent = req.Ext[index].AddPositionPriceRatio
mainParam.AddPositionType = req.Ext[index].AddPositionType
mainParam.AddPositionVal = req.Ext[index].AddPositionVal
mainParam.ReducePercent = decimal.Zero
e.CalculateBreakEvenRatio(&mainParam, &calculateResp)
ext.TotalAfterAdding = calculateResp.RemainingQuantity
req.Ext[index].ReTakeProfitRatio = calculateResp.Ratio
mainParam.LossBeginPercent = req.Ext[index].AddPositionPriceRatio
mainParam.RemainingQuantity = calculateResp.RemainingQuantity
mainParam.TotalLossAmountU = calculateResp.TotalLossAmountU
mainParam.LossEndPercent = req.Ext[index].ReducePriceRatio
mainParam.AddPositionVal = decimal.Zero
mainParam.ReducePercent = req.Ext[index].ReduceNumRatio
e.CalculateBreakEvenRatio(&mainParam, &calculateResp)
req.Ext[index].ReduceReTakeProfitRatio = calculateResp.Ratio
mainParam.LossBeginPercent = req.Ext[index].ReducePriceRatio
mainParam.RemainingQuantity = calculateResp.RemainingQuantity
mainParam.TotalLossAmountU = calculateResp.TotalLossAmountU
ext.TotalAfterReducing = calculateResp.RemainingQuantity
ext.ReTakeRatio = req.Ext[index].ReTakeProfitRatio
ext.ReduceReTakeRatio = req.Ext[index].ReduceReTakeProfitRatio
preOrderExts = append(preOrderExts, ext)
}
@ -520,10 +567,77 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
stopOrder.OrderType = 4
stopOrder.Status = 0
stopOrder.Rate = req.ReducePriceRatio.String()
stopOrder.Num = utility.StrToDecimal(AddOrder.Num).Mul(req.ReduceNumRatio.Div(decimal.NewFromInt(100)).Truncate(4)).Truncate(int32(tradeSet.AmountDigit)).String()
tx.Model(&models.LinePreOrder{}).Omit("id", "save_template", "template_name").Create(&stopOrder)
if req.ReduceNumRatio.Cmp(decimal.Zero) > 0 && req.ReduceNumRatio.Cmp(decimal.NewFromInt(100)) < 0 {
if newOrders, err := makeReduceTakeAndStoploss(&stopOrder, defultExt, tradeSet); err != nil {
logger.Errorf("主单减仓生成止盈、减仓失败 err:%v", err)
return err
} else if len(newOrders) > 0 {
if err := e.Orm.Create(&newOrders).Error; err != nil {
logger.Errorf("主单减仓保存止盈、减仓失败 err:%v", err)
return err
}
}
}
}
//添加止盈单
for index, v := range preOrderExts {
preOrderExts[index].MainOrderId = AddOrder.Id
if index == 0 {
preOrderExts[index].OrderId = AddOrder.Id
continue
}
addPosition := createPreAddPosition(&AddOrder, v, tradeSet)
if addPosition.OrderSn == "" {
continue
}
preOrderExts[index].OrderId = addPosition.Id
if err := e.Orm.Create(&addPosition).Error; err != nil {
logger.Error("保存加仓单失败")
return err
}
//止盈、减仓
orders, err := makeFuturesTakeAndReduce(&addPosition, v, tradeSet)
if err != nil {
logger.Error("构造加仓单止盈、减仓失败")
return err
}
if err := e.Orm.Create(&orders).Error; err != nil {
logger.Error("保存加仓单止盈、减仓失败")
return err
}
for index := range orders {
//减仓单且 减仓比例大于0 小于100 就冲下止盈止损
if orders[index].OrderType == 4 && v.ReduceNumRatio.Cmp(decimal.Zero) > 0 && v.ReduceNumRatio.Cmp(decimal.NewFromInt(100)) < 0 {
reduceChildOrders, err := makeReduceTakeAndStoploss(&(orders[index]), v, tradeSet)
if err != nil {
logger.Error("生产加仓单止盈、减仓失败")
return err
}
if len(reduceChildOrders) == 0 {
continue
}
if err := e.Orm.Create(&reduceChildOrders).Error; err != nil {
logger.Error("报错减仓后止盈止损失败")
return err
}
}
}
}
return nil
})
}
@ -531,6 +645,160 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
return nil
}
// 生成加仓单
func createPreAddPosition(preOrder *models.LinePreOrder, v models.LinePreOrderExt, tradeSet models2.TradeSet) models.LinePreOrder {
data := models.LinePreOrder{}
//主单类型
if v.AddPositionVal.Cmp(decimal.Zero) <= 0 {
logger.Errorf("预生成加仓单失败, 主订单号:%s 加仓数值不大于0", preOrder.OrderSn)
return data
}
price := utility.StrToDecimal(preOrder.Price)
copier.Copy(&data, preOrder)
data.Id = 0
data.Pid = preOrder.Id
data.OrderSn = utility.Int64ToString(snowflakehelper.GetOrderId())
data.MainId = preOrder.Id
data.CreatedAt = time.Now()
data.MainOrderType = v.AddPositionOrderType
data.Status = 0
data.OrderCategory = 3
data.Rate = v.AddPositionPriceRatio.String()
var percentage decimal.Decimal
if data.Site == "BUY" {
percentage = decimal.NewFromInt(1).Sub(v.AddPositionPriceRatio.Div(decimal.NewFromInt(100)))
} else {
percentage = decimal.NewFromInt(1).Add(v.AddPositionPriceRatio.Div(decimal.NewFromInt(100)))
}
dataPrice := price.Mul(percentage).Truncate(int32(tradeSet.PriceDigit))
data.Price = dataPrice.String()
if v.AddPositionType == 1 {
buyPrice := utility.StrToDecimal(preOrder.BuyPrice).Mul(v.AddPositionVal.Div(decimal.NewFromInt(100))).Truncate(2)
data.Num = buyPrice.Div(dataPrice).Truncate(int32(tradeSet.AmountDigit)).String()
data.BuyPrice = buyPrice.String()
} else {
data.BuyPrice = v.AddPositionVal.Truncate(2).String()
data.Num = v.AddPositionVal.Truncate(2).Div(dataPrice).Truncate(int32(tradeSet.AmountDigit)).String()
}
return data
}
// 构建合约止盈、减仓单
func makeFuturesTakeAndReduce(preOrder *models.LinePreOrder, ext models.LinePreOrderExt, tradeSet models2.TradeSet) ([]models.LinePreOrder, error) {
num := ext.TotalAfterAdding
orders := make([]models.LinePreOrder, 0)
//止盈单
profitOrder := models.LinePreOrder{}
copier.Copy(&profitOrder, preOrder)
profitOrder.Id = 0
profitOrder.OrderSn = strconv.FormatInt(snowflakehelper.GetOrderId(), 10)
profitOrder.Pid = preOrder.Id
profitOrder.OrderType = 1
profitOrder.Status = 0
profitOrder.MainId = preOrder.MainId
profitOrder.Num = num.Truncate(int32(tradeSet.AmountDigit)).String()
profitOrder.BuyPrice = "0"
// profitOrder.Rate = ext.TakeProfitRatio.String()
//止盈需要累加之前的亏损
profitOrder.Rate = ext.TakeProfitRatio.Add(ext.ReTakeRatio).Truncate(2).String()
if strings.ToUpper(preOrder.Site) == "BUY" {
profitOrder.Site = "SELL"
} else {
profitOrder.Site = "BUY"
}
binanceservice.SetPrice(&profitOrder, preOrder, tradeSet)
orders = append(orders, profitOrder)
//减仓单
if ext.ReducePriceRatio.Cmp(decimal.Zero) > 0 {
stopOrder := models.LinePreOrder{}
copier.Copy(&stopOrder, preOrder)
stopOrder.Id = 0
stopOrder.OrderSn = strconv.FormatInt(snowflakehelper.GetOrderId(), 10)
stopOrder.Pid = preOrder.Id
stopOrder.MainId = preOrder.MainId
stopOrder.OrderType = 4
stopOrder.Status = 0
stopOrder.Rate = ext.ReducePriceRatio.String()
stopOrder.Num = num.String()
stopOrder.BuyPrice = "0"
if ext.ReduceNumRatio.Cmp(decimal.Zero) > 0 {
stopOrder.Num = num.Mul(ext.ReduceNumRatio.Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit)).String()
}
if strings.ToUpper(preOrder.Site) == "BUY" {
stopOrder.Site = "SELL"
} else {
stopOrder.Site = "BUY"
}
binanceservice.SetPrice(&stopOrder, preOrder, tradeSet)
orders = append(orders, stopOrder)
}
return orders, nil
}
// 构建减仓后止盈止损
func makeReduceTakeAndStoploss(parentOrder *models.LinePreOrder, ext models.LinePreOrderExt, tradeSet models2.TradeSet) ([]models.LinePreOrder, error) {
orders := make([]models.LinePreOrder, 0)
takeProfitOrder := models.LinePreOrder{}
copier.Copy(&takeProfitOrder, parentOrder)
takeProfitOrder.Id = 0
takeProfitOrder.Pid = parentOrder.Id
takeProfitOrder.OrderSn = utility.Int64ToString(snowflakehelper.GetOrderId())
takeProfitOrder.Status = 0
takeProfitOrder.OrderType = 1
takeProfitOrder.Rate = ext.ReduceTakeProfitRatio.String()
takeProfitOrder.SignPrice = parentOrder.Price
takeProfitOrder.CreatedAt = time.Now()
takeProfitOrder.BuyPrice = "0"
takeProfitOrder.MainOrderType = "LIMIT"
takeProfitOrder.Num = ext.TotalAfterReducing.Truncate(int32(tradeSet.AmountDigit)).String()
// takeProfitOrder.Rate = ext.ReduceTakeProfitRatio.String()
//止盈需要累加之前的亏损
takeProfitOrder.Rate = ext.ReduceTakeProfitRatio.Add(ext.ReduceReTakeRatio).String()
takeProfitOrder.BuyPrice = "0"
binanceservice.SetPrice(&takeProfitOrder, parentOrder, tradeSet)
orders = append(orders, takeProfitOrder)
//有止损单
if ext.ReduceStopLossRatio.Cmp(decimal.Zero) > 0 {
var stoploss models.LinePreOrder
copier.Copy(&stoploss, parentOrder)
stoploss.Id = 0
stoploss.Pid = parentOrder.Id
stoploss.OrderSn = utility.Int64ToString(snowflakehelper.GetOrderId())
stoploss.Status = 0
stoploss.CreatedAt = time.Now()
stoploss.OrderType = 2
stoploss.SignPrice = parentOrder.Price
stoploss.BuyPrice = "0"
stoploss.Rate = ext.ReduceStopLossRatio.String()
stoploss.MainOrderType = "LIMIT"
stoploss.Num = ext.TotalAfterReducing.Truncate(int32(tradeSet.AmountDigit)).String()
stoploss.BuyPrice = "0"
binanceservice.SetPrice(&stoploss, parentOrder, tradeSet)
orders = append(orders, stoploss)
}
return orders, nil
}
// CheckRepeatOrder 检查重复下单 检查基础货币
func (e *LinePreOrder) CheckRepeatOrder(orderType int, apiUserId, site, baseCoin string) int64 {
var count int64
@ -1317,6 +1585,83 @@ func (e *LinePreOrder) QueryAiCoinPrice(req *dto.QueryAiCoinPriceReq) (models.Li
return info, err
}
// 根据请求参数重新生成亏损回本止盈百分比
func (e *LinePreOrder) GenerateOrder(req *dto.LineAddPreOrderReq) ([]models.LineDirection, error) {
var tradeSet models2.TradeSet
var tickerPrice decimal.Decimal
if req.SymbolType == 1 {
tradeSet, _ = binanceservice.GetTradeSet(req.Symbol, 0)
} else {
tradeSet, _ = binanceservice.GetTradeSet(req.Symbol, 1)
}
if tradeSet.LastPrice == "" {
return nil, errors.New("获取不到交易对信息")
}
var price decimal.Decimal
tickerPrice = utility.StrToDecimal(tradeSet.LastPrice)
if req.PricePattern == "percentage" {
orderPrice, _ := decimal.NewFromString(req.Price) //下单价百分比 10%
priceRate := orderPrice.Div(decimal.NewFromInt(100)) //下单价除100 =0.1
if strings.ToUpper(req.Site) == "BUY" { //购买方向
//实际下单价格
price = tickerPrice.Mul(decimal.NewFromInt(1).Sub(priceRate)).Truncate(int32(tradeSet.PriceDigit))
} else {
price = tickerPrice.Mul(decimal.NewFromInt(1).Add(priceRate)).Truncate(int32(tradeSet.PriceDigit))
}
} else { //实际价格下单
price = utility.StringToDecimal(req.Price).Truncate(int32(tradeSet.PriceDigit))
}
buyPrice := utility.StrToDecimal(req.BuyPrice)
mainAmount := buyPrice.Div(price)
calculateResp := dto.CalculateBreakEvenRatioResp{}
mainParam := dto.CalculateBreakEevenRatioReq{
Price: price,
ExchangeType: req.ExchangeType,
Symbol: req.Symbol,
SymbolType: req.SymbolType,
BuyPrice: buyPrice,
LossBeginPercent: decimal.Zero,
LossEndPercent: req.ReducePriceRatio,
AddPositionType: 2,
AddPositionVal: decimal.Zero,
ReducePercent: req.ReduceNumRatio,
}
//计算减仓后
mainParam.LossBeginPercent = req.ReducePriceRatio
mainParam.RemainingQuantity = mainAmount.Mul(decimal.NewFromInt(100).Sub(req.ReduceNumRatio).Div(decimal.NewFromInt(100))).Truncate(int32(tradeSet.AmountDigit))
mainParam.TotalLossAmountU = buyPrice.Mul(req.ReducePriceRatio.Div(decimal.NewFromInt(100)).Truncate(4)).Truncate(int32(tradeSet.PriceDigit))
for index := range req.Ext {
mainParam.LossEndPercent = req.Ext[index].AddPositionPriceRatio
mainParam.AddPositionType = req.Ext[index].AddPositionType
mainParam.AddPositionVal = req.Ext[index].AddPositionVal
mainParam.ReducePercent = decimal.Zero
e.CalculateBreakEvenRatio(&mainParam, &calculateResp)
req.Ext[index].ReTakeProfitRatio = calculateResp.Ratio
mainParam.LossBeginPercent = req.Ext[index].AddPositionPriceRatio
mainParam.RemainingQuantity = calculateResp.RemainingQuantity
mainParam.TotalLossAmountU = calculateResp.TotalLossAmountU
mainParam.LossEndPercent = req.Ext[index].ReducePriceRatio
mainParam.AddPositionVal = decimal.Zero
mainParam.ReducePercent = req.Ext[index].ReduceNumRatio
e.CalculateBreakEvenRatio(&mainParam, &calculateResp)
req.Ext[index].ReduceReTakeProfitRatio = calculateResp.Ratio
mainParam.LossBeginPercent = req.Ext[index].ReducePriceRatio
mainParam.RemainingQuantity = calculateResp.RemainingQuantity
mainParam.TotalLossAmountU = calculateResp.TotalLossAmountU
}
return nil, nil
}
// 计算亏损百分比
func (e *LinePreOrder) CalculateBreakEvenRatio(req *dto.CalculateBreakEevenRatioReq, data *dto.CalculateBreakEvenRatioResp) error {
var tradeSet models2.TradeSet
@ -1351,7 +1696,7 @@ func (e *LinePreOrder) CalculateBreakEvenRatio(req *dto.CalculateBreakEevenRatio
var percentDiff decimal.Decimal
var reduceAmount decimal.Decimal
nowPrice := req.Price.Mul(decimal.NewFromInt(1).Sub(req.LossEndPercent.Div(decimal.NewFromInt(100).Truncate(4))))
nowPrice := req.Price.Mul(decimal.NewFromInt(1).Sub(req.LossEndPercent.Div(decimal.NewFromInt(100)).Truncate(4))).Truncate(int32(tradeSet.PriceDigit))
addPositionAmount := addPositionBuyPrice.Div(nowPrice).Truncate(int32(tradeSet.AmountDigit))
//计算价格下跌价差
@ -1360,7 +1705,7 @@ func (e *LinePreOrder) CalculateBreakEvenRatio(req *dto.CalculateBreakEevenRatio
}
totalAmount := req.RemainingQuantity.Add(addPositionAmount)
lossAmountU := req.Price.Mul(percentDiff.Div(decimal.NewFromInt(100)).Truncate(4)).Mul(req.RemainingQuantity).Truncate(int32(tradeSet.AmountDigit))
lossAmountU := req.Price.Mul(percentDiff.Div(decimal.NewFromInt(100).Truncate(4))).Mul(req.RemainingQuantity).Truncate(int32(tradeSet.AmountDigit))
//计算减仓数量
if req.ReducePercent.Cmp(decimal.NewFromInt(0)) > 0 {
@ -1373,6 +1718,8 @@ func (e *LinePreOrder) CalculateBreakEvenRatio(req *dto.CalculateBreakEevenRatio
//计算百分比
if data.RemainingQuantity.Cmp(decimal.Zero) > 0 {
data.Ratio = data.TotalLossAmountU.Div(data.RemainingQuantity).Div(nowPrice).Mul(decimal.NewFromInt(100)).Truncate(2)
} else {
data.Ratio = decimal.Zero
}
return nil

View File

@ -158,7 +158,7 @@ func (t LimitOrderTimeoutDuration) Exec(arg interface{}) error {
}
limitOrderTimeoutDuration := utility.StringAsInt64(resp.ConfigValue)
orders := make([]models.LinePreOrder, 0)
err := db.Model(&models.LinePreOrder{}).Where("status = '5' AND main_order_type = 'LIMIT' AND order_type in ('0','4') AND order_category = 3 AND updated_at < ?", time.Now().Add(-time.Duration(limitOrderTimeoutDuration)*time.Second)).Find(&orders).Error
err := db.Model(&models.LinePreOrder{}).Where("status = '5' AND main_order_type = 'LIMIT' AND order_type in ('4') AND order_category = 3 AND updated_at < ?", time.Now().Add(-time.Duration(limitOrderTimeoutDuration)*time.Second)).Find(&orders).Error
if err != nil {
return err
}