package base /* #cgo CFLAGS: -I./include #cgo LDFLAGS: -L./lib -lm -lbase #include #include #include #include #include #include */ import "C" import "fmt" import "unsafe" import "reflect" type Candle struct { obj *C.struct_candle } type Timezone struct { obj *C.struct_timezone } type TimezoneTrans struct { obj *C.struct_timezone_trans } type Ohlc struct { data C.struct_ohlc } type Tick struct { data C.struct_tick } type OhlcTmp struct { Time int32 Open float32 High float32 Low float32 Close float32 Spread int32 TickVolumn int64 RealVolumn float64 } type OhlcGo struct { Time int32 Open float64 High float64 Low float64 Close float64 Spread int32 TickVolumn int64 RealVolumn float64 } //类型转换 func (ohlc *OhlcGo) ToCStruct() *Ohlc { tmp := &OhlcTmp{} tmp.Time = ohlc.Time tmp.Spread = ohlc.Spread tmp.TickVolumn = ohlc.TickVolumn tmp.RealVolumn = ohlc.RealVolumn tmp.Open = float32(ohlc.Open) tmp.High = float32(ohlc.High) tmp.Low = float32(ohlc.Low) tmp.Close = float32(ohlc.Close) return (*Ohlc)(unsafe.Pointer(tmp)) } type TickGo struct { Time int32 Bid float32 Ask float32 Bidv float32 Askv float32 Ms int16 Symbol int16 } const ( S1 = 1 S2 = 2 S3 = 3 S5 = 5 S10 = 10 S15 = 15 S20 = 20 S30 = 30 M1 = 1 * 60 M2 = 2 * 60 M3 = 3 * 60 M4 = 4 * 60 M5 = 5 * 60 M15 = 15 * 60 M30 = 30 * 60 H1 = 60 * 60 H2 = 2 * 60 * 60 H4 = 4 * 60 * 60 D1 = 24 * 3600 W1 = 7 * 24 * 3600 MN1 = 30 * 24 * 3600 ) var periodName = map[int]string{ S1: "S1", S2: "S2", S3: "S3", S5: "S5", S10: "S10", S15: "S15", S20: "S20", S30: "S30", M1: "M1", M2: "M2", M3: "M3", M4: "M4", M5: "M5", M15: "M15", M30: "M30", H1: "H1", H2: "H2", H4: "H4", D1: "D1", W1: "W1", MN1: "MN1", } var PeriodIds = map[string]int{ "S1": S1, "S2": S2, "S3": S3, "S5": S5, "S10": S10, "S15": S15, "S20": S20, "S30": S30, "M1": M1, "M2": M2, "M3": M3, "M4": M4, "M5": M5, "M15": M15, "M30": M30, "H1": H1, "H2": H2, "H4": H4, "D1": D1, "W1": W1, "MN1": MN1, } const CANDLE_OHLC = 0 const CANDLE_TICK = 1 const CANDLE_ASK = 0 const CANDLE_BID = 1 const CANDLE_TIME_IN = 1 const CANDLE_TIME_OUT = 2 const CANDLE_TIME_GMT = 3 const ( CANDLE_LINE_TYPR = iota //bid = CANDLE_BID, ask = CANDLE_ASK, default = CANDLE_BID CANDLE_AUTOCOMPLETE //1 complete, 0 not complete, default = 0, 补全暂时只考虑周末.元旦,圣诞,时间. CANDLE_CLOSE_AS_OPEN //1 on , 0 off, default = off CANDLE_AUTOCOMPLETE_MAX //默认情况下,12个小时内没有数据,就不进行补全 CANDLE_TIMEZONE_CACHE_TIME CANDLE_SPREAD_AGV CANDLE_MAX_INT_CONF ) func PeriodName(period int) (string, error) { value, ok := periodName[period] if !ok { return "", fmt.Errorf("find period name error") } return value, nil } func PeriodId(name string) (int, error) { value, ok := PeriodIds[name] if !ok { return 0, fmt.Errorf("find period id error") } return value, nil } func NewCandle(period int, point int, data unsafe.Pointer, flag int) (candle *Candle, err error) { c := C.candle_new(C.int(period), C.int(point), data, C.int(flag)) if c == nil { return nil, fmt.Errorf("create new candle object error.") } return &Candle{obj: c}, nil } func (c *Candle) Free() { C.candle_free(c.obj) } func (c *Candle) Set(key int, value interface{}) (int, error) { v := reflect.ValueOf(value) switch v.Kind() { case reflect.Int: ret := C.candle_set_integer(c.obj, C.int(key), C.int(v.Int())) return int(ret), nil case reflect.String: cstr := C.CString(cstring(v.Bytes())) defer C.free(unsafe.Pointer(cstr)) ret := C.candle_set_string(c.obj, C.int(key), cstr) return int(ret), nil case reflect.Float64: ret := C.candle_set_double(c.obj, C.int(key), C.double(v.Float())) return int(ret), nil default: } return 0, fmt.Errorf("unknow type of value.") } func (c *Candle) UpdateOhlc(data *Ohlc) int { ret := C.candle_updateby_ohlc(c.obj, &data.data) return int(ret) } func (c *Candle) UpdateTick(data *Tick) int { ret := C.candle_updateby_tick(c.obj, &data.data) return int(ret) } func (c *Candle) Next(data *Ohlc) int { ret := C.candle_read_next(c.obj, &data.data) return int(ret) } func (c *Candle) Last(data *Ohlc) int { ret := C.candle_read_last_end(c.obj, &data.data) return int(ret) } func (c *Candle) SetTimezoneTrans(trans *TimezoneTrans) int { ret := C.candle_set_timezone_trans(c.obj, trans.obj) return int(ret) } func cstring(b []byte) string { var i int for i = 0; i < len(b) && b[i] != 0; i++ { } return string(b[0:i]) } func NewTimezone(s string) (t *Timezone, err error) { cstr := C.CString(s) defer C.free(unsafe.Pointer(cstr)) tz := C.timezone_open(cstr) if tz == nil { return nil, fmt.Errorf("create time zone error") } return &Timezone{tz}, nil } func (t *Timezone) Version() string { cstr := C.timezone_version_get() return C.GoString(cstr) } func (t *Timezone) Name() string { cstr := C.timezone_name_get(t.obj) return C.GoString(cstr) } func (t *Timezone) Offset(time int) int { offset := C.timezone_offset_get(t.obj, C.int(time)) return int(offset) } func (t *Timezone) OffsetLocal(time int) int { offset := C.timezone_offset_get_local(t.obj, C.int(time)) return int(offset) } func (t *Timezone) FixedOffset() int { offset := C.timezone_fixed_offset(t.obj) return int(offset) } func (t *Timezone) TimeStamp(time int, offset int) int { ret := C.timezone_get_timestamp(t.obj, C.int(time), C.int(offset)) return int(ret) } func (t *Timezone) LocalTime(time int, offset int) int { ret := C.timezone_get_localtime(t.obj, C.int(time), C.int(offset)) return int(ret) } func (t *Timezone) DumpInfo() { C.timezone_dump_tzinfo(t.obj) } func (t *Timezone) Free() { C.timezone_close(t.obj) } type TimezoneConf struct { In string Inoffset int Out string Outoffset int CacheTime int } func NewTimezoneTrans(in string, inoffset int, out string, outoffset int, cache_second int) (t *TimezoneTrans, err error) { incstr := C.CString(in) defer C.free(unsafe.Pointer(incstr)) outcstr := C.CString(out) defer C.free(unsafe.Pointer(outcstr)) trans := C.timezone_trans_new(incstr, C.int(inoffset), outcstr, C.int(outoffset), C.int(cache_second)) if trans == nil { return nil, fmt.Errorf("create timezone trans error.") } return &TimezoneTrans{trans}, nil } func (t *TimezoneTrans) Free() { C.timezone_trans_free(t.obj) } func (t *TimezoneTrans) Offset(time int) int { ret := C.timezone_trans_offset(t.obj, C.int(time)) return int(ret) } func (t *Tick) ToGOStruct() (tick TickGo) { tmp := (*TickGo)(unsafe.Pointer(t)) tick = *tmp return } func (t *Ohlc) ToGOStruct() (tick OhlcGo) { var time, spread C.int var open, high, low, close C.float var tick_volumn C.longlong var real_volumn C.double C.get_ohlc_data(&t.data, &time, &open, &high, &low, &close, &spread, &tick_volumn, &real_volumn) tick.Time = int32(time) tick.Open = float64(open) tick.High = float64(high) tick.Low = float64(low) tick.Close = float64(close) tick.Spread = int32(spread) tick.TickVolumn = int64(tick_volumn) tick.RealVolumn = float64(real_volumn) /*tick2 := OhlcTmp{} C.memcpy(unsafe.Pointer(&tick2), unsafe.Pointer(t), C.size_t(unsafe.Sizeof(tick2))) tick.Time = tick2.Time tick.Open = float64(tick2.Open) tick.High = float64(tick2.High) tick.Low = float64(tick2.Low) tick.Close = float64(tick2.Close) tick.Spread = tick2.Spread tick.TickVolumn = tick2.TickVolumn tick.RealVolumn = tick2.RealVolumn*/ return }