base_from_ths_ds.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package services
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_index_lib/models"
  6. "eta/eta_index_lib/utils"
  7. "fmt"
  8. "github.com/rdlucklib/rdluck_tools/http"
  9. )
  10. func GetEdbDataFromThsDs(stockCode, edbCode, startDate, endDate, edbTerminalCode string) (item models.EdbDataFromThs, err error) {
  11. terminal, err := GetTerminal(utils.DATA_SOURCE_THS, edbTerminalCode)
  12. if err != nil {
  13. err = fmt.Errorf("获取同花顺接口配置出错 Err: %s", err)
  14. return
  15. }
  16. if terminal.ServerUrl == "" {
  17. err = fmt.Errorf("同花顺接口未配置")
  18. return
  19. }
  20. if edbTerminalCode == "" {
  21. // 设置指标与终端关系的缓存
  22. terminalCodeCacheKey := utils.CACHE_EDB_TERMINAL_CODE_URL + stockCode
  23. _ = utils.Rc.Put(terminalCodeCacheKey, terminal.TerminalCode, utils.GetTodayLastSecond())
  24. }
  25. // 如果没有配置,获取配置的方式是api,那么就走官方接口
  26. if utils.ThsDataMethod == "" || utils.ThsDataMethod == "api" {
  27. var token string
  28. token, err = GetAccessToken(false, terminal.Value)
  29. if err != nil {
  30. return
  31. }
  32. return getEdbDataFromThsDsHttp(stockCode, edbCode, startDate, endDate, terminal.Value, token)
  33. }
  34. return getEdbDataFromThsDsApp(stockCode,edbCode, startDate, endDate, 0, terminal.ServerUrl)
  35. }
  36. type EdbDataFromThsSdInterface struct {
  37. Errorcode int `json:"errorcode"`
  38. Errmsg string `json:"errmsg"`
  39. Tables []Table `json:"tables"`
  40. Datatype []Type `json:"datatype"`
  41. InputParams interface{} `json:"inputParams"`
  42. DataVol int `json:"dataVol"`
  43. Perf int `json:"perf"`
  44. }
  45. type Table struct {
  46. Thscode string `json:"thscode"`
  47. Time []string `json:"time"`
  48. Table map[string]interface{} `json:"table"`
  49. }
  50. type StockData struct {
  51. THSOpenPriceStock []float64 `json:"ths_open_price_stock"`
  52. THSHighPriceStock []float64 `json:"ths_high_price_stock"`
  53. THSLowStock []float64 `json:"ths_low_stock"`
  54. THSClosePriceStock []float64 `json:"ths_close_price_stock"`
  55. THSChgRatioStock []float64 `json:"ths_chg_ratio_stock"`
  56. THSChgStock []float64 `json:"ths_chg_stock"`
  57. THSVolStock []float64 `json:"ths_vol_stock"`
  58. THSPreCloseStock []float64 `json:"ths_pre_close_stock"`
  59. THSSwingStock []float64 `json:"ths_swing_stock"`
  60. THSTurnoverRatioStock []float64 `json:"ths_turnover_ratio_stock"`
  61. THSAmtStock []float64 `json:"ths_amt_stock"`
  62. }
  63. type Type struct {
  64. Itemid string `json:"itemid"`
  65. Type string `json:"type"`
  66. }
  67. //
  68. //type Params struct {
  69. // Jsonrpc bool `json:"jsonrpc"`
  70. // Params []Param `json:"params"`
  71. //}
  72. //
  73. //type Param struct {
  74. // Function string `json:"function"`
  75. // ID string `json:"id"`
  76. // Params []Param2 `json:"params"`
  77. //}
  78. //
  79. //type Param2 struct {
  80. // Name string `json:"name"`
  81. // System string `json:"system"`
  82. // Value string `json:"value"`
  83. //}
  84. // getEdbDataFromThsDs 获取同花顺接口数据
  85. func getEdbDataFromThsDsApp(stockCode, edbCode, startDate, endDate string, num int, serverUrl string) (item models.EdbDataFromThs, err error) {
  86. if serverUrl == `` {
  87. err = errors.New("同花顺接口未配置")
  88. return
  89. }
  90. thsUrl := serverUrl + `edbInfo/ths/ds?StockCode=%s&EdbCode=%s&StartDate=%s&EndDate=%s`
  91. thsUrl = fmt.Sprintf(thsUrl, stockCode, edbCode, startDate, endDate)
  92. utils.FileLog.Info("thsUrl:" + thsUrl)
  93. body, err := http.Get(thsUrl)
  94. utils.FileLog.Info("ths result:" + string(body))
  95. if err != nil {
  96. err = errors.New(" Err:" + err.Error() + ";result:" + string(body))
  97. return
  98. }
  99. if string(body) == "null" {
  100. err = errors.New("同花顺数据获取异常:" + err.Error() + ";result:" + string(body))
  101. return
  102. }
  103. println(string(body))
  104. var jsonArray []string
  105. if err = json.Unmarshal(body, &jsonArray); err != nil {
  106. fmt.Println("json.Unmarshal Err:", err)
  107. return
  108. }
  109. tablesList := make([]models.Tables, 0)
  110. // 解码数组内的每个 JSON 字符串
  111. //var responses []TerminalResponse
  112. var errCode int64
  113. for _, data := range jsonArray {
  114. tableTimeList := make([]string, 0)
  115. tableValueList := make([]float64, 0)
  116. var response TerminalResponse
  117. if err = json.Unmarshal([]byte(data), &response); err != nil {
  118. fmt.Println("json.Unmarshal Err:", err)
  119. return
  120. }
  121. errCode = int64(response.ErrorCode)
  122. if response.ErrorCode != 0 {
  123. //session has expired,please re-login after using the system
  124. //如果是同花顺登录session失效了,那么就重新请求获取数据
  125. if response.ErrorCode == -1020 && num == 0 {
  126. return getEdbDataFromThsDsApp(stockCode, edbCode, startDate, endDate, 1, serverUrl)
  127. }
  128. err = errors.New(string(body))
  129. return
  130. }
  131. for _, stockData := range response.Data {
  132. time := stockData["time"].(string)
  133. //thsCode := stockData["thscode"].(string)
  134. tableTimeList = append(tableTimeList, time)
  135. for k, v := range stockData {
  136. if k != "time" && k != "thscode" {
  137. tableValueList = append(tableValueList, v.(float64))
  138. }
  139. }
  140. }
  141. tmpTable := models.Tables{
  142. ID: []string{},
  143. Time: tableTimeList,
  144. Value: tableValueList,
  145. }
  146. tablesList = append(tablesList, tmpTable)
  147. }
  148. item = models.EdbDataFromThs{
  149. DataVol: 0,
  150. Errmsg: "",
  151. Errorcode: errCode,
  152. Perf: "",
  153. Tables: tablesList,
  154. }
  155. //tmpItems := new([]TerminalResponse)
  156. //err = json.Unmarshal(body, &tmpItems)
  157. //if err != nil {
  158. // err = errors.New("GetEdbDataFromThs json.Unmarshal Err:" + err.Error())
  159. // return
  160. //}
  161. //// 因为table里面的value有的时候返回的是string,有的是float64,所以需要用interface来反射取值
  162. //tablesList := make([]models.Tables, 0)
  163. //for _, table := range tmpItems.Tables {
  164. // tableIdList := make([]string, 0)
  165. // tableTimeList := make([]string, 0)
  166. // tableValueList := make([]float64, 0)
  167. //
  168. // for _, tableId := range table.ID {
  169. // tableIdList = append(tableIdList, tableId)
  170. // }
  171. // for _, tableTime := range table.Time {
  172. // tableTimeList = append(tableTimeList, tableTime)
  173. // }
  174. //
  175. // //指标数据
  176. // for _, tmpValue := range table.Value {
  177. // var tableValue float64
  178. // if reflect.TypeOf(tmpValue).Kind() == reflect.Float64 {
  179. // tableValue = reflect.ValueOf(tmpValue).Float()
  180. // } else if reflect.TypeOf(tmpValue).Kind() == reflect.String {
  181. // tmpTableValue, tmpErr := decimal.NewFromString(reflect.ValueOf(tmpValue).String())
  182. // if tmpErr != nil {
  183. // err = tmpErr
  184. // return
  185. // }
  186. // tableValue, _ = tmpTableValue.Truncate(4).Float64()
  187. // } else {
  188. // err = errors.New("错误的数据类型" + reflect.TypeOf(tmpValue).String())
  189. // return
  190. // }
  191. // tableValueList = append(tableValueList, tableValue)
  192. // }
  193. // tmpTable := models.Tables{
  194. // ID: tableIdList,
  195. // Time: tableTimeList,
  196. // Value: tableValueList,
  197. // }
  198. // tablesList = append(tablesList, tmpTable)
  199. //}
  200. //item = models.EdbDataFromThs{
  201. // DataVol: tmpItems.DataVol,
  202. // Errmsg: tmpItems.Errmsg,
  203. // Errorcode: tmpItems.Errorcode,
  204. // Perf: tmpItems.Perf,
  205. // Tables: tablesList,
  206. //}
  207. return item, nil
  208. }