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 }