ds_fix.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // +build linux
  2. // Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
  3. package tick
  4. // 本文件实现方正FIX数据源接口, 实时数据和历史数据的获取和保存
  5. import (
  6. "encoding/json"
  7. "errors"
  8. "io/ioutil"
  9. "log"
  10. "os"
  11. "strconv"
  12. "strings"
  13. "tickserver/api/gofix"
  14. )
  15. type StockInfo struct {
  16. Id string
  17. Name string
  18. ExId string
  19. PriceInc float64
  20. Margin float64
  21. StartTime string
  22. }
  23. // FixDS实现了dataSource接口, 并对fix的历史数据和实时数据保存
  24. type FixDS struct {
  25. *DSBase
  26. conf *DsConf
  27. fixCfgFile string
  28. symbolMap map[string]string
  29. insMap map[int64]*StockInfo
  30. }
  31. func init() {
  32. drivers[Fix] = newFixDS
  33. }
  34. func newFixDS(conf *DsConf) (DataSource, error) {
  35. m := make(map[string]*StockInfo)
  36. f, err := os.Open(conf.SymbolsFile)
  37. if err != nil {
  38. si := &StockInfo{
  39. Id: "600000",
  40. ExId: "XSHG",
  41. Name: "浦发银行",
  42. PriceInc: 0.01,
  43. StartTime: "1999-11-10",
  44. }
  45. m[si.Id] = si
  46. b, _ := json.MarshalIndent(&m, "", " ")
  47. ioutil.WriteFile(conf.SymbolsFile, b, os.ModePerm)
  48. return nil, err
  49. }
  50. dec := json.NewDecoder(f)
  51. err = dec.Decode(&m)
  52. if err != nil {
  53. return nil, err
  54. }
  55. symbolMap := make(map[string]string)
  56. insMap := make(map[int64]*StockInfo)
  57. for k, v := range m {
  58. symbolMap[k] = v.ExId
  59. insId, _ := strconv.ParseInt(k, 10, 64)
  60. //insId := market.FixPrefix + k
  61. ss := strings.Split(v.StartTime, "-")
  62. if len(ss) != 3 {
  63. return nil, errors.New("StartTime format is Illegal. MUST yyyy-mm-dd format")
  64. }
  65. _, err := strconv.Atoi(ss[0])
  66. if err != nil {
  67. return nil, errors.New("StartTime format error:" + err.Error())
  68. }
  69. _, err = strconv.Atoi(ss[1])
  70. if err != nil {
  71. return nil, errors.New("StartTime format error:" + err.Error())
  72. }
  73. _, err = strconv.Atoi(ss[2])
  74. if err != nil {
  75. return nil, errors.New("StartTime format error:" + err.Error())
  76. }
  77. //t := time.Date(y, time.Month(m), d, 0, 0, 0, 0, time.Local)
  78. /*ins := &market.Instrument{
  79. Id: insId,
  80. Name: v.Name,
  81. Typ: market.Securities,
  82. ExId: v.ExId,
  83. PriceInc: v.PriceInc,
  84. Margin: v.Margin,
  85. StartTime: t.Unix() * 1000,
  86. }*/
  87. //insMap[insId] = ins
  88. insMap[insId] = v
  89. }
  90. return &FixDS{
  91. DSBase: NewDsBase(conf),
  92. conf: conf,
  93. symbolMap: symbolMap,
  94. insMap: insMap,
  95. }, nil
  96. }
  97. //func (fds *FixDS) SubIns() *event.Event {
  98. //return fds.insPublisher.Event()
  99. //}
  100. // func (fds *FixDS) GetInsMap() map[string]*market.Instrument {
  101. // return fds.insMap
  102. // }
  103. // func (fds *FixDS) GetInsName(insId string) string {
  104. // return fds.insMap[insId].Name
  105. // }
  106. func (fds *FixDS) Name() string {
  107. return Fix
  108. }
  109. func (fds *FixDS) Run() {
  110. log.Println("FixDS.Run")
  111. //for _, ins := range fds.insMap {
  112. //fds.insPublisher.Publish(ins)
  113. //}
  114. fixApp := gofix.NewApp(fds.symbolMap, fds.conf.User, fds.conf.PassWord)
  115. go fixApp.Run(fds.conf.CfgFile)
  116. //go fds.RunSave(16)
  117. log.Printf("%+v\n", fds.insMap)
  118. for fixTick := range fixApp.Ch {
  119. m := convMarket(fixTick)
  120. _, ok := fds.insMap[m.InsId]
  121. if !ok {
  122. for k, _ := range fds.insMap {
  123. log.Println(k, m.InsId, k == m.InsId) //, []byte(k), []byte(m.InsId)
  124. }
  125. log.Println("error: the market data NOT in insMap:", m.InsId, fds.insMap)
  126. continue
  127. }
  128. //if m.Timestamp < ins.StartTime {
  129. //log.Println("error: m.Timestamp < ins.StartTime:", m.Timestamp, ins.StartTime)
  130. //continue
  131. //}
  132. // log.Println(market.GetTime(m.Timestamp))
  133. // fds.marketPublisher.Publish(m)
  134. //ins.SetMk(m)
  135. fds.Save(m)
  136. }
  137. }
  138. func convMarket(tick *gofix.FixTick) *Market {
  139. //insId := market.FixPrefix + gofix.Symbol(tick.Symbol)
  140. insId, _ := strconv.ParseInt(string(tick.Symbol[:]), 10, 64)
  141. asks := make([]PP, tick.AskCount)
  142. bids := make([]PP, tick.BidCount)
  143. for i := 0; i < int(tick.AskCount); i++ {
  144. asks[i][0] = tick.AskPrice[i]
  145. asks[i][1] = float64(tick.AskVolume[i])
  146. }
  147. for i := 0; i < int(tick.AskCount); i++ {
  148. bids[i][0] = tick.BidPrice[i]
  149. bids[i][1] = float64(tick.BidVolume[i])
  150. }
  151. return &Market{
  152. InsId: insId,
  153. Type: IntFix,
  154. Timestamp: int64(tick.Time)*1000 + int64(tick.Millisecond),
  155. Bids: bids,
  156. Asks: asks,
  157. }
  158. }