package socket import ( "context" "encoding/json" "github.com/shopspring/decimal" "matchmaking-system/internal/data" "matchmaking-system/internal/data/socket/forexData" "matchmaking-system/internal/data/tradedeal/forex" "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" "time" ) // orderSubForexSubscribe // // @Description: 用户外汇订单订阅 // @receiver u // @param psgMsg func (u *Client) orderSubForexSubscribe(psgMsg *SymbolMessage) { for { userId, err := GetUserIdByToken(u.token) if err != nil { time.Sleep(5 * time.Second) cleanSubscriptionKey(u) break } if userId != flags.AdministratorsId && psgMsg.Symbol == setting.ForexSubscribe { orderTokenKey := virtual.OrderIdListKey(setting.ForexSubscribe, 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 forex.ForexTallyCache if err = json.Unmarshal([]byte(value), &msg); err != nil { time.Sleep(5 * time.Second) continue } orderModel := forexData.ForexOrderProcessing(setting.ForexSubscribe, msg) if orderModel != nil { _, ok := u.symbol.Load(psgMsg.Symbol) 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("ForexSubscribe.HDel:%v", err) continue } } orderStr, err := json.Marshal(orderModel) if err != nil { applogger.Error("orderSubForexSubscribe.Marshal:%v", err) time.Sleep(5 * time.Second) continue } u.msg <- orderStr // 用户外汇(挂单|持仓)订阅 } else { applogger.Info("User cancels Forex order subscription.") return } } } } time.Sleep(600 * time.Millisecond) } } func (u *Client) orderSubShareForexMarketSubscribe(psgMsg *SymbolMessage) { var n int var MarketForexCache 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.ShareForexMarketSubscribe { var marketTotalAssets decimal.Decimal // 用户市场总资产 var marketAvailable decimal.Decimal // 用户市场可用 var marketFreeze decimal.Decimal // 用户市场冻结 var marketFloatingPL decimal.Decimal // 用户市场总浮动盈亏 // 统计用户市场可用余额和冻结余额 var botUserForex []models.BotUserForex err = data.Msql.Table(flags.BotUserForex).Where("user_id = ?", userId).Where("contract_id = ?", flags.ForexUnit).Find(&botUserForex) if err != nil { marketAvailable = decimal.Zero marketFreeze = decimal.Zero } for _, value := range botUserForex { marketAvailable = decimal.RequireFromString(value.UsableNum) marketFreeze = decimal.RequireFromString(value.FrozenNum) } // 判定是否存在订单 if marketAvailable.IsZero() || marketFreeze.IsZero() { if n == 0 { tradeCount, _ := data.Msql.Table(flags.BotForexTrade).Where("user_id = ?", userId).In("status", 1, 3).Count() if tradeCount > 0 { n = 1 } } } if marketAvailable.Cmp(MarketForexCache) != 0 || n == 1 { // 统计用户市场累计盈亏 var botForexTrade []models.BotForexTrade err = data.Msql.Table(flags.BotForexTrade).Where("user_id = ?", userId).Where("status = 3").Find(&botForexTrade) if err != nil { marketProfitAndLoss = decimal.Zero } for key, value := range botForexTrade { 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 botForexTradeFee models.BotForexTrade totalFee, err := data.Msql.Table(flags.BotForexTrade).Where("user_id = ?", userId).In("status", 1, 3).Sums(botForexTradeFee, "service_cost", "closing_cost") if err != nil || len(totalFee) != 2 { marketTotalFee = decimal.Zero } marketTotalFee = decimal.NewFromFloat(totalFee[0]).Add(decimal.NewFromFloat(totalFee[1])) MarketForexCache = marketAvailable n = 2 } // 用户市场总浮动盈亏 pLPriceSum := GetForexByPriceSum(userId, setting.AdminForexSubscribe) // 统计用户市场总资产 marketTotalAssets = marketAvailable.Add(marketFreeze).Add(pLPriceSum) // 统计用户市场总浮动盈亏 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 Forex stock subscription cache order error:%v", err) time.Sleep(5 * time.Second) continue } u.msg <- orderStr // 用户市场统计订阅 } else { applogger.Info("User market cancels subscription to Forex stock orders.") return } } time.Sleep(800 * time.Millisecond) } }