package socket import ( "context" "encoding/json" "fmt" "github.com/shopspring/decimal" "matchmaking-system/internal/data" "matchmaking-system/internal/data/memory" "matchmaking-system/internal/data/socket/moneyData" "matchmaking-system/internal/data/socket/publicData" "matchmaking-system/internal/data/tradedeal/money" "matchmaking-system/internal/data/tradedeal/virtual" "matchmaking-system/internal/pkg/flags" "matchmaking-system/internal/pkg/logging/applogger" models "matchmaking-system/internal/pkg/model" "matchmaking-system/internal/pkg/setting" "strconv" "strings" "time" ) // orderSubMoneySubscribe // // @Description: 用户综合(现货|合约|外汇)订单订阅 // @receiver u // @param psgMsg func (u *Client) orderSubMoneySubscribe(psgMsg *SymbolMessage, makeType int) { for { userId, err := GetUserIdByToken(u.token) if err != nil { time.Sleep(5 * time.Second) cleanSubscriptionKey(u) break } if userId != flags.AdministratorsId && psgMsg.Symbol == setting.MoneySubscribe { orderTokenKey := virtual.OrderIdListKey(setting.MoneySubscribe, userId) // 获取订阅Key orderList, err := data.Reds.HGetAll(context.Background(), orderTokenKey).Result() if err != nil { time.Sleep(5 * time.Second) continue } for _, value := range orderList { var msg money.MoneyTallyCache if err = json.Unmarshal([]byte(value), &msg); err != nil { time.Sleep(5 * time.Second) continue } var checkBool bool if makeType == 0 { checkBool = true // 现货|合约|外汇 } else { switch msg.Order.Type { case int64(makeType): // 可能-(现货|合约|外汇) checkBool = true default: checkBool = false } } if checkBool { orderModel := moneyData.MoneyOrderProcessing(setting.MoneySubscribe, msg) if orderModel != nil { var ok bool if makeType == 0 { _, ok = u.symbol.Load(psgMsg.Symbol) } else { _, ok = u.symbol.Load(fmt.Sprintf("%v-%v", psgMsg.Symbol, makeType)) } if ok { // 清理订阅缓存订单中(撤单|平仓)状态的订单 if orderModel.Status == flags.Cancel || orderModel.Status == flags.Close { err = data.Reds.HDel(context.Background(), orderTokenKey, msg.OrderId).Err() if err != nil { time.Sleep(5 * time.Second) applogger.Error("MoneySubscribe.HDel:%v", err) continue } } orderStr, err := json.Marshal(orderModel) if err != nil { applogger.Error("orderSubMoneySubscribe.Marshal:%v", err) time.Sleep(5 * time.Second) continue } u.msg <- orderStr // 用户(挂单|持仓)订阅 } else { applogger.Info("User cancels Money order subscription.") return } } } } } time.Sleep(600 * time.Millisecond) } } func (u *Client) orderSubShareMoneyMarketSubscribe(psgMsg *SymbolMessage) { var n int var MarketMoneyCache decimal.Decimal // 缓存记录 var marketProfitAndLoss decimal.Decimal // 用户市场累计盈亏 var marketTotalFee decimal.Decimal // 用户市场总手续费 for { userId, err := GetUserIdByToken(u.token) if err != nil { time.Sleep(5 * time.Second) cleanSubscriptionKey(u) break } if userId != flags.AdministratorsId && psgMsg.Symbol == setting.ShareMoneyMarketSubscribe { var marketTotalAssets decimal.Decimal // 用户市场总资产 var marketSpotsTotalAssets decimal.Decimal // 用户现货市场总资产 var marketAvailable decimal.Decimal // 用户市场可用 var marketFreeze decimal.Decimal // 用户市场冻结 var marketFloatingPL decimal.Decimal // 用户市场总浮动盈亏 // 统计用户现货资产 var botUserMoneySpots []models.BotUserMoney err = data.Msql.Table(flags.BotUserMoney).Where("user_id = ?", userId).Where("stock_id NOT REGEXP 'USD$'").Find(&botUserMoneySpots) if err != nil { marketAvailable = decimal.Zero marketFreeze = decimal.Zero } for _, value := range botUserMoneySpots { stockId := strings.ToLower(value.StockId) keyPrice := publicData.SymbolCache(flags.Xh, stockId, flags.TradeTypeAdminPrice) priceNew, err := memory.GetMoneySpotsCache(keyPrice) if err != nil { continue } priceN := decimal.RequireFromString(string(priceNew)) usableNum := decimal.RequireFromString(value.UsableNum) marketSpotsTotalAssets = marketSpotsTotalAssets.Add(priceN.Mul(usableNum)) } // 统计用户市场可用余额和冻结余额 var botUserMoney []models.BotUserMoney err = data.Msql.Table(flags.BotUserMoney).Where("user_id = ?", userId).Where("stock_id = ?", flags.MoneyUnit).Find(&botUserMoney) if err != nil { marketAvailable = decimal.Zero marketFreeze = decimal.Zero } for _, value := range botUserMoney { marketAvailable = decimal.RequireFromString(value.UsableNum) marketFreeze = decimal.RequireFromString(value.FrozenNum) } // 判定是否存在订单 if marketAvailable.IsZero() || marketFreeze.IsZero() { if n == 0 { tradeCount, _ := data.Msql.Table(flags.BotMoneyTrade).Where("user_id = ?", userId).In("status", 1, 3).Count() if tradeCount > 0 { n = 1 } } } if marketAvailable.Cmp(MarketMoneyCache) != 0 || n == 1 { // 统计用户市场累计盈亏 var botMoneyTrade []models.BotMoneyTrade err = data.Msql.Table(flags.BotMoneyTrade).Where("user_id = ?", userId).Where("status = 3").Find(&botMoneyTrade) if err != nil { marketProfitAndLoss = decimal.Zero } for _, value := range botMoneyTrade { sumValue := decimal.Zero openPrice := decimal.RequireFromString(value.DealPrice) closePrice := decimal.RequireFromString(value.ClosingPrice) orderNum := decimal.RequireFromString(value.OrderNumber) pryNum := decimal.RequireFromString(strconv.Itoa(value.PryNum)) switch value.TradeType { case 1: // 买张 sumValue = closePrice.Sub(openPrice) case 2: // 买跌 sumValue = openPrice.Sub(closePrice) default: continue } profLass := sumValue.Mul(orderNum).Mul(pryNum) //applogger.Error("第一个:%v,买涨还是买跌:%v,开仓价:%v,平仓价:%v,订单量:%v,杠杆:%v,盈亏:%v", key, value.TradeType, openPrice, closePrice, orderNum, pryNum, profLass) marketProfitAndLoss = marketProfitAndLoss.Add(profLass) } // 统计用户市场总手续费 var botMoneyTradeFee models.BotMoneyTrade totalFee, err := data.Msql.Table(flags.BotMoneyTrade).Where("user_id = ?", userId).In("status", 1, 3).Sums(botMoneyTradeFee, "service_cost", "closing_cost") if err != nil || len(totalFee) != 2 { marketTotalFee = decimal.Zero } marketTotalFee = decimal.NewFromFloat(totalFee[0]).Add(decimal.NewFromFloat(totalFee[1])) MarketMoneyCache = marketAvailable n = 2 } // 用户市场总浮动盈亏 pLPriceSum := GetMoneyByPriceSum(userId, setting.AdminMoneySubscribe) // 统计用户市场总资产 marketTotalAssets = marketAvailable.Add(marketFreeze).Add(pLPriceSum).Add(marketSpotsTotalAssets) // 统计用户市场总浮动盈亏 marketFloatingPL = pLPriceSum orderModel := &UserMarketStatistics{ UserMarkerSubscribe: psgMsg.Symbol, UserMarketTotalAssets: marketTotalAssets.String(), UserMarketAvailable: marketAvailable.String(), UserMarketFreeze: marketFreeze.String(), UserMarketProfitAndLoss: marketProfitAndLoss.String(), UserMarketTotalFee: marketTotalFee.String(), UserMarketFloatingPL: marketFloatingPL.String(), } _, ok := u.symbol.Load(psgMsg.Symbol) if ok { orderStr, err := json.Marshal(orderModel) if err != nil { applogger.Error("User market Money stock subscription cache order error:%v", err) time.Sleep(5 * time.Second) continue } u.msg <- orderStr // 用户市场统计订阅 } else { applogger.Info("User market cancels subscription to Money stock orders.") return } } time.Sleep(800 * time.Millisecond) } }