go// 客户订单信息
type SubOrder struct {
Id int
OrderNumber string
IsReady bool
}
func (t *ConsolidateOrderWorker) Run(ctx context.Context) error {
var (
now = carbon.Now()
l = log.FromContext(ctx)
fundCalendarMap = make(map[string]*mktmapping.FundCalendar, 0)
)
var iter *utils.Iterator
// Step1: 取客户订单
fundType := t.commandArgs[0]
if fundType == constant.WorkerArgFundTypeMonetary {
iter = utils.NewIterator(dao.WealthOrder.IteratorGetCanConsolidateMonetaryOrders, 100) // 只查货币型基金
} else {
iter = utils.NewIterator(dao.WealthOrder.IteratorGetCanConsolidateNotMonetaryOrders, 100) // 只查非货币型基金
}
// Step2: 遍历客户订单, 在代码中计算合单
mapNOSubOrders := make(map[string][]*SubOrder)
mapNO := make(map[string]*nomineeOrderInfo)
for {
var (
fundCalendar *mktmapping.FundCalendar
isReady = true
)
pRecord, err := iter.Next()
if err != nil {
log.Errorf("iteration error:%v", err.Error())
continue
}
if pRecord == nil {
break
}
record := pRecord.(*model.TWealthOrder)
// 获取基金节假日
fundCalendar, findFundCalendar := fundCalendarMap[record.ProductSymbol]
if !findFundCalendar {
var (
startDate = now.ToDateStruct()
endDate = startDate.AddDays(mktwealthconstant.FundHolidaySpan)
)
fundCalendars, err := t.mktWealthClient.GetFundCalendar(ctx, &mktmapping.FundHolidayParams{
Symbols: []string{record.ProductSymbol}, StartDate: startDate.ToDateString(), EndDate: endDate.ToDateString(),
})
if err != nil {
l.Error("search get fund holidays failed", zap.Error(err))
isReady = false
}
fundCalendar_, find := lo.Find[*mktmapping.FundCalendar](fundCalendars, func(item *mktmapping.FundCalendar) bool {
return item.Symbol == record.ProductSymbol
})
if !find {
l.Error("search get fund holidays failed", zap.String("symbol", record.ProductSymbol))
isReady = false
} else {
fundCalendar = fundCalendar_
fundCalendarMap[record.ProductSymbol] = fundCalendar_
}
}
// 基金节假日判定
if fundCalendar != nil && fundCalendar.IsHoliday(now.ToDateStruct(), mktwealthconstant.HolidayTypeNone) {
log.Warn("order skiped beacause of the fund holiday", zap.String("symbol", record.ProductSymbol))
isReady = false
}
// 订单归属的合单类型 key
ot := record.ProductCode + "," + strconv.Itoa(record.Direction) + "," + strconv.Itoa(record.TradeMode)
// 添加订单到对应合单类型的集合中
no, ok := mapNO[ot]
if !ok {
no = new(nomineeOrderInfo)
no.Currency = record.Currency
no.Direction = record.Direction
no.ISIN = record.ISIN
no.Symbol = record.ProductSymbol
no.OrderType = record.Direction
no.ProductCode = record.ProductCode
no.ProductName = record.ProductName
no.ProductType = record.ProductType
no.TradeMode = record.TradeMode
no.FeeRate = record.FeeRate
no.stat.SourceType = record.SourceType // 第一个客户订单的订单类型
mapNO[ot] = no
noso := make([]*SubOrder, 0)
mapNOSubOrders[ot] = noso
}
// statistic
netAmountD, _ := decimal.NewFromString(record.ApplyNetAmount)
quantityD, _ := decimal.NewFromString(record.ApplyQuantity)
feeAmountD, _ := decimal.NewFromString(record.ApplyFeeAmount)
// 只要存在不一致就是混合下单
if record.SourceType != no.stat.SourceType {
no.stat.SourceType = orderconstant.OrderSourceTypeMix
}
if no.TradeMode == orderconstant.W_TRADE_MODE_AMOUNT {
no.stat.ApplyAmount = no.stat.ApplyAmount.Add(netAmountD)
no.stat.ApplyQuantity = no.stat.ApplyQuantity.Add(quantityD)
} else {
no.stat.ApplyQuantity = no.stat.ApplyQuantity.Add(quantityD)
}
no.stat.Fee = no.stat.Fee.Add(feeAmountD)
// 计算预计结算日
if fundCalendar != nil {
expectSettledDate, err := t.getExpectSettledDateV3(ctx, now.ToStdTime(), no.ProductCode, no.Symbol, no.Direction, fundCalendarMap)
if err != nil {
log.Errorf("t.getExpectSettledDate failed :%v", err.Error())
isReady = false
} else {
no.ExpectSettleDate = &expectSettledDate
}
}
// record sub-order
mapNOSubOrders[ot] = append(mapNOSubOrders[ot], &SubOrder{
Id: record.Id,
OrderNumber: record.OrderNumber,
IsReady: isReady,
})
}
go for k, v := range mapNO {
// 判断是否所有子订单都准备好
subOrders := mapNOSubOrders[k]
unreadySubOrders := lo.Filter[*SubOrder](subOrders, func(item *SubOrder, index int) bool {
return !item.IsReady
})
if len(unreadySubOrders) > 0 {
orderNumbers := lo.Map[*SubOrder, string](unreadySubOrders, func(item *SubOrder, index int) string {
return item.OrderNumber
})
l.Error("nomineeOrder skiped because of unready subOrder", zap.String("nomineeOrderInfo", k), zap.String("orderNumbers", strings.Join(orderNumbers, ",")))
continue
}
本文作者:JIeJaitt
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!