gitee.com/quant1x/engine@v1.8.4/factors/feature_f10.go (about) 1 package factors 2 3 import ( 4 "context" 5 "gitee.com/quant1x/engine/cache" 6 "gitee.com/quant1x/engine/config" 7 "gitee.com/quant1x/engine/datasource/dfcf" 8 "gitee.com/quant1x/engine/datasource/tdxweb" 9 "gitee.com/quant1x/engine/market" 10 "gitee.com/quant1x/exchange" 11 "gitee.com/quant1x/gotdx/securities" 12 "gitee.com/quant1x/gox/api" 13 "gitee.com/quant1x/gox/logger" 14 "gitee.com/quant1x/num" 15 ) 16 17 const ( 18 cacheL5KeyF10 = "f10" 19 ) 20 21 // F10 证券基本面 22 type F10 struct { 23 cache.DataSummary `dataframe:"-"` 24 Date string `name:"日期" dataframe:"Date"` // 日期 25 Code string `name:"代码" dataframe:"Code"` // 证券代码 26 SecurityName string `name:"名称" dataframe:"Name"` // 证券名称 27 SubNew bool `name:"次新股" dataframe:"SubNew"` // 是否次新股 28 MarginTradingTarget bool `name:"两融" dataframe:"MarginTradingTarget"` // 是否两融标的 29 VolUnit int `name:"每手" dataframe:"VolUnit"` // 每手单位 30 DecimalPoint int `name:"小数点" dataframe:"DecimalPoint"` // 小数点 31 IpoDate string `name:"上市日期" dataframe:"IpoDate"` // 上市日期 32 UpdateDate string `name:"更新日期" dataframe:"UpdateDate"` // 更新日期 33 TotalCapital float64 `name:"总股本" dataframe:"TotalCapital"` // 总股本 34 Capital float64 `name:"流通股本" dataframe:"Capital"` // 流通股本 35 FreeCapital float64 `name:"自由流通股本" dataframe:"FreeCapital"` // 自由流通股本 36 Top10Capital float64 `name:"前十大流通股东总股本" dataframe:"Top10Capital"` // 前十大流通股东股本 37 Top10Change float64 `name:"前十大流通股东总股本变化" dataframe:"Top10Change"` //前十大流通股东股本变化 38 ChangeCapital float64 `name:"前十大流通股东持仓变化" dataframe:"ChangeCapital"` // 前十大流通股东持仓变化 39 IncreaseRatio float64 `name:"当期增持比例" dataframe:"IncreaseRatio"` // 当期增持比例 40 ReductionRatio float64 `name:"当期减持比例" dataframe:"ReductionRatio"` // 当期减持比例 41 QuarterlyYearQuarter string `name:"季报期" dataframe:"quarterly_year_quarter"` // 当前市场处于哪个季报期, 用于比较个股的季报数据是否存在拖延的情况 42 QDate string `name:"新报告期" dataframe:"qdate"` // 最新报告期 43 AnnualReportDate string `name:"年报披露日期" dataframe:"annual_report_date"` // 年报披露日期 44 QuarterlyReportDate string `name:"季报披露日期" dataframe:"quarterly_report_date"` // 最新季报披露日期 45 TotalOperateIncome float64 `name:"营业总收入" dataframe:"TotalOperateIncome"` // 当期营业总收入 46 BPS float64 `name:"每股净资产" dataframe:"BPS"` // 每股净资产 47 BasicEPS float64 `name:"每股收益" dataframe:"BasicEPS"` // 每股收益 48 DeductBasicEPS float64 `name:"每股收益(扣除)" dataframe:"DeductBasicEPS"` // 每股收益(扣除) 49 SafetyScore int `name:"安全分" dataframe:"SafetyScore"` // 通达信安全分 50 Increases int `name:"增持" dataframe:"Increases"` // 公告-增持 51 Reduces int `name:"减持" dataframe:"Reduces"` // 公告-减持 52 Risk int `name:"风险数" dataframe:"Risk"` // 公告-风险数 53 RiskKeywords string `name:"风险关键词" dataframe:"RiskKeywords"` // 公告-风险关键词 54 UpdateTime string `name:"更新时间" dataframe:"update_time"` // 更新时间 55 State uint64 `name:"样本状态" dataframe:"样本状态"` 56 } 57 58 func NewF10(date, code string) *F10 { 59 summary := __mapFeatures[FeatureF10] 60 v := F10{ 61 DataSummary: summary, 62 Date: date, 63 Code: code, 64 SecurityName: securities.GetStockName(code), 65 VolUnit: 100, 66 DecimalPoint: 2, 67 SubNew: market.IsSubNewStock(code), 68 } 69 securityInfo, ok := securities.CheckoutSecurityInfo(code) 70 if ok { 71 v.VolUnit = int(securityInfo.VolUnit) 72 v.DecimalPoint = int(securityInfo.DecimalPoint) 73 v.SecurityName = securityInfo.Name 74 } 75 // 检测是否两融标的 76 v.MarginTradingTarget = securities.IsMarginTradingTarget(code) 77 return &v 78 } 79 80 func (this *F10) GetDate() string { 81 return this.Date 82 } 83 84 func (this *F10) GetSecurityCode() string { 85 return this.Code 86 } 87 88 func (this *F10) Factory(date string, code string) Feature { 89 v := NewF10(date, code) 90 return v 91 } 92 93 func (this *F10) Init(ctx context.Context, date string) error { 94 loadQuarterlyReports(this.GetDate()) 95 _ = ctx 96 _ = date 97 return nil 98 } 99 100 func (this *F10) FromHistory(history History) Feature { 101 _ = history 102 return this 103 } 104 105 func (this *F10) Update(code, cacheDate, featureDate string, complete bool) { 106 securityCode := this.GetSecurityCode() 107 logger.Warnf("update f10, code=%s", securityCode) 108 109 // 1. 基本信息 110 securityInfo := checkoutSecurityBasicInfo(securityCode, featureDate) 111 _ = api.Copy(this, &securityInfo) 112 // 2. 前十大流通股股东 113 shareHolder := checkoutShareHolder(securityCode, featureDate) 114 _ = api.Copy(this, shareHolder) 115 if this.FreeCapital == 0 { 116 this.FreeCapital = this.Capital 117 } 118 // 3. 上市公司公告 119 notice := getOneNotice(securityCode, featureDate) 120 _ = api.Copy(this, ¬ice) 121 // 4. 季报 122 this.QuarterlyYearQuarter = getQuarterlyYearQuarter(featureDate) 123 report := getQuarterlyReportSummary(securityCode, featureDate) 124 _ = api.Copy(this, &report) 125 126 // 5. 安全分 127 safetyScore := tdxweb.GetSafetyScore(securityCode) 128 this.SafetyScore = safetyScore 129 130 // 6. 年报季报披露日期 131 annualReportDate, quarterlyReportDate := dfcf.NoticeDateForReport(securityCode, cacheDate) 132 this.AnnualReportDate = annualReportDate 133 this.QuarterlyReportDate = quarterlyReportDate 134 135 this.UpdateTime = GetTimestamp() 136 this.State |= this.Kind() 137 logger.Warnf("update f10, code=%s, OK", securityCode) 138 _ = complete 139 } 140 141 func (this *F10) Repair(code, cacheDate, featureDate string, complete bool) { 142 securityCode := code 143 144 // 1. 基本信息 145 securityInfo := checkoutSecurityBasicInfo(securityCode, featureDate) 146 _ = api.Copy(this, &securityInfo) 147 // 2. 前十大流通股股东 148 shareHolder := checkoutShareHolder(securityCode, featureDate) 149 _ = api.Copy(this, shareHolder) 150 if this.FreeCapital == 0 { 151 this.FreeCapital = this.Capital 152 } 153 // 3. 上市公司公告 154 notice := getOneNotice(securityCode, featureDate) 155 _ = api.Copy(this, ¬ice) 156 // 4. 季报 157 report := getQuarterlyReportSummary(securityCode, featureDate) 158 _ = api.Copy(this, &report) 159 160 // 5. 安全分 161 if this.SafetyScore == 0 { 162 safetyScore := tdxweb.GetSafetyScore(securityCode) 163 this.SafetyScore = safetyScore 164 } 165 166 // 6. 年报季报披露日期 167 annualReportDate, quarterlyReportDate := dfcf.NoticeDateForReport(securityCode, cacheDate) 168 this.AnnualReportDate = annualReportDate 169 this.QuarterlyReportDate = quarterlyReportDate 170 171 this.UpdateTime = GetTimestamp() 172 this.State |= this.Kind() 173 174 _ = complete 175 } 176 177 func (this *F10) Increase(snapshot QuoteSnapshot) Feature { 178 //TODO implement me 179 panic("implement me") 180 } 181 182 func (this *F10) ValidateSample() error { 183 if this.State > 0 { 184 return nil 185 } 186 return ErrInvalidFeatureSample 187 } 188 189 func (this *F10) TurnZ(v any) float64 { 190 freeCapital := this.FreeCapital 191 if freeCapital == 0 { 192 freeCapital = this.Capital 193 } 194 if freeCapital == 0 { 195 return 0.00 196 } 197 n := num.AnyToFloat64(v) 198 turnoverRateZ := num.ChangeRate(freeCapital, n) 199 turnoverRateZ *= 10000 200 turnoverRateZ = num.Decimal(turnoverRateZ) 201 return turnoverRateZ 202 } 203 204 // IsReportingRiskPeriod 是否财报披露前夕 205 func (this *F10) IsReportingRiskPeriod() bool { 206 if len(this.AnnualReportDate) == 0 || len(this.QuarterlyReportDate) == 0 { 207 // 如果年报和季报日期不确定, 判定为非风险期, 返回false 208 // 这种情况有可能是次新股的保护期 209 return false 210 } 211 f10Config := config.GetDataConfig().Feature.F10 212 date := this.GetDate() 213 ys := exchange.DateRange(date, this.AnnualReportDate) 214 ly := len(ys) 215 qs := exchange.DateRange(date, this.QuarterlyReportDate) 216 lq := len(qs) 217 if (ly > 0 && ly < f10Config.ReportingRiskPeriod) || (lq > 0 && lq < f10Config.ReportingRiskPeriod) { 218 return true 219 } 220 return false 221 }