fzm.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
  2. package market
  3. // 本文件实现fzm相关的操作: 获取历史数据和动态行情数据以及产品列表
  4. import (
  5. "encoding/json"
  6. "errors"
  7. "io/ioutil"
  8. "log"
  9. "os"
  10. "sync"
  11. "tickserver/framework/event"
  12. )
  13. const fzmInsTable = "Fzm_inss"
  14. const (
  15. BufMax = 2048
  16. )
  17. // FzmFx定义了交易所
  18. // 集成了所有的数据源: lmax, easyforex, oanda, macoin等
  19. // 使用数据库管理下载的历史数据
  20. // 并在内存中缓存了最新的tick数据和candleK线数据
  21. // 实现了Server服务的接口
  22. type FzmEx struct {
  23. db *MyDB // 数据库
  24. dsMap map[string]DataSource // 数据源map
  25. imu sync.Mutex // 保护insMap
  26. insMap map[string]*Instrument // 保存所有的instrument
  27. inssFname string // instruments 列表文件
  28. }
  29. func makeTBMap() map[int]map[string]*TickBuffer {
  30. tbMap := make(map[int]map[string]*TickBuffer)
  31. for k, _ := range basePeriodSet {
  32. tbMap[k] = make(map[string]*TickBuffer)
  33. }
  34. return tbMap
  35. }
  36. func NewFzmEx(db *MyDB, inssFname string) *FzmEx {
  37. insMap, err := readInssTable(inssFname)
  38. if err != nil {
  39. //log.Println("NewFzmEx warning:", err)
  40. insMap = make(map[string]*Instrument)
  41. }
  42. //log.Println("NewFzmEx:", insMap)
  43. return &FzmEx{
  44. dsMap: make(map[string]DataSource),
  45. insMap: insMap,
  46. db: db,
  47. inssFname: inssFname,
  48. }
  49. }
  50. func (ex *FzmEx) GetIns(insId string) *Instrument {
  51. ex.imu.Lock()
  52. defer ex.imu.Unlock()
  53. return ex.insMap[insId]
  54. }
  55. func (ex *FzmEx) setIns(ins *Instrument) {
  56. ex.imu.Lock()
  57. delete(ex.insMap, ins.Id)
  58. ex.insMap[ins.Id] = ins
  59. ex.imu.Unlock()
  60. // f := ex.onMarket()
  61. // ins.OnMarket().Attach(f)
  62. }
  63. func (ex *FzmEx) GetCacheCandles(insId string, period int) ([]Candle, error) {
  64. ds, ok := ex.dsMap[InsIdPrefix(insId)]
  65. if !ok {
  66. return nil, errors.New("GetCacheCandles error: insId is NOT in insMap: " + insId)
  67. }
  68. return ds.GetCacheCandles(insId, period)
  69. }
  70. func (ex *FzmEx) GetCacheTicks(insId string) ([]Tick, error) {
  71. ds, ok := ex.dsMap[InsIdPrefix(insId)]
  72. if !ok {
  73. return nil, errors.New("GetLastTicks error: insId is NOT in insMap: " + insId)
  74. }
  75. return ds.GetCacheTicks(insId)
  76. }
  77. func (ex *FzmEx) GetTimeList(insId, period, beginStr string) ([]string, error) {
  78. ds, ok := ex.dsMap[InsIdPrefix(insId)]
  79. if !ok {
  80. return nil, errors.New("GetLastTicks error: insId is NOT in insMap: " + insId)
  81. }
  82. return ds.GetTimeList(insId, period, beginStr)
  83. }
  84. func (ex *FzmEx) SaveAllTicks() {
  85. for _, ds := range ex.dsMap {
  86. ds.SaveAllTicks()
  87. }
  88. }
  89. func (ex *FzmEx) AddDS(name string, ds DataSource) {
  90. ex.dsMap[name] = ds
  91. ds.SubIns().Attach(func(v interface{}) error {
  92. ins, ok := v.(*Instrument)
  93. if !ok {
  94. log.Fatal("FzmEx.AddDS error. v is NOT *Instrument")
  95. }
  96. ex.setIns(ins)
  97. return nil
  98. })
  99. }
  100. func readInssTable(inssFname string) (map[string]*Instrument, error) {
  101. f, err := os.Open(inssFname)
  102. if err != nil {
  103. return nil, err
  104. }
  105. defer f.Close()
  106. dec := json.NewDecoder(f)
  107. insMap := make(map[string]*Instrument)
  108. err = dec.Decode(&insMap)
  109. if err != nil {
  110. return nil, err
  111. }
  112. return insMap, nil
  113. }
  114. func (ex *FzmEx) writeInssTable() error {
  115. b, err := json.MarshalIndent(ex.insMap, "", " ")
  116. if err != nil {
  117. return err
  118. }
  119. ioutil.WriteFile(ex.inssFname, b, os.ModePerm)
  120. return nil
  121. }
  122. func (ex *FzmEx) Instruments() map[string]*Instrument {
  123. ex.writeInssTable()
  124. return ex.insMap
  125. }
  126. func (ex *FzmEx) SubMarket(insId string) *event.Event {
  127. ex.imu.Lock()
  128. ins, ok := ex.insMap[insId]
  129. ex.imu.Unlock()
  130. if !ok {
  131. return nil
  132. }
  133. //log.Println("FzmEx.SubMarket:", insId)
  134. return ins.mkPublisher.Event()
  135. }