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

     1  package rules
     2  
     3  import (
     4  	"gitee.com/quant1x/engine/config"
     5  	"gitee.com/quant1x/engine/factors"
     6  	"gitee.com/quant1x/engine/market"
     7  	"gitee.com/quant1x/gox/api"
     8  	"gitee.com/quant1x/gox/exception"
     9  	"gitee.com/quant1x/gox/logger"
    10  	"gitee.com/quant1x/num"
    11  )
    12  
    13  func init() {
    14  	err := RegisterFunc(KRuleF10, "基本面", ruleF10)
    15  	if err != nil {
    16  		logger.Fatalf("%+v", err)
    17  	}
    18  }
    19  
    20  var (
    21  	ErrF10IgnoreStock                 = exception.New(errorRuleF10+0, "忽略的个股")
    22  	ErrF10SubNewStock                 = exception.New(errorRuleF10+1, "次新股")
    23  	ErrF10DisableBeijingStockExchange = exception.New(errorRuleF10+2, "禁止北交所")
    24  	ErrF10DisableChiNextBoard         = exception.New(errorRuleF10+3, "禁止创业板")
    25  	ErrF10DisableSciTechBoard         = exception.New(errorRuleF10+4, "禁止科创板")
    26  	ErrF10PriceRange                  = exception.New(errorRuleF10+5, "股价控制")
    27  	ErrF10RangeOfCapital              = exception.New(errorRuleF10+6, "非流通盘范围")
    28  	ErrF10RangeOfSafetyCode           = exception.New(errorRuleF10+7, "非安全分范围")
    29  	ErrF10RangeOfBasicEPS             = exception.New(errorRuleF10+8, "非每股收益范围")
    30  	ErrF10RangeOfBPS                  = exception.New(errorRuleF10+9, "非净增长范围")
    31  	ErrF10RangeOfMarketCap            = exception.New(errorRuleF10+10, "非市值范围")
    32  	ErrF10RangeOfTotalOperateIncome   = exception.New(errorRuleF10+11, "非营业总收入")
    33  	ErrF10ReportingRiskPeriod         = exception.New(errorRuleF10+12, "财报披露前的风险期")
    34  )
    35  
    36  // RuleF10 基本面规则
    37  func ruleF10(ruleParameter config.RuleParameter, snapshot factors.QuoteSnapshot) error {
    38  	// 基础过滤规则, 检测F10基本面
    39  	securityCode := snapshot.SecurityCode
    40  	// 1. 去掉需要忽略的个股
    41  	if market.IsNeedIgnore(securityCode) {
    42  		return ErrF10IgnoreStock
    43  	}
    44  	// 2. 过滤指定的代码前缀
    45  	if api.StartsWith(securityCode, ruleParameter.IgnoreCodes) {
    46  		return ErrF10IgnoreStock
    47  	}
    48  	// 3. 去掉次新股
    49  	if market.IsSubNewStock(securityCode) {
    50  		return ErrF10SubNewStock
    51  	}
    52  	// 4. 股价控制
    53  	if num.IsNaN(snapshot.LastClose) || !ruleParameter.Price.Validate(snapshot.LastClose) {
    54  		return ErrF10PriceRange
    55  	}
    56  	// 5. F10数据
    57  	f10 := factors.GetL5F10(securityCode)
    58  	if f10 != nil {
    59  		// 5.1 流通股本控制
    60  		capital := f10.Capital / config.Billion
    61  		if f10.Capital != 0 && !ruleParameter.Capital.Validate(capital) {
    62  			return ErrF10RangeOfCapital
    63  		}
    64  		// 5.1.1 市值控制
    65  		marketValue := f10.TotalCapital * snapshot.LastClose / config.Billion
    66  		if !ruleParameter.MarketCap.Validate(marketValue) {
    67  			return ErrF10RangeOfMarketCap
    68  		}
    69  		// 5.2 安全分太低
    70  		if ruleParameter.CheckSafetyScore && f10.SafetyScore != 0 && !ruleParameter.SafetyScore.Validate(float64(f10.SafetyScore)) {
    71  			return ErrF10RangeOfSafetyCode
    72  		}
    73  		// 5.3 季报不理想
    74  		errF10RangeOfBasicEPS := ruleParameter.CheckEPS && f10.BasicEPS != 0 && f10.BasicEPS < 0
    75  		// 5.4 净增长小于0
    76  		errF10RangeOfBPS := ruleParameter.CheckBPS && f10.BPS != 0 && f10.BPS < 0
    77  		// 5.5 年报季报风险期
    78  		IsReportingRiskPeriod := f10.IsReportingRiskPeriod()
    79  		if IsReportingRiskPeriod {
    80  			return ErrF10ReportingRiskPeriod
    81  		} else if errF10RangeOfBPS {
    82  			return ErrF10RangeOfBPS
    83  		} else if errF10RangeOfBasicEPS {
    84  			return ErrF10RangeOfBasicEPS
    85  		}
    86  
    87  		//// 5.5 处理季报有增减持数据, 两个季度前十大流通股总数对比
    88  		//reportDate, _ := api.ParseTime(f10.UpdateDate)
    89  		//after := reportDate.AddDate(0, 2, 0).After(time.Now())
    90  		//// 两月内减持的剔掉, 或者减持统计超过1%
    91  		//if after && (f10.Top10Capital < 0 || f10.ReductionRatio < -1.00) {
    92  		//	return false
    93  		//}
    94  		//// 5.6. 处理上市公司公告
    95  		//if f10.Reduce > 0 || f10.Increase > 0 || f10.Risk > 0 {
    96  		//	return false
    97  		//}
    98  	}
    99  	// 规则通过
   100  	return nil
   101  }