candle.go 2.7 KB

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