commodity_trade_cffex.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. package services
  2. import (
  3. "bufio"
  4. "encoding/json"
  5. "encoding/xml"
  6. "eta/eta_crawler/models"
  7. "eta/eta_crawler/utils"
  8. "fmt"
  9. "io/ioutil"
  10. netHttp "net/http"
  11. "regexp"
  12. "strings"
  13. "time"
  14. "github.com/mozillazg/go-pinyin"
  15. )
  16. type XmlItem struct {
  17. XMLName xml.Name `xml:"positionRank"`
  18. Data []struct {
  19. ContractCode string `xml:"instrumentid"`
  20. Value string `xml:"Value,attr"`
  21. Text string `xml:"Text,attr"`
  22. Tradingday string `xml:"tradingday"`
  23. Datatypeid string `xml:"datatypeid"`
  24. Rank int `xml:"rank"`
  25. ShortName string `xml:"shortname"`
  26. Volume int `xml:"volume"`
  27. Varvolume int `xml:"varvolume"`
  28. ProductId string `xml:"productid"`
  29. } `xml:"data"`
  30. }
  31. var cffexIndexCode string
  32. var cffexIndexCodeMap = make(map[string]string)
  33. var cffexActionCodeMap = make(map[string]map[string]int)
  34. func cffexIndexCodeGenerator(shortName, indexName, contractCode, suffix string) string {
  35. if shortName == "" {
  36. cffexIndexCode = ""
  37. return cffexIndexCode
  38. }
  39. //取公司全拼
  40. strResult := ""
  41. a := pinyin.NewArgs()
  42. rows := pinyin.LazyPinyin(shortName, a)
  43. for i := 0; i < len(rows); i++ {
  44. strResult += rows[i]
  45. }
  46. cffexIndexCode, _ := cffexIndexCodeMap[indexName]
  47. if cffexIndexCode == "" {
  48. cffexIndexCode = strResult + contractCode + suffix
  49. cffexIndexCodeMap[indexName] = cffexIndexCode
  50. err := models.AddBaseFromTradeMapping(indexName, cffexIndexCode, "CFFEX")
  51. if err != nil {
  52. fmt.Println("add Code err:", err)
  53. }
  54. }
  55. return cffexIndexCode
  56. }
  57. // getProductId 获取中金所产品ID
  58. func getProductId() ([]string, error) {
  59. var productUrl = "http://www.cffex.com.cn/r/cms/www/default/js/config.js"
  60. req, _ := netHttp.NewRequest("GET", productUrl, nil)
  61. req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36")
  62. client := netHttp.Client{}
  63. res, err := client.Do(req)
  64. if err != nil {
  65. return []string{}, err
  66. }
  67. defer res.Body.Close()
  68. scanner := bufio.NewScanner(res.Body)
  69. for scanner.Scan() {
  70. line := scanner.Text()
  71. if strings.Contains(line, "productids :") {
  72. reg := regexp.MustCompile(`\[(.*?)\]`)
  73. var result []string
  74. err = json.Unmarshal([]byte(reg.FindString(line)), &result)
  75. if err != nil {
  76. return []string{}, err
  77. }
  78. return result, nil
  79. }
  80. }
  81. if err := scanner.Err(); err != nil {
  82. return []string{}, err
  83. }
  84. return []string{}, err
  85. }
  86. // SyncRankingFromCffex 中国金融期货交易所
  87. func SyncRankingFromCffex() {
  88. n := utils.GetRandInt(10, 120)
  89. time.Sleep(time.Duration(n) * time.Second)
  90. allCode, err := models.GetIndexCodeFromMapping("CFFEX")
  91. if err != nil {
  92. fmt.Println("select Code err:", err)
  93. }
  94. for _, item := range allCode {
  95. cffexIndexCodeMap[item.IndexName] = item.IndexCode
  96. }
  97. productIds, err := getProductId()
  98. if err != nil {
  99. utils.FileLog.Info("getProductId err:", err)
  100. }
  101. for i := 2; i >= 0; i-- {
  102. zzUrl := "http://www.cffex.com.cn/sj/ccpm/%s/%s/"
  103. date := time.Now().AddDate(0, 0, -i)
  104. dateStr := date.Format(utils.FormatDateUnSpace)
  105. pre := dateStr[:6]
  106. sub := dateStr[6:]
  107. zzUrl = fmt.Sprintf(zzUrl, pre, sub)
  108. fmt.Println(zzUrl)
  109. var xmlItems = make([]*XmlItem, len(productIds))
  110. if len(productIds) == 0 {
  111. utils.FileLog.Info("SyncRankingFromCffex warning:中金所无法获取产品信息, 使用默认产品")
  112. xmlItems = make([]*XmlItem, 8)
  113. xmlItems[0] = GetXmlItem(zzUrl, "IF")
  114. xmlItems[1] = GetXmlItem(zzUrl, "IC")
  115. xmlItems[2] = GetXmlItem(zzUrl, "IH")
  116. xmlItems[3] = GetXmlItem(zzUrl, "TS")
  117. xmlItems[4] = GetXmlItem(zzUrl, "TF")
  118. xmlItems[5] = GetXmlItem(zzUrl, "T")
  119. xmlItems[6] = GetXmlItem(zzUrl, "IM")
  120. xmlItems[7] = GetXmlItem(zzUrl, "TL")
  121. } else {
  122. for i, productId := range productIds {
  123. xmlItems[i] = GetXmlItem(zzUrl, productId)
  124. }
  125. }
  126. //获取新的指标信息
  127. var sRank string
  128. //获取所有指标信息
  129. allIndex, err := models.GetBaseFromTradeCffexIndexAll(dateStr)
  130. if err != nil {
  131. fmt.Println("select err:", err)
  132. }
  133. existDealMap := make(map[string]int)
  134. existBuyMap := make(map[string]int)
  135. existSoldMap := make(map[string]int)
  136. for _, v := range allIndex {
  137. existDealMap[v.DealName] = v.BaseFromTradeCffexIndexId
  138. existBuyMap[v.BuyName] = v.BaseFromTradeCffexIndexId
  139. existSoldMap[v.SoldName] = v.BaseFromTradeCffexIndexId
  140. sRank = fmt.Sprintf("%d", v.Rank)
  141. time := strings.Replace(v.DataTime, "-", "", -1)
  142. cffexActionCodeMap[sRank+v.ClassifyType+time] = map[string]int{"0": v.DealValue, "1": v.BuyValue, "2": v.SoldValue, "id": v.BaseFromTradeCffexIndexId}
  143. }
  144. shortNameColum := map[string]string{"0": "deal_short_name", "1": "buy_short_name", "2": "sold_short_name"}
  145. nameColum := map[string]string{"0": "deal_name", "1": "buy_name", "2": "sold_name"}
  146. codeColum := map[string]string{"0": "deal_code", "1": "buy_code", "2": "sold_code"}
  147. valueColum := map[string]string{"0": "deal_value", "1": "buy_value", "2": "sold_value"}
  148. changeColum := map[string]string{"0": "deal_change", "1": "buy_change", "2": "sold_change"}
  149. var dataName string
  150. var dataCode string
  151. var indexKey string
  152. for _, xmlItem := range xmlItems {
  153. for _, i := range xmlItem.Data {
  154. i.ShortName = strings.Replace(i.ShortName, "(经纪)", "", -1)
  155. i.ShortName = strings.Replace(i.ShortName, "(代客)", "", -1)
  156. var item = new(models.BaseFromTradeCffexIndex)
  157. item.DealValue = -1
  158. item.BuyValue = -1
  159. item.SoldValue = -1
  160. item.Rank = i.Rank
  161. switch i.Value {
  162. case "0":
  163. item.DealShortName = i.ShortName
  164. item.DealName = fmt.Sprintf("%s", i.ShortName+"_"+i.ContractCode+"_成交量(手)")
  165. item.DealCode = cffexIndexCodeGenerator(item.DealShortName, item.DealName, i.ContractCode, "deal")
  166. item.DealValue = i.Volume
  167. item.DealChange = i.Varvolume
  168. dataName = item.DealName
  169. dataCode = item.DealCode
  170. case "1":
  171. item.BuyShortName = i.ShortName
  172. item.BuyName = fmt.Sprintf("%s", i.ShortName+"_"+i.ContractCode+"_持买单量(手)")
  173. item.BuyCode = cffexIndexCodeGenerator(item.BuyShortName, item.BuyName, i.ContractCode, "buy")
  174. item.BuyValue = i.Volume
  175. item.BuyChange = i.Varvolume
  176. dataName = item.BuyName
  177. dataCode = item.BuyCode
  178. case "2":
  179. item.SoldShortName = i.ShortName
  180. item.SoldName = fmt.Sprintf("%s", i.ShortName+"_"+i.ContractCode+"_持卖单量(手)")
  181. item.SoldCode = cffexIndexCodeGenerator(item.SoldShortName, item.SoldName, i.ContractCode, "sold")
  182. item.SoldValue = i.Volume
  183. item.SoldChange = i.Varvolume
  184. dataName = item.SoldName
  185. dataCode = item.SoldCode
  186. default:
  187. fmt.Println("No data value")
  188. }
  189. item.Frequency = "日度"
  190. item.ClassifyName = i.ProductId
  191. item.ClassifyType = i.ContractCode
  192. item.CreateTime = time.Now()
  193. item.ModifyTime = time.Now()
  194. item.DataTime = i.Tradingday
  195. valueMap := map[string]int{"0": item.DealValue, "1": item.BuyValue, "2": item.SoldValue}
  196. //检查在actionCodeMap中是否已经有了
  197. indexKey = fmt.Sprintf("%d", item.Rank) + item.ClassifyType + item.DataTime
  198. if existMap, ok := cffexActionCodeMap[indexKey]; !ok {
  199. //没有,新增
  200. newID, err := models.AddBaseFromTradeCffexIndex(item)
  201. if err != nil {
  202. fmt.Println("insert error:", err)
  203. }
  204. fmt.Println("insert new indexID:", newID)
  205. existMap = make(map[string]int)
  206. existMap[i.Value] = i.Volume
  207. existMap["id"] = int(newID)
  208. cffexActionCodeMap[indexKey] = existMap
  209. } else if existMap != nil && existMap[i.Value] != i.Volume {
  210. //更新
  211. var columnList = [5]string{
  212. shortNameColum[i.Value],
  213. nameColum[i.Value],
  214. codeColum[i.Value],
  215. valueColum[i.Value],
  216. changeColum[i.Value],
  217. }
  218. var dataList = [5]interface{}{
  219. i.ShortName,
  220. dataName,
  221. dataCode,
  222. valueMap[i.Value],
  223. i.Varvolume,
  224. }
  225. err := models.ModifyBaseFromTradeCffexIndex(columnList, dataList, existMap["id"])
  226. if err != nil {
  227. fmt.Println("data update err:", err)
  228. }
  229. cffexActionCodeMap[indexKey][i.Value] = i.Volume
  230. } else if _, ok := existDealMap[item.DealName]; !ok {
  231. //更新
  232. var columnList = [5]string{
  233. shortNameColum[i.Value],
  234. nameColum[i.Value],
  235. codeColum[i.Value],
  236. valueColum[i.Value],
  237. changeColum[i.Value],
  238. }
  239. var dataList = [5]interface{}{
  240. i.ShortName,
  241. dataName,
  242. dataCode,
  243. valueMap[i.Value],
  244. i.Varvolume,
  245. }
  246. err := models.ModifyBaseFromTradeCffexIndex(columnList, dataList, existMap["id"])
  247. if err != nil {
  248. fmt.Println("data update err:", err)
  249. }
  250. cffexActionCodeMap[indexKey][i.Value] = i.Volume
  251. } else if _, ok := existBuyMap[item.BuyName]; !ok {
  252. //更新
  253. var columnList = [5]string{
  254. shortNameColum[i.Value],
  255. nameColum[i.Value],
  256. codeColum[i.Value],
  257. valueColum[i.Value],
  258. changeColum[i.Value],
  259. }
  260. var dataList = [5]interface{}{
  261. i.ShortName,
  262. dataName,
  263. dataCode,
  264. valueMap[i.Value],
  265. i.Varvolume,
  266. }
  267. err := models.ModifyBaseFromTradeCffexIndex(columnList, dataList, existMap["id"])
  268. if err != nil {
  269. fmt.Println("data update err:", err)
  270. }
  271. cffexActionCodeMap[indexKey][i.Value] = i.Volume
  272. } else if _, ok := existSoldMap[item.SoldName]; !ok {
  273. //更新
  274. var columnList = [5]string{
  275. shortNameColum[i.Value],
  276. nameColum[i.Value],
  277. codeColum[i.Value],
  278. valueColum[i.Value],
  279. changeColum[i.Value],
  280. }
  281. var dataList = [5]interface{}{
  282. i.ShortName,
  283. dataName,
  284. dataCode,
  285. valueMap[i.Value],
  286. i.Varvolume,
  287. }
  288. err := models.ModifyBaseFromTradeCffexIndex(columnList, dataList, existMap["id"])
  289. if err != nil {
  290. fmt.Println("data update err:", err)
  291. }
  292. cffexActionCodeMap[indexKey][i.Value] = i.Volume
  293. }
  294. }
  295. }
  296. }
  297. }
  298. func GetXmlItem(url, contract string) *XmlItem {
  299. zzUrl := url + contract + ".xml"
  300. fmt.Println(zzUrl)
  301. //body, err := http.Get(zzUrl)
  302. //if err != nil {
  303. // fmt.Println("err:", err)
  304. //}
  305. req, _ := netHttp.NewRequest("GET", zzUrl, nil)
  306. req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36")
  307. client := netHttp.Client{}
  308. res, err := client.Do(req)
  309. if err != nil {
  310. fmt.Println(err)
  311. return nil
  312. }
  313. defer res.Body.Close()
  314. // 读取响应的内容
  315. body, err := ioutil.ReadAll(res.Body)
  316. if err != nil {
  317. fmt.Println(err)
  318. return nil
  319. }
  320. xmlItem := new(XmlItem)
  321. err = xml.Unmarshal(body, &xmlItem)
  322. if err != nil {
  323. fmt.Println("xml.Unmarshal:", err.Error())
  324. }
  325. return xmlItem
  326. }