1
This commit is contained in:
		| @ -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)) | ||||
|  | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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(), "删除成功") | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
|  | ||||
| @ -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最后通信时间 | ||||
|  | ||||
| @ -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:对冲止损百分比"` | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
|  | ||||
| @ -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"` | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
|  | ||||
| @ -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 // 添加这而,需要记录是被谁更新的 | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -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()), | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
| @ -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{}) | ||||
| 	} | ||||
|  | ||||
| @ -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) | ||||
| 		} | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 { | ||||
|  | ||||
| @ -63,7 +63,7 @@ const ( | ||||
|  | ||||
| const ( | ||||
| 	//交易对-现货 | ||||
| 	SYMBOL_SPOT = 0 | ||||
| 	SYMBOL_SPOT = 1 | ||||
| 	//交易对-合约 | ||||
| 	SYMBOL_FUTURES = 1 | ||||
| 	SYMBOL_FUTURES = 2 | ||||
| ) | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
|  | ||||
| @ -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用户信息 | ||||
| */ | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -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]) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user