diff --git a/app/admin/apis/line_api_group.go b/app/admin/apis/line_api_group.go index ab7b91d..23cc4e9 100644 --- a/app/admin/apis/line_api_group.go +++ b/app/admin/apis/line_api_group.go @@ -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)) diff --git a/app/admin/apis/line_api_user.go b/app/admin/apis/line_api_user.go index 71a7983..c0a7f9c 100644 --- a/app/admin/apis/line_api_user.go +++ b/app/admin/apis/line_api_user.go @@ -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 diff --git a/app/admin/apis/line_symbol.go b/app/admin/apis/line_symbol.go index 6aff8df..d0c43ae 100644 --- a/app/admin/apis/line_symbol.go +++ b/app/admin/apis/line_symbol.go @@ -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 diff --git a/app/admin/apis/line_symbol_group.go b/app/admin/apis/line_symbol_group.go index 2dc803d..6fff24b 100644 --- a/app/admin/apis/line_symbol_group.go +++ b/app/admin/apis/line_symbol_group.go @@ -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(), "删除成功") } diff --git a/app/admin/models/line_api_group.go b/app/admin/models/line_api_group.go index 8c105a2..12fa4c7 100644 --- a/app/admin/models/line_api_group.go +++ b/app/admin/models/line_api_group.go @@ -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 } diff --git a/app/admin/models/line_api_user.go b/app/admin/models/line_api_user.go index e8010d7..2d29adf 100644 --- a/app/admin/models/line_api_user.go +++ b/app/admin/models/line_api_user.go @@ -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最后通信时间 diff --git a/app/admin/models/line_pre_order.go b/app/admin/models/line_pre_order.go index bc8c082..f0bca42 100644 --- a/app/admin/models/line_pre_order.go +++ b/app/admin/models/line_pre_order.go @@ -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:对冲止损百分比"` diff --git a/app/admin/models/line_symbol.go b/app/admin/models/line_symbol.go index 724e391..1bd68bf 100644 --- a/app/admin/models/line_symbol.go +++ b/app/admin/models/line_symbol.go @@ -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 } diff --git a/app/admin/models/line_symbol_group.go b/app/admin/models/line_symbol_group.go index cd795a9..3fc93c0 100644 --- a/app/admin/models/line_symbol_group.go +++ b/app/admin/models/line_symbol_group.go @@ -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 } diff --git a/app/admin/service/dto/line_api_group.go b/app/admin/service/dto/line_api_group.go index f47eaf3..49760d3 100644 --- a/app/admin/service/dto/line_api_group.go +++ b/app/admin/service/dto/line_api_group.go @@ -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 } diff --git a/app/admin/service/dto/line_api_user.go b/app/admin/service/dto/line_api_user.go index a9a1b62..60ea651 100644 --- a/app/admin/service/dto/line_api_user.go +++ b/app/admin/service/dto/line_api_user.go @@ -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"` } diff --git a/app/admin/service/dto/line_pre_order.go b/app/admin/service/dto/line_pre_order.go index cc56698..d13ff4d 100644 --- a/app/admin/service/dto/line_pre_order.go +++ b/app/admin/service/dto/line_pre_order.go @@ -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 } diff --git a/app/admin/service/dto/line_symbol.go b/app/admin/service/dto/line_symbol.go index 757a16e..e055299 100644 --- a/app/admin/service/dto/line_symbol.go +++ b/app/admin/service/dto/line_symbol.go @@ -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 } diff --git a/app/admin/service/dto/line_symbol_group.go b/app/admin/service/dto/line_symbol_group.go index f707915..45b4161 100644 --- a/app/admin/service/dto/line_symbol_group.go +++ b/app/admin/service/dto/line_symbol_group.go @@ -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 } diff --git a/app/admin/service/dto/line_system_setting.go b/app/admin/service/dto/line_system_setting.go index 1f2811e..d539f28 100644 --- a/app/admin/service/dto/line_system_setting.go +++ b/app/admin/service/dto/line_system_setting.go @@ -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 // 添加这而,需要记录是被谁更新的 } diff --git a/app/admin/service/line_api_group.go b/app/admin/service/line_api_group.go index f79a60e..fb217a9 100644 --- a/app/admin/service/line_api_group.go +++ b/app/admin/service/line_api_group.go @@ -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()), diff --git a/app/admin/service/line_api_user.go b/app/admin/service/line_api_user.go index cf14bee..23b1551 100644 --- a/app/admin/service/line_api_user.go +++ b/app/admin/service/line_api_user.go @@ -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 diff --git a/app/admin/service/line_direction.go b/app/admin/service/line_direction.go index 3a3e482..7e73397 100644 --- a/app/admin/service/line_direction.go +++ b/app/admin/service/line_direction.go @@ -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) diff --git a/app/admin/service/line_pre_order.go b/app/admin/service/line_pre_order.go index 41ff678..ec2ab4e 100644 --- a/app/admin/service/line_pre_order.go +++ b/app/admin/service/line_pre_order.go @@ -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{}) } diff --git a/app/admin/service/line_price_limit.go b/app/admin/service/line_price_limit.go index 30fd41e..0989a77 100644 --- a/app/admin/service/line_price_limit.go +++ b/app/admin/service/line_price_limit.go @@ -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) } diff --git a/app/admin/service/line_symbol.go b/app/admin/service/line_symbol.go index 7567182..fc4bd93 100644 --- a/app/admin/service/line_symbol.go +++ b/app/admin/service/line_symbol.go @@ -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 diff --git a/app/admin/service/line_symbol_group.go b/app/admin/service/line_symbol_group.go index 1dc0bb9..79cbcfc 100644 --- a/app/admin/service/line_symbol_group.go +++ b/app/admin/service/line_symbol_group.go @@ -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 { diff --git a/common/global/redis_prefix.go b/common/global/redis_prefix.go index 9549576..3181f6a 100644 --- a/common/global/redis_prefix.go +++ b/common/global/redis_prefix.go @@ -63,7 +63,7 @@ const ( const ( //交易对-现货 - SYMBOL_SPOT = 0 + SYMBOL_SPOT = 1 //交易对-合约 - SYMBOL_FUTURES = 1 + SYMBOL_FUTURES = 2 ) diff --git a/config/serverinit/usersubscribeinit.go b/config/serverinit/usersubscribeinit.go index b4f6df0..465e908 100644 --- a/config/serverinit/usersubscribeinit.go +++ b/config/serverinit/usersubscribeinit.go @@ -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) diff --git a/config/settings.yml b/config/settings.yml index f02ad69..3d888a0 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -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 diff --git a/services/binanceservice/binancerest.go b/services/binanceservice/binancerest.go index 338befb..14e3704 100644 --- a/services/binanceservice/binancerest.go +++ b/services/binanceservice/binancerest.go @@ -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用户信息 */ diff --git a/services/binanceservice/futuresbinancerest.go b/services/binanceservice/futuresbinancerest.go index 0259928..c0d581c 100644 --- a/services/binanceservice/futuresbinancerest.go +++ b/services/binanceservice/futuresbinancerest.go @@ -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, diff --git a/services/binanceservice/futuresrest.go b/services/binanceservice/futuresrest.go index ed4f5db..5117f65 100644 --- a/services/binanceservice/futuresrest.go +++ b/services/binanceservice/futuresrest.go @@ -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 diff --git a/services/binanceservice/spotreset.go b/services/binanceservice/spotreset.go index 79bbbfd..b81da03 100644 --- a/services/binanceservice/spotreset.go +++ b/services/binanceservice/spotreset.go @@ -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 } } diff --git a/services/spotservice/binancemarket.go b/services/spotservice/binancemarket.go index 26f3062..9481dc4 100644 --- a/services/spotservice/binancemarket.go +++ b/services/spotservice/binancemarket.go @@ -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]) } } }