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