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  //}