1、暂存
This commit is contained in:
@ -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
|
||||
|
||||
@ -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{}
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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"`
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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("获取交易对失败")
|
||||
|
||||
Reference in New Issue
Block a user