1、暂存

This commit is contained in:
2025-10-14 19:58:59 +08:00
parent 556a32cb7c
commit 643eab3496
60 changed files with 5244 additions and 657 deletions

View File

@ -14,6 +14,7 @@ import (
"go-admin/models/spot"
"go-admin/pkg/httputils"
"go-admin/pkg/utility"
"go-admin/services/commonservice"
"strings"
"time"
@ -126,7 +127,7 @@ func (e SpotRestApi) GetSpotTicker24h(tradeSet *map[string]models.TradeSet) (del
log.Error("缓存交易对失败|", item.Symbol, err)
}
helper.DefaultRedis.AddSortSet(global.COIN_PRICE_CHANGE, symbol.PriceChange, symbol.Coin)
helper.DefaultRedis.AddSortSet(fmt.Sprintf(global.COIN_PRICE_CHANGE, global.EXCHANGE_BINANCE), symbol.PriceChange, symbol.Coin)
}
return deleteSymbols, nil
}
@ -169,12 +170,12 @@ type Ticker struct {
Price string `json:"price"`
}
func (e SpotRestApi) Ticker() {
tickerApi := fmt.Sprintf("%s%s", binanceRestApi, "/api/v3/ticker/price")
mapData, _ := httputils.NewHttpRequestWithFasthttp("GET", tickerApi, "", map[string]string{})
//sonic.Unmarshal(mapData, &tickerData)
helper.DefaultRedis.SetString(rediskey.SpotSymbolTicker, string(mapData))
}
// func (e SpotRestApi) Ticker() {
// tickerApi := fmt.Sprintf("%s%s", binanceRestApi, "/api/v3/ticker/price")
// mapData, _ := httputils.NewHttpRequestWithFasthttp("GET", tickerApi, "", map[string]string{})
// //sonic.Unmarshal(mapData, &tickerData)
// helper.DefaultRedis.SetString(rediskey.SpotSymbolTicker, string(mapData))
// }
// 循环下单
func (e SpotRestApi) OrderPlaceLoop(db *gorm.DB, params OrderPlacementService, retryCount int) error {
@ -452,7 +453,7 @@ func GetApiInfo(apiId int) (DbModels.LineApiUser, error) {
}
}
db := GetDBConnection()
db := commonservice.GetDBConnection()
if err := db.Model(&api).Where("id =?", apiId).First(&api).Error; err != nil {
return api, err

View File

@ -9,6 +9,7 @@ import (
"go-admin/common/helper"
"go-admin/models/positiondto"
"go-admin/pkg/utility"
"go-admin/services/commonservice"
"go-admin/services/positionservice"
"strings"
"time"
@ -16,7 +17,6 @@ import (
"github.com/bytedance/sonic"
"github.com/go-admin-team/go-admin-core/logger"
log "github.com/go-admin-team/go-admin-core/logger"
"github.com/go-admin-team/go-admin-core/sdk"
"github.com/shopspring/decimal"
"gorm.io/gorm"
)
@ -105,7 +105,7 @@ func CancelSpotOrder(symbol string, apiUserInfo *DbModels.LineApiUser, side stri
}
client := GetClient(apiUserInfo)
resp, _, err := client.SendSpotAuth(searchEndpoint, "GET", searchParams)
db := GetDBConnection()
db := commonservice.GetDBConnection()
if err != nil {
if len(resp) > 0 {
@ -209,44 +209,6 @@ func (e *AddPosition) GetFutSpotOrderInfo(req dto.ManuallyCover, symbol, orderTy
return orderInfo, nil
}
// CalculateAmount 计算加仓数量
func (e *AddPosition) CalculateAmount(req dto.ManuallyCover, totalNum, lastPrice decimal.Decimal, amountDigit int, notUsdt bool, symbolInfo DbModels.LineSymbol) (decimal.Decimal, error) {
var amt decimal.Decimal
if req.CoverType == 1 {
decimalValue := utility.StringToDecimal(req.Value).Div(decimal.NewFromInt(100))
amt = totalNum.Mul(decimalValue)
} else {
decimalValue := utility.StringToDecimal(req.Value)
if notUsdt {
tickerSymbolMaps := make([]dto.Ticker, 0)
tickerSymbol := helper.DefaultRedis.Get(rediskey.SpotSymbolTicker).Val()
if err := sonic.Unmarshal([]byte(tickerSymbol), &tickerSymbolMaps); err != nil {
return decimal.Zero, err
}
var tickerPrice decimal.Decimal
for _, symbolMap := range tickerSymbolMaps {
if symbolMap.Symbol == strings.ToUpper(symbolInfo.BaseAsset+"USDT") {
tickerPrice, _ = decimal.NewFromString(symbolMap.Price)
break
}
}
for _, symbolMap := range tickerSymbolMaps {
if symbolMap.Symbol == strings.ToUpper(symbolInfo.QuoteAsset+"USDT") {
uTickerPrice, _ := decimal.NewFromString(symbolMap.Price)
div := tickerPrice.Div(decimal.NewFromInt(1).Div(uTickerPrice))
amt = decimalValue.Div(div)
break
}
}
} else {
amt = decimalValue.Div(lastPrice)
}
}
return amt.Truncate(int32(amountDigit)), nil
}
// 主单平仓删除缓存
// mainOrderId 主单id
// symbolType 1现货 2合约
@ -256,7 +218,7 @@ func MainClosePositionClearCache(mainId int, symbolType int) {
keySpotAddposition := fmt.Sprintf(rediskey.SpotAddPositionList, global.EXCHANGE_BINANCE)
spotStopArray, _ := helper.DefaultRedis.GetAllList(keySpotStop)
spotAddpositionArray, _ := helper.DefaultRedis.GetAllList(keySpotAddposition)
var position AddPositionList
var position positiondto.AddPositionList
var stop dto.StopLossRedisList
for _, item := range spotAddpositionArray {
@ -284,7 +246,7 @@ func MainClosePositionClearCache(mainId int, symbolType int) {
keyFutAddposition := fmt.Sprintf(rediskey.FuturesStopLossList, global.EXCHANGE_BINANCE)
futAddpositionArray, _ := helper.DefaultRedis.GetAllList(keyFutStop)
futStopArray, _ := helper.DefaultRedis.GetAllList(keyFutAddposition)
var position AddPositionList
var position positiondto.AddPositionList
var stop dto.StopLossRedisList
for _, item := range futAddpositionArray {
@ -309,15 +271,6 @@ func MainClosePositionClearCache(mainId int, symbolType int) {
}
}
// 获取数据库连接
func GetDBConnection() *gorm.DB {
dbs := sdk.Runtime.GetDb()
for _, db := range dbs {
return db
}
return nil
}
// 查询订单
func getPreOrder(db *gorm.DB, orderSn interface{}) (*DbModels.LinePreOrder, error) {
preOrder := &DbModels.LinePreOrder{}

View File

@ -6,6 +6,7 @@ import (
"go-admin/common/global"
"go-admin/common/helper"
"go-admin/models"
"go-admin/models/positiondto"
"go-admin/services/cacheservice"
"testing"
@ -29,7 +30,7 @@ func TestFutureJudge(t *testing.T) {
key := fmt.Sprintf(rediskey.FuturesReduceList, global.EXCHANGE_BINANCE)
item := `{"id":50,"apiId":49,"mainId":47,"pid":47,"symbol":"ADAUSDT","price":"0.5936","side":"SELL","num":"12","orderSn":"397913127842217984"}`
reduceOrder := ReduceListItem{}
reduceOrder := positiondto.ReduceListItem{}
futApi := FutRestApi{}
setting, err := cacheservice.GetSystemSetting(db)

View File

@ -5,7 +5,6 @@ import (
"fmt"
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"
"go-admin/models"
@ -13,6 +12,7 @@ import (
"go-admin/models/futuresdto"
"go-admin/pkg/httputils"
"go-admin/pkg/utility"
"go-admin/services/cacheservice"
"strconv"
"strings"
"time"
@ -261,18 +261,18 @@ func GetAndReloadSymbols(data *map[string]models.TradeSet) error {
return nil
}
func (e FutRestApi) Ticker() {
url := fmt.Sprintf("%s%s", futureApi, "/fapi/v1/ticker/price")
mapData, err := httputils.NewHttpRequestWithFasthttp("GET", url, "", map[string]string{})
if err != nil {
log.Error("获取合约交易对行情失败:err:", err)
}
// func (e FutRestApi) Ticker() {
// url := fmt.Sprintf("%s%s", futureApi, "/fapi/v1/ticker/price")
// mapData, err := httputils.NewHttpRequestWithFasthttp("GET", url, "", map[string]string{})
// if err != nil {
// log.Error("获取合约交易对行情失败:err:", err)
// }
if len(mapData) == 0 {
log.Error("获取合约交易对行情失败,或数量为空")
}
helper.DefaultRedis.SetString(rediskey.FutSymbolTicker, string(mapData))
}
// if len(mapData) == 0 {
// log.Error("获取合约交易对行情失败,或数量为空")
// }
// helper.DefaultRedis.SetString(rediskey.FutSymbolTicker, string(mapData))
// }
// 获取合约行情
func GetTicker24h() ([]futuresdto.FutureTicker24h, error) {
@ -862,9 +862,10 @@ func (e FutRestApi) CancelBatchFutOrder(apiUserInfo DbModels.LineApiUser, symbol
// quoteSymbol 计价货币 ETHBTC -> 计价货币就是BTC
// totalMoney 兑换的总金额
func (e FutRestApi) CalcSymbolExchangeAmt(symbol string, quoteSymbol string, totalMoney decimal.Decimal) decimal.Decimal {
tickerSymbol := helper.DefaultRedis.Get(rediskey.FutSymbolTicker).Val()
tickerSymbolMaps := make([]dto.Ticker, 0)
sonic.Unmarshal([]byte(tickerSymbol), &tickerSymbolMaps)
// tickerSymbol := helper.DefaultRedis.Get(rediskey.FutSymbolTicker).Val()
// tickerSymbolMaps := make([]dto.Ticker, 0)
// sonic.Unmarshal([]byte(tickerSymbol), &tickerSymbolMaps)
tickerSymbolMaps, _ := cacheservice.GetExchangeTradeSets(global.EXCHANGE_BINANCE, 1)
targetSymbol := strings.Replace(symbol, quoteSymbol, "USDT", 1) //ETHBTC -》 ETHUSDT
key := fmt.Sprintf("%s:%s", global.TICKER_FUTURES, targetSymbol)
@ -873,7 +874,7 @@ func (e FutRestApi) CalcSymbolExchangeAmt(symbol string, quoteSymbol string, tot
quantity := decimal.Zero
for _, symbolMap := range tickerSymbolMaps {
if symbolMap.Symbol == strings.ToUpper(targetSymbol) {
targetPrice, _ = decimal.NewFromString(symbolMap.Price)
targetPrice, _ = decimal.NewFromString(symbolMap.LastPrice)
quantity = totalMoney.Div(targetPrice).Truncate(int32(tradeSet.AmountDigit))
}
}

View File

@ -10,8 +10,11 @@ import (
"go-admin/common/global"
"go-admin/common/helper"
"go-admin/models"
"go-admin/models/positiondto"
"go-admin/pkg/utility"
"go-admin/services/cacheservice"
"go-admin/services/commonservice"
"go-admin/services/orderservice"
"strings"
"time"
@ -26,7 +29,7 @@ import (
*/
func JudgeFuturesPrice(tradeSet models.TradeSet) {
preOrderVal, _ := helper.DefaultRedis.GetAllList(fmt.Sprintf(rediskey.PreFutOrderList, global.EXCHANGE_BINANCE))
db := GetDBConnection()
db := commonservice.GetDBConnection()
if len(preOrderVal) == 0 {
return
@ -153,7 +156,7 @@ func JudgeFuturesReduce(trade models.TradeSet) {
key := fmt.Sprintf(rediskey.FuturesReduceList, global.EXCHANGE_BINANCE)
reduceVal, _ := helper.DefaultRedis.GetAllList(key)
db := GetDBConnection()
db := commonservice.GetDBConnection()
futApi := FutRestApi{}
setting, err := cacheservice.GetSystemSetting(db)
@ -162,12 +165,14 @@ func JudgeFuturesReduce(trade models.TradeSet) {
return
}
reduceOrder := ReduceListItem{}
reduceOrder := positiondto.ReduceListItem{}
tradePrice, _ := decimal.NewFromString(trade.LastPrice)
//减仓单减仓策略
reduceReduceListKey := fmt.Sprintf(rediskey.FutOrderReduceStrategyList, global.EXCHANGE_BINANCE)
orderReduceVal, _ := helper.DefaultRedis.HGetAllFields(reduceReduceListKey)
reduceOrderStrategy := dto.LineOrderReduceStrategyResp{}
orderService := orderservice.OrderService{}
orderService.Orm = db
for _, item := range orderReduceVal {
sonic.Unmarshal([]byte(item), &reduceOrderStrategy)
@ -193,7 +198,7 @@ func JudgeFuturesReduce(trade models.TradeSet) {
return
}
order, err := CreateReduceReduceOrder(db, reduceOrderStrategy.OrderId, item2.Price, item2.Num, trade.PriceDigit)
order, err := orderService.CreateReduceReduceOrder(db, reduceOrderStrategy.OrderId, item2.Price, item2.Num, trade.PriceDigit)
if err != nil {
log.Errorf("%d 生成订单失败", reduceOrderStrategy.OrderId)
@ -261,8 +266,8 @@ func JudgeFuturesReduce(trade models.TradeSet) {
// 触发合约减仓
// isStrategy 是否是策略减仓
// reduceId 父减仓单id
func FuturesReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, futApi FutRestApi, setting DbModels.LineSystemSetting, key, item string, isStrategy bool, reduceId int) bool {
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, reduceOrder.Symbol, 1)
func FuturesReduceTrigger(db *gorm.DB, reduceOrder positiondto.ReduceListItem, futApi FutRestApi, setting DbModels.LineSystemSetting, key, item string, isStrategy bool, reduceId int) bool {
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, reduceOrder.Symbol, 2)
result := true
if tradeSet.LastPrice == "" {
@ -362,7 +367,7 @@ func FuturesReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, futApi FutRes
func JudgeFutAddPosition(trade models.TradeSet) {
key := fmt.Sprintf(rediskey.FuturesAddPositionList, global.EXCHANGE_BINANCE)
preOrderVal, _ := helper.DefaultRedis.GetAllList(key)
db := GetDBConnection()
db := commonservice.GetDBConnection()
if len(preOrderVal) == 0 {
return
@ -370,7 +375,7 @@ func JudgeFutAddPosition(trade models.TradeSet) {
futApi := FutRestApi{}
for _, item := range preOrderVal {
preOrder := AddPositionList{}
preOrder := positiondto.AddPositionList{}
if err := sonic.Unmarshal([]byte(item), &preOrder); err != nil {
log.Error("反序列化失败")
continue
@ -394,7 +399,7 @@ func JudgeFutAddPosition(trade models.TradeSet) {
}
// 合约加仓触发
func FutAddPositionTrigger(db *gorm.DB, v *AddPositionList, item string, futApi FutRestApi) {
func FutAddPositionTrigger(db *gorm.DB, v *positiondto.AddPositionList, item string, futApi FutRestApi) {
lock := helper.NewRedisLock(fmt.Sprintf(rediskey.FutTrigger, v.ApiId, v.Symbol), 20, 5, 100*time.Millisecond)
if ok, err := lock.AcquireWait(context.Background()); err != nil {
@ -404,7 +409,7 @@ func FutAddPositionTrigger(db *gorm.DB, v *AddPositionList, item string, futApi
defer lock.Release()
setting, _ := cacheservice.GetSystemSetting(db)
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, v.Symbol, 1)
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, v.Symbol, 2)
if tradeSet.LastPrice == "" {
log.Errorf("合约加仓触发 查询交易对失败 交易对:%s ordersn:%s", v.Symbol, v.OrderSn)

View File

@ -14,6 +14,7 @@ import (
"go-admin/models/positiondto"
"go-admin/pkg/utility"
"go-admin/services/cacheservice"
"go-admin/services/commonservice"
"strings"
"time"
@ -42,7 +43,7 @@ func ChangeFutureOrder(mapData map[string]interface{}) {
}
// 获取数据库连接
db := GetDBConnection()
db := commonservice.GetDBConnection()
if db == nil {
logger.Error("合约订单回调失败,无法获取数据库连接")
return
@ -127,7 +128,7 @@ func handleReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
return
}
tradeSet, err := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, preOrder.Symbol, 1)
tradeSet, err := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, preOrder.Symbol, 2)
if err != nil {
logger.Errorf("handleReduceFilled 获取交易对设置失败,订单号:%s", preOrder.OrderSn)
@ -266,7 +267,7 @@ func nextFuturesReduceTrigger(db *gorm.DB, mainId int, totalNum decimal.Decimal,
//移除缓存
key := fmt.Sprintf(rediskey.FuturesReduceList, global.EXCHANGE_BINANCE)
vals, _ := helper.DefaultRedis.GetAllList(key)
item := ReduceListItem{}
item := positiondto.ReduceListItem{}
for _, val := range vals {
sonic.Unmarshal([]byte(val), &item)
@ -438,8 +439,8 @@ func removeFutLossAndAddPosition(mainId int, orderSn string) {
reduceKey := fmt.Sprintf(rediskey.FuturesReduceList, global.EXCHANGE_BINANCE)
reduceVal, _ := helper.DefaultRedis.GetAllList(reduceKey)
stoploss := dto.StopLossRedisList{}
addPosition := AddPositionList{}
reduce := ReduceListItem{}
addPosition := positiondto.AddPositionList{}
reduce := positiondto.ReduceListItem{}
//移除减仓后减仓策略
RemoveReduceReduceCacheByMainId(mainId, 2)
@ -483,7 +484,7 @@ func removeFutLossAndAddPosition(mainId int, orderSn string) {
// 处理主单成交,处理止盈、止损、减仓订单
func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder, extOrderId int, first bool) {
// 获取交易对配置和API信息
tradeSet, err := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, preOrder.Symbol, 1)
tradeSet, err := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, preOrder.Symbol, 2)
mainId := preOrder.Id
if err != nil || tradeSet.Coin == "" {
logger.Errorf("获取交易对配置失败, 回调订单号:%s, 错误信息: %v", preOrder.OrderSn, err)
@ -522,7 +523,7 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder, extOrd
keyFutAddpositionKey := fmt.Sprintf(rediskey.FuturesAddPositionList, global.EXCHANGE_BINANCE)
for _, addPositionOrder := range addPositionOrders {
addPositionData := AddPositionList{
addPositionData := positiondto.AddPositionList{
Id: addPositionOrder.Id,
OrderSn: addPositionOrder.OrderSn,
MainId: addPositionOrder.MainId,
@ -728,7 +729,7 @@ func updateOrderQuantity(db *gorm.DB, order models.LinePreOrder, preOrder *model
// 减仓单
func processFutReduceOrder(order DbModels.LinePreOrder, price, num decimal.Decimal) {
key := fmt.Sprintf(rediskey.FuturesReduceList, global.EXCHANGE_BINANCE)
item := ReduceListItem{
item := positiondto.ReduceListItem{
Id: order.Id,
ApiId: order.ApiId,
Pid: order.Pid,
@ -756,7 +757,7 @@ func processFutReduceOrder(order DbModels.LinePreOrder, price, num decimal.Decim
// 处理止盈订单
func processFutTakeProfitOrder(db *gorm.DB, futApi FutRestApi, order models.LinePreOrder, num decimal.Decimal) {
price, _ := decimal.NewFromString(order.Price)
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, order.Symbol, 1)
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, order.Symbol, 2)
params := FutOrderPlace{
ApiId: order.ApiId,
@ -793,7 +794,7 @@ func processFutTakeProfitOrder(db *gorm.DB, futApi FutRestApi, order models.Line
// 处理止损订单
// order 止损单
func processFutStopLossOrder(db *gorm.DB, order models.LinePreOrder, price, num decimal.Decimal) error {
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, order.Symbol, 1)
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, order.Symbol, 2)
params := FutOrderPlace{
ApiId: order.ApiId,

View File

@ -186,19 +186,6 @@ type OpenOrders struct {
GoodTillDate int `json:"goodTillDate"` //order pre-set auot cancel time for TIF GTD order
}
// 待触发加仓单
type AddPositionList struct {
Id int `json:"id"` //订单id
Pid int `json:"pid"` //父级id
MainId int `json:"mainId"` //主单Id
ApiId int `json:"apiId"` //触发账户id
Symbol string `json:"symbol"` //交易对
Price decimal.Decimal `json:"price"` //触发价
Side string `json:"side"` //买卖方向
SymbolType int `json:"type" comment:"交易对类别 1-现货 2-合约"`
OrderSn string `json:"prderSn"`
}
// SpotAccountInfo 现货账户信息
type SpotAccountInfo struct {
MakerCommission int `json:"makerCommission"`
@ -227,15 +214,3 @@ type SpotAccountInfo struct {
Permissions []string `json:"permissions"`
Uid int `json:"uid"`
}
type ReduceListItem struct {
Id int `json:"id"`
ApiId int `json:"apiId"`
MainId int `json:"mainId"`
Pid int `json:"pid"`
Symbol string `json:"symbol"`
Price decimal.Decimal `json:"price"`
Side string `json:"side"`
Num decimal.Decimal `json:"num"`
OrderSn string `json:"orderSn"`
}

View File

@ -1,15 +1,10 @@
package binanceservice
import (
"fmt"
"go-admin/app/admin/models"
DbModels "go-admin/app/admin/models"
"go-admin/pkg/utility"
"go-admin/pkg/utility/snowflakehelper"
"time"
"github.com/go-admin-team/go-admin-core/logger"
"github.com/jinzhu/copier"
"github.com/shopspring/decimal"
"gorm.io/gorm"
)
@ -175,69 +170,3 @@ func GetChildTpOrder(db *gorm.DB, pid int) (int, error) {
return int(count), nil
}
// 创建减仓后减仓单
func CreateReduceReduceOrder(db *gorm.DB, pid int, price, num decimal.Decimal, priceDigit int) (models.LinePreOrder, error) {
var preOrder models.LinePreOrder
var result models.LinePreOrder
var ext models.LinePreOrderExt
if err := db.Model(&models.LinePreOrder{}).Preload("Childs").Where("id =? ", pid).First(&preOrder).Error; err != nil {
return preOrder, err
}
if err := db.Model(&models.LinePreOrderExt{}).Where("order_id =? ", pid).Find(&ext).Error; err != nil {
return preOrder, err
}
copier.Copy(&result, &preOrder)
result.Id = 0
result.OrderSn = utility.Int64ToString(snowflakehelper.GetOrderId())
result.Status = 0
result.CreatedAt = time.Now()
result.TriggerTime = nil
result.UpdatedAt = time.Now()
result.BuyPrice = decimal.Zero.String()
result.Price = price.String()
result.Num = num.String()
result.ReduceOrderId = preOrder.Id
for index := range result.Childs {
result.Childs[index].Id = 0
result.Childs[index].OrderSn = utility.Int64ToString(snowflakehelper.GetOrderId())
result.Childs[index].Status = 0
result.Childs[index].CreatedAt = time.Now()
result.Childs[index].TriggerTime = nil
result.Childs[index].UpdatedAt = time.Now()
result.Childs[index].BuyPrice = decimal.Zero.String()
var pricePercent decimal.Decimal
if result.Childs[index].OrderType == 1 && ext.TakeProfitRatio.Cmp(decimal.Zero) > 0 {
// 减仓单卖出
if preOrder.Site == "SELL" {
pricePercent = decimal.NewFromInt(100).Add(ext.TakeProfitRatio).Div(decimal.NewFromInt(100))
} else {
pricePercent = decimal.NewFromInt(100).Sub(ext.TakeProfitRatio).Div(decimal.NewFromInt(100))
}
} else if result.Childs[index].OrderType == 2 && ext.StopLossRatio.Cmp(decimal.Zero) > 0 {
if preOrder.Site == "SELL" {
pricePercent = decimal.NewFromInt(100).Sub(ext.StopLossRatio).Div(decimal.NewFromInt(100))
} else {
pricePercent = decimal.NewFromInt(100).Add(ext.StopLossRatio).Div(decimal.NewFromInt(100))
}
}
//重新计算止盈止损价
if pricePercent.Cmp(decimal.Zero) > 0 {
result.Childs[index].Price = price.Mul(pricePercent).Truncate(int32(priceDigit)).String()
}
}
if err := db.Create(&result).Error; err != nil {
return result, fmt.Errorf("复制减仓单失败pid:%d err:%v", pid, err)
}
return result, nil
}

View File

@ -8,6 +8,7 @@ import (
"go-admin/common/global"
"go-admin/common/helper"
models2 "go-admin/models"
"go-admin/models/positiondto"
"go-admin/pkg/utility"
"github.com/bytedance/sonic"
@ -19,7 +20,7 @@ import (
// 缓存减仓节点和重新生成
// reduceOrder:原始减仓单
// reduceOrderStrategy:减仓策略
func CacheOrderStrategyAndReCreate(db *gorm.DB, reduceOrder ReduceListItem, symbolType int, tradeSet models2.TradeSet, setting models.LineSystemSetting) error {
func CacheOrderStrategyAndReCreate(db *gorm.DB, reduceOrder positiondto.ReduceListItem, symbolType int, tradeSet models2.TradeSet, setting models.LineSystemSetting) error {
reduceOrderStrategy := models.LineOrderReduceStrategy{}
var key string

View File

@ -6,6 +6,7 @@ import (
"go-admin/common/global"
"go-admin/common/helper"
"go-admin/models"
"go-admin/models/positiondto"
"go-admin/services/cacheservice"
"testing"
@ -29,7 +30,7 @@ func TestSpotJudge(t *testing.T) {
key := fmt.Sprintf(rediskey.SpotReduceList, global.EXCHANGE_BINANCE)
item := `{"id":66,"apiId":49,"mainId":63,"pid":63,"symbol":"ADAUSDT","price":"0.5912","side":"SELL","num":"12.6","orderSn":"397919643961917440"}`
reduceOrder := ReduceListItem{}
reduceOrder := positiondto.ReduceListItem{}
spotApi := SpotRestApi{}
setting, err := cacheservice.GetSystemSetting(db)

View File

@ -10,8 +10,11 @@ import (
"go-admin/common/global"
"go-admin/common/helper"
"go-admin/models"
"go-admin/models/positiondto"
"go-admin/pkg/utility"
"go-admin/services/cacheservice"
"go-admin/services/commonservice"
"go-admin/services/orderservice"
"strings"
"time"
@ -27,13 +30,16 @@ import (
func JudgeSpotPrice(trade models.TradeSet) {
key := fmt.Sprintf(rediskey.PreSpotOrderList, global.EXCHANGE_BINANCE)
preOrderVal, _ := helper.DefaultRedis.GetAllList(key)
db := GetDBConnection()
db := commonservice.GetDBConnection()
if len(preOrderVal) == 0 {
return
}
spotApi := SpotRestApi{}
orderService := orderservice.OrderService{}
orderService.Orm = db
for _, item := range preOrderVal {
preOrder := dto.PreOrderRedisList{}
if err := sonic.Unmarshal([]byte(item), &preOrder); err != nil {
@ -46,6 +52,18 @@ func JudgeSpotPrice(trade models.TradeSet) {
tradePrice, _ := decimal.NewFromString(trade.LastPrice)
//买入
if strings.ToUpper(preOrder.Site) == "BUY" && orderPrice.Cmp(tradePrice) >= 0 && orderPrice.Cmp(decimal.Zero) > 0 && tradePrice.Cmp(decimal.Zero) > 0 {
//判断个人websocket是否超时
apiInfo, _ := GetApiInfo(preOrder.ApiId)
if err := commonservice.JudgeWebsocketTimeout(apiInfo.ApiKey, 1); err != nil {
log.Errorf("现货行情订阅超时,apiKey:%s err:%v", err)
if err1 := orderService.ErrorTrigger(&preOrder, fmt.Sprintf("行情触发失败,err:%v", err)); err1 != nil {
log.Error("触发失败", err1)
}
continue
}
SpotOrderLock(db, &preOrder, item, spotApi)
}
}
@ -140,7 +158,7 @@ func JudgeSpotStopLoss(trade models.TradeSet) {
return
}
db := GetDBConnection()
db := commonservice.GetDBConnection()
spotApi := SpotRestApi{}
setting, err := cacheservice.GetSystemSetting(db)
@ -149,7 +167,7 @@ func JudgeSpotStopLoss(trade models.TradeSet) {
return
}
tradeSet, err := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, trade.Coin+trade.Currency, 0)
tradeSet, err := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, trade.Coin+trade.Currency, 1)
if err != nil {
log.Error("获取交易设置失败")
@ -257,7 +275,7 @@ func SpotStopLossTrigger(db *gorm.DB, stopOrder dto.StopLossRedisList, spotApi S
// 判断是否触发现货减仓
func JudgeSpotReduce(trade models.TradeSet) {
key := fmt.Sprintf(rediskey.SpotReduceList, global.EXCHANGE_BINANCE)
db := GetDBConnection()
db := commonservice.GetDBConnection()
spotApi := SpotRestApi{}
setting, err := cacheservice.GetSystemSetting(db)
@ -266,12 +284,14 @@ func JudgeSpotReduce(trade models.TradeSet) {
return
}
reduceOrder := ReduceListItem{}
reduceOrder := positiondto.ReduceListItem{}
tradePrice, _ := decimal.NewFromString(trade.LastPrice)
//减仓单减仓策略
reduceReduceListKey := fmt.Sprintf(rediskey.SpotOrderReduceStrategyList, global.EXCHANGE_BINANCE)
orderReduceVal, _ := helper.DefaultRedis.HGetAllFields(reduceReduceListKey)
reduceOrderStrategy := dto.LineOrderReduceStrategyResp{}
orderService := orderservice.OrderService{}
orderService.Orm = db
for _, item := range orderReduceVal {
sonic.Unmarshal([]byte(item), &reduceOrderStrategy)
@ -297,7 +317,7 @@ func JudgeSpotReduce(trade models.TradeSet) {
return
}
order, err := CreateReduceReduceOrder(db, reduceOrderStrategy.OrderId, item2.Price, item2.Num, trade.PriceDigit)
order, err := orderService.CreateReduceReduceOrder(db, reduceOrderStrategy.OrderId, item2.Price, item2.Num, trade.PriceDigit)
if err != nil {
log.Errorf("%d 生成订单失败", reduceOrderStrategy.OrderId)
@ -367,8 +387,8 @@ func JudgeSpotReduce(trade models.TradeSet) {
// 触发现货减仓
// isStrategy 是否是策略减仓单
// reduceId 策略主减仓单id
func SpotReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, spotApi SpotRestApi, setting DbModels.LineSystemSetting, key, item string, isStrategy bool, reduceId int) bool {
tradeSet, err := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, reduceOrder.Symbol, 0)
func SpotReduceTrigger(db *gorm.DB, reduceOrder positiondto.ReduceListItem, spotApi SpotRestApi, setting DbModels.LineSystemSetting, key, item string, isStrategy bool, reduceId int) bool {
tradeSet, err := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, reduceOrder.Symbol, 1)
result := true
if err != nil {
@ -470,7 +490,7 @@ func SpotReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, spotApi SpotRest
func JudgeSpotAddPosition(trade models.TradeSet) {
key := fmt.Sprintf(rediskey.SpotAddPositionList, global.EXCHANGE_BINANCE)
preOrderVal, _ := helper.DefaultRedis.GetAllList(key)
db := GetDBConnection()
db := commonservice.GetDBConnection()
if len(preOrderVal) == 0 {
return
@ -478,7 +498,7 @@ func JudgeSpotAddPosition(trade models.TradeSet) {
spotApi := SpotRestApi{}
for _, item := range preOrderVal {
preOrder := AddPositionList{}
preOrder := positiondto.AddPositionList{}
if err := sonic.Unmarshal([]byte(item), &preOrder); err != nil {
log.Error("反序列化失败")
continue
@ -495,7 +515,7 @@ func JudgeSpotAddPosition(trade models.TradeSet) {
}
}
func SpotAddPositionTrigger(db *gorm.DB, v *AddPositionList, item string, spotApi SpotRestApi) {
func SpotAddPositionTrigger(db *gorm.DB, v *positiondto.AddPositionList, item string, spotApi SpotRestApi) {
lock := helper.NewRedisLock(fmt.Sprintf(rediskey.SpotTrigger, v.ApiId, v.Symbol), 20, 5, 100*time.Millisecond)
if ok, err := lock.AcquireWait(context.Background()); err != nil {
@ -505,7 +525,7 @@ func SpotAddPositionTrigger(db *gorm.DB, v *AddPositionList, item string, spotAp
defer lock.Release()
setting, _ := cacheservice.GetSystemSetting(db)
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, v.Symbol, 0)
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, v.Symbol, 1)
if tradeSet.LastPrice == "" {
log.Errorf("现货加仓触发 查询交易对失败 交易对:%s ordersn:%s", v.Symbol, v.OrderSn)

View File

@ -14,6 +14,7 @@ import (
"go-admin/models/positiondto"
"go-admin/pkg/utility"
"go-admin/services/cacheservice"
"go-admin/services/commonservice"
"go-admin/services/positionservice"
"strconv"
"strings"
@ -44,7 +45,7 @@ func ChangeSpotOrder(mapData map[string]interface{}) {
}
// 获取数据库连接
db := GetDBConnection()
db := commonservice.GetDBConnection()
if db == nil {
logger.Error("订单回调失败, 无法获取数据库连接")
return
@ -166,7 +167,7 @@ func handleMainReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
return
}
tradeSet, err := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, preOrder.Symbol, 0)
tradeSet, err := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, preOrder.Symbol, 1)
if err != nil {
logger.Errorf("handleMainReduceFilled 获取交易对设置失败,订单号:%s", preOrder.OrderSn)
@ -300,7 +301,7 @@ func nextSpotReduceTrigger(db *gorm.DB, mainId int, totalNum decimal.Decimal, tr
//移除缓存
key := fmt.Sprintf(rediskey.SpotReduceList, global.EXCHANGE_BINANCE)
vals, _ := helper.DefaultRedis.GetAllList(key)
item := ReduceListItem{}
item := positiondto.ReduceListItem{}
for _, val := range vals {
sonic.Unmarshal([]byte(val), &item)
@ -553,8 +554,8 @@ func removeSpotLossAndAddPosition(mainId int, orderSn string) {
reduceKey := fmt.Sprintf(rediskey.SpotReduceList, global.EXCHANGE_BINANCE)
reduceVal, _ := helper.DefaultRedis.GetAllList(reduceKey)
stoploss := dto.StopLossRedisList{}
addPosition := AddPositionList{}
reduce := ReduceListItem{}
addPosition := positiondto.AddPositionList{}
reduce := positiondto.ReduceListItem{}
//移除减仓后减仓策略
RemoveReduceReduceCacheByMainId(mainId, 1)
@ -646,7 +647,7 @@ func handleMainOrderFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) {
keySpotAddPosition := fmt.Sprintf(rediskey.SpotAddPositionList, global.EXCHANGE_BINANCE)
for _, addPositionOrder := range addPositionOrders {
addPositionData := AddPositionList{
addPositionData := positiondto.AddPositionList{
Id: addPositionOrder.Id,
OrderSn: addPositionOrder.OrderSn,
MainId: addPositionOrder.MainId,
@ -744,7 +745,7 @@ func updateOrderStatus(db *gorm.DB, preOrder *models.LinePreOrder, status int, r
// fist 首次止盈止损
func processTakeProfitAndStopLossOrders(db *gorm.DB, preOrder *models.LinePreOrder, positionData *positiondto.PositionDto, extOrderId int, fist bool) {
orders := []models.LinePreOrder{}
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, preOrder.Symbol, 0)
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, preOrder.Symbol, 1)
mainId := preOrder.Id
if preOrder.MainId > 0 {
@ -855,7 +856,7 @@ func SetPrice(order *models.LinePreOrder, preOrder *models.LinePreOrder, tradeSe
// 现货减仓
func processSpotReduceOrder(preOrder DbModels.LinePreOrder) {
key := fmt.Sprintf(rediskey.SpotReduceList, global.EXCHANGE_BINANCE)
item := ReduceListItem{
item := positiondto.ReduceListItem{
Id: preOrder.Id,
ApiId: preOrder.ApiId,
Pid: preOrder.Pid,
@ -882,7 +883,7 @@ func processSpotReduceOrder(preOrder DbModels.LinePreOrder) {
// 处理止盈订单
func processTakeProfitOrder(db *gorm.DB, spotApi SpotRestApi, order models.LinePreOrder) {
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, order.Symbol, 0)
tradeSet, _ := cacheservice.GetTradeSet(global.EXCHANGE_BINANCE, order.Symbol, 1)
if tradeSet.Coin == "" {
logger.Error("获取交易对失败")