|
@@ -0,0 +1,226 @@
|
|
|
+package services
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/json"
|
|
|
+ "errors"
|
|
|
+ "eta/eta_index_lib/models"
|
|
|
+ "eta/eta_index_lib/utils"
|
|
|
+ "fmt"
|
|
|
+ "github.com/rdlucklib/rdluck_tools/http"
|
|
|
+)
|
|
|
+
|
|
|
+func GetEdbDataFromThsDs(stockCode, edbCode, startDate, endDate, edbTerminalCode string) (item models.EdbDataFromThs, err error) {
|
|
|
+ terminal, err := GetTerminal(utils.DATA_SOURCE_THS, edbTerminalCode)
|
|
|
+ if err != nil {
|
|
|
+ err = fmt.Errorf("获取同花顺接口配置出错 Err: %s", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if terminal.ServerUrl == "" {
|
|
|
+ err = fmt.Errorf("同花顺接口未配置")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if edbTerminalCode == "" {
|
|
|
+ // 设置指标与终端关系的缓存
|
|
|
+ terminalCodeCacheKey := utils.CACHE_EDB_TERMINAL_CODE_URL + stockCode
|
|
|
+ _ = utils.Rc.Put(terminalCodeCacheKey, terminal.TerminalCode, utils.GetTodayLastSecond())
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果没有配置,获取配置的方式是api,那么就走官方接口
|
|
|
+ if utils.ThsDataMethod == "" || utils.ThsDataMethod == "api" {
|
|
|
+ var token string
|
|
|
+ token, err = GetAccessToken(false, terminal.Value)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ return getEdbDataFromThsDsHttp(stockCode, edbCode, startDate, endDate, terminal.Value, token)
|
|
|
+ }
|
|
|
+
|
|
|
+ return getEdbDataFromThsDsApp(stockCode,edbCode, startDate, endDate, 0, terminal.ServerUrl)
|
|
|
+}
|
|
|
+
|
|
|
+type EdbDataFromThsSdInterface struct {
|
|
|
+ Errorcode int `json:"errorcode"`
|
|
|
+ Errmsg string `json:"errmsg"`
|
|
|
+ Tables []Table `json:"tables"`
|
|
|
+ Datatype []Type `json:"datatype"`
|
|
|
+ InputParams interface{} `json:"inputParams"`
|
|
|
+ DataVol int `json:"dataVol"`
|
|
|
+ Perf int `json:"perf"`
|
|
|
+}
|
|
|
+
|
|
|
+type Table struct {
|
|
|
+ Thscode string `json:"thscode"`
|
|
|
+ Time []string `json:"time"`
|
|
|
+ Table map[string]interface{} `json:"table"`
|
|
|
+}
|
|
|
+
|
|
|
+type StockData struct {
|
|
|
+ THSOpenPriceStock []float64 `json:"ths_open_price_stock"`
|
|
|
+ THSHighPriceStock []float64 `json:"ths_high_price_stock"`
|
|
|
+ THSLowStock []float64 `json:"ths_low_stock"`
|
|
|
+ THSClosePriceStock []float64 `json:"ths_close_price_stock"`
|
|
|
+ THSChgRatioStock []float64 `json:"ths_chg_ratio_stock"`
|
|
|
+ THSChgStock []float64 `json:"ths_chg_stock"`
|
|
|
+ THSVolStock []float64 `json:"ths_vol_stock"`
|
|
|
+ THSPreCloseStock []float64 `json:"ths_pre_close_stock"`
|
|
|
+ THSSwingStock []float64 `json:"ths_swing_stock"`
|
|
|
+ THSTurnoverRatioStock []float64 `json:"ths_turnover_ratio_stock"`
|
|
|
+ THSAmtStock []float64 `json:"ths_amt_stock"`
|
|
|
+}
|
|
|
+
|
|
|
+type Type struct {
|
|
|
+ Itemid string `json:"itemid"`
|
|
|
+ Type string `json:"type"`
|
|
|
+}
|
|
|
+//
|
|
|
+//type Params struct {
|
|
|
+// Jsonrpc bool `json:"jsonrpc"`
|
|
|
+// Params []Param `json:"params"`
|
|
|
+//}
|
|
|
+//
|
|
|
+//type Param struct {
|
|
|
+// Function string `json:"function"`
|
|
|
+// ID string `json:"id"`
|
|
|
+// Params []Param2 `json:"params"`
|
|
|
+//}
|
|
|
+//
|
|
|
+//type Param2 struct {
|
|
|
+// Name string `json:"name"`
|
|
|
+// System string `json:"system"`
|
|
|
+// Value string `json:"value"`
|
|
|
+//}
|
|
|
+
|
|
|
+// getEdbDataFromThsDs 获取同花顺接口数据
|
|
|
+func getEdbDataFromThsDsApp(stockCode, edbCode, startDate, endDate string, num int, serverUrl string) (item models.EdbDataFromThs, err error) {
|
|
|
+ if serverUrl == `` {
|
|
|
+ err = errors.New("同花顺接口未配置")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ thsUrl := serverUrl + `edbInfo/ths/ds?StockCode=%s&EdbCode=%s&StartDate=%s&EndDate=%s`
|
|
|
+ thsUrl = fmt.Sprintf(thsUrl, stockCode, edbCode, "2023-11-01", "2023-11-05")
|
|
|
+ utils.FileLog.Info("thsUrl:" + thsUrl)
|
|
|
+ body, err := http.Get(thsUrl)
|
|
|
+ utils.FileLog.Info("ths result:" + string(body))
|
|
|
+ if err != nil {
|
|
|
+ err = errors.New(" Err:" + err.Error() + ";result:" + string(body))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if string(body) == "null" {
|
|
|
+ err = errors.New("同花顺数据获取异常:" + err.Error() + ";result:" + string(body))
|
|
|
+ return
|
|
|
+ }
|
|
|
+println(string(body))
|
|
|
+
|
|
|
+ var jsonArray []string
|
|
|
+ if err = json.Unmarshal(body, &jsonArray); err != nil {
|
|
|
+ fmt.Println("json.Unmarshal Err:", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ tablesList := make([]models.Tables, 0)
|
|
|
+
|
|
|
+ // 解码数组内的每个 JSON 字符串
|
|
|
+ //var responses []TerminalResponse
|
|
|
+ var errCode int64
|
|
|
+ for _, data := range jsonArray {
|
|
|
+ tableTimeList := make([]string, 0)
|
|
|
+ tableValueList := make([]float64, 0)
|
|
|
+ var response TerminalResponse
|
|
|
+ if err = json.Unmarshal([]byte(data), &response); err != nil {
|
|
|
+ fmt.Println("json.Unmarshal Err:", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ errCode = int64(response.ErrorCode)
|
|
|
+ if response.ErrorCode != 0 {
|
|
|
+ //session has expired,please re-login after using the system
|
|
|
+ //如果是同花顺登录session失效了,那么就重新请求获取数据
|
|
|
+ if response.ErrorCode == -1020 && num == 0 {
|
|
|
+ return getEdbDataFromThsDsApp(stockCode, edbCode, startDate, endDate, 1, serverUrl)
|
|
|
+ }
|
|
|
+ err = errors.New(string(body))
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, stockData := range response.Data {
|
|
|
+ time := stockData["time"].(string)
|
|
|
+ //thsCode := stockData["thscode"].(string)
|
|
|
+ tableTimeList = append(tableTimeList, time)
|
|
|
+
|
|
|
+ for k, v := range stockData {
|
|
|
+ if k != "time" && k != "thscode" {
|
|
|
+ tableValueList = append(tableValueList, v.(float64))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tmpTable := models.Tables{
|
|
|
+ ID: []string{},
|
|
|
+ Time: tableTimeList,
|
|
|
+ Value: tableValueList,
|
|
|
+ }
|
|
|
+ tablesList = append(tablesList, tmpTable)
|
|
|
+ }
|
|
|
+ item = models.EdbDataFromThs{
|
|
|
+ DataVol: 0,
|
|
|
+ Errmsg: "",
|
|
|
+ Errorcode: errCode,
|
|
|
+ Perf: "",
|
|
|
+ Tables: tablesList,
|
|
|
+ }
|
|
|
+ //tmpItems := new([]TerminalResponse)
|
|
|
+ //err = json.Unmarshal(body, &tmpItems)
|
|
|
+ //if err != nil {
|
|
|
+ // err = errors.New("GetEdbDataFromThs json.Unmarshal Err:" + err.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //// 因为table里面的value有的时候返回的是string,有的是float64,所以需要用interface来反射取值
|
|
|
+ //tablesList := make([]models.Tables, 0)
|
|
|
+ //for _, table := range tmpItems.Tables {
|
|
|
+ // tableIdList := make([]string, 0)
|
|
|
+ // tableTimeList := make([]string, 0)
|
|
|
+ // tableValueList := make([]float64, 0)
|
|
|
+ //
|
|
|
+ // for _, tableId := range table.ID {
|
|
|
+ // tableIdList = append(tableIdList, tableId)
|
|
|
+ // }
|
|
|
+ // for _, tableTime := range table.Time {
|
|
|
+ // tableTimeList = append(tableTimeList, tableTime)
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // //指标数据
|
|
|
+ // for _, tmpValue := range table.Value {
|
|
|
+ // var tableValue float64
|
|
|
+ // if reflect.TypeOf(tmpValue).Kind() == reflect.Float64 {
|
|
|
+ // tableValue = reflect.ValueOf(tmpValue).Float()
|
|
|
+ // } else if reflect.TypeOf(tmpValue).Kind() == reflect.String {
|
|
|
+ // tmpTableValue, tmpErr := decimal.NewFromString(reflect.ValueOf(tmpValue).String())
|
|
|
+ // if tmpErr != nil {
|
|
|
+ // err = tmpErr
|
|
|
+ // return
|
|
|
+ // }
|
|
|
+ // tableValue, _ = tmpTableValue.Truncate(4).Float64()
|
|
|
+ // } else {
|
|
|
+ // err = errors.New("错误的数据类型" + reflect.TypeOf(tmpValue).String())
|
|
|
+ // return
|
|
|
+ // }
|
|
|
+ // tableValueList = append(tableValueList, tableValue)
|
|
|
+ // }
|
|
|
+ // tmpTable := models.Tables{
|
|
|
+ // ID: tableIdList,
|
|
|
+ // Time: tableTimeList,
|
|
|
+ // Value: tableValueList,
|
|
|
+ // }
|
|
|
+ // tablesList = append(tablesList, tmpTable)
|
|
|
+ //}
|
|
|
+ //item = models.EdbDataFromThs{
|
|
|
+ // DataVol: tmpItems.DataVol,
|
|
|
+ // Errmsg: tmpItems.Errmsg,
|
|
|
+ // Errorcode: tmpItems.Errorcode,
|
|
|
+ // Perf: tmpItems.Perf,
|
|
|
+ // Tables: tablesList,
|
|
|
+ //}
|
|
|
+ return item, nil
|
|
|
+}
|