This commit is contained in:
2025-02-08 14:05:57 +08:00
parent c0b8749eef
commit 979ef507fe
30 changed files with 660 additions and 431 deletions

View File

@ -111,6 +111,12 @@ func (e LineApiGroup) Insert(c *gin.Context) {
e.Error(500, err, err.Error())
return
}
if err := req.Valid(); err != nil {
e.Error(500, err, err.Error())
return
}
// 设置创建人
req.SetCreateBy(user.GetUserId(c))

View File

@ -236,7 +236,7 @@ func (e LineApiUser) GetUser(c *gin.Context) {
}
//p := actions.GetPermissionFromContext(c)
list := make([]models.LineApiUser, 0)
err = s.GetUser(&list)
err = s.GetUser(&req, &list)
if err != nil {
e.Error(500, err, fmt.Sprintf("获取失败,\r\n失败信息 %s", err.Error()))
return
@ -247,8 +247,10 @@ func (e LineApiUser) GetUser(c *gin.Context) {
// GetMainUser 获取主账号
func (e LineApiUser) GetMainUser(c *gin.Context) {
s := service.LineApiUser{}
req := dto.GetMainUserReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
@ -258,7 +260,7 @@ func (e LineApiUser) GetMainUser(c *gin.Context) {
}
//p := actions.GetPermissionFromContext(c)
list := make([]models.LineApiUser, 0)
err = s.GetMainUser(&list)
err = s.GetMainUser(&req, &list)
if err != nil {
e.Error(500, err, fmt.Sprintf("获取失败,\r\n失败信息 %s", err.Error()))
return

View File

@ -245,7 +245,7 @@ func (e LineSymbol) SyncSpotSymbol(c *gin.Context) {
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
continue
}
key := fmt.Sprintf("%s:%s", global.TICKER_SPOT, symbol)
key := fmt.Sprintf(global.TICKER_SPOT, global.EXCHANGE_BINANCE, symbol)
//判断是否在黑名单里面
for _, black := range symbolBlack {
@ -283,6 +283,7 @@ func (e LineSymbol) SyncSpotSymbol(c *gin.Context) {
}
}
if lineSymbol.Id <= 0 {
lineSymbol.ExchangeType = global.EXCHANGE_BINANCE
lineSymbol.Symbol = symbol
lineSymbol.BaseAsset = tradeSet.Coin
lineSymbol.QuoteAsset = tradeSet.Currency
@ -308,7 +309,7 @@ func (e LineSymbol) SyncSpotSymbol(c *gin.Context) {
e.Orm.Model(&models.LineSymbolGroup{}).Where("id = ?", group.Id).Update("symbol", join)
}
}
e.Orm.Model(&models.LineSymbol{}).Where("symbol = ? AND type = 1", symbol).Unscoped().Delete(&models.LineSymbol{})
e.Orm.Model(&models.LineSymbol{}).Where("symbol = ? AND type = 1 AND exchange_type =?", symbol, global.EXCHANGE_BINANCE).Unscoped().Delete(&models.LineSymbol{})
}
}
@ -406,6 +407,7 @@ func (e LineSymbol) SyncFutSymbol(c *gin.Context) {
}
if lineSymbol.Id <= 0 {
lineSymbol.ExchangeType = global.EXCHANGE_BINANCE
lineSymbol.Symbol = symbol
lineSymbol.BaseAsset = tradeSet.Coin
lineSymbol.QuoteAsset = tradeSet.Currency
@ -423,8 +425,8 @@ func (e LineSymbol) SyncFutSymbol(c *gin.Context) {
//如果在交易对组里面
groups := make([]models.LineSymbolGroup, 0)
//var symbolGroup []models.LineSymbolGroup
sql := "SELECT * FROM line_symbol_group WHERE FIND_IN_SET( ? , symbol) AND type = 2 AND deleted_at is NULL;"
e.Orm.Model(&models.LineSymbolGroup{}).Exec(sql, symbol).Find(&groups)
sql := "SELECT * FROM line_symbol_group WHERE FIND_IN_SET( ? , symbol) AND type = 2 AND exchange_type =? AND deleted_at is NULL;"
e.Orm.Model(&models.LineSymbolGroup{}).Exec(sql, symbol, global.EXCHANGE_BINANCE).Find(&groups)
for _, group := range groups {
if group.Id > 0 {
split := strings.Split(group.Symbol, ",")
@ -433,7 +435,7 @@ func (e LineSymbol) SyncFutSymbol(c *gin.Context) {
e.Orm.Model(&models.LineSymbolGroup{}).Where("id = ?", group.Id).Update("symbol", join)
}
}
e.Orm.Model(&models.LineSymbol{}).Where("symbol = ? AND type = 2", symbol).Unscoped().Delete(&models.LineSymbol{})
e.Orm.Model(&models.LineSymbol{}).Where("symbol = ? AND exchange_type =? AND type = 2", symbol, global.EXCHANGE_BINANCE).Unscoped().Delete(&models.LineSymbol{})
}
}
@ -450,8 +452,10 @@ func (e LineSymbol) SyncFutSymbol(c *gin.Context) {
// GetSymbol 获取现货和合约都有的交易对
func (e LineSymbol) GetSymbol(c *gin.Context) {
s := service.LineSymbol{}
req := dto.LineSymbolGetListReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
@ -460,7 +464,7 @@ func (e LineSymbol) GetSymbol(c *gin.Context) {
return
}
data, err := s.GetSymbol()
data, err := s.GetSymbol(&req)
if err != nil {
e.Error(500, err, fmt.Sprintf("获取失败,\r\n失败信息 %s", err.Error()))
return

View File

@ -1,7 +1,7 @@
package apis
import (
"fmt"
"fmt"
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/sdk/api"
@ -29,18 +29,18 @@ type LineSymbolGroup struct {
// @Router /api/v1/line-symbol-group [get]
// @Security Bearer
func (e LineSymbolGroup) GetPage(c *gin.Context) {
req := dto.LineSymbolGroupGetPageReq{}
s := service.LineSymbolGroup{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req := dto.LineSymbolGroupGetPageReq{}
s := service.LineSymbolGroup{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
p := actions.GetPermissionFromContext(c)
list := make([]models.LineSymbolGroup, 0)
@ -49,7 +49,7 @@ func (e LineSymbolGroup) GetPage(c *gin.Context) {
err = s.GetPage(&req, p, &list, &count)
if err != nil {
e.Error(500, err, fmt.Sprintf("获取交易对组列表失败,\r\n失败信息 %s", err.Error()))
return
return
}
e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
@ -66,7 +66,7 @@ func (e LineSymbolGroup) GetPage(c *gin.Context) {
func (e LineSymbolGroup) Get(c *gin.Context) {
req := dto.LineSymbolGroupGetReq{}
s := service.LineSymbolGroup{}
err := e.MakeContext(c).
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
@ -82,10 +82,10 @@ func (e LineSymbolGroup) Get(c *gin.Context) {
err = s.Get(&req, p, &object)
if err != nil {
e.Error(500, err, fmt.Sprintf("获取交易对组列表失败,\r\n失败信息 %s", err.Error()))
return
return
}
e.OK( object, "查询成功")
e.OK(object, "查询成功")
}
// Insert 创建交易对组列表
@ -99,25 +99,25 @@ func (e LineSymbolGroup) Get(c *gin.Context) {
// @Router /api/v1/line-symbol-group [post]
// @Security Bearer
func (e LineSymbolGroup) Insert(c *gin.Context) {
req := dto.LineSymbolGroupInsertReq{}
s := service.LineSymbolGroup{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req := dto.LineSymbolGroupInsertReq{}
s := service.LineSymbolGroup{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// 设置创建人
req.SetCreateBy(user.GetUserId(c))
err = s.Insert(&req)
if err != nil {
e.Error(500, err, fmt.Sprintf("创建交易对组列表失败,\r\n失败信息 %s", err.Error()))
return
return
}
e.OK(req.GetId(), "创建成功")
@ -135,27 +135,27 @@ func (e LineSymbolGroup) Insert(c *gin.Context) {
// @Router /api/v1/line-symbol-group/{id} [put]
// @Security Bearer
func (e LineSymbolGroup) Update(c *gin.Context) {
req := dto.LineSymbolGroupUpdateReq{}
s := service.LineSymbolGroup{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req := dto.LineSymbolGroupUpdateReq{}
s := service.LineSymbolGroup{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
req.SetUpdateBy(user.GetUserId(c))
p := actions.GetPermissionFromContext(c)
err = s.Update(&req, p)
if err != nil {
e.Error(500, err, fmt.Sprintf("修改交易对组列表失败,\r\n失败信息 %s", err.Error()))
return
return
}
e.OK( req.GetId(), "修改成功")
e.OK(req.GetId(), "修改成功")
}
// Delete 删除交易对组列表
@ -167,18 +167,18 @@ func (e LineSymbolGroup) Update(c *gin.Context) {
// @Router /api/v1/line-symbol-group [delete]
// @Security Bearer
func (e LineSymbolGroup) Delete(c *gin.Context) {
s := service.LineSymbolGroup{}
req := dto.LineSymbolGroupDeleteReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
s := service.LineSymbolGroup{}
req := dto.LineSymbolGroupDeleteReq{}
err := e.MakeContext(c).
MakeOrm().
Bind(&req).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Error(500, err, err.Error())
return
}
// req.SetUpdateBy(user.GetUserId(c))
p := actions.GetPermissionFromContext(c)
@ -186,7 +186,7 @@ func (e LineSymbolGroup) Delete(c *gin.Context) {
err = s.Remove(&req, p)
if err != nil {
e.Error(500, err, fmt.Sprintf("删除交易对组列表失败,\r\n失败信息 %s", err.Error()))
return
return
}
e.OK( req.GetId(), "删除成功")
e.OK(req.GetId(), "删除成功")
}

View File

@ -7,10 +7,11 @@ import (
type LineApiGroup struct {
models.Model
GroupName string `json:"groupName" gorm:"type:varchar(255);comment:用户组名称"`
ApiUserId string `json:"apiUserId" gorm:"type:varchar(255);comment:绑定的api账户id"`
AApiName string `json:"a_api_name" gorm:"-"`
BApiName string `json:"b_api_name" gorm:"-"`
ExchangeType string `json:"exchangeType" gorm:"type:varchar(20);comment:交易所 字典exchange_type"`
GroupName string `json:"groupName" gorm:"type:varchar(255);comment:用户组名称"`
ApiUserId string `json:"apiUserId" gorm:"type:varchar(255);comment:绑定的api账户id"`
AApiName string `json:"a_api_name" gorm:"-"`
BApiName string `json:"b_api_name" gorm:"-"`
models.ModelTime
models.ControlBy
}

View File

@ -7,20 +7,21 @@ import (
type LineApiUser struct {
models.Model
UserId int64 `json:"userId" gorm:"type:int unsigned;comment:用户id"`
JysId int64 `json:"jysId" gorm:"type:int;comment:关联交易所账号id"`
ApiName string `json:"apiName" gorm:"type:varchar(255);comment:api用户名"`
ApiKey string `json:"apiKey" gorm:"type:varchar(255);comment:apiKey"`
ApiSecret string `json:"apiSecret" gorm:"type:varchar(255);comment:apiSecret"`
IpAddress string `json:"ipAddress" gorm:"type:varchar(255);comment:代理地址"`
UserPass string `json:"userPass" gorm:"type:varchar(255);comment:代码账号密码"`
AdminId int64 `json:"adminId" gorm:"type:int unsigned;comment:管理员id"`
Affiliation int64 `json:"affiliation" gorm:"type:int;comment:归属:1=现货,2=合约,3=现货合约"`
AdminShow int64 `json:"adminShow" gorm:"type:int;comment:是否超管可见:1=是,0=否"`
Site string `json:"site" gorm:"type:enum('1','2','3');comment:允许下单的方向:1=多;2=空;3=多空"`
Subordinate string `json:"subordinate" gorm:"type:enum('0','1','2');comment:从属关系:0=未绑定关系;1=主账号;2=副帐号"`
GroupId int64 `json:"groupId" gorm:"type:int unsigned;comment:所属组id"`
OpenStatus int64 `json:"openStatus" gorm:"type:int unsigned;comment:开启状态 0=关闭 1=开启"`
ExchangeType string `json:"exchangeType" gorm:"type:varchar(20);comment:交易所类型(字典 exchange_type)"`
UserId int64 `json:"userId" gorm:"type:int unsigned;comment:用户id"`
JysId int64 `json:"jysId" gorm:"type:int;comment:关联交易所账号id"`
ApiName string `json:"apiName" gorm:"type:varchar(255);comment:api用户名"`
ApiKey string `json:"apiKey" gorm:"type:varchar(255);comment:apiKey"`
ApiSecret string `json:"apiSecret" gorm:"type:varchar(255);comment:apiSecret"`
IpAddress string `json:"ipAddress" gorm:"type:varchar(255);comment:代理地址"`
UserPass string `json:"userPass" gorm:"type:varchar(255);comment:代码账号密码"`
AdminId int64 `json:"adminId" gorm:"type:int unsigned;comment:管理员id"`
Affiliation int64 `json:"affiliation" gorm:"type:int;comment:归属:1=现货,2=合约,3=现货合约"`
AdminShow int64 `json:"adminShow" gorm:"type:int;comment:是否超管可见:1=是,0=否"`
Site string `json:"site" gorm:"type:enum('1','2','3');comment:允许下单的方向:1=多;2=空;3=多空"`
Subordinate string `json:"subordinate" gorm:"type:enum('0','1','2');comment:从属关系:0=未绑定关系;1=主账号;2=副帐号"`
GroupId int64 `json:"groupId" gorm:"type:int unsigned;comment:所属组id"`
OpenStatus int64 `json:"openStatus" gorm:"type:int unsigned;comment:开启状态 0=关闭 1=开启"`
SpotLastTime string `json:"spotLastTime" gorm:"-"` //现货websocket最后通信时间
FuturesLastTime string `json:"futuresLastTime" gorm:"-"` //合约websocket最后通信时间

View File

@ -34,7 +34,8 @@ type LinePreOrder struct {
CoverType int `json:"coverType" gorm:"type:int unsigned;omitempty;comment:对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货"`
ExpireTime time.Time `json:"expireTime" gorm:"comment:过期时间"`
MainOrderType string `json:"mainOrderType" gorm:"type:enum;comment:第一笔(主单类型) 限价LIMIT市价(MARKET)"`
HedgeBuyTotal decimal.Decimal `json:"hedgeBuyTotal" gorm:"type:decimal(10,2);comment:对冲买总金额U"`
HedgeBuyType int `json:"hedge_buy_type" gorm:"type:int;comment:对冲单购买类型 1-百分比 2-实际金额"`
HedgeBuyTotal decimal.Decimal `json:"hedgeBuyTotal" gorm:"type:decimal(10,2);comment:对冲买总金额"`
HedgeOrderType string `json:"hedgeOrderType" gorm:"type:enum;comment:第二笔类型 限价LIMIT市价(MARKET)"`
HedgeTakeProfit decimal.Decimal `json:"hedgeTakeProfit" gorm:"type:decimal(10,2);comment:对冲止盈百分比"`
HedgeStopLoss decimal.Decimal `json:"hedgeStopLoss" gorm:"type:decimal(10,2);comment:对冲止损百分比"`

View File

@ -7,13 +7,14 @@ import (
type LineSymbol struct {
models.Model
ApiId string `json:"apiId" gorm:"type:int;comment:api账户id"`
Symbol string `json:"symbol" gorm:"type:varchar(32);comment:交易对"`
BaseAsset string `json:"baseAsset" gorm:"type:varchar(255);comment:基础货币"`
QuoteAsset string `json:"quoteAsset" gorm:"type:varchar(255);comment:计价货币"`
Switch string `json:"switch" gorm:"type:enum('0','1');comment:状态"`
Type string `json:"type" gorm:"type:enum('1','2');comment:交易对类型"`
Number int `json:"number" gorm:"->"`
ExchangeType string `json:"exchangeType" gorm:"type:varchar(20);comment:交易所类型 字典 exchange_type"`
ApiId string `json:"apiId" gorm:"type:int;comment:api账户id"`
Symbol string `json:"symbol" gorm:"type:varchar(32);comment:交易对"`
BaseAsset string `json:"baseAsset" gorm:"type:varchar(255);comment:基础货币"`
QuoteAsset string `json:"quoteAsset" gorm:"type:varchar(255);comment:计价货币"`
Switch string `json:"switch" gorm:"type:enum('0','1');comment:状态"`
Type string `json:"type" gorm:"type:enum('1','2');comment:交易对类型"`
Number int `json:"number" gorm:"->"`
models.ModelTime
models.ControlBy
}

View File

@ -6,12 +6,12 @@ import (
type LineSymbolGroup struct {
models.Model
GroupName string `json:"groupName" gorm:"type:varchar(255);comment:交易对组名称"`
Symbol string `json:"symbol" gorm:"type:text;comment:交易对"`
GroupType string `json:"groupType" gorm:"type:enum('1','2');comment:分组类型:1=普通类型"`
Type string `json:"type" gorm:"type:enum('1','2');comment:类型:1=现货,2=合约"`
Count int `json:"count" gorm:"->"`
ExchangeType string `json:"exchangeType" gorm:"type:varchar(50);comment:交易所类型"`
GroupName string `json:"groupName" gorm:"type:varchar(255);comment:交易对组名称"`
Symbol string `json:"symbol" gorm:"type:text;comment:交易对"`
GroupType string `json:"groupType" gorm:"type:enum('1','2');comment:分组类型:1=普通类型"`
Type string `json:"type" gorm:"type:enum('1','2');comment:类型:1=现货,2=合约"`
Count int `json:"count" gorm:"->"`
models.ModelTime
models.ControlBy
}

View File

@ -1,28 +1,28 @@
package dto
import (
"errors"
"go-admin/app/admin/models"
"go-admin/common/dto"
common "go-admin/common/models"
)
type LineApiGroupGetPageReq struct {
dto.Pagination `search:"-"`
GroupName string `form:"groupName" search:"type:exact;column:group_name;table:line_api_group" comment:"用户组名称"`
LineApiGroupOrder
dto.Pagination `search:"-"`
ExchangeType string `form:"exchangeType" search:"-"`
GroupName string `form:"groupName" search:"type:exact;column:group_name;table:line_api_group" comment:"用户组名称"`
LineApiGroupOrder
}
type LineApiGroupOrder struct {
Id string `form:"idOrder" search:"type:order;column:id;table:line_api_group"`
GroupName string `form:"groupNameOrder" search:"type:order;column:group_name;table:line_api_group"`
ApiUserId string `form:"apiUserIdOrder" search:"type:order;column:api_user_id;table:line_api_group"`
CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:line_api_group"`
UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:line_api_group"`
DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:line_api_group"`
CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:line_api_group"`
UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:line_api_group"`
Id string `form:"idOrder" search:"type:order;column:id;table:line_api_group"`
GroupName string `form:"groupNameOrder" search:"type:order;column:group_name;table:line_api_group"`
ApiUserId string `form:"apiUserIdOrder" search:"type:order;column:api_user_id;table:line_api_group"`
CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:line_api_group"`
UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:line_api_group"`
DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:line_api_group"`
CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:line_api_group"`
UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:line_api_group"`
}
func (m *LineApiGroupGetPageReq) GetNeedSearch() interface{} {
@ -30,19 +30,28 @@ func (m *LineApiGroupGetPageReq) GetNeedSearch() interface{} {
}
type LineApiGroupInsertReq struct {
Id int `json:"-" comment:""` //
GroupName string `json:"groupName" comment:"用户组名称"`
ApiUserId string `json:"apiUserId" comment:"绑定的api账户id"`
common.ControlBy
Id int `json:"-" comment:""` //
ExchangeType string `json:"exchangeType" comment:"交易所编码"`
GroupName string `json:"groupName" comment:"用户组名称"`
ApiUserId string `json:"apiUserId" comment:"绑定的api账户id"`
common.ControlBy
}
func (s *LineApiGroupInsertReq) Generate(model *models.LineApiGroup) {
if s.Id == 0 {
model.Model = common.Model{ Id: s.Id }
}
model.GroupName = s.GroupName
model.ApiUserId = s.ApiUserId
model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
func (req *LineApiGroupInsertReq) Valid() error {
if req.ExchangeType == "" {
return errors.New("交易所不能为空")
}
return nil
}
func (s *LineApiGroupInsertReq) Generate(model *models.LineApiGroup) {
if s.Id == 0 {
model.Model = common.Model{Id: s.Id}
}
model.ExchangeType = s.ExchangeType
model.GroupName = s.GroupName
model.ApiUserId = s.ApiUserId
model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
}
func (s *LineApiGroupInsertReq) GetId() interface{} {
@ -50,19 +59,21 @@ func (s *LineApiGroupInsertReq) GetId() interface{} {
}
type LineApiGroupUpdateReq struct {
Id int `uri:"id" comment:""` //
GroupName string `json:"groupName" comment:"用户组名称"`
ApiUserId string `json:"apiUserId" comment:"绑定的api账户id"`
common.ControlBy
Id int `uri:"id" comment:""` //
ExchangeType string `json:"exchangeType" comment:"交易所编码"`
GroupName string `json:"groupName" comment:"用户组名称"`
ApiUserId string `json:"apiUserId" comment:"绑定的api账户id"`
common.ControlBy
}
func (s *LineApiGroupUpdateReq) Generate(model *models.LineApiGroup) {
if s.Id == 0 {
model.Model = common.Model{ Id: s.Id }
}
model.GroupName = s.GroupName
model.ApiUserId = s.ApiUserId
model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
func (s *LineApiGroupUpdateReq) Generate(model *models.LineApiGroup) {
if s.Id == 0 {
model.Model = common.Model{Id: s.Id}
}
model.ExchangeType = s.ExchangeType
model.GroupName = s.GroupName
model.ApiUserId = s.ApiUserId
model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
}
func (s *LineApiGroupUpdateReq) GetId() interface{} {
@ -71,8 +82,9 @@ func (s *LineApiGroupUpdateReq) GetId() interface{} {
// LineApiGroupGetReq 功能获取请求参数
type LineApiGroupGetReq struct {
Id int `uri:"id"`
Id int `uri:"id"`
}
func (s *LineApiGroupGetReq) GetId() interface{} {
return s.Id
}

View File

@ -8,6 +8,7 @@ import (
type LineApiUserGetPageReq struct {
dto.Pagination `search:"-"`
ExchangeType string `form:"exchangeType" search:"-"`
LineApiUserOrder
}
@ -39,21 +40,22 @@ func (m *LineApiUserGetPageReq) GetNeedSearch() interface{} {
}
type LineApiUserInsertReq struct {
Id int `json:"-" comment:"id"` // id
UserId int64 `json:"userId" comment:"用户id"`
JysId int64 `json:"jysId" comment:"关联交易所账号id"`
ApiName string `json:"apiName" comment:"api用户名"`
ApiKey string `json:"apiKey" comment:"apiKey"`
ApiSecret string `json:"apiSecret" comment:"apiSecret"`
IpAddress string `json:"ipAddress" comment:"代理地址"`
UserPass string `json:"userPass" comment:"代码账号密码"`
AdminId int64 `json:"adminId" comment:"管理员id"`
Affiliation int64 `json:"affiliation" comment:"归属:1=现货,2=合约,3=现货合约"`
AdminShow int64 `json:"adminShow" comment:"是否超管可见:1=是,0=否"`
Site string `json:"site" comment:"允许下单的方向:1=多;2=空;3=多空"`
Subordinate string `json:"subordinate" comment:"从属关系:0=未绑定关系;1=主账号;2=副帐号"`
GroupId int64 `json:"groupId" comment:"所属组id"`
OpenStatus int64 `json:"openStatus" comment:"开启状态 0=关闭 1=开启"`
Id int `json:"-" comment:"id"` // id
ExchangeType string `json:"exchangeType" comment:"交易所code"`
UserId int64 `json:"userId" comment:"用户id"`
JysId int64 `json:"jysId" comment:"关联交易所账号id"`
ApiName string `json:"apiName" comment:"api用户名"`
ApiKey string `json:"apiKey" comment:"apiKey"`
ApiSecret string `json:"apiSecret" comment:"apiSecret"`
IpAddress string `json:"ipAddress" comment:"代理地址"`
UserPass string `json:"userPass" comment:"代码账号密码"`
AdminId int64 `json:"adminId" comment:"管理员id"`
Affiliation int64 `json:"affiliation" comment:"归属:1=现货,2=合约,3=现货合约"`
AdminShow int64 `json:"adminShow" comment:"是否超管可见:1=是,0=否"`
Site string `json:"site" comment:"允许下单的方向:1=多;2=空;3=多空"`
Subordinate string `json:"subordinate" comment:"从属关系:0=未绑定关系;1=主账号;2=副帐号"`
GroupId int64 `json:"groupId" comment:"所属组id"`
OpenStatus int64 `json:"openStatus" comment:"开启状态 0=关闭 1=开启"`
common.ControlBy
}
@ -61,6 +63,7 @@ func (s *LineApiUserInsertReq) Generate(model *models.LineApiUser) {
if s.Id == 0 {
model.Model = common.Model{Id: s.Id}
}
model.ExchangeType = s.ExchangeType
model.UserId = s.UserId
model.JysId = s.JysId
model.ApiName = s.ApiName
@ -83,21 +86,22 @@ func (s *LineApiUserInsertReq) GetId() interface{} {
}
type LineApiUserUpdateReq struct {
Id int `uri:"id" comment:"id"` // id
UserId int64 `json:"userId" comment:"用户id"`
JysId int64 `json:"jysId" comment:"关联交易所账号id"`
ApiName string `json:"apiName" comment:"api用户名"`
ApiKey string `json:"apiKey" comment:"apiKey"`
ApiSecret string `json:"apiSecret" comment:"apiSecret"`
IpAddress string `json:"ipAddress" comment:"代理地址"`
UserPass string `json:"userPass" comment:"代码账号密码"`
AdminId int64 `json:"adminId" comment:"管理员id"`
Affiliation int64 `json:"affiliation" comment:"归属:1=现货,2=合约,3=现货合约"`
AdminShow int64 `json:"adminShow" comment:"是否超管可见:1=是,0=否"`
Site string `json:"site" comment:"允许下单的方向:1=多;2=空;3=多空"`
Subordinate string `json:"subordinate" comment:"从属关系:0=未绑定关系;1=主账号;2=副帐号"`
GroupId int64 `json:"groupId" comment:"所属组id"`
OpenStatus int64 `json:"openStatus" comment:"开启状态 0=关闭 1=开启"`
Id int `uri:"id" comment:"id"` // id
ExchangeType string `json:"exchangeType" comment:"交易所code"`
UserId int64 `json:"userId" comment:"用户id"`
JysId int64 `json:"jysId" comment:"关联交易所账号id"`
ApiName string `json:"apiName" comment:"api用户名"`
ApiKey string `json:"apiKey" comment:"apiKey"`
ApiSecret string `json:"apiSecret" comment:"apiSecret"`
IpAddress string `json:"ipAddress" comment:"代理地址"`
UserPass string `json:"userPass" comment:"代码账号密码"`
AdminId int64 `json:"adminId" comment:"管理员id"`
Affiliation int64 `json:"affiliation" comment:"归属:1=现货,2=合约,3=现货合约"`
AdminShow int64 `json:"adminShow" comment:"是否超管可见:1=是,0=否"`
Site string `json:"site" comment:"允许下单的方向:1=多;2=空;3=多空"`
Subordinate string `json:"subordinate" comment:"从属关系:0=未绑定关系;1=主账号;2=副帐号"`
GroupId int64 `json:"groupId" comment:"所属组id"`
OpenStatus int64 `json:"openStatus" comment:"开启状态 0=关闭 1=开启"`
common.ControlBy
}
@ -105,6 +109,7 @@ func (s *LineApiUserUpdateReq) Generate(model *models.LineApiUser) {
if s.Id == 0 {
model.Model = common.Model{Id: s.Id}
}
model.ExchangeType = s.ExchangeType
model.UserId = s.UserId
model.JysId = s.JysId
model.ApiName = s.ApiName
@ -145,6 +150,11 @@ func (s *LineApiUserDeleteReq) GetId() interface{} {
}
type LineApiUserBindSubordinateReq struct {
UserIdStr string `json:"user_id_str"`
GroupName string `json:"group_name"`
ExchangeType string `json:"exchangeType"`
UserIdStr string `json:"user_id_str"`
GroupName string `json:"group_name"`
}
type GetMainUserReq struct {
ExchangeType string `json:"exchangeType"`
}

View File

@ -197,24 +197,28 @@ func (s *LinePreOrderDeleteReq) GetId() interface{} {
}
type LineAddPreOrderReq struct {
ExchangeType string `json:"exchange_type"` //交易所类型
OrderType int `json:"order_type"` //订单类型
Symbol string `json:"symbol"` //交易对
ApiUserId string `json:"api_id"` //下单用户
Site string `json:"site"` //购买方向
BuyPrice string `json:"buy_price"` //购买金额 U
PricePattern string `json:"price_pattern"` //价格模式
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"` //对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货
ExpireHour int `json:"expire_hour"` // 过期时间 单位小时
MainOrderType string `json:"main_order_type"` //主单类型:限价(LIMIT)或市价(MARKET)
HedgeOrderType string `json:"hedge_order_type"` //第二笔(对冲单)类型:限价(LIMIT)或市价(MARKET)
ExchangeType string `json:"exchange_type"` //交易所类型
OrderType int `json:"order_type"` //订单类型
Symbol string `json:"symbol"` //交易对
ApiUserId string `json:"api_id"` //下单用户
Site string `json:"site"` //购买方向
BuyPrice string `json:"buy_price"` //购买金额 U
PricePattern string `json:"price_pattern"` //价格模式
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"` //对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货
ExpireHour int `json:"expire_hour"` // 过期时间 单位小时
MainOrderType string `json:"main_order_type"` //主单类型:限价(LIMIT)或市价(MARKET)
HedgeOrderType string `json:"hedge_order_type"` //第二笔(对冲单)类型:限价(LIMIT)或市价(MARKET)
HedgeBuyType int `json:"hedge_buy_type"` //对冲单购买类型 1-百分比 2-实际金额
HedgeBuyTotal decimal.Decimal `json:"hedge_buy_total"` //对冲购买金额
HedgeTakeProfit decimal.Decimal `json:"hedge_take_profit"` //对冲止盈
HedgeStopLoss decimal.Decimal `json:"hedge_stop_loss"` //对冲止损
}
func (req LineAddPreOrderReq) CheckParams() error {
@ -237,32 +241,40 @@ func (req LineAddPreOrderReq) CheckParams() error {
return errors.New("请选择价格类型")
}
if req.ExchangeType == "" {
return errors.New("请选择交易所")
}
return nil
}
// LineBatchAddPreOrderReq 批量添加订单请求参数
type LineBatchAddPreOrderReq struct {
ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type
SymbolType int `json:"symbolType"` //主单交易对类型 0-现货 1-合约
OrderType int `json:"order_type"` //订单类型
SymbolGroupId string `json:"symbol_group_id"` //交易对组id
Symbol string `json:"symbol"` //交易对
ApiUserId string `json:"api_id"` //下单用户
Site string `json:"site"` //购买方向
BuyPrice string `json:"buy_price"` //购买金额 U
PricePattern string `json:"price_pattern"` //价格模式
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"` //模板名字
OrderNum int `json:"order_num"` //脚本运行次数
Script string `json:"script"` //是否是脚本运行 1 = 是 0= 否
CoverType int `json:"cover_type"` //对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货
ExpireHour int `json:"expire_hour"` // 过期时间 单位小时
MainOrderType string `json:"main_order_type"` //主单类型:限价(LIMIT)或市价(MARKET)
HedgeOrderType string `json:"hedge_order_type"` //第二笔(对冲单)类型:限价(LIMIT)或市价(MARKET)
ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type
SymbolType int `json:"symbolType"` //主单交易对类型 0-现货 1-合约
OrderType int `json:"order_type"` //订单类型
SymbolGroupId string `json:"symbol_group_id"` //交易对组id
Symbol string `json:"symbol"` //交易对
ApiUserId string `json:"api_id"` //下单用户
Site string `json:"site"` //购买方向
BuyPrice string `json:"buy_price"` //购买金额 U
PricePattern string `json:"price_pattern"` //价格模式
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"` //模板名字
OrderNum int `json:"order_num"` //脚本运行次数
Script string `json:"script"` //是否是脚本运行 1 = 是 0= 否
CoverType int `json:"cover_type"` //对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货
ExpireHour int `json:"expire_hour"` // 过期时间 单位小时
MainOrderType string `json:"main_order_type"` //主单类型:限价(LIMIT)或市价(MARKET)
HedgeOrderType string `json:"hedge_order_type"` //第二笔(对冲单)类型:限价(LIMIT)或市价(MARKET)
HedgeBuyType int `json:"hedge_buy_type"` //对冲单购买类型 1-百分比 2-实际金额
HedgeBuyTotal decimal.Decimal `json:"hedge_buy_total"` //对冲购买金额
HedgeTakeProfit decimal.Decimal `json:"hedge_take_profit"` //对冲止盈
HedgeStopLoss decimal.Decimal `json:"hedge_stop_loss"` //对冲止损
}
func (req LineBatchAddPreOrderReq) CheckParams() error {
@ -285,6 +297,10 @@ func (req LineBatchAddPreOrderReq) CheckParams() error {
return errors.New("请选择价格类型")
}
if req.ExchangeType == "" {
return errors.New("请选择交易所")
}
return nil
}

View File

@ -1,6 +1,7 @@
package dto
import (
"errors"
"go-admin/app/admin/models"
"go-admin/common/dto"
common "go-admin/common/models"
@ -8,6 +9,7 @@ import (
type LineSymbolGetPageReq struct {
dto.Pagination `search:"-"`
ExchangeType string `form:"exchangeType" search:"type:exact;column:exchange_type;table:line_symbol"`
Symbol string `form:"symbol" search:"type:contains;column:symbol;table:line_symbol" comment:"交易对"`
BaseAsset string `form:"baseAsset" search:"type:contains;column:base_asset;table:line_symbol" comment:"基础货币"`
QuoteAsset string `form:"quoteAsset" search:"type:exact;column:quote_asset;table:line_symbol" comment:"计价货币"`
@ -30,6 +32,18 @@ type LineSymbolOrder struct {
Type string `form:"typeOrder" search:"type:order;column:type;table:line_symbol"`
}
type LineSymbolGetListReq struct {
ExchangeType string `json:"exchangeType" form:"exchangeType"`
}
func (req *LineSymbolGetListReq) Valid() error {
if req.ExchangeType == "" {
return errors.New("交易所不能为空")
}
return nil
}
func (m *LineSymbolGetPageReq) GetNeedSearch() interface{} {
return *m
}

View File

@ -1,30 +1,30 @@
package dto
import (
"go-admin/app/admin/models"
"go-admin/common/dto"
common "go-admin/common/models"
)
type LineSymbolGroupGetPageReq struct {
dto.Pagination `search:"-"`
Type string `form:"type" search:"type:exact;column:type;table:line_symbol_group" comment:"类型:1=现货,2=合约"`
LineSymbolGroupOrder
dto.Pagination `search:"-"`
ExchangeType string `form:"exchangeType" search:"-"`
Type string `form:"type" search:"type:exact;column:type;table:line_symbol_group" comment:"类型:1=现货,2=合约"`
LineSymbolGroupOrder
}
type LineSymbolGroupOrder struct {
Id string `form:"idOrder" search:"type:order;column:id;table:line_symbol_group"`
GroupName string `form:"groupNameOrder" search:"type:order;column:group_name;table:line_symbol_group"`
Symbol string `form:"symbolOrder" search:"type:order;column:symbol;table:line_symbol_group"`
GroupType string `form:"groupTypeOrder" search:"type:order;column:groupType;table:line_symbol_group"`
Type string `form:"typeOrder" search:"type:order;column:type;table:line_symbol_group"`
CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:line_symbol_group"`
UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:line_symbol_group"`
DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:line_symbol_group"`
CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:line_symbol_group"`
UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:line_symbol_group"`
Id string `form:"idOrder" search:"type:order;column:id;table:line_symbol_group"`
// Exchange string `form:"exchangeOrder" `
GroupName string `form:"groupNameOrder" search:"type:order;column:group_name;table:line_symbol_group"`
Symbol string `form:"symbolOrder" search:"type:order;column:symbol;table:line_symbol_group"`
GroupType string `form:"groupTypeOrder" search:"type:order;column:groupType;table:line_symbol_group"`
Type string `form:"typeOrder" search:"type:order;column:type;table:line_symbol_group"`
CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:line_symbol_group"`
UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:line_symbol_group"`
DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:line_symbol_group"`
CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:line_symbol_group"`
UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:line_symbol_group"`
}
func (m *LineSymbolGroupGetPageReq) GetNeedSearch() interface{} {
@ -32,23 +32,25 @@ func (m *LineSymbolGroupGetPageReq) GetNeedSearch() interface{} {
}
type LineSymbolGroupInsertReq struct {
Id int `json:"-" comment:""` //
GroupName string `json:"groupName" comment:"交易对组名称"`
Symbol string `json:"symbol" comment:"交易对"`
GroupType string `json:"groupType" comment:"分组类型:1=普通类型"`
Type string `json:"type" comment:"类型:1=现货,2=合约"`
common.ControlBy
Id int `json:"-" comment:""` //
ExchangeType string `json:"exchangeType"`
GroupName string `json:"groupName" comment:"交易对组名称"`
Symbol string `json:"symbol" comment:"交易对"`
GroupType string `json:"groupType" comment:"分组类型:1=普通类型"`
Type string `json:"type" comment:"类型:1=现货,2=合约"`
common.ControlBy
}
func (s *LineSymbolGroupInsertReq) Generate(model *models.LineSymbolGroup) {
if s.Id == 0 {
model.Model = common.Model{ Id: s.Id }
}
model.GroupName = s.GroupName
model.Symbol = s.Symbol
model.GroupType = s.GroupType
model.Type = s.Type
model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
func (s *LineSymbolGroupInsertReq) Generate(model *models.LineSymbolGroup) {
if s.Id == 0 {
model.Model = common.Model{Id: s.Id}
}
// model.ExchangeType = s.ExchangeType
model.GroupName = s.GroupName
model.Symbol = s.Symbol
model.GroupType = s.GroupType
model.Type = s.Type
model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
}
func (s *LineSymbolGroupInsertReq) GetId() interface{} {
@ -56,23 +58,25 @@ func (s *LineSymbolGroupInsertReq) GetId() interface{} {
}
type LineSymbolGroupUpdateReq struct {
Id int `uri:"id" comment:""` //
GroupName string `json:"groupName" comment:"交易对组名称"`
Symbol string `json:"symbol" comment:"交易对"`
GroupType string `json:"groupType" comment:"分组类型:1=普通类型"`
Type string `json:"type" comment:"类型:1=现货,2=合约"`
common.ControlBy
Id int `uri:"id" comment:""` //
ExchangeType string `json:"exchangeType"`
GroupName string `json:"groupName" comment:"交易对组名称"`
Symbol string `json:"symbol" comment:"交易对"`
GroupType string `json:"groupType" comment:"分组类型:1=普通类型"`
Type string `json:"type" comment:"类型:1=现货,2=合约"`
common.ControlBy
}
func (s *LineSymbolGroupUpdateReq) Generate(model *models.LineSymbolGroup) {
if s.Id == 0 {
model.Model = common.Model{ Id: s.Id }
}
model.GroupName = s.GroupName
model.Symbol = s.Symbol
model.GroupType = s.GroupType
model.Type = s.Type
model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
func (s *LineSymbolGroupUpdateReq) Generate(model *models.LineSymbolGroup) {
if s.Id == 0 {
model.Model = common.Model{Id: s.Id}
}
// model.ExchangeType = s.ExchangeType
model.GroupName = s.GroupName
model.Symbol = s.Symbol
model.GroupType = s.GroupType
model.Type = s.Type
model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
}
func (s *LineSymbolGroupUpdateReq) GetId() interface{} {
@ -81,8 +85,9 @@ func (s *LineSymbolGroupUpdateReq) GetId() interface{} {
// LineSymbolGroupGetReq 功能获取请求参数
type LineSymbolGroupGetReq struct {
Id int `uri:"id"`
Id int `uri:"id"`
}
func (s *LineSymbolGroupGetReq) GetId() interface{} {
return s.Id
}

View File

@ -14,22 +14,16 @@ type LineSystemSettingGetPageReq struct {
}
type LineSystemSettingOrder struct {
Id string `form:"idOrder" search:"type:order;column:id;table:line_system_setting"`
CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:line_system_setting"`
UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:line_system_setting"`
DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:line_system_setting"`
Time string `form:"timeOrder" search:"type:order;column:time;table:line_system_setting"`
BatchTime string `form:"batchTimeOrder" search:"type:order;column:batch_time;table:line_system_setting"`
ProfitRate string `form:"profitRateOrder" search:"type:order;column:profit_rate;table:line_system_setting"`
CoverOrderTypeBRate string `form:"coverOrderTypeBRateOrder" search:"type:order;column:cover_order_type_b_rate;table:line_system_setting"`
ScaleOrderTypeARate string `form:"scaleOrderTypeARateOrder" search:"type:order;column:scale_order_type_a_rate;table:line_system_setting"`
ScaleOrderTypeBRate string `form:"scaleOrderTypeBRateOrder" search:"type:order;column:scale_order_type_b_rate;table:line_system_setting"`
ScaleUnRealizedProfitRate string `form:"scaleUnRealizedProfitRateOrder" search:"type:order;column:scale_unRealizedProfitRate;table:line_system_setting"`
ScaleNum string `form:"scaleNumOrder" search:"type:order;column:scale_num;table:line_system_setting"`
ScaleSubordinate string `form:"scaleSubordinateOrder" search:"type:order;column:scale_subordinate;table:line_system_setting"`
AutoScaleTimes string `form:"autoScaleTimesOrder" search:"type:order;column:auto_scale_times;table:line_system_setting"`
CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:line_system_setting"`
UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:line_system_setting"`
Id string `form:"idOrder" search:"type:order;column:id;table:line_system_setting"`
CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:line_system_setting"`
UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:line_system_setting"`
DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:line_system_setting"`
Time string `form:"timeOrder" search:"type:order;column:time;table:line_system_setting"`
BatchTime string `form:"batchTimeOrder" search:"type:order;column:batch_time;table:line_system_setting"`
ProfitRate string `form:"profitRateOrder" search:"type:order;column:profit_rate;table:line_system_setting"`
CoverOrderTypeBRate string `form:"coverOrderTypeBRateOrder" search:"type:order;column:cover_order_type_b_rate;table:line_system_setting"`
CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:line_system_setting"`
UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:line_system_setting"`
}
func (m *LineSystemSettingGetPageReq) GetNeedSearch() interface{} {
@ -37,18 +31,12 @@ func (m *LineSystemSettingGetPageReq) GetNeedSearch() interface{} {
}
type LineSystemSettingInsertReq struct {
Id int `json:"-" comment:"id"` // id
Time int64 `json:"time" comment:"导入:挂单时长达到时间后失效"`
BatchTime int64 `json:"batchTime" comment:"批量:挂单时长达到时间后失效"`
ProfitRate string `json:"profitRate" comment:"平仓盈利比例"`
CoverOrderTypeBRate string `json:"coverOrderTypeBRate" comment:"b账户限价补单的买入百分比"`
ScaleOrderTypeARate string `json:"scaleOrderTypeARate" comment:"a账户限价加仓买入百分比"`
ScaleOrderTypeBRate string `json:"scaleOrderTypeBRate" comment:"b账户限价加仓买入百分比"`
ScaleUnRealizedProfitRate string `json:"scaleUnRealizedProfitRate" comment:"亏损百分比加仓"`
ScaleNum string `json:"scaleNum" comment:"加仓数值"`
ScaleSubordinate int64 `json:"scaleSubordinate" comment:"加仓账户:1=A账户;2=副账户;3=都加"`
AutoScaleTimes int64 `json:"autoScaleTimes" comment:"自动加仓次数"`
ProtectHedgeEnable int `json:"protectHedgeEnable" comment:"是否只开启保险对冲 0-否 1-是"`
Id int `json:"-" comment:"id"` // id
Time int64 `json:"time" comment:"导入:挂单时长达到时间后失效"`
BatchTime int64 `json:"batchTime" comment:"批量:挂单时长达到时间后失效"`
ProfitRate string `json:"profitRate" comment:"平仓盈利比例"`
CoverOrderTypeBRate string `json:"coverOrderTypeBRate" comment:"b账户限价补单的买入百分比"`
StopLossPremium decimal.Decimal `json:"stopLossPremium" comment:"限价止损溢价"`
common.ControlBy
}
@ -60,12 +48,7 @@ func (s *LineSystemSettingInsertReq) Generate(model *models.LineSystemSetting) {
model.BatchTime = s.BatchTime
model.ProfitRate = s.ProfitRate
model.CoverOrderTypeBRate = s.CoverOrderTypeBRate
model.ScaleOrderTypeARate = s.ScaleOrderTypeARate
model.ScaleOrderTypeBRate = s.ScaleOrderTypeBRate
model.ScaleUnrealizedProfitRate = s.ScaleUnRealizedProfitRate
model.ScaleNum = s.ScaleNum
model.ScaleSubordinate = s.ScaleSubordinate
model.AutoScaleTimes = s.AutoScaleTimes
model.StopLossPremium = s.StopLossPremium
model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的
}
@ -74,20 +57,12 @@ func (s *LineSystemSettingInsertReq) GetId() interface{} {
}
type LineSystemSettingUpdateReq struct {
Id int `uri:"id" comment:"id"` // id
Time int64 `json:"time" comment:"导入:挂单时长达到时间后失效"`
BatchTime int64 `json:"batchTime" comment:"批量:挂单时长达到时间后失效"`
ProfitRate string `json:"profitRate" comment:"平仓盈利比例"`
CoverOrderTypeBRate string `json:"coverOrderTypeBRate" comment:"b账户限价补单的买入百分比"`
ScaleOrderTypeARate string `json:"scaleOrderTypeARate" comment:"a账户限价加仓买入百分比"`
ScaleOrderTypeBRate string `json:"scaleOrderTypeBRate" comment:"b账户限价加仓买入百分比"`
ScaleUnrealizedProfitRate string `json:"scaleUnRealizedProfitRate" comment:"亏损百分比加仓"`
ScaleNum string `json:"scaleNum" comment:"加仓数值"`
ScaleSubordinate int64 `json:"scaleSubordinate" comment:"加仓账户:1=A账户;2=副账户;3=都加"`
AutoScaleTimes int64 `json:"autoScaleTimes" comment:"自动加仓次数"`
HedgePerformance decimal.Decimal `json:"hedgePerformance" comment:"对冲平仓涨跌幅"`
ProtectHedgeRate decimal.Decimal `json:"protectHedgeRate" comment:"对冲市价亏损百分比"`
ProtectHedgeEnable int `json:"protectHedgeEnable" comment:"是否只开启保险对冲 0-否 1-是"`
Id int `uri:"id" comment:"id"` // id
Time int64 `json:"time" comment:"导入:挂单时长达到时间后失效"`
BatchTime int64 `json:"batchTime" comment:"批量:挂单时长达到时间后失效"`
ProfitRate string `json:"profitRate" comment:"平仓盈利比例"`
CoverOrderTypeBRate string `json:"coverOrderTypeBRate" comment:"b账户限价补单的买入百分比"`
StopLossPremium decimal.Decimal `json:"stopLossPremium" comment:"限价止损溢价"`
common.ControlBy
}
@ -99,15 +74,7 @@ func (s *LineSystemSettingUpdateReq) Generate(model *models.LineSystemSetting) {
model.BatchTime = s.BatchTime
model.ProfitRate = s.ProfitRate
model.CoverOrderTypeBRate = s.CoverOrderTypeBRate
model.ScaleOrderTypeARate = s.ScaleOrderTypeARate
model.ScaleOrderTypeBRate = s.ScaleOrderTypeBRate
model.ScaleUnrealizedProfitRate = s.ScaleUnrealizedProfitRate
model.ScaleNum = s.ScaleNum
model.ScaleSubordinate = s.ScaleSubordinate
model.AutoScaleTimes = s.AutoScaleTimes
model.HedgePerformance = s.HedgePerformance
model.ProtectHedgeRate = s.ProtectHedgeRate
model.ProtectHedgeEnable = s.ProtectHedgeEnable
model.StopLossPremium = s.StopLossPremium
model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的
}

View File

@ -29,7 +29,13 @@ func (e *LineApiGroup) GetPage(c *dto.LineApiGroupGetPageReq, p *actions.DataPer
var err error
var data models.LineApiGroup
err = e.Orm.Model(&data).
query := e.Orm.Model(&data)
if c.ExchangeType != "" {
query.Where("exchange_type = ?", c.ExchangeType)
}
err = query.
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),

View File

@ -29,13 +29,18 @@ type LineApiUser struct {
func (e *LineApiUser) GetPage(c *dto.LineApiUserGetPageReq, p *actions.DataPermission, list *[]models.LineApiUser, count *int64) error {
var err error
var data models.LineApiUser
err = e.Orm.Model(&data).
query := e.Orm.Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
actions.Permission(data.TableName(), p),
).
)
if c.ExchangeType != "" {
query.Where("exchange_type = ?", c.ExchangeType)
}
err = query.
Find(list).Limit(-1).Offset(-1).
Count(count).Error
if err != nil {
@ -309,11 +314,16 @@ func (e *LineApiUser) Bind(req *dto.LineApiUserBindSubordinateReq, p *actions.Da
}
// GetUser 获取未绑定的用户列表
func (e *LineApiUser) GetUser(list *[]models.LineApiUser) error {
func (e *LineApiUser) GetUser(req *dto.LineApiUserBindSubordinateReq, list *[]models.LineApiUser) error {
var err error
var data models.LineApiUser
query := e.Orm.Model(&data).Where("subordinate = '0'")
err = e.Orm.Model(&data).Where("subordinate = '0'").Find(list).Error
if req.ExchangeType != "" {
query = query.Where("exchange_type = ?", req.ExchangeType)
}
err = query.Find(list).Error
if err != nil {
e.Log.Errorf("LineApiUserService error:%s \r\n", err)
return err
@ -322,11 +332,15 @@ func (e *LineApiUser) GetUser(list *[]models.LineApiUser) error {
}
// GetMainUser 获取主账号
func (e *LineApiUser) GetMainUser(list *[]models.LineApiUser) error {
func (e *LineApiUser) GetMainUser(req *dto.GetMainUserReq, list *[]models.LineApiUser) error {
var err error
var data models.LineApiUser
query := e.Orm.Model(&data).Where("subordinate = '1' AND group_id > 0")
err = e.Orm.Model(&data).Where("subordinate = '1' AND group_id > 0").Find(list).Error
if req.ExchangeType != "" {
query = query.Where("exchange_type =?", req.ExchangeType)
}
err = query.Find(list).Error
if err != nil {
e.Log.Errorf("LineApiUserService error:%s \r\n", err)
return err

View File

@ -13,6 +13,7 @@ import (
"go-admin/app/admin/service/dto"
"go-admin/common/actions"
cDto "go-admin/common/dto"
"go-admin/common/global"
)
type LineDirection struct {
@ -183,10 +184,11 @@ func (e *LineDirection) ReloadGroup() error {
groupName := fmt.Sprintf("现货-%s", key)
group := models.LineSymbolGroup{
GroupName: groupName,
Type: "1",
GroupType: "1",
Symbol: strings.Join(item, ","),
ExchangeType: global.EXCHANGE_BINANCE,
GroupName: groupName,
Type: "1",
GroupType: "1",
Symbol: strings.Join(item, ","),
}
groupNames = append(groupNames, groupName)
@ -197,10 +199,11 @@ func (e *LineDirection) ReloadGroup() error {
groupName := fmt.Sprintf("合约-%s", key)
group := models.LineSymbolGroup{
GroupName: groupName,
Type: "2",
GroupType: "1",
Symbol: strings.Join(item, ","),
ExchangeType: global.EXCHANGE_BINANCE,
GroupName: groupName,
Type: "2",
GroupType: "1",
Symbol: strings.Join(item, ","),
}
groupNames = append(groupNames, groupName)

View File

@ -241,13 +241,15 @@ func (e *LinePreOrder) Remove(d *dto.LinePreOrderDeleteReq, p *actions.DataPermi
apiIds = append(apiIds, order.ApiId)
}
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf("%s:%s", global.TICKER_SPOT, order.Symbol))
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf(global.TICKER_SPOT, order.ExchangeType, order.Symbol))
redisList.Price = utility.StringToDecimal(redisList.Price).Truncate(int32(tradeSet.PriceDigit)).String()
marshal, _ := sonic.Marshal(redisList)
if order.SymbolType == 1 {
helper.DefaultRedis.LRem(rediskey.PreFutOrderList, string(marshal))
listKey := fmt.Sprintf(rediskey.PreSpotOrderList, order.ExchangeType)
helper.DefaultRedis.LRem(listKey, string(marshal))
} else {
helper.DefaultRedis.LRem(rediskey.PreSpotOrderList, string(marshal))
listKey := fmt.Sprintf(rediskey.PreFutOrderList, order.ExchangeType)
helper.DefaultRedis.LRem(listKey, string(marshal))
}
binanceservice.MainClosePositionClearCache(order.Id, order.CoverType)
@ -340,9 +342,9 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
}
var key string
if req.SymbolType == global.SYMBOL_SPOT {
key = fmt.Sprintf("%s:%s", global.TICKER_SPOT, req.Symbol)
key = fmt.Sprintf(global.TICKER_SPOT, req.ExchangeType, req.Symbol)
} else {
key = fmt.Sprintf("%s:%s", global.TICKER_FUTURES, req.Symbol)
key = fmt.Sprintf(global.TICKER_FUTURES, req.ExchangeType, req.Symbol)
}
for _, id := range apiUserIds {
@ -361,32 +363,14 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
*errs = append(*errs, fmt.Errorf("api_id:%s 获取交易对:%s 该交易对已存在,请勿重复下单", id, req.Symbol))
continue
}
var tickerPrice decimal.Decimal
ticker := models2.TradeSet{}
tickerVal := ""
if req.SymbolType == 1 {
tickerVal, _ = helper.DefaultRedis.GetString(fmt.Sprintf(global.TICKER_SPOT, req.ExchangeType, req.Symbol))
} else {
tickerVal, _ = helper.DefaultRedis.GetString(fmt.Sprintf(global.TICKER_FUTURES, req.ExchangeType, req.Symbol))
}
if tickerVal == "" {
logger.Error("获取交易对:%s 现货ticker失败", req.Symbol)
continue
}
err := sonic.Unmarshal([]byte(tickerVal), &ticker)
if ticker.LastPrice == "" {
logger.Error("获取交易对:%s 现货ticker失败,err:%v", req.Symbol, err)
continue
}
tickerPrice := utility.StrToDecimal(tradeSet.LastPrice)
if tickerPrice.Equal(decimal.Zero) { //redis 没有这个值
*errs = append(*errs, fmt.Errorf("api_id:%s 获取交易对:%s 交易行情出错", id, req.Symbol))
continue
}
AddOrder.HedgeBuyType = req.HedgeBuyType
AddOrder.ExchangeType = req.ExchangeType
AddOrder.OrderCategory = 1
AddOrder.SignPriceType = "new"
AddOrder.BuyPrice = req.BuyPrice //购买多少U
@ -434,7 +418,7 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
continue
}
err = sonic.Unmarshal([]byte(tickerVal), &ticker2)
err := sonic.Unmarshal([]byte(tickerVal), &ticker2)
if ticker2.LastPrice == "" {
logger.Errorf("查询行情失败 %s err:%v", strings.ToUpper(symbolInfo.QuoteAsset+"USDT"), err)
@ -465,10 +449,13 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
AddOrder.GroupId = "0"
AddOrder.AdminId = "0"
AddOrder.Status = 0
AddOrder.HedgeBuyTotal = req.HedgeBuyTotal
AddOrder.HedgeStopLoss = req.HedgeStopLoss
AddOrder.HedgeTakeProfit = req.HedgeTakeProfit
copier.Copy(&profitOrder, &AddOrder)
copier.Copy(&stopOrder, &AddOrder)
err = e.Orm.Model(&models.LinePreOrder{}).Omit("id", "save_template", "template_name").Create(&AddOrder).Error
err := e.Orm.Model(&models.LinePreOrder{}).Omit("id", "save_template", "template_name").Create(&AddOrder).Error
if err != nil {
*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%s 获取交易对:%s 生成订单失败", id, req.Symbol)))
continue
@ -491,10 +478,10 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
}
marshal, _ := sonic.Marshal(&list)
var preKey string
if AddOrder.OrderType == global.SYMBOL_SPOT {
preKey = rediskey.PreSpotOrderList
if AddOrder.SymbolType == global.SYMBOL_SPOT {
preKey = fmt.Sprintf(rediskey.PreSpotOrderList, AddOrder.ExchangeType)
} else {
preKey = rediskey.PreFutOrderList
preKey = fmt.Sprintf(rediskey.PreFutOrderList, AddOrder.ExchangeType)
}
helper.DefaultRedis.LPushList(preKey, string(marshal))
@ -540,7 +527,7 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP
// CheckRepeatOrder 检查重复下单 检查基础货币
func (e *LinePreOrder) CheckRepeatOrder(orderType int, apiUserId, site, baseCoin string) int64 {
var count int64
e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol like ? AND order_type = ? AND site = ? AND `status` != '2' AND `status`!='4' AND `status` != '0' AND `status` != '6'", apiUserId, baseCoin+"%", orderType, site).Count(&count)
e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol like ? AND order_type = ? AND site = ? AND `status` IN (1,5)", apiUserId, baseCoin+"%", orderType, site).Count(&count)
return count
}
@ -884,6 +871,8 @@ func (e *LinePreOrder) ClearAll() error {
"holde_a",
"holde_b",
"stop_loss_markt",
"_PreSpotOrderList_",
"_PreFutOrderList_",
}
err = helper.DefaultRedis.DeleteKeysByPrefix(prefixs...)
if err != nil {
@ -1014,9 +1003,9 @@ func (e *LinePreOrder) SpotClosePosition(position *dto.ClosePosition, errs *[]er
//查询已经开仓的现货交易对
var spotList []models.LinePreOrder
if position.Symbol == "" { //全平
e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND status = '9' AND pid = 0 AND order_type = '1'", position.ApiId).Find(&spotList)
e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND status = 6 AND pid = 0 AND order_type = 0", position.ApiId).Find(&spotList)
} else {
e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND status = '9' AND pid = 0 AND order_type = '1'", position.ApiId, position.Symbol).Find(&spotList)
e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND status = 6 AND pid = 0 AND order_type = 0", position.ApiId, position.Symbol).Find(&spotList)
}
if len(spotList) <= 0 {
*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 没有可平仓的交易对", position.ApiId)))
@ -1034,7 +1023,7 @@ func (e *LinePreOrder) SpotClosePosition(position *dto.ClosePosition, errs *[]er
"symbol": list.Symbol,
})
}
key := fmt.Sprintf("%s:%s", global.TICKER_SPOT, list.Symbol)
key := fmt.Sprintf(global.TICKER_SPOT, list.ExchangeType, list.Symbol)
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, key)
total := utility.StringToDecimal(balance.Free).Add(utility.StringToDecimal(balance.Locked)).Truncate(int32(tradeSet.AmountDigit))
lastPrice := api.GetSpotSymbolLastPrice(list.Symbol)
@ -1108,12 +1097,12 @@ func (e *LinePreOrder) FutClosePosition(position *dto.ClosePosition, errs *[]err
//查询已经开仓的合约交易对
var futList []models.LinePreOrder
if position.Symbol == "" {
e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND status = '13' AND pid = 0 AND order_type = '2'", position.ApiId).Find(&futList)
e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND status = 6 AND order_category=2 AND order_type =0", position.ApiId).Find(&futList)
} else {
e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND status = '13' AND pid = 0 AND order_type = '2'", position.ApiId, position.Symbol).Find(&futList)
e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND status = 6 AND order_category=2 AND order_type = 0", position.ApiId, position.Symbol).Find(&futList)
}
if len(futList) <= 0 {
*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 没有可平仓的交易对", position.ApiId)))
*errs = append(*errs, fmt.Errorf("api_id:%d 没有可平仓的交易对", position.ApiId))
return
}
@ -1122,15 +1111,22 @@ func (e *LinePreOrder) FutClosePosition(position *dto.ClosePosition, errs *[]err
for _, list := range futList {
risks, err := api.GetPositionV3(&apiUserInfo, list.Symbol)
if err != nil {
*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 获取仓位信息时 没有可平仓的交易对 err: %s", position.ApiId, err)))
*errs = append(*errs, fmt.Errorf("api_id:%d 获取仓位信息时 没有可平仓的交易对 err: %s", position.ApiId, err))
continue
}
key := fmt.Sprintf(global.TICKER_FUTURES, list.SymbolType, list.Symbol)
key := fmt.Sprintf(global.TICKER_FUTURES, list.ExchangeType, list.Symbol)
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, key)
lastPrice := api.GetFutSymbolLastPrice(list.Symbol)
parentId := list.Id
if list.Pid > 0 {
parentId = list.Pid
}
for _, risk := range risks {
positionAmt := utility.StringToDecimal(risk.PositionAmt)
var riskSide string
var orderSide string
if positionAmt.GreaterThan(decimal.Zero) {
@ -1154,12 +1150,12 @@ func (e *LinePreOrder) FutClosePosition(position *dto.ClosePosition, errs *[]err
}
if positionAmt.Abs().LessThanOrEqual(decimal.NewFromFloat(tradeSet.MinQty)) {
*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 下单数量小于最小下单数量", position.ApiId)))
*errs = append(*errs, fmt.Errorf("api_id:%d 下单数量小于最小下单数量", position.ApiId))
continue
}
order := models.LinePreOrder{
Pid: list.Id,
Pid: parentId,
ApiId: list.ApiId,
GroupId: "0",
Symbol: list.Symbol,
@ -1185,7 +1181,7 @@ func (e *LinePreOrder) FutClosePosition(position *dto.ClosePosition, errs *[]err
}
err = e.Orm.Model(&models.LinePreOrder{}).Create(&order).Error
if err != nil {
*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 生成平仓单错误:%s", position.ApiId, err)))
*errs = append(*errs, fmt.Errorf("api_id:%d 生成平仓单错误:%s", position.ApiId, err))
continue
}
@ -1202,7 +1198,7 @@ func (e *LinePreOrder) FutClosePosition(position *dto.ClosePosition, errs *[]err
err = api.ClosePosition(list.Symbol, order.OrderSn, utility.StringToDecimal(order.Num), "SELL", "LONG", apiUserInfo, "LIMIT", "0", price)
}
if err != nil {
*errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 币安平仓单错误:%s", position.ApiId, err)))
*errs = append(*errs, fmt.Errorf("api_id:%d 币安平仓单错误:%s", position.ApiId, err))
continue
}
// 主单平仓删除缓存
@ -1229,13 +1225,15 @@ func (e *LinePreOrder) ClearUnTriggered() error {
OrderSn: order.OrderSn,
QuoteSymbol: order.QuoteSymbol,
}
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf("%s:%s", global.TICKER_SPOT, order.Symbol))
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf(global.TICKER_SPOT, order.ExchangeType, order.Symbol))
redisList.Price = utility.StringToDecimal(redisList.Price).Truncate(int32(tradeSet.PriceDigit)).String()
marshal, _ := sonic.Marshal(redisList)
if order.SymbolType == 1 {
helper.DefaultRedis.LRem(rediskey.PreFutOrderList, string(marshal))
key := fmt.Sprintf(rediskey.PreFutOrderList, order.ExchangeType)
helper.DefaultRedis.LRem(key, string(marshal))
} else {
helper.DefaultRedis.LRem(rediskey.PreSpotOrderList, string(marshal))
key := fmt.Sprintf(rediskey.PreSpotOrderList, order.ExchangeType)
helper.DefaultRedis.LRem(key, string(marshal))
}
e.Orm.Model(&models.LinePreOrder{}).Where("pid = ?", order.Id).Unscoped().Delete(&models.LinePreOrder{})
}

View File

@ -148,7 +148,7 @@ func (e *LinePriceLimit) UpRange() error {
}
for _, hr := range spotTicker24HrAll {
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf("%s:%s", global.TICKER_SPOT, hr.Symbol))
tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, fmt.Sprintf(global.TICKER_SPOT, global.EXCHANGE_BINANCE, hr.Symbol))
if tradeSet.Currency != "" && tradeSet.Coin != "" {
spotTicker24Hr = append(spotTicker24Hr, hr)
}

View File

@ -61,6 +61,11 @@ func (e *LineSymbol) GetSamePage(c *dto.LineSymbolGetPageReq, p *actions.DataPer
Scopes(
actions.Permission(data.TableName(), p),
)
if c.ExchangeType != "" {
tx.Where("exchange_type = ?", c.ExchangeType)
scopes.Where("exchange_type = ?", c.ExchangeType)
}
if c.Symbol != "" {
tx.Where("symbol = ?", c.Symbol)
scopes.Where("symbol = ?", c.Symbol)
@ -153,16 +158,16 @@ func (e *LineSymbol) Remove(d *dto.LineSymbolDeleteReq, p *actions.DataPermissio
return nil
}
func (e *LineSymbol) GetSymbol() (data []models.LineSymbol, err error) {
func (e *LineSymbol) GetSymbol(req *dto.LineSymbolGetListReq) (data []models.LineSymbol, err error) {
var (
spotSymbol, futSymbol []models.LineSymbol
)
err = e.Orm.Model(&models.LineSymbol{}).Where("type = '1' AND switch = 1").Find(&spotSymbol).Error
err = e.Orm.Model(&models.LineSymbol{}).Where("type = '1' AND switch = 1 AND exchange_type =?", req.ExchangeType).Find(&spotSymbol).Error
if err != nil {
e.Log.Errorf("Service GetSpotSymbol error:%s \r\n", err)
return data, err
}
err = e.Orm.Model(&models.LineSymbol{}).Where("type = '2' AND switch = 1").Find(&futSymbol).Error
err = e.Orm.Model(&models.LineSymbol{}).Where("type = '2' AND switch = 1 AND exchange_type =?", req.ExchangeType).Find(&futSymbol).Error
if err != nil {
e.Log.Errorf("Service GetFutSymbol error:%s \r\n", err)
return data, err
@ -224,7 +229,7 @@ func (e *LineSymbol) ResetSpotSymbol() error {
for symbol, tradeSet := range tradeSets {
key := fmt.Sprintf("%s:%s", global.TICKER_SPOT, symbol)
key := fmt.Sprintf(global.TICKER_SPOT, global.EXCHANGE_BINANCE, symbol)
//判断是否在黑名单里面
for _, black := range symbolBlack {
@ -265,6 +270,7 @@ func (e *LineSymbol) ResetSpotSymbol() error {
lineSymbol, _ := oldMapSymbols[symbol]
if lineSymbol.Id <= 0 {
lineSymbol.ExchangeType = global.EXCHANGE_BINANCE
lineSymbol.Symbol = symbol
lineSymbol.BaseAsset = tradeSet.Coin
lineSymbol.QuoteAsset = tradeSet.Currency
@ -380,7 +386,7 @@ func (e *LineSymbol) ResetFuturesSymbol() error {
e.Orm.Model(&models.LineSymbolBlack{}).Where("type = 2").Find(&symbolBlack)
for symbol, tradeSet := range tradeSets {
key := fmt.Sprintf("%s:%s", global.TICKER_FUTURES, symbol)
key := fmt.Sprintf(global.TICKER_FUTURES, global.EXCHANGE_BINANCE, symbol)
//判断是否在黑名单里面
for _, black := range symbolBlack {
@ -419,6 +425,7 @@ func (e *LineSymbol) ResetFuturesSymbol() error {
lineSymbol, _ := oldMapSymbols[symbol]
if lineSymbol.Id <= 0 {
lineSymbol.ExchangeType = global.EXCHANGE_BINANCE
lineSymbol.Symbol = symbol
lineSymbol.BaseAsset = tradeSet.Coin
lineSymbol.QuoteAsset = tradeSet.Currency

View File

@ -21,13 +21,17 @@ type LineSymbolGroup struct {
func (e *LineSymbolGroup) GetPage(c *dto.LineSymbolGroupGetPageReq, p *actions.DataPermission, list *[]models.LineSymbolGroup, count *int64) error {
var err error
var data models.LineSymbolGroup
err = e.Orm.Model(&data).
query := e.Orm.Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
actions.Permission(data.TableName(), p),
).
)
if c.ExchangeType != "" {
query = query.Where("exchange_type = ?", c.ExchangeType)
}
err = query.
Find(list).Limit(-1).Offset(-1).
Count(count).Error
if err != nil {

View File

@ -63,7 +63,7 @@ const (
const (
//交易对-现货
SYMBOL_SPOT = 0
SYMBOL_SPOT = 1
//交易对-合约
SYMBOL_FUTURES = 1
SYMBOL_FUTURES = 2
)

View File

@ -5,6 +5,7 @@ import (
"go-admin/app/admin/models"
"go-admin/app/admin/service"
"go-admin/common/const/rediskey"
"go-admin/common/global"
"go-admin/common/helper"
"go-admin/pkg/utility"
"go-admin/services/excservice"
@ -20,7 +21,7 @@ import (
func UserSubscribeInit(orm *gorm.DB, ctx context.Context) {
var list []models.LineApiUser
err := orm.Model(&models.LineApiUser{}).Where("open_status=1 ").Find(&list).Error
err := orm.Model(&models.LineApiUser{}).Where("open_status=1 AND exchange_type =?", global.EXCHANGE_BINANCE).Find(&list).Error
if err != nil {
log.Error("获取用户api失败", err)

View File

@ -5,7 +5,7 @@ settings:
# 服务器ip默认使用 0.0.0.0
host: 0.0.0.0
# 服务名称
name: testApp
name: exchange_go
# 端口号
port: 6789 # 服务端口号
readtimeout: 1
@ -31,7 +31,7 @@ settings:
# sqlserver: sqlserver://用户名:密码@地址?database=数据库名
driver: mysql
# 数据库连接字符串 mysql 缺省信息 charset=utf8&parseTime=True&loc=Local&timeout=1000ms
source: root:root@tcp(192.168.1.12:3306)/gp-bian?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms
source: root:root@tcp(192.168.1.12:3306)/go_exchange?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms
# databases:
# 'locaohost:8000':
# driver: mysql
@ -53,7 +53,7 @@ settings:
redis:
addr: "192.168.1.12:6379"
password: ""
db: 0
db: 1
# 雪花算法设备id
serviceId: 1

View File

@ -93,7 +93,7 @@ func (e SpotRestApi) GetSpotTicker24h(tradeSet *map[string]models.TradeSet) (del
}
for _, item := range tickers {
key := fmt.Sprintf("%s:%s", global.TICKER_SPOT, item.Symbol)
key := fmt.Sprintf(global.TICKER_SPOT, global.EXCHANGE_BINANCE, item.Symbol)
symbol, exits := (*tradeSet)[item.Symbol]
if !exits {
@ -138,7 +138,7 @@ func (e SpotRestApi) GetSpotTicker24h(tradeSet *map[string]models.TradeSet) (del
- @data 结果
*/
func (e SpotRestApi) GetSpotTicker24(symbol string, data *models.Ticker24, tradeSet *models.TradeSet) error {
key := fmt.Sprintf("%s:%s", global.TICKER_SPOT, symbol)
key := fmt.Sprintf(global.TICKER_SPOT, global.EXCHANGE_BINANCE, symbol)
val, err := helper.DefaultRedis.GetString(key)
if err != nil {
@ -304,7 +304,7 @@ func (e SpotRestApi) CancelOpenOrderByOrderSn(apiUserInfo DbModels.LineApiUser,
} else {
client, _ = helper.NewBinanceClient(apiUserInfo.ApiKey, apiUserInfo.ApiSecret, "socks5", apiUserInfo.UserPass+"@"+apiUserInfo.IpAddress)
}
_, code, err := client.SendSpotAuth("/api/v3/order ", "DELETE", params)
_, code, err := client.SendSpotAuth("/api/v3/order", "DELETE", params)
if err != nil || code != 200 {
log.Error("取消现货委托失败 参数:", params)
log.Error("取消现货委托失败 code:", code)
@ -352,7 +352,7 @@ func (e SpotRestApi) ClosePosition(symbol string, orderSn string, quantity decim
}
if orderType == "LIMIT" {
key := fmt.Sprintf("%s:%s", global.TICKER_SPOT, symbol)
key := fmt.Sprintf(global.TICKER_SPOT, global.EXCHANGE_BINANCE, symbol)
tradeSet, _ := helper.GetObjString[models.TradeSet](helper.DefaultRedis, key)
rateFloat, _ := decimal.NewFromString(rate)
if rateFloat.GreaterThan(decimal.Zero) {
@ -515,6 +515,117 @@ func SpotOrderLock(db *gorm.DB, v *dto.PreOrderRedisList, item string, spotApi S
}
}
// 判断是否触发止损
func JudgeSpotStopLoss(trade models.TradeSet) {
key := fmt.Sprintf(rediskey.SpotStopLossList, global.EXCHANGE_BINANCE)
stopLossVal, _ := helper.DefaultRedis.GetAllList(key)
if len(stopLossVal) == 0 {
return
}
db := GetDBConnection()
spotApi := SpotRestApi{}
setting, err := GetSystemSetting(db)
if err != nil {
log.Error("获取系统设置失败")
return
}
tradeSet, err := GetTradeSet(trade.Coin+trade.Currency, 0)
if err != nil {
log.Error("获取交易设置失败")
return
}
for _, item := range stopLossVal {
stopOrder := dto.StopLossRedisList{}
if err := sonic.Unmarshal([]byte(item), &stopOrder); err != nil {
log.Error("反序列化失败")
continue
}
if stopOrder.Symbol == trade.Coin+trade.Currency {
orderPrice := stopOrder.Price
tradePrice, _ := decimal.NewFromString(trade.LastPrice)
//买入
if strings.ToUpper(stopOrder.Site) == "SELL" &&
orderPrice.Cmp(tradePrice) >= 0 &&
orderPrice.Cmp(decimal.Zero) > 0 &&
tradePrice.Cmp(decimal.Zero) > 0 {
SpotStopLossTrigger(db, stopOrder, spotApi, setting, tradeSet, key, item)
}
}
}
}
// 触发现货止损
func SpotStopLossTrigger(db *gorm.DB, stopOrder dto.StopLossRedisList, spotApi SpotRestApi, setting DbModels.LineSystemSetting, tradeSet models.TradeSet, key string, item string) {
lock := helper.NewRedisLock(fmt.Sprintf(rediskey.SpotTrigger, stopOrder.ApiId, stopOrder.Symbol), 20, 5, 100*time.Millisecond)
if ok, err := lock.AcquireWait(context.Background()); err != nil {
log.Error("获取锁失败", err)
return
} else if ok {
defer lock.Release()
takeOrder := DbModels.LinePreOrder{}
if err := db.Model(&DbModels.LinePreOrder{}).Where("pid =? AND order_type =1", stopOrder.PId).Find(&takeOrder).Error; err != nil {
log.Error("查询止盈单失败")
return
}
apiInfo, _ := GetApiInfo(takeOrder.ApiId)
if apiInfo.Id == 0 {
log.Error("现货止损 查询api用户不存在")
return
}
var err error
for x := 1; x <= 4; x++ {
err = spotApi.CancelOpenOrderByOrderSn(apiInfo, takeOrder.Symbol, takeOrder.OrderSn)
if err == nil {
break
}
}
if err != nil {
log.Error("现货止损撤单失败", err)
return
}
stopPreOrder, _ := GetOrderById(db, stopOrder.Id)
price := stopOrder.Price.Mul(decimal.NewFromInt(1).Sub(setting.StopLossPremium.Div(decimal.NewFromInt(100)))).Truncate(int32(tradeSet.PriceDigit))
num := utility.StrToDecimal(takeOrder.Num).Truncate(int32(tradeSet.AmountDigit))
params := OrderPlacementService{
ApiId: takeOrder.ApiId,
Side: takeOrder.Site,
Type: "LIMIT",
TimeInForce: "GTC",
Symbol: takeOrder.Symbol,
Price: price,
Quantity: num,
NewClientOrderId: stopPreOrder.OrderSn,
}
if err := spotApi.OrderPlace(db, params); err != nil {
log.Errorf("现货止损挂单失败 id%s err:%v", stopOrder.Id, err)
}
if _, err := helper.DefaultRedis.LRem(key, item); err != nil {
log.Errorf("现货止损 删除缓存失败 id:%v err:%v", stopOrder.Id, err)
}
} else {
log.Error("获取锁失败")
}
}
/*
获取api用户信息
*/

View File

@ -319,7 +319,7 @@ func InitSymbolsTicker24h(maps *map[string]models.TradeSet) (deletes []string, e
symbol.QuoteVolume = item.QuoteVolume
symbol.LastPrice = item.LastPrice
key := fmt.Sprintf("%s:%s", global.TICKER_FUTURES, item.Symbol)
key := fmt.Sprintf(global.TICKER_FUTURES, global.EXCHANGE_BINANCE, item.Symbol)
if !strings.HasSuffix(item.Symbol, symbol.Currency) || item.Count <= 0 || utility.StringToFloat64(item.QuoteVolume) <= 0 {
helper.DefaultRedis.DeleteString(key)
deleteSymbol = append(deleteSymbol, item.Symbol)
@ -332,7 +332,7 @@ func InitSymbolsTicker24h(maps *map[string]models.TradeSet) (deletes []string, e
log.Error("设置行情序列化报错", err)
}
tcKey := fmt.Sprintf("%s:%s", global.TICKER_FUTURES, item.Symbol)
tcKey := fmt.Sprintf(global.TICKER_FUTURES, global.EXCHANGE_BINANCE, item.Symbol)
caches[tcKey] = string(val)
priceChange = append(priceChange, &redis.Z{
Score: symbol.PriceChange,

View File

@ -2,11 +2,9 @@ package binanceservice
import (
"context"
"errors"
"fmt"
"go-admin/app/admin/models"
DbModels "go-admin/app/admin/models"
"go-admin/app/admin/service/dto"
"go-admin/common/const/rediskey"
"go-admin/common/global"
"go-admin/common/helper"
@ -28,11 +26,17 @@ import (
func ChangeFutureOrder(mapData map[string]interface{}) {
// 检查订单号是否存在
orderSn, ok := mapData["c"]
originOrderSn := mapData["C"] //取消操作 代表原始订单号
if !ok {
logger.Error("合约订单回调失败,没有订单号")
return
}
if originOrderSn != "" {
orderSn = originOrderSn
}
// 获取数据库连接
db := GetDBConnection()
if db == nil {
@ -134,42 +138,47 @@ func handleStopLoss(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
return
}
// 获取交易对配置
triggerHedgeOrder(order, db, preOrder)
}
// 下合约对冲单
func triggerHedgeOrder(order DbModels.LinePreOrder, db *gorm.DB, preOrder *DbModels.LinePreOrder) bool {
symbolName := utility.ReplaceSuffix(order.Symbol, order.QuoteSymbol, "USDT")
// 获取交易对配置
tradeSet, err := GetTradeSet(symbolName, 1)
if tradeSet.Coin == "" || err != nil {
logger.Errorf("止损单成交 获取交易对配置失败 交易对:%s 订单号:%s err:%v", symbolName, order.OrderSn, err)
return
return true
}
// 检查对冲单购买金额
if order.HedgeBuyTotal.Cmp(decimal.Zero) <= 0 {
logger.Errorf("止损单成交 对冲单购买金额为0 订单号:%s", order.OrderSn)
return
return true
}
// 获取系统设置
setting, err := GetSystemSetting(db)
if err != nil {
logger.Errorf("止损单成交 获取系统设置失败 订单号:%s err:%v", order.OrderSn, err)
return
return true
}
// 获取API信息
apiInfo, err := GetChildApiInfo(order.ApiId)
if err != nil {
logger.Errorf("止损单成交 获取api信息失败 订单号:%s err:%v", order.OrderSn, err)
return
return true
}
// 计算价格
price := utility.StrToDecimal(preOrder.Price).Truncate(int32(tradeSet.PriceDigit))
if order.CoverType == 2 {
if order.CoverType == 1 {
price = utility.StrToDecimal(tradeSet.LastPrice).Truncate(int32(tradeSet.PriceDigit))
}
if price.Cmp(decimal.Zero) <= 0 {
logger.Errorf("单价异常 price:%v 止损单编号:%s 行情:%v", price, order.OrderSn, tradeSet)
return
return true
}
// 创建对冲订单
@ -179,17 +188,25 @@ func handleStopLoss(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
// 批量插入订单
if err := db.Model(&DbModels.LinePreOrder{}).CreateInBatches(orders, 1).Error; err != nil {
logger.Errorf("主单止损 重下对冲失败止损单id%s err:%v", order.OrderSn, err)
return
return true
}
// 调用API下单
if err := placeFutOrder(db, hedgeOrder, price, &apiInfo); err != nil {
logger.Errorf("主单止损 重下对冲失败,止损单号:%s err:%v", order.OrderSn, err)
}
return false
}
// 创建对冲订单
func createHedgeOrders(order DbModels.LinePreOrder, price decimal.Decimal, tradeSet *models2.TradeSet, apiInfo *DbModels.LineApiUser, setting *DbModels.LineSystemSetting) (DbModels.LinePreOrder, DbModels.LinePreOrder, DbModels.LinePreOrder) {
buyPrice := order.HedgeBuyTotal.String()
if order.HedgeBuyType == 1 {
mainTotal := utility.StrToDecimal(order.BuyPrice)
buyPrice = mainTotal.Mul(order.HedgeBuyTotal).Truncate(int32(tradeSet.PriceDigit)).String()
}
hedgeOrder := DbModels.LinePreOrder{
ApiId: apiInfo.Id,
ExchangeType: order.ExchangeType,
@ -199,7 +216,7 @@ func createHedgeOrders(order DbModels.LinePreOrder, price decimal.Decimal, trade
SignPrice: order.Price,
SignPriceType: "new",
Rate: "0",
BuyPrice: order.HedgeBuyTotal.String(),
BuyPrice: buyPrice,
OrderCategory: 2,
OrderSn: utility.Int64ToString(snowflakehelper.GetOrderId()),
OrderType: 0,
@ -302,7 +319,9 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder) {
if i >= 2 { // 最多处理 2 个订单
break
}
price := utility.StrToDecimal(order.Price).Truncate(int32(tradeSet.PriceDigit))
num = num.Truncate(int32(tradeSet.AmountDigit))
order.Price = price.String()
if err := db.Model(&order).Update("num", num).Error; err != nil {
logger.Errorf("修改止盈止损数量失败 订单号:%s err:%v", order.OrderSn, err)
@ -312,7 +331,7 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder) {
case 1: // 止盈
processFutTakeProfitOrder(db, futApi, order, num)
case 2: // 止损
processFutStopLossOrder(order)
processFutStopLossOrder(db, order, price, num)
}
}
}
@ -345,6 +364,8 @@ func processFutTakeProfitOrder(db *gorm.DB, futApi FutRestApi, order models.Line
if err == nil {
break
}
time.Sleep(time.Millisecond * 250)
}
}
@ -364,29 +385,39 @@ func processFutTakeProfitOrder(db *gorm.DB, futApi FutRestApi, order models.Line
// 处理止损订单
// order 止损单
func processFutStopLossOrder(order models.LinePreOrder) error {
price := utility.StrToDecimal(order.Price)
stopLoss := dto.StopLossRedisList{
Id: order.Id,
PId: order.Pid,
ApiId: order.ApiId,
OrderTye: order.OrderType,
OrderCategory: order.OrderCategory,
Price: price,
SymbolType: order.SymbolType,
Symbol: order.Symbol,
Site: order.Site,
func processFutStopLossOrder(db *gorm.DB, order models.LinePreOrder, price, num decimal.Decimal) error {
params := FutOrderPlace{
ApiId: order.ApiId,
Symbol: order.Symbol,
Side: order.Site,
Price: price,
Quantity: num,
OrderType: "STOP_MARKET",
StopPrice: price,
NewClientOrderId: order.OrderSn,
}
futApi := FutRestApi{}
var err error
for x := 1; x < 4; x++ {
err = futApi.OrderPlace(db, params)
if err == nil {
break
}
time.Sleep(time.Millisecond * 200)
}
stoplossVal, _ := sonic.MarshalString(&stopLoss)
stoplossKey := fmt.Sprintf(rediskey.FuturesStopLossList, global.EXCHANGE_BINANCE)
if stoplossVal == "" {
return errors.New("stoplossVal is empty")
}
if err := helper.DefaultRedis.RPushList(stoplossKey, stoplossVal); err != nil {
return err
if err != nil {
if err2 := db.Model(&order).Updates(map[string]interface{}{"status": 2, "desc": err.Error()}).Error; err2 != nil {
logger.Error("合约止损下单失败,更新状态失败:", order.OrderSn, " err:", err2)
}
} else {
if err := db.Model(&order).Where("status =0").
Updates(map[string]interface{}{"status": "1"}).Error; err != nil {
logger.Error("合约止损下单成功,更新状态失败:", order.OrderSn, " err:", err)
}
}
return nil

View File

@ -27,11 +27,17 @@ import (
func ChangeSpotOrder(mapData map[string]interface{}) {
// 检查订单号是否存在
orderSn, ok := mapData["c"]
originOrderSn := mapData["C"] //取消操作 代表原始订单号
if !ok {
logger.Error("订单回调失败, 没有订单号", mapData)
return
}
if originOrderSn != "" {
orderSn = originOrderSn
}
// 获取数据库连接
db := GetDBConnection()
if db == nil {
@ -123,6 +129,13 @@ func handleOrderByType(db *gorm.DB, preOrder *DbModels.LinePreOrder, orderStatus
if err := db.Model(&DbModels.LinePreOrder{}).Where("id =?", preOrder.Pid).Update("status", 9).Error; err != nil {
logger.Errorf("主单止损回调 订单号:%s 修改主单状态失败:%v", preOrder.OrderSn, err)
}
} else {
order, err := GetOrderById(db, preOrder.Pid)
if err != nil {
logger.Errorf("主单止损回调 获取主单失败 订单号:%s err:%v", preOrder.OrderSn, err)
return
}
triggerHedgeOrder(order, db, preOrder)
}
}
}
@ -178,7 +191,7 @@ func handleSpotTakeProfitFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
for _, v := range stoplossVal {
sonic.Unmarshal([]byte(v), &stoploss)
if stoploss.Pid == preOrder.Id {
if stoploss.Pid == preOrder.Pid {
_, err := helper.DefaultRedis.LRem(stoplossKey, v)
if err != nil {
@ -235,7 +248,7 @@ func updateOrderStatus(db *gorm.DB, preOrder *models.LinePreOrder, status int, r
params["num"] = num
params["price"] = total.Div(totalAmount)
preOrder.Num = num.String()
preOrder.Price = params["price"].(string)
preOrder.Price = total.Div(totalAmount).String()
}
case false:
status, _ := mapData["X"].(string)
@ -243,10 +256,11 @@ func updateOrderStatus(db *gorm.DB, preOrder *models.LinePreOrder, status int, r
if status == "FILLED" {
num, _ := decimal.NewFromString(mapData["z"].(string))
params["num"] = num.Mul(decimal.NewFromFloat(0.998)).String()
params["price"], _ = mapData["ap"].(string)
price, _ := mapData["ap"].(string)
params["price"] = price
preOrder.Num = num.String()
preOrder.Price = params["price"].(string)
preOrder.Price = price
}
}

View File

@ -203,7 +203,7 @@ func handleTickerMessage(msg []byte) {
continue
}
key := fmt.Sprintf("%s:%s", global.TICKER_SPOT, symbolName)
key := fmt.Sprintf(global.TICKER_SPOT, global.EXCHANGE_BINANCE, symbolName)
tcVal, _ := helper.DefaultRedis.GetString(key)
tradeSet := models.TradeSet{}
if err := sonic.UnmarshalString(tcVal, &tradeSet); err != nil {
@ -245,7 +245,7 @@ func handleTickerMessage(msg []byte) {
utility.SafeGoParam(binanceservice.JudgeSpotPrice, trades[index])
// 止损单
// utility.SafeGoParam(binanceservice.JudgeSpotStopLoss, trades[index])
utility.SafeGoParam(binanceservice.JudgeSpotStopLoss, trades[index])
}
}
}