base.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. package base
  2. /*
  3. #cgo CFLAGS: -I./include
  4. #cgo LDFLAGS: -L./lib -lm -lbase
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <timezone.h>
  9. #include <candle.h>
  10. #include <ctype.h>
  11. */
  12. import "C"
  13. import "fmt"
  14. import "unsafe"
  15. import "reflect"
  16. type Candle struct {
  17. obj *C.struct_candle
  18. }
  19. type Timezone struct {
  20. obj *C.struct_timezone
  21. }
  22. type TimezoneTrans struct {
  23. obj *C.struct_timezone_trans
  24. }
  25. type Ohlc struct {
  26. data C.struct_ohlc
  27. }
  28. type Tick struct {
  29. data C.struct_tick
  30. }
  31. type OhlcTmp struct {
  32. Time int32
  33. Open float32
  34. High float32
  35. Low float32
  36. Close float32
  37. Spread int32
  38. TickVolumn int64
  39. RealVolumn int64
  40. }
  41. type OhlcGo struct {
  42. Time int32
  43. Open float64
  44. High float64
  45. Low float64
  46. Close float64
  47. Spread int32
  48. TickVolumn int64
  49. RealVolumn int64
  50. }
  51. //类型转换
  52. func (ohlc *OhlcGo) ToCStruct() *Ohlc {
  53. tmp := &OhlcTmp{}
  54. tmp.Time = ohlc.Time
  55. tmp.Spread = ohlc.Spread
  56. tmp.TickVolumn = ohlc.TickVolumn
  57. tmp.RealVolumn = ohlc.RealVolumn
  58. tmp.Open = float32(ohlc.Open)
  59. tmp.High = float32(ohlc.High)
  60. tmp.Low = float32(ohlc.Low)
  61. tmp.Close = float32(ohlc.Close)
  62. return (*Ohlc)(unsafe.Pointer(tmp))
  63. }
  64. type TickGo struct {
  65. Time int32
  66. Bid float32
  67. Ask float32
  68. Bidv int32
  69. Askv int32
  70. Ms int16
  71. Symbol int16
  72. }
  73. const (
  74. S1 = 1
  75. S2 = 2
  76. S3 = 3
  77. S4 = 4
  78. S5 = 5
  79. S15 = 15
  80. S30 = 30
  81. M1 = 1 * 60
  82. M2 = 2 * 60
  83. M3 = 3 * 60
  84. M4 = 4 * 60
  85. M5 = 5 * 60
  86. M15 = 15 * 60
  87. M30 = 30 * 60
  88. H1 = 60 * 60
  89. H2 = 2 * 60 * 60
  90. H3 = 3 * 60 * 60
  91. H4 = 4 * 60 * 60
  92. H6 = 6 * 60 * 60
  93. H8 = 8 * 60 * 60
  94. D1 = 24 * 3600
  95. W1 = 7 * 24 * 3600
  96. MN1 = 30 * 24 * 3600
  97. )
  98. var periodName = map[int]string{
  99. S1: "S1",
  100. S2: "S2",
  101. S3: "S3",
  102. S4: "S4",
  103. S5: "S5",
  104. S15: "S15",
  105. S30: "S30",
  106. M1: "M1",
  107. M2: "M2",
  108. M3: "M3",
  109. M4: "M4",
  110. M5: "M5",
  111. M15: "M15",
  112. M30: "M30",
  113. H1: "H1",
  114. H2: "H2",
  115. H3: "H3",
  116. H4: "H4",
  117. H6: "H6",
  118. H8: "H8",
  119. D1: "D1",
  120. W1: "W1",
  121. MN1: "MN1",
  122. }
  123. var periodIds = map[string]int{
  124. "S1": S1,
  125. "S2": S2,
  126. "S3": S3,
  127. "S4": S4,
  128. "S5": S5,
  129. "S15": S15,
  130. "S30": S30,
  131. "M1": M1,
  132. "M2": M2,
  133. "M3": M3,
  134. "M4": M4,
  135. "M5": M5,
  136. "M15": M15,
  137. "M30": M30,
  138. "H1": H1,
  139. "H2": H2,
  140. "H3": H3,
  141. "H4": H4,
  142. "H6": H6,
  143. "H8": H8,
  144. "D1": D1,
  145. "W1": W1,
  146. "MN1": MN1,
  147. }
  148. const CANDLE_OHLC = 0
  149. const CANDLE_TICK = 1
  150. const CANDLE_ASK = 0
  151. const CANDLE_BID = 1
  152. const CANDLE_TIME_IN = 1
  153. const CANDLE_TIME_OUT = 2
  154. const CANDLE_TIME_GMT = 3
  155. const (
  156. CANDLE_LINE_TYPR = iota //bid = CANDLE_BID, ask = CANDLE_ASK, default = CANDLE_BID
  157. CANDLE_AUTOCOMPLETE //1 complete, 0 not complete, default = 0, 补全暂时只考虑周末.元旦,圣诞,时间.
  158. CANDLE_CLOSE_AS_OPEN //1 on , 0 off, default = off
  159. CANDLE_AUTOCOMPLETE_MAX //默认情况下,12个小时内没有数据,就不进行补全
  160. CANDLE_TIMEZONE_CACHE_TIME
  161. CANDLE_SPREAD_AGV
  162. CANDLE_MAX_INT_CONF
  163. )
  164. var sizeofOhlcTmp int
  165. func init() {
  166. tmp := OhlcTmp{}
  167. sizeofOhlcTmp = int(unsafe.Sizeof(tmp))
  168. }
  169. func PeriodName(period int) (string, error) {
  170. value, ok := periodName[period]
  171. if !ok {
  172. return "", fmt.Errorf("find period name error")
  173. }
  174. return value, nil
  175. }
  176. func PeriodId(name string) (int, error) {
  177. value, ok := periodIds[name]
  178. if !ok {
  179. return 0, fmt.Errorf("find period id error")
  180. }
  181. return value, nil
  182. }
  183. func NewCandle(period int, point int, data unsafe.Pointer, flag int) (candle *Candle, err error) {
  184. c := C.candle_new(C.int(period), C.int(point), data, C.int(flag))
  185. if c == nil {
  186. return nil, fmt.Errorf("create new candle object error.")
  187. }
  188. return &Candle{obj: c}, nil
  189. }
  190. func (c *Candle) Free() {
  191. C.candle_free(c.obj)
  192. }
  193. func (c *Candle) Set(key int, value interface{}) (int, error) {
  194. v := reflect.ValueOf(value)
  195. switch v.Kind() {
  196. case reflect.Int:
  197. ret := C.candle_set_integer(c.obj, C.int(key), C.int(v.Int()))
  198. return int(ret), nil
  199. case reflect.String:
  200. cstr := C.CString(cstring(v.Bytes()))
  201. defer C.free(unsafe.Pointer(cstr))
  202. ret := C.candle_set_string(c.obj, C.int(key), cstr)
  203. return int(ret), nil
  204. case reflect.Float64:
  205. ret := C.candle_set_double(c.obj, C.int(key), C.double(v.Float()))
  206. return int(ret), nil
  207. default:
  208. }
  209. return 0, fmt.Errorf("unknow type of value.")
  210. }
  211. func (c *Candle) UpdateOhlc(data *Ohlc) int {
  212. ret := C.candle_updateby_ohlc(c.obj, &data.data)
  213. return int(ret)
  214. }
  215. func (c *Candle) UpdateTick(data *Tick) int {
  216. ret := C.candle_updateby_tick(c.obj, &data.data)
  217. return int(ret)
  218. }
  219. func (c *Candle) Next(data *Ohlc) int {
  220. ret := C.candle_read_next(c.obj, &data.data)
  221. return int(ret)
  222. }
  223. func (c *Candle) Last(data *Ohlc) int {
  224. ret := C.candle_read_last_end(c.obj, &data.data)
  225. return int(ret)
  226. }
  227. func (c *Candle) SetTimezoneTrans(trans *TimezoneTrans) int {
  228. ret := C.candle_set_timezone_trans(c.obj, trans.obj)
  229. return int(ret)
  230. }
  231. func cstring(b []byte) string {
  232. var i int
  233. for i = 0; i < len(b) && b[i] != 0; i++ {
  234. }
  235. return string(b[0:i])
  236. }
  237. func NewTimezone(s string) (t *Timezone, err error) {
  238. cstr := C.CString(s)
  239. defer C.free(unsafe.Pointer(cstr))
  240. tz := C.timezone_open(cstr)
  241. if tz == nil {
  242. return nil, fmt.Errorf("create time zone error")
  243. }
  244. return &Timezone{tz}, nil
  245. }
  246. func (t *Timezone) Version() string {
  247. cstr := C.timezone_version_get()
  248. return C.GoString(cstr)
  249. }
  250. func (t *Timezone) Name() string {
  251. cstr := C.timezone_name_get(t.obj)
  252. return C.GoString(cstr)
  253. }
  254. func (t *Timezone) Offset(time int) int {
  255. offset := C.timezone_offset_get(t.obj, C.int(time))
  256. return int(offset)
  257. }
  258. func (t *Timezone) OffsetLocal(time int) int {
  259. offset := C.timezone_offset_get_local(t.obj, C.int(time))
  260. return int(offset)
  261. }
  262. func (t *Timezone) FixedOffset() int {
  263. offset := C.timezone_fixed_offset(t.obj)
  264. return int(offset)
  265. }
  266. func (t *Timezone) TimeStamp(time int, offset int) int {
  267. ret := C.timezone_get_timestamp(t.obj, C.int(time), C.int(offset))
  268. return int(ret)
  269. }
  270. func (t *Timezone) LocalTime(time int, offset int) int {
  271. ret := C.timezone_get_localtime(t.obj, C.int(time), C.int(offset))
  272. return int(ret)
  273. }
  274. func (t *Timezone) DumpInfo() {
  275. C.timezone_dump_tzinfo(t.obj)
  276. }
  277. func (t *Timezone) Free() {
  278. C.timezone_close(t.obj)
  279. }
  280. type TimezoneConf struct {
  281. In string
  282. Inoffset int
  283. Out string
  284. Outoffset int
  285. CacheTime int
  286. }
  287. func NewTimezoneTrans(in string, inoffset int, out string, outoffset int, cache_second int) (t *TimezoneTrans, err error) {
  288. incstr := C.CString(in)
  289. defer C.free(unsafe.Pointer(incstr))
  290. outcstr := C.CString(out)
  291. defer C.free(unsafe.Pointer(outcstr))
  292. trans := C.timezone_trans_new(incstr, C.int(inoffset), outcstr, C.int(outoffset), C.int(cache_second))
  293. if trans == nil {
  294. return nil, fmt.Errorf("create timezone trans error.")
  295. }
  296. return &TimezoneTrans{trans}, nil
  297. }
  298. func (t *TimezoneTrans) Free() {
  299. C.timezone_trans_free(t.obj)
  300. }
  301. func (t *TimezoneTrans) Offset(time int) int {
  302. ret := C.timezone_trans_offset(t.obj, C.int(time))
  303. return int(ret)
  304. }
  305. func (t *Tick) ToGOStruct() (tick TickGo) {
  306. tmp := (*TickGo)(unsafe.Pointer(t))
  307. tick = *tmp
  308. return
  309. }
  310. func (t *Ohlc) ToGOStruct() (tick OhlcGo) {
  311. tick2 := OhlcTmp{}
  312. C.memcpy(unsafe.Pointer(&tick2), unsafe.Pointer(t), C.size_t(sizeofOhlcTmp))
  313. tick.Time = tick2.Time
  314. tick.Open = float64(tick2.Open)
  315. tick.High = float64(tick2.High)
  316. tick.Low = float64(tick2.Low)
  317. tick.Close = float64(tick2.Close)
  318. tick.Spread = tick2.Spread
  319. tick.TickVolumn = tick2.TickVolumn
  320. tick.RealVolumn = tick2.RealVolumn
  321. return
  322. }