package base import "tickserver/markinfo" import "unsafe" import "errors" type TickReader interface { Read() (*TickGo, error) } type CandleReader interface { Read() (*OhlcGo, error) } type CandleGenerate struct { candle *Candle reader TickReader creader CandleReader symbolId int period int maxComp int num int trans *TimezoneTrans } func NewCandleGenerate(symbolId int, period int, data *OhlcGo, trans *TimezoneTrans, reader interface{}) (*CandleGenerate, error) { name, err := markinfo.SymbolName(symbolId) if err != nil { return nil, err } point, err := markinfo.SymbolPoint(name) if err != nil { return nil, err } var p unsafe.Pointer p = unsafe.Pointer(data) if data != nil { p = unsafe.Pointer(data.ToCStruct()) } candle, err := NewCandle(period, point, p, 0) if err != nil { return nil, err } if trans == nil { trans, err = NewTimezoneTrans("etc/GMT", 0, "etc/GMT", 0, 0) if err != nil { return nil, err } } candle.SetTimezoneTrans(trans) calc := CandleGenerate{} calc.candle = candle calc.trans = trans if read, ok := reader.(TickReader); ok { calc.reader = read } else if cread, ok := reader.(CandleReader); ok { calc.creader = cread } else { return nil, errors.New("unknow reader interface, must TickReader or OhlcReader") } calc.symbolId = symbolId calc.period = period calc.maxComp = 12 * 3600 return &calc, nil } func (calc *CandleGenerate) SetConf(key int, conf interface{}) (int, error) { if key == CANDLE_AUTOCOMPLETE_MAX { calc.maxComp = conf.(int) } return calc.candle.Set(key, conf) } func (calc *CandleGenerate) Close() { calc.candle.Free() calc.trans.Free() } func (calc *CandleGenerate) PeriodSecond() int { return calc.period } func (calc *CandleGenerate) MaxAlignTime() int { return calc.maxComp } //CandleReader Interface func (calc *CandleGenerate) Read() (*OhlcGo, error) { if calc.num > 0 { calc.num-- return calc.readNext() } if calc.reader != nil { tick, err := calc.reader.Read() if err != nil { return nil, err } if tick == nil { panic("tick error.") } calc.num = calc.candle.UpdateTick((*Tick)(unsafe.Pointer(tick))) } else { ohlc, err := calc.creader.Read() if err != nil { return nil, err } if ohlc == nil { panic("ohlc error.") } calc.num = calc.candle.UpdateOhlc(ohlc.ToCStruct()) } if calc.num == 0 { //没有补全 return calc.readNext() } calc.num-- return calc.readNext() } func (calc *CandleGenerate) readNext() (*OhlcGo, error) { ohlc := &Ohlc{} calc.candle.Next(ohlc) ret := ohlc.ToGOStruct() return &ret, nil }