gitee.com/quant1x/engine@v1.8.4/datasource/dfcf/finance.go (about)

     1  package dfcf
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"gitee.com/quant1x/exchange"
     7  	"gitee.com/quant1x/gox/http"
     8  	urlpkg "net/url"
     9  	"strings"
    10  )
    11  
    12  const (
    13  	urlFinanceReports               = "https://datacenter-web.eastmoney.com/api/data/v1/get"
    14  	EastmoneyFinanceReportsPageSize = 100
    15  )
    16  
    17  // PreviewQuarterlyReport 业绩预报详情
    18  type PreviewQuarterlyReport struct {
    19  	SecurityCode        string  `name:"证券代码" json:"SECURITY_CODE"`
    20  	SecurityName        string  `name:"证券名称" json:"SECURITY_NAME"`
    21  	OrgCode             string  `name:"机构代码" json:"ORG_CODE"`
    22  	NoticeDate          string  `name:"公告日期" json:"NOTICE_DATE"`
    23  	ReportDate          string  `name:"报告日期" json:"REPORT_DATE"`
    24  	PredictFinanceCode  string  `name:"预告代码" json:"PREDICT_FINANCE_CODE"`
    25  	PredictFinance      string  `name:"预告财报" json:"PREDICT_FINANCE"`
    26  	PredictAmtLower     float64 `name:"预计营收下限" json:"PREDICT_AMT_LOWER"`
    27  	PredictAmtUpper     float64 `name:"预计营收上限" json:"PREDICT_AMT_UPPER"`
    28  	AddAmpLower         float64 `name:"增长下限" json:"ADD_AMP_LOWER"`
    29  	AddAmpUpper         float64 `name:"增长下限" json:"ADD_AMP_UPPER"`
    30  	PredictContent      string  `name:"预告内容" json:"PREDICT_CONTENT"`
    31  	ChangeReasonExplain string  `name:"改变原因" json:"CHANGE_REASON_EXPLAIN"`
    32  	PredictType         string  `name:"预计类型" json:"PREDICT_TYPE"`
    33  	PreyearSamePeriod   float64 `name:"上年同期" json:"PREYEAR_SAME_PERIOD"`
    34  	TradeMarket         string  `name:"所在交易所" json:"TRADE_MARKET"`
    35  	TradeMarketCode     string  `name:"场内交易代码" json:"TRADE_MARKET_CODE"`
    36  	SecurityType        string  `name:"证券类型" json:"SECURITY_TYPE"`
    37  	SecurityTypeCode    string  `name:"证券类型代码" json:"SECURITY_TYPE_CODE"`
    38  	IncreaseJz          float64 `name:"增长均值" json:"INCREASE_JZ"`
    39  	ForecastJz          float64 `name:"预测均值" json:"FORECAST_JZ"`
    40  	ForecastState       string  `name:"预测状态" json:"FORECAST_STATE"`
    41  	IsLatest            string  `name:"是否最新财报" json:"IS_LATEST"`
    42  	PredictRatioLower   float64 `name:"预测增速下限" json:"PREDICT_RATIO_LOWER"`
    43  	PredictRatioUpper   float64 `name:"预测增速上限" json:"PREDICT_RATIO_UPPER"`
    44  	PredictHbmean       float64 `name:"预计每股盈利?" json:"PREDICT_HBMEAN"`
    45  }
    46  
    47  func (f PreviewQuarterlyReport) GetDate() string {
    48  	return f.NoticeDate
    49  }
    50  
    51  func (f PreviewQuarterlyReport) GetSecurityCode() string {
    52  	return f.SecurityCode
    53  }
    54  
    55  // FinanceReports 获取哪天开始的财报数据
    56  // https://data.eastmoney.com/bbsj/202303/yjyg.html?type=increase
    57  // https://data.eastmoney.com/bbsj/202303/yjbb.html
    58  func FinanceReports(date string, pageNumber ...int) (reports []PreviewQuarterlyReport, pages, originalRecords int, err error) {
    59  	pageNo := 1
    60  	pageSize := EastmoneyFinanceReportsPageSize
    61  	if len(pageNumber) > 0 {
    62  		pageNo = pageNumber[0]
    63  	}
    64  	beginDate := exchange.FixTradeDate(date)
    65  	params := urlpkg.Values{
    66  		"page_size":   {fmt.Sprintf("%d", pageSize)},
    67  		"page_index":  {fmt.Sprintf("%d", pageNo)},
    68  		"sortColumns": {"NOTICE_DATE", "SECURITY_CODE"},
    69  		"sortTypes":   {"-1", "-1"},
    70  		"reportName":  {"RPT_PUBLIC_OP_NEWPREDICT"},
    71  		"columns":     {"ALL"},
    72  		"filter":      {fmt.Sprintf("(REPORT_DATE>='%s')", beginDate)},
    73  		//"callback": {"jQuery1123017378221241641723_1683879528446"},
    74  	}
    75  	url := urlFinanceReports + "?" + params.Encode()
    76  	data, err := http.Get(url)
    77  	if err != nil {
    78  		return
    79  	}
    80  	//fmt.Println(api.Bytes2String(data))
    81  	var raw rawFinanceReport
    82  	err = json.Unmarshal(data, &raw)
    83  	if err != nil {
    84  		return
    85  	}
    86  	if !raw.Success || raw.Code != 0 || len(raw.Result.Data) == 0 {
    87  		err = ErrNoticeNotFound
    88  		return
    89  	}
    90  	//pages = functions.GetPages(pageSize, raw.Result.Count)
    91  	pages = raw.Result.Pages
    92  	originalRecords = len(raw.Result.Data)
    93  	for _, v := range raw.Result.Data {
    94  		securityName := strings.TrimSpace(v.SECURITY_NAME_ABBR)
    95  		if len(v.SECUCODE) == 0 || len(securityName) == 0 {
    96  			continue
    97  		}
    98  		code := strings.TrimSpace(v.SECUCODE)
    99  		_, mflag, msymbol := exchange.DetectMarket(code)
   100  		securityCode := mflag + msymbol
   101  
   102  		report := PreviewQuarterlyReport{
   103  			SecurityCode: securityCode,
   104  			SecurityName: securityName,
   105  			ReportDate:   v.REPORT_DATE,
   106  			NoticeDate:   v.NOTICE_DATE,
   107  			OrgCode:      v.ORG_CODE,
   108  			//PredictFinanceCode  string  `name:"预告代码" json:"PREDICT_FINANCE_CODE"`
   109  			PredictFinanceCode: v.PREDICT_FINANCE_CODE,
   110  			//PredictFinance      string  `name:"预告财报" json:"PREDICT_FINANCE"`
   111  			PredictFinance: v.PREDICT_FINANCE,
   112  			//PredictAmtLower     float64 `name:"预计营收下限" json:"PREDICT_AMT_LOWER"`
   113  			PredictAmtLower: v.PREDICT_AMT_LOWER,
   114  			//PredictAmtUpper     float64 `name:"预计营收上限" json:"PREDICT_AMT_UPPER"`
   115  			PredictAmtUpper: v.PREDICT_AMT_UPPER,
   116  			//AddAmpLower         float64 `name:"增长下限" json:"ADD_AMP_LOWER"`
   117  			AddAmpLower: v.ADD_AMP_LOWER,
   118  			//AddAmpUpper         float64 `name:"增长下限" json:"ADD_AMP_UPPER"`
   119  			AddAmpUpper: v.ADD_AMP_UPPER,
   120  			//PredictContent      string  `name:"预告内容" json:"PREDICT_CONTENT"`
   121  			PredictContent: v.PREDICT_CONTENT,
   122  			//ChangeReasonExplain string  `name:"改变原因" json:"CHANGE_REASON_EXPLAIN"`
   123  			ChangeReasonExplain: v.CHANGE_REASON_EXPLAIN,
   124  			//PredictType         string  `name:"预计类型" json:"PREDICT_TYPE"`
   125  			PredictType: v.PREDICT_TYPE,
   126  			//PreyearSamePeriod   float64 `name:"上年同期" json:"PREYEAR_SAME_PERIOD"`
   127  			PreyearSamePeriod: v.PREYEAR_SAME_PERIOD,
   128  			//TradeMarket         string  `name:"所在交易所" json:"TRADE_MARKET"`
   129  			TradeMarket: v.TRADE_MARKET,
   130  			//TradeMarketCode     string  `name:"场内交易代码" json:"TRADE_MARKET_CODE"`
   131  			TradeMarketCode: v.TRADE_MARKET_CODE,
   132  			//SecurityType        string  `name:"证券类型" json:"SECURITY_TYPE"`
   133  			SecurityType: v.SECURITY_TYPE,
   134  			//SecurityTypeCode    string  `name:"证券类型代码" json:"SECURITY_TYPE_CODE"`
   135  			SecurityTypeCode: v.SECURITY_TYPE_CODE,
   136  			//IncreaseJz          float64 `name:"增长均值" json:"INCREASE_JZ"`
   137  			IncreaseJz: v.INCREASE_JZ,
   138  			//ForecastJz          float64 `name:"预测均值" json:"FORECAST_JZ"`
   139  			ForecastJz: v.FORECAST_JZ,
   140  			//ForecastState       string  `name:"预测状态" json:"FORECAST_STATE"`
   141  			ForecastState: v.FORECAST_STATE,
   142  			//IsLatest            string  `name:"是否最新财报" json:"IS_LATEST"`
   143  			IsLatest: v.IS_LATEST,
   144  			//PredictRatioLower   float64 `name:"预测增速下限" json:"PREDICT_RATIO_LOWER"`
   145  			PredictRatioLower: v.PREDICT_RATIO_LOWER,
   146  			//PredictRatioUpper   float64 `name:"预测增速上限" json:"PREDICT_RATIO_UPPER"`
   147  			PredictRatioUpper: v.PREDICT_RATIO_UPPER,
   148  			//PredictHbmean       float64 `name:"预计每股盈利?" json:"PREDICT_HBMEAN"`
   149  			PredictHbmean: v.PREDICT_HBMEAN,
   150  		}
   151  		reports = append(reports, report)
   152  	}
   153  	return
   154  }
   155  
   156  // 财报原始数据结构
   157  type rawFinanceReport struct {
   158  	Version string `json:"version"`
   159  	Result  struct {
   160  		Pages int `json:"pages"`
   161  		Data  []struct {
   162  			SECUCODE              string  `json:"SECUCODE"`
   163  			SECURITY_CODE         string  `json:"SECURITY_CODE"`
   164  			SECURITY_NAME_ABBR    string  `json:"SECURITY_NAME_ABBR"`
   165  			ORG_CODE              string  `json:"ORG_CODE"`
   166  			NOTICE_DATE           string  `json:"NOTICE_DATE"`
   167  			REPORT_DATE           string  `json:"REPORT_DATE"`
   168  			PREDICT_FINANCE_CODE  string  `json:"PREDICT_FINANCE_CODE"`
   169  			PREDICT_FINANCE       string  `json:"PREDICT_FINANCE"`
   170  			PREDICT_AMT_LOWER     float64 `json:"PREDICT_AMT_LOWER"`
   171  			PREDICT_AMT_UPPER     float64 `json:"PREDICT_AMT_UPPER"`
   172  			ADD_AMP_LOWER         float64 `json:"ADD_AMP_LOWER"`
   173  			ADD_AMP_UPPER         float64 `json:"ADD_AMP_UPPER"`
   174  			PREDICT_CONTENT       string  `json:"PREDICT_CONTENT"`
   175  			CHANGE_REASON_EXPLAIN string  `json:"CHANGE_REASON_EXPLAIN"`
   176  			PREDICT_TYPE          string  `json:"PREDICT_TYPE"`
   177  			PREYEAR_SAME_PERIOD   float64 `json:"PREYEAR_SAME_PERIOD"`
   178  			TRADE_MARKET          string  `json:"TRADE_MARKET"`
   179  			TRADE_MARKET_CODE     string  `json:"TRADE_MARKET_CODE"`
   180  			SECURITY_TYPE         string  `json:"SECURITY_TYPE"`
   181  			SECURITY_TYPE_CODE    string  `json:"SECURITY_TYPE_CODE"`
   182  			INCREASE_JZ           float64 `json:"INCREASE_JZ"`
   183  			FORECAST_JZ           float64 `json:"FORECAST_JZ"`
   184  			FORECAST_STATE        string  `json:"FORECAST_STATE"`
   185  			IS_LATEST             string  `json:"IS_LATEST"`
   186  			PREDICT_RATIO_LOWER   float64 `json:"PREDICT_RATIO_LOWER"`
   187  			PREDICT_RATIO_UPPER   float64 `json:"PREDICT_RATIO_UPPER"`
   188  			PREDICT_HBMEAN        float64 `json:"PREDICT_HBMEAN"`
   189  		} `json:"data"`
   190  		Count int `json:"count"`
   191  	} `json:"result"`
   192  	Success bool   `json:"success"`
   193  	Message string `json:"message"`
   194  	Code    int    `json:"code"`
   195  }