gitee.com/quant1x/engine@v1.8.4/rules/rule.go (about)

     1  package rules
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"gitee.com/quant1x/engine/config"
     7  	"gitee.com/quant1x/engine/factors"
     8  	"gitee.com/quant1x/gox/api"
     9  	"gitee.com/quant1x/gox/runtime"
    10  	bitmap "github.com/bits-and-blooms/bitset"
    11  	"slices"
    12  	"sync"
    13  )
    14  
    15  // Kind 规则类型
    16  type Kind = uint
    17  
    18  const (
    19  	Pass Kind = 0
    20  )
    21  
    22  const (
    23  	engineBaseRule Kind = 1
    24  	KRuleF10            = engineBaseRule + 0 // 基础规则
    25  	KRuleBase           = engineBaseRule + 1 // 基础规则
    26  )
    27  
    28  // 规则错误码, 每一组规则错误拟1000个错误码
    29  const (
    30  	errorRuleF10  = (iota + 1) * 1000 // F10错误码
    31  	errorRuleBase                     // 基础规则错误码
    32  )
    33  
    34  // Rule 规则接口封装
    35  type Rule struct {
    36  	kind Kind
    37  	name string
    38  	Exec func(ruleParameter config.RuleParameter, snapshot factors.QuoteSnapshot) error
    39  }
    40  
    41  func (this Rule) Kind() Kind {
    42  	return this.kind
    43  }
    44  
    45  func (this Rule) Name() string {
    46  	return this.name
    47  }
    48  
    49  var (
    50  	mutex    sync.RWMutex
    51  	mapRules = map[Kind]Rule{}
    52  )
    53  
    54  var (
    55  	ErrAlreadyExists = errors.New("the rule already exists") // 规则已经存在
    56  )
    57  
    58  // RegisterFunc 注册规则回调函数
    59  func RegisterFunc(kind Kind, name string, cb func(ruleParameter config.RuleParameter, snapshot factors.QuoteSnapshot) error) error {
    60  	rule := Rule{kind: kind, name: name, Exec: cb}
    61  	mutex.Lock()
    62  	defer mutex.Unlock()
    63  	_, ok := mapRules[rule.Kind()]
    64  	if ok {
    65  		return ErrAlreadyExists
    66  	}
    67  	mapRules[rule.Kind()] = rule
    68  	return nil
    69  }
    70  
    71  // Filter 遍历所有规则
    72  func Filter(ruleParameter config.RuleParameter, snapshot factors.QuoteSnapshot) (passed []uint64, failed Kind, err error) {
    73  	mutex.RLock()
    74  	defer mutex.RUnlock()
    75  	if len(mapRules) == 0 {
    76  		return
    77  	}
    78  	var bitset bitmap.BitSet
    79  	// 规则按照kind排序
    80  	kinds := api.Keys(mapRules)
    81  	slices.Sort(kinds)
    82  	for _, kind := range kinds {
    83  		if rule, ok := mapRules[kind]; ok {
    84  			if slices.Contains(ruleParameter.IgnoreRuleGroup, int(rule.Kind())) {
    85  				continue
    86  			}
    87  			err = rule.Exec(ruleParameter, snapshot)
    88  			if err != nil {
    89  				failed = rule.Kind()
    90  				break
    91  			}
    92  			bitset.Set(rule.Kind())
    93  		}
    94  	}
    95  	return bitset.Bytes(), failed, err
    96  }
    97  
    98  // PrintRuleList 输出规则列表
    99  func PrintRuleList() {
   100  	fmt.Println("规则总数:", len(mapRules))
   101  	// 规则按照kind排序
   102  	kinds := api.Keys(mapRules)
   103  	slices.Sort(kinds)
   104  	for _, kind := range kinds {
   105  		if rule, ok := mapRules[kind]; ok {
   106  			fmt.Printf("kind: %d, name: %s, method: %s\n", rule.Kind(), rule.Name(), runtime.FuncName(rule.Exec))
   107  		}
   108  	}
   109  }