gitee.com/quant1x/engine@v1.8.4/config/config_strategy.go (about)

     1  package config
     2  
     3  import (
     4  	"gitee.com/quant1x/engine/market"
     5  	"gitee.com/quant1x/gotdx/securities"
     6  	"gitee.com/quant1x/gox/api"
     7  	"slices"
     8  	"strings"
     9  )
    10  
    11  // StrategyParameter 策略参数
    12  type StrategyParameter struct {
    13  	Id                          uint64         `name:"策略编码" yaml:"id" default:"1"`                                     // 策略ID, 默认是1
    14  	Auto                        bool           `name:"是否自动执行" yaml:"auto" default:"false"`                             // 是否自动执行
    15  	Name                        string         `name:"策略名称" yaml:"name"`                                               // 策略名称
    16  	Flag                        string         `name:"订单标识" yaml:"flag"`                                               // 订单标识,分早盘,尾盘和盘中
    17  	Session                     TradingSession `name:"时间范围" yaml:"time" default:"09:30:00~11:30:00,13:00:00~14:56:30"` // 可操作的交易时段
    18  	Weight                      float64        `name:"持仓占比" yaml:"weight" default:"0"`                                 // 策略权重, 默认0, 由系统自动分配
    19  	Total                       int            `name:"订单数上限" yaml:"total" default:"3"`                                 // 订单总数, 默认是3
    20  	PriceCageRatio              float64        `name:"价格笼子比例" yaml:"price_cage_ratio" default:"0.00"`                  // 价格笼子比例, 默认0%
    21  	MinimumPriceFluctuationUnit float64        `name:"价格变动最小单位" yaml:"minimum_price_fluctuation_unit" default:"0.05"`  // 价格最小变动单位, 默认0.05
    22  	FeeMax                      float64        `name:"最大费用" yaml:"fee_max" default:"20000.00"`                         // 可投入资金-最大
    23  	FeeMin                      float64        `name:"最小费用" yaml:"fee_min" default:"10000.00"`                         // 可投入资金-最小
    24  	Sectors                     []string       `name:"板块" yaml:"sectors" default:""`                                   // 板块, 策略适用的板块列表, 默认板块为空, 即全部个股
    25  	IgnoreMarginTrading         bool           `name:"剔除两融" yaml:"ignore_margin_trading" default:"true"`               // 剔除两融标的, 默认是剔除
    26  	HoldingPeriod               int            `name:"持仓周期" yaml:"holding_period" default:"1"`                         // 持仓周期, 默认为1天, 即T+1日触发117号策略
    27  	SellStrategy                uint64         `name:"卖出策略" yaml:"sell_strategy" default:"117"`                        // 卖出策略, 默认117
    28  	FixedYield                  float64        `name:"固定收益率" yaml:"fixed_yield" default:"0"`                           // 固定收益率, 只能和卖出策略绑定
    29  	TakeProfitRatio             float64        `name:"止盈比例" yaml:"take_profit_ratio" default:"15.00"`                  // 止盈比例, 默认15%
    30  	StopLossRatio               float64        `name:"止损比例" yaml:"stop_loss_ratio" default:"-2.00"`                    // 止损比例, 默认-2%
    31  	Rules                       RuleParameter  `name:"规则参数" yaml:"rules"`                                              // 过滤规则
    32  	excludeCodes                []string       `name:"过滤列表"`                                                           //  需要排除的个股
    33  }
    34  
    35  func (this *StrategyParameter) QmtStrategyName() string {
    36  	return QmtStrategyNameFromId(this.Id)
    37  }
    38  
    39  // Enable 策略是否有效
    40  func (this *StrategyParameter) Enable() bool {
    41  	return this.Auto && this.Id >= 0
    42  }
    43  
    44  // BuyEnable 获取可买入状态
    45  func (this *StrategyParameter) BuyEnable() bool {
    46  	return this.Enable() && this.Total > 0
    47  }
    48  
    49  // SellEnable 获取可卖出状态
    50  func (this *StrategyParameter) SellEnable() bool {
    51  	return this.Enable()
    52  }
    53  
    54  // IsCookieCutterForSell 是否一刀切卖出
    55  func (this *StrategyParameter) IsCookieCutterForSell() bool {
    56  	return this.SellEnable() && this.Total == 0
    57  }
    58  
    59  // NumberOfTargets 获得可买入标的总数
    60  func (this *StrategyParameter) NumberOfTargets() int {
    61  	if !this.BuyEnable() {
    62  		return 0
    63  	}
    64  	return this.Total
    65  }
    66  
    67  func (this *StrategyParameter) initExclude() {
    68  	if len(this.excludeCodes) > 0 {
    69  		return
    70  	}
    71  	var excludeCodes []string
    72  	for _, v := range this.Sectors {
    73  		sectorCode := strings.TrimSpace(v)
    74  		if strings.HasPrefix(sectorCode, sectorIgnorePrefix) {
    75  			sectorCode = strings.TrimSpace(sectorCode[sectorPrefixLength:])
    76  			blockInfo := securities.GetBlockInfo(sectorCode)
    77  			if blockInfo != nil {
    78  				excludeCodes = append(excludeCodes, blockInfo.ConstituentStocks...)
    79  			}
    80  		}
    81  	}
    82  	excludeCodes = api.Unique(excludeCodes)
    83  	this.excludeCodes = excludeCodes
    84  }
    85  
    86  func (this *StrategyParameter) Filter(codes []string) []string {
    87  	this.initExclude()
    88  	// 过滤需要忽略的板块成份股
    89  	newCodeList := api.Filter(codes, func(s string) bool {
    90  		return !slices.Contains(this.excludeCodes, s)
    91  	})
    92  	newCodeList = api.SliceUnique(newCodeList, func(a string, b string) int {
    93  		if a < b {
    94  			return -1
    95  		} else if a > b {
    96  			return 1
    97  		} else {
    98  			return 0
    99  		}
   100  	})
   101  
   102  	if this.IgnoreMarginTrading {
   103  		// 过滤两融
   104  		marginTradingList := securities.MarginTradingList()
   105  		newCodeList = api.Filter(newCodeList, func(s string) bool {
   106  			if slices.Contains(marginTradingList, s) {
   107  				return false
   108  			}
   109  			return true
   110  		})
   111  	}
   112  	return newCodeList
   113  }
   114  
   115  // StockList 取得可以交易的证券代码列表
   116  func (this *StrategyParameter) StockList() []string {
   117  	var codes []string
   118  	for _, v := range this.Sectors {
   119  		sectorCode := strings.TrimSpace(v)
   120  		if !strings.HasPrefix(sectorCode, sectorIgnorePrefix) {
   121  			blockInfo := securities.GetBlockInfo(sectorCode)
   122  			if blockInfo != nil {
   123  				codes = append(codes, blockInfo.ConstituentStocks...)
   124  
   125  			}
   126  		}
   127  	}
   128  	if len(codes) == 0 {
   129  		codes = market.GetStockCodeList()
   130  	}
   131  	codes = this.Filter(codes)
   132  	return codes
   133  }