package share import ( "context" "encoding/json" "github.com/redis/go-redis/v9" "github.com/shopspring/decimal" "matchmaking-system/internal/biz/structure" "matchmaking-system/internal/data/memory" "matchmaking-system/internal/pkg/flags" "matchmaking-system/internal/pkg/logging/applogger" "matchmaking-system/internal/pkg/logging/common" "matchmaking-system/internal/pkg/setting" "matchmaking-system/internal/pkg/utils" "time" ) /* 处理港股下单交易(订单状态:0-挂单(委托),1-持仓订单,2-已撤单,3-完成订单) 1>写入挂单缓存列表 2>监控挂单缓存列表 3>监控持仓缓存列表 4>处理完成订单 5>清理缓存列表 */ // ShareHkdTallyCache // @Description: type ShareHkdTallyCache struct { UserId int64 // 用户ID OrderId string // 订单ID Symbol string // 交易对 Status string // 订单状态 OpenPrice string // 开仓价格 ClosingPrice string // 平仓价格 ClosingTime time.Time // 平仓时间 Order structure.ShareOrder // 下单信息 } // ShareHkdCacheDeal // // @Description: // @param ctx // @param userId // @param orderId // @param subKey // @param order // @param chg // @param priceNew // @param closingTime // @return string // @return *ShareHkdTallyCache // @return error func ShareHkdCacheDeal(ctx context.Context, userId int64, orderId, subKey string, order structure.ShareOrder, chg, priceNew string, closingTime, blockTime time.Time) (string, *ShareHkdTallyCache, error) { var marketStatus string tallyCache := ShareHkdTallyCache{ UserId: userId, // 股票下单用户Id OrderId: orderId, // 股票下单订单Id Symbol: order.StockId, // 股票下单交易对 Status: flags.Entrust, // 股票下单挂单状态 Order: order, // 股票完整下单信息 } // TODO: 交易下单判定(是否市价交易) //switch order.DealType { //case flags.DealTypeLimited: // 限价(买涨|买跌) // marketStatus = flags.MarketShareHkdEntrust //case flags.DealTypeMarket: // 市价(买涨|买跌) // if len(priceNew) == 0 { // marketStatus = flags.MarketShareHkdEntrust // } else { // marketStatus, tallyCache = GetOrderHkdByChg(priceNew, tallyCache, chg) // } //} // 交易判定 if order.Type <= 0 { marketStatus = setting.MarketShareHkdEntrust tallyCache.ClosingTime = closingTime } else { marketStatus = setting.MarketShareBlkEntrust tallyCache.OpenPrice = priceNew tallyCache.ClosingTime = blockTime } return marketStatus, &tallyCache, nil } // GetOrderHkdByChg // // @Description: 处理涨跌幅 // @param priceNew // @param tallyCache // @param chg // @return string // @return ShareHkdTallyCache func GetOrderHkdByChg(priceNew string, tallyCache ShareHkdTallyCache, chg string) (string, ShareHkdTallyCache) { var marketStatus string switch chg { case flags.UpLimit: // 涨停 switch tallyCache.Order.TradeType { case flags.TradeTypeBuy: // 买涨:涨停-下单不到持仓,可以平仓 if !flags.CheckSetting { applogger.Debug("下单股票买涨涨停,只能挂单......") } marketStatus = setting.MarketShareHkdEntrust case flags.TradeTypeSell: // 买跌:涨停-下单到持仓,不能平仓 marketStatus, tallyCache = GetOrderHkdMarketPrice(priceNew, tallyCache) default: marketStatus = setting.MarketShareHkdEntrust } case flags.DownLimit: // 跌停 switch tallyCache.Order.TradeType { case flags.TradeTypeBuy: // 买涨:跌停-下单到持仓,不能平仓 marketStatus, tallyCache = GetOrderHkdMarketPrice(priceNew, tallyCache) case flags.TradeTypeSell: // 买跌:跌停-下单不到持仓,可以平仓 if !flags.CheckSetting { applogger.Debug("下单股票买跌跌停,只能挂单......") } marketStatus = setting.MarketShareHkdEntrust default: marketStatus = setting.MarketShareHkdEntrust } default: marketStatus, tallyCache = GetOrderHkdMarketPrice(priceNew, tallyCache) } return marketStatus, tallyCache } // CheckOrderHkdByChg // // @Description: 股票判定涨跌幅业务逻辑 // @param orderMarket // @param tallyCache // @param chg // @return bool func CheckOrderHkdByChg(orderMarket string, tallyCache ShareHkdTallyCache, chg string) bool { var checkBool bool switch chg { case flags.UpLimit: // 涨停 switch tallyCache.Order.TradeType { case flags.TradeTypeBuy: // 买涨:涨停-下单不到持仓,持仓可以平仓 checkBool = CheckOrderHkdBuyMarket(orderMarket) case flags.TradeTypeSell: // 买跌:涨停-下单到持仓,持仓不能平仓 checkBool = CheckOrderHkdSellMarket(orderMarket) } case flags.DownLimit: // 跌停 switch tallyCache.Order.TradeType { case flags.TradeTypeBuy: // 买涨:跌停-下单到持仓,持仓不能平仓 checkBool = CheckOrderHkdSellMarket(orderMarket) case flags.TradeTypeSell: // 买跌:跌停-下单不到持仓,持仓可以平仓 checkBool = CheckOrderHkdBuyMarket(orderMarket) } default: checkBool = false } return checkBool } // CheckOrderHkdBuyMarket // // @Description: 买涨-涨跌幅 // @param orderMarket // @return bool func CheckOrderHkdBuyMarket(orderMarket string) bool { var checkBool bool switch orderMarket { case setting.MarketShareHkdEntrust: // 挂单缓存状态--不到持仓 checkBool = true case setting.MarketShareHkdPosition: // 持仓缓存状态--可以平仓 checkBool = false } return checkBool } // CheckOrderHkdSellMarket // // @Description: 买跌-涨跌幅 // @param orderMarket // @return bool func CheckOrderHkdSellMarket(orderMarket string) bool { var checkBool bool switch orderMarket { case setting.MarketShareHkdEntrust: // 挂单缓存状态-- 到持仓 checkBool = false case setting.MarketShareHkdPosition: // 持仓缓存状态-- 不能平仓 checkBool = true } return checkBool } // GetOrderHkdMarketPrice // // @Description: 市价下单开仓信息 // @param priceNew // @param tallyCache // @return string // @return ShareHkdTallyCache func GetOrderHkdMarketPrice(priceNew string, tallyCache ShareHkdTallyCache) (string, ShareHkdTallyCache) { var marketStatus string priceS := decimal.RequireFromString(priceNew) // 最新市价 var openPrice decimal.Decimal difference := priceS.Mul(utils.Difference()) // 设置价差 switch tallyCache.Order.TradeType { case flags.TradeTypeBuy: // 买入 openPrice = priceS.Add(difference) // 开盘价格 case flags.TradeTypeSell: // 卖出 openPrice = priceS.Sub(difference) // 开盘价格 } tallyCache.OpenPrice = openPrice.String() // 股票市价下单开盘价格(price) tallyCache.Status = flags.Position // 股票市价下单持仓状态(status) marketStatus = setting.MarketShareHkdPosition // 股票下单状态(挂单|持仓)缓存列表 return marketStatus, tallyCache } // ShareHkdSubMarketPrice // // @Description: 下单订阅行情数据 // @param subKey // @return string // @return error func ShareHkdSubMarketPrice(subKey string) (string, error) { price, err := memory.GetShareHkdCache(subKey) if err != nil { return flags.SetNull, err } return string(price), nil } // ShareHkdHashUserOrder // // @Description: 下单录入订阅缓存列表(用户订阅|管理员订阅|挂单|持仓) // @param red // @param cacheKey // @param order // @return error func ShareHkdHashUserOrder(red *redis.Client, cacheKey string, order *ShareHkdTallyCache) error { orderStr, err := json.Marshal(order) if err != nil { applogger.Error("%v ShareHkdHashUserOrder.Marshal:%v", common.ErrShareHkd, err) return err } if err = red.HSet(context.Background(), cacheKey, order.OrderId, string(orderStr)).Err(); err != nil { applogger.Error("%v ShareHkdHashUserOrder.HSet:%v", common.ErrShareHkd, err) return err } return nil } // UpdateShareHkdHashByOrderId // // @Description: 更新缓存列表 // @param reds // @param orderId // @param updateKey // @param status // @return error func UpdateShareHkdHashByOrderId(reds *redis.Client, orderId, updateKey, status string) error { order, err := reds.HGet(context.Background(), updateKey, orderId).Result() if err != nil { return err } var orderModel ShareHkdTallyCache if err = json.Unmarshal([]byte(order), &orderModel); err != nil { return err } orderModel.Status = status orderStr, err := json.Marshal(&orderModel) if err != nil { return err } err = reds.HSet(context.Background(), updateKey, orderId, string(orderStr)).Err() if err != nil { return err } return nil } // UpdateShareHkdStopByOrderId // // @Description: 更新止盈止損設置 // @param reds // @param order // @param updateKey // @param status // @return error func UpdateShareHkdStopByOrderId(reds *redis.Client, order structure.StopOrder, updateKey, status string) error { orderHash, err := reds.HGet(context.Background(), updateKey, order.OrderId).Result() if err != nil { return err } var orderModel ShareHkdTallyCache if err = json.Unmarshal([]byte(orderHash), &orderModel); err != nil { return err } orderModel.Status = status orderModel.Order.StopType = order.StopType orderModel.Order.StopLossPrice = order.StopLossPrice orderModel.Order.StopWinPrice = order.StopWinPrice orderStr, err := json.Marshal(&orderModel) if err != nil { return err } err = reds.HSet(context.Background(), updateKey, order.OrderId, string(orderStr)).Err() if err != nil { return err } return nil }