candle.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package base
  2. import "tickserver/api/lmaxapi/markinfo"
  3. import "unsafe"
  4. import "errors"
  5. type TickReader interface {
  6. Read() (*TickGo, error)
  7. }
  8. type CandleReader interface {
  9. Read() (*OhlcGo, error)
  10. }
  11. type CandleGenerate struct {
  12. candle *Candle
  13. reader TickReader
  14. creader CandleReader
  15. symbolId int
  16. period int
  17. maxComp int
  18. num int
  19. }
  20. func NewCandleGenerate(symbolId int, period int, data *OhlcGo, trans *TimezoneTrans, reader interface{}) (*CandleGenerate, error) {
  21. name, err := markinfo.SymbolName(symbolId)
  22. if err != nil {return nil, err}
  23. point, err := markinfo.SymbolPoint(name)
  24. if err != nil {return nil, err}
  25. var p unsafe.Pointer
  26. p = unsafe.Pointer(data)
  27. if data != nil {
  28. p = unsafe.Pointer(data.ToCStruct())
  29. }
  30. candle , err := NewCandle(period, point, p, 0)
  31. if err != nil {
  32. return nil, err
  33. }
  34. if trans == nil {
  35. trans, err = NewTimezoneTrans("etc/GMT", 0, "etc/GMT", 0, 0)
  36. if err != nil {
  37. return nil, err
  38. }
  39. }
  40. candle.SetTimezoneTrans(trans)
  41. calc := CandleGenerate{}
  42. calc.candle = candle
  43. if read, ok := reader.(TickReader) ; ok {
  44. calc.reader = read
  45. } else if cread, ok := reader.(CandleReader) ; ok {
  46. calc.creader = cread
  47. } else {
  48. return nil, errors.New("unknow reader interface, must TickReader or OhlcReader")
  49. }
  50. calc.symbolId = symbolId
  51. calc.period = period
  52. calc.maxComp = 12 * 3600
  53. return &calc, nil
  54. }
  55. func (calc *CandleGenerate) SetConf(key int, conf interface{}) (int, error) {
  56. if key == CANDLE_AUTOCOMPLETE_MAX {
  57. calc.maxComp = conf.(int)
  58. }
  59. return calc.candle.Set(key, conf)
  60. }
  61. func (calc *CandleGenerate) PeriodSecond() int {
  62. return calc.period
  63. }
  64. func (calc *CandleGenerate) MaxAlignTime() int {
  65. return calc.maxComp
  66. }
  67. //CandleReader Interface
  68. func (calc *CandleGenerate) Read() (*OhlcGo, error) {
  69. if calc.num > 0 {
  70. calc.num--
  71. return calc.readNext()
  72. }
  73. if calc.reader != nil {
  74. tick, err := calc.reader.Read()
  75. if err != nil {
  76. return nil, err
  77. }
  78. if tick == nil {
  79. panic("tick error.")
  80. }
  81. calc.num = calc.candle.UpdateTick((*Tick)(unsafe.Pointer(tick)))
  82. } else {
  83. ohlc, err := calc.creader.Read()
  84. if err != nil {
  85. return nil, err
  86. }
  87. if ohlc == nil {
  88. panic("ohlc error.")
  89. }
  90. calc.num = calc.candle.UpdateOhlc(ohlc.ToCStruct())
  91. }
  92. if calc.num == 0 { //没有补全
  93. return calc.readNext()
  94. }
  95. calc.num--
  96. return calc.readNext()
  97. }
  98. func (calc *CandleGenerate) readNext() (*OhlcGo, error) {
  99. ohlc := &Ohlc{}
  100. calc.candle.Next(ohlc)
  101. ret := ohlc.ToGOStruct()
  102. return &ret, nil
  103. }