You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

330 lines
9.3 KiB

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
}