gitee.com/quant1x/engine@v1.8.4/services/task_sell_orders.go (about) 1 package services 2 3 import ( 4 "gitee.com/quant1x/engine/cache" 5 "gitee.com/quant1x/engine/config" 6 "gitee.com/quant1x/engine/models" 7 "gitee.com/quant1x/engine/storages" 8 "gitee.com/quant1x/engine/trader" 9 "gitee.com/quant1x/exchange" 10 "gitee.com/quant1x/gox/api" 11 "gitee.com/quant1x/gox/logger" 12 "slices" 13 "strings" 14 ) 15 16 // 获得T+HoldingPeriod的具体日期 17 func getEarlierDate(period int) string { 18 dates := exchange.LastNDate(exchange.LastTradeDate(), period) 19 earlier_date := exchange.FixTradeDate(dates[0], cache.CACHE_DATE) 20 return earlier_date 21 } 22 23 // 不包含最后一个交易日的持股日期列表 24 func getHoldingDates(period int) []string { 25 dates := exchange.LastNDate(exchange.LastTradeDate(), period) 26 for i := 0; i < len(dates); i++ { 27 dates[i] = exchange.FixTradeDate(dates[i], cache.CACHE_DATE) 28 } 29 return dates 30 } 31 32 // 获取所有挂接了指定的卖出策略ID的交易规则 33 func getStrategyParameterList(sellStrategyId uint64) []config.StrategyParameter { 34 traderConfig := config.TraderConfig() 35 var list []config.StrategyParameter 36 for _, v := range traderConfig.Strategies { 37 if v.Flag == models.OrderFlagSell || v.SellStrategy != sellStrategyId { 38 continue 39 } 40 list = append(list, v) 41 } 42 return list 43 } 44 45 // CheckoutCanSellStockList 捡出T+HoldingPeriod日的股票列表 46 func CheckoutCanSellStockList(sellStrategyId uint64, holdings []string) []string { 47 tradeRules := getStrategyParameterList(sellStrategyId) 48 if len(tradeRules) == 0 { 49 return nil 50 } 51 // 1. 到期 52 var listCanSell []string 53 for _, v := range tradeRules { 54 dates := getHoldingDates(v.HoldingPeriod) 55 // 1. 到期日 56 earlierDate := dates[0] 57 qmtStrategyName := v.QmtStrategyName() 58 codes := storages.FetchListForFirstPurchase(earlierDate, qmtStrategyName, trader.BUY) 59 logger.Infof("sell strategy[%d]: from %d, last-day codes=%s", sellStrategyId, v.Id, strings.Join(codes, ",")) 60 if len(codes) == 0 { 61 continue 62 } 63 // 筛选包含持股到期日的个股 64 codes = api.Filter(codes, func(s string) bool { 65 return slices.Contains(holdings, s) 66 }) 67 listCanSell = append(listCanSell, codes...) 68 } 69 listCanSell = api.Unique(listCanSell) 70 // 2. 未到期 71 var listNoSell []string 72 for _, v := range tradeRules { 73 dates := getHoldingDates(v.HoldingPeriod) 74 qmtStrategyName := v.QmtStrategyName() 75 // 2. 未到期 76 for _, orderDate := range dates[1:] { 77 codes := storages.FetchListForFirstPurchase(orderDate, qmtStrategyName, trader.BUY) 78 // 剔除包含持股到期日的个股 79 codes = api.Filter(codes, func(s string) bool { 80 return !slices.Contains(listCanSell, s) 81 }) 82 listNoSell = append(listNoSell, codes...) 83 } 84 } 85 listNoSell = api.Unique(listNoSell) 86 // 3. 矫正持仓过期未卖出的个股 87 for _, code := range holdings { 88 if slices.Contains(listCanSell, code) || slices.Contains(listNoSell, code) { 89 // 到期和未到期的忽略 90 continue 91 } 92 // 流程走这里, 一般是非机器自动交易或者前一个交易日自动没出未成交造成的 93 listCanSell = append(listCanSell, code) 94 } 95 return listCanSell 96 } 97 98 //// CheckoutUnsellableStockList 捡出不可卖的股票列表, T+HoldingPeriod日内的股票列表 99 //func CheckoutUnsellableStockList(sellStrategyId uint64) []string { 100 // return nil 101 //}