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.
331 lines
9.3 KiB
331 lines
9.3 KiB
2 months ago
|
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>清理缓存列表
|
||
|
*/
|
||
|
|
||
|
// ShareEurTallyCache
|
||
|
// @Description:
|
||
|
type ShareFurTallyCache struct {
|
||
|
UserId int64 // 用户ID
|
||
|
OrderId string // 订单ID
|
||
|
Symbol string // 交易对
|
||
|
Status string // 订单状态
|
||
|
OpenPrice string // 开仓价格
|
||
|
ClosingPrice string // 平仓价格
|
||
|
ClosingTime time.Time // 平仓时间
|
||
|
Order structure.ShareOrder // 下单信息
|
||
|
}
|
||
|
|
||
|
// ShareFurCacheDeal
|
||
|
//
|
||
|
// @Description:
|
||
|
// @param ctx
|
||
|
// @param userId
|
||
|
// @param orderId
|
||
|
// @param subKey
|
||
|
// @param order
|
||
|
// @param chg
|
||
|
// @param priceNew
|
||
|
// @param closingTime
|
||
|
// @return string
|
||
|
// @return *ShareEurTallyCache
|
||
|
// @return error
|
||
|
func ShareFurCacheDeal(ctx context.Context, userId int64,
|
||
|
orderId, subKey string, order structure.ShareOrder,
|
||
|
chg, priceNew string, closingTime, blockTime time.Time) (string, *ShareFurTallyCache, error) {
|
||
|
var marketStatus string
|
||
|
tallyCache := ShareFurTallyCache{
|
||
|
UserId: userId, // 股票下单用户Id
|
||
|
OrderId: orderId, // 股票下单订单Id
|
||
|
Symbol: order.StockId, // 股票下单交易对
|
||
|
Status: flags.Entrust, // 股票下单挂单状态
|
||
|
Order: order, // 股票完整下单信息
|
||
|
}
|
||
|
|
||
|
// TODO: 交易下单判定(是否市价交易)
|
||
|
//switch order.DealType {
|
||
|
//case flags.DealTypeLimited: // 限价(买涨|买跌)
|
||
|
// marketStatus = flags.MarketShareFurEntrust
|
||
|
//case flags.DealTypeMarket: // 市价(买涨|买跌)
|
||
|
// if len(priceNew) == 0 {
|
||
|
// marketStatus = flags.MarketShareFurEntrust
|
||
|
// } else {
|
||
|
// marketStatus, tallyCache = GetOrderFurByChg(priceNew, tallyCache, chg)
|
||
|
// }
|
||
|
//}
|
||
|
|
||
|
// 交易判定
|
||
|
if order.Type <= 0 {
|
||
|
marketStatus = setting.MarketShareFurEntrust
|
||
|
tallyCache.ClosingTime = closingTime // 平仓时间
|
||
|
} else {
|
||
|
marketStatus = setting.MarketShareBlkEntrust
|
||
|
tallyCache.OpenPrice = priceNew // 开仓价格
|
||
|
tallyCache.ClosingTime = blockTime // 平仓时间
|
||
|
}
|
||
|
|
||
|
return marketStatus, &tallyCache, nil
|
||
|
}
|
||
|
|
||
|
// GetOrderFurByChg
|
||
|
//
|
||
|
// @Description: 处理涨跌幅
|
||
|
// @param priceNew
|
||
|
// @param tallyCache
|
||
|
// @param chg
|
||
|
// @return string
|
||
|
// @return ShareFurTallyCache
|
||
|
func GetOrderFurByChg(priceNew string, tallyCache ShareFurTallyCache, chg string) (string, ShareFurTallyCache) {
|
||
|
var marketStatus string
|
||
|
switch chg {
|
||
|
case flags.UpLimit: // 涨停
|
||
|
switch tallyCache.Order.TradeType {
|
||
|
case flags.TradeTypeBuy: // 买涨:涨停-下单不到持仓,可以平仓
|
||
|
if !flags.CheckSetting {
|
||
|
applogger.Debug("下单股票买涨涨停,只能挂单......")
|
||
|
}
|
||
|
|
||
|
marketStatus = setting.MarketShareFurEntrust
|
||
|
case flags.TradeTypeSell: // 买跌:涨停-下单到持仓,不能平仓
|
||
|
marketStatus, tallyCache = GetOrderFurMarketPrice(priceNew, tallyCache)
|
||
|
default:
|
||
|
marketStatus = setting.MarketShareFurEntrust
|
||
|
}
|
||
|
case flags.DownLimit: // 跌停
|
||
|
switch tallyCache.Order.TradeType {
|
||
|
case flags.TradeTypeBuy: // 买涨:跌停-下单到持仓,不能平仓
|
||
|
marketStatus, tallyCache = GetOrderFurMarketPrice(priceNew, tallyCache)
|
||
|
case flags.TradeTypeSell: // 买跌:跌停-下单不到持仓,可以平仓
|
||
|
if !flags.CheckSetting {
|
||
|
applogger.Debug("下单股票买跌跌停,只能挂单......")
|
||
|
}
|
||
|
|
||
|
marketStatus = setting.MarketShareFurEntrust
|
||
|
default:
|
||
|
marketStatus = setting.MarketShareFurEntrust
|
||
|
}
|
||
|
default:
|
||
|
marketStatus, tallyCache = GetOrderFurMarketPrice(priceNew, tallyCache)
|
||
|
}
|
||
|
|
||
|
return marketStatus, tallyCache
|
||
|
}
|
||
|
|
||
|
// CheckOrderFurByChg
|
||
|
//
|
||
|
// @Description: 股票判定涨跌幅业务逻辑
|
||
|
// @param orderMarket
|
||
|
// @param tallyCache
|
||
|
// @param chg
|
||
|
// @return bool
|
||
|
func CheckOrderFurByChg(orderMarket string, tallyCache ShareFurTallyCache, chg string) bool {
|
||
|
var checkBool bool
|
||
|
switch chg {
|
||
|
case flags.UpLimit: // 涨停
|
||
|
switch tallyCache.Order.TradeType {
|
||
|
case flags.TradeTypeBuy: // 买涨:涨停-下单不到持仓,持仓可以平仓
|
||
|
checkBool = CheckOrderFurBuyMarket(orderMarket)
|
||
|
case flags.TradeTypeSell: // 买跌:涨停-下单到持仓,持仓不能平仓
|
||
|
checkBool = CheckOrderFurSellMarket(orderMarket)
|
||
|
}
|
||
|
case flags.DownLimit: // 跌停
|
||
|
switch tallyCache.Order.TradeType {
|
||
|
case flags.TradeTypeBuy: // 买涨:跌停-下单到持仓,持仓不能平仓
|
||
|
checkBool = CheckOrderFurSellMarket(orderMarket)
|
||
|
case flags.TradeTypeSell: // 买跌:跌停-下单不到持仓,持仓可以平仓
|
||
|
checkBool = CheckOrderFurBuyMarket(orderMarket)
|
||
|
}
|
||
|
default:
|
||
|
checkBool = false
|
||
|
}
|
||
|
|
||
|
return checkBool
|
||
|
}
|
||
|
|
||
|
// CheckOrderFurBuyMarket
|
||
|
//
|
||
|
// @Description: 买涨-涨跌幅
|
||
|
// @param orderMarket
|
||
|
// @return bool
|
||
|
func CheckOrderFurBuyMarket(orderMarket string) bool {
|
||
|
var checkBool bool
|
||
|
switch orderMarket {
|
||
|
case setting.MarketShareFurEntrust: // 挂单缓存状态--不到持仓
|
||
|
checkBool = true
|
||
|
case setting.MarketShareFurPosition: // 持仓缓存状态--可以平仓
|
||
|
checkBool = false
|
||
|
}
|
||
|
|
||
|
return checkBool
|
||
|
}
|
||
|
|
||
|
// CheckOrderFurSellMarket
|
||
|
//
|
||
|
// @Description: 买跌-涨跌幅
|
||
|
// @param orderMarket
|
||
|
// @return bool
|
||
|
func CheckOrderFurSellMarket(orderMarket string) bool {
|
||
|
var checkBool bool
|
||
|
switch orderMarket {
|
||
|
case setting.MarketShareFurEntrust: // 挂单缓存状态-- 到持仓
|
||
|
checkBool = false
|
||
|
case setting.MarketShareFurPosition: // 持仓缓存状态-- 不能平仓
|
||
|
checkBool = true
|
||
|
}
|
||
|
|
||
|
return checkBool
|
||
|
}
|
||
|
|
||
|
// GetOrderFurMarketPrice
|
||
|
//
|
||
|
// @Description: 获取市价下单开仓信息
|
||
|
// @param priceNew
|
||
|
// @param tallyCache
|
||
|
// @return string
|
||
|
// @return ShareFurTallyCache
|
||
|
func GetOrderFurMarketPrice(priceNew string, tallyCache ShareFurTallyCache) (string, ShareFurTallyCache) {
|
||
|
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.MarketShareFurPosition // 股票下单状态(挂单|持仓)缓存列表
|
||
|
|
||
|
return marketStatus, tallyCache
|
||
|
}
|
||
|
|
||
|
// ShareFurSubMarketPrice
|
||
|
//
|
||
|
// @Description: 获取下单订阅行情数据
|
||
|
// @param subKey
|
||
|
// @return string
|
||
|
// @return error
|
||
|
func ShareFurSubMarketPrice(subKey string) (string, error) {
|
||
|
price, err := memory.GetShareFurCache(subKey)
|
||
|
if err != nil {
|
||
|
return flags.SetNull, err
|
||
|
}
|
||
|
|
||
|
return string(price), nil
|
||
|
}
|
||
|
|
||
|
// ShareFurHashUserOrder
|
||
|
//
|
||
|
// @Description: 下单录入订阅缓存列表(用户订阅|管理员订阅|挂单|持仓)
|
||
|
// @param red
|
||
|
// @param cacheKey
|
||
|
// @param order
|
||
|
// @return error
|
||
|
func ShareFurHashUserOrder(red *redis.Client, cacheKey string, order *ShareFurTallyCache) error {
|
||
|
orderStr, err := json.Marshal(order)
|
||
|
if err != nil {
|
||
|
applogger.Error("%v ShareFurHashUserOrder.Marshal:%v", common.ErrShareFur, err)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if err = red.HSet(context.Background(), cacheKey, order.OrderId, string(orderStr)).Err(); err != nil {
|
||
|
applogger.Error("%v ShareFurHashUserOrder.HSet:%v", common.ErrShareFur, err)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// UpdateShareFurHashByOrderId
|
||
|
//
|
||
|
// @Description: 更新缓存列表
|
||
|
// @param reds
|
||
|
// @param orderId
|
||
|
// @param updateKey
|
||
|
// @param status
|
||
|
// @return error
|
||
|
func UpdateShareFurHashByOrderId(reds *redis.Client, orderId, updateKey, status string) error {
|
||
|
order, err := reds.HGet(context.Background(), updateKey, orderId).Result()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
var orderModel ShareFurTallyCache
|
||
|
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
|
||
|
}
|
||
|
|
||
|
// UpdateShareFurStopByOrderId
|
||
|
//
|
||
|
// @Description: 設置止盈止損
|
||
|
// @param reds
|
||
|
// @param order
|
||
|
// @param updateKey
|
||
|
// @param status
|
||
|
// @return error
|
||
|
func UpdateShareFurStopByOrderId(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 ShareFurTallyCache
|
||
|
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
|
||
|
}
|