quote.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. package models
  2. import (
  3. "errors"
  4. "fmt"
  5. "mtp2_if/db"
  6. "strings"
  7. "time"
  8. "gopkg.in/mgo.v2/bson"
  9. )
  10. // CycleType 周期类型
  11. type CycleType int
  12. const (
  13. // CycleTypeSecond 周期类型 - 秒
  14. CycleTypeSecond CycleType = 0
  15. // CycleTypeMinutes1 周期类型 - 1分钟
  16. CycleTypeMinutes1 CycleType = 1
  17. // CycleTypeMinutes5 周期类型 - 5分钟
  18. CycleTypeMinutes5 CycleType = 2
  19. // CycleTypeMinutes30 周期类型 - 30分钟
  20. CycleTypeMinutes30 CycleType = 3
  21. // CycleTypeMinutes60 周期类型 - 60分钟
  22. CycleTypeMinutes60 CycleType = 4
  23. // CycleTypeMinutes120 周期类型 - 2小时
  24. CycleTypeMinutes120 CycleType = 120
  25. // CycleTypeMinutes240 周期类型 - 4小时
  26. CycleTypeMinutes240 CycleType = 240
  27. // CycleTypeMinutesDay 周期类型 - 日线
  28. CycleTypeMinutesDay CycleType = 11
  29. // CycleTypeWeek 周期类型 - 周线
  30. CycleTypeWeek CycleType = 12
  31. // CycleTypeMonth 周期类型 - 月线
  32. CycleTypeMonth CycleType = 13
  33. // CycleTypeYear 周期类型 - 年线
  34. CycleTypeYear CycleType = 14
  35. // CycleTypeTik 周期类型 - Tik
  36. CycleTypeTik CycleType = 10
  37. )
  38. // CycleData MongoDB中历史数据模型
  39. type CycleData struct {
  40. ID bson.ObjectId `json:"-" bson:"_id"` // id
  41. GC string `bson:"GC"` // 商品代码
  42. ST int `json:"-" bson:"ST"` // 时间戳
  43. SST string `bson:"SST"` // 时间文本
  44. Open int `bson:"Open"` // 开盘价
  45. High int `bson:"High"` // 最高价
  46. Low int `bson:"Low"` // 最低价
  47. Close int `bson:"Close"` // 收盘价
  48. TV int `bson:"TV"` // 总量
  49. TT int `bson:"TT"` // 总金额
  50. HV int `bson:"HV"` // 持仓量
  51. SP int `bson:"SP"` // 结算价,日线周期(包括)以上才有
  52. FI bool `json:"FI"` // 是否补充数据
  53. }
  54. // TikData MongoDB中Tik数据模型
  55. type TikData struct {
  56. ID bson.ObjectId `json:"-" bson:"_id"` // id
  57. GC string `bson:"GC"` // 商品代码
  58. TD int `bson:"TD"` // 交易日时间戳
  59. AT int `bson:"AT"` // 行情时间戳
  60. SAT string `bson:"SAT"` // 行情时间文本
  61. PE int `bson:"PE"` // 现价
  62. Vol int `bson:"Vol"` // 现量
  63. TT int `bson:"TT"` // 现金额
  64. Bid int `bson:"Bid"` // 买价
  65. BV int `bson:"BV"` // 买量
  66. Ask int `bson:"Ask"` // 卖价
  67. AV int `bson:"AV"` // 卖量
  68. HV int `bson:"HV"` // 持仓量
  69. HI int `bson:"HI"` // 单笔持仓
  70. TDR int `bson:"TDR"` // 交易方向
  71. TK int `bson:"TK"` // 交易类型
  72. OId int `bson:"OId"` // 行情序号
  73. }
  74. // Quoteday 行情盘面
  75. type Quoteday struct {
  76. Id int64 `xorm:"pk autoincr BIGINT(20)"`
  77. Exchangedate int64 `xorm:"not null BIGINT(20)"` // 交易日
  78. Goodscode string `xorm:"not null unique CHAR(10)"` // 商品代码
  79. Exchangecode int `xorm:"INT(11)"` // 交易所代码
  80. Preclose int64 `xorm:"default 0 BIGINT(20)"` // 昨收
  81. Opentime int64 `xorm:"BIGINT(20)"` // 开盘时间
  82. Opened int64 `xorm:"not null default 0 BIGINT(20)"` // 开盘价
  83. Highest int64 `xorm:"not null default 0 BIGINT(20)"` // 最高价
  84. Lowest int64 `xorm:"not null default 0 BIGINT(20)"` // 最低价
  85. Lasttime string `xorm:"VARCHAR(20)"` // 行情时间(只有现价变化行情时间才变化)
  86. Utclasttime int64 `xorm:"not null BIGINT(20)"` // utc的行情时间
  87. Last int64 `xorm:"not null BIGINT(20)"` // 最新价
  88. Lastvolume int64 `xorm:"default 0 BIGINT(20)"` // 最新成交量
  89. Lastturnover int64 `xorm:"default 0 BIGINT(20)"` // 最新成交金额
  90. Totalbidvolume int64 `xorm:"default 0 BIGINT(20)"` // 外盘
  91. Totalaskvolume int64 `xorm:"default 0 BIGINT(20)"` // 内盘
  92. Totalvolume int64 `xorm:"default 0 BIGINT(20)"` // 总量
  93. Totalturnover int64 `xorm:"default 0 BIGINT(20)"` // 总金额
  94. Bid int64 `xorm:"default 0 BIGINT(20)"` // 买1
  95. Bid2 int64 `xorm:"default 0 BIGINT(20)"` // 买2
  96. Bid3 int64 `xorm:"default 0 BIGINT(20)"` // 买3
  97. Bid4 int64 `xorm:"default 0 BIGINT(20)"` // 买4
  98. Bid5 int64 `xorm:"default 0 BIGINT(20)"` // 买5
  99. Bidvolume int64 `xorm:"default 0 BIGINT(20)"` // 买量1
  100. Bidvolume2 int64 `xorm:"default 0 BIGINT(20)"` // 买量2
  101. Bidvolume3 int64 `xorm:"default 0 BIGINT(20)"` // 买量3
  102. Bidvolume4 int64 `xorm:"default 0 BIGINT(20)"` // 买量4
  103. Bidvolume5 int64 `xorm:"default 0 BIGINT(20)"` // 买量5
  104. Ask int64 `xorm:"default 0 BIGINT(20)"` // 卖1
  105. Ask2 int64 `xorm:"default 0 BIGINT(20)"` // 卖2
  106. Ask3 int64 `xorm:"default 0 BIGINT(20)"` // 卖3
  107. Ask4 int64 `xorm:"default 0 BIGINT(20)"` // 卖4
  108. Ask5 int64 `xorm:"default 0 BIGINT(20)"` // 卖5
  109. Askvolume int64 `xorm:"default 0 BIGINT(20)"` // 卖量1
  110. Askvolume2 int64 `xorm:"default 0 BIGINT(20)"` // 卖量2
  111. Askvolume3 int64 `xorm:"default 0 BIGINT(20)"` // 卖量3
  112. Askvolume4 int64 `xorm:"default 0 BIGINT(20)"` // 卖量4
  113. Askvolume5 int64 `xorm:"default 0 BIGINT(20)"` // 卖量5
  114. Presettle int64 `xorm:"default 0 BIGINT(20)"` // 昨结价
  115. Settle int64 `xorm:"default 0 BIGINT(20)"` // 结算价
  116. Preholdvolume int64 `xorm:"default 0 BIGINT(20)"` // 昨持仓
  117. Holdvolume int64 `xorm:"default 0 BIGINT(20)"` // 持仓
  118. Averageprice int64 `xorm:"default 0 BIGINT(20)"` // 均价
  119. Orderid int64 `xorm:"default 0 BIGINT(20)"` // 序号
  120. Limitup int64 `xorm:"default 0 BIGINT(20)"` // 涨停价
  121. Limitdown int64 `xorm:"default 0 BIGINT(20)"` // 跌停价
  122. Inventory int64 `xorm:"default 0 BIGINT(20)"` // 库存
  123. Holdincrement int64 `xorm:"default 0 BIGINT(20)"` // 单笔持仓
  124. Iscleared int `xorm:"INT(11)"` // 是否清盘标志
  125. Issettled int `xorm:"INT(11)"` // 是否结算标志
  126. Bidqueueinfo string `xorm:"VARCHAR(2000)"` // 大利市买港股用
  127. Askqueueinfo string `xorm:"VARCHAR(2000)"` // 大利市卖港股用
  128. Bidorderid int64 `xorm:"BIGINT(20)"` // 买单号1
  129. Bidorderid2 int64 `xorm:"BIGINT(20)"` // 买单号2
  130. Bidorderid3 int64 `xorm:"BIGINT(20)"` // 买单号3
  131. Bidorderid4 int64 `xorm:"BIGINT(20)"` // 买单号4
  132. Bidorderid5 int64 `xorm:"BIGINT(20)"` // 买单号5
  133. Askorderid int64 `xorm:"BIGINT(20)"` // 卖单号1
  134. Askorderid2 int64 `xorm:"BIGINT(20)"` // 卖单号2
  135. Askorderid3 int64 `xorm:"BIGINT(20)"` // 卖单号3
  136. Askorderid4 int64 `xorm:"BIGINT(20)"` // 卖单号4
  137. Askorderid5 int64 `xorm:"BIGINT(20)"` // 卖单号5
  138. Lastlot int64 `xorm:"BIGINT(20)"` // 最新成交手数
  139. Totallot int64 `xorm:"BIGINT(20)"` // 总手数
  140. Strikeprice int64 `xorm:"BIGINT(20)"` // 发行价
  141. Cleartime int64 `xorm:"BIGINT(20)"` // 清盘时间
  142. Calloptionpremiums int64 `xorm:"default 0 BIGINT(20)"` // 认购期权1
  143. Calloptionpremiums2 int64 `xorm:"default 0 BIGINT(20)"` // 认购期权2
  144. Calloptionpremiums3 int64 `xorm:"default 0 BIGINT(20)"` // 认购期权3
  145. Calloptionpremiums4 int64 `xorm:"default 0 BIGINT(20)"` // 认购期权4
  146. Calloptionpremiums5 int64 `xorm:"default 0 BIGINT(20)"` // 认购期权5
  147. Putoptionpremiums int64 `xorm:"default 0 BIGINT(20)"` // 认沽期权1
  148. Putoptionpremiums2 int64 `xorm:"default 0 BIGINT(20)"` // 认沽期权2
  149. Putoptionpremiums3 int64 `xorm:"default 0 BIGINT(20)"` // 认沽期权3
  150. Putoptionpremiums4 int64 `xorm:"default 0 BIGINT(20)"` // 认沽期权4
  151. Putoptionpremiums5 int64 `xorm:"default 0 BIGINT(20)"` // 认沽期权5
  152. Nontotalvolume int64 `xorm:"default 0 BIGINT(20)"` // 非交易总量
  153. Nontotalholdervolume int64 `xorm:"default 0 BIGINT(20)"` // 非交易持仓量
  154. Nontotalturnover int64 `xorm:"default 0 BIGINT(20)"` // 非交易总金额
  155. Nontotallot int64 `xorm:"default 0 BIGINT(20)"` // 非交易总手数
  156. Publictradetype string `xorm:"VARCHAR(2)"` // 公共交易标志类型 港股专用
  157. Iep int64 `xorm:"default 0 BIGINT(20)"` // 平衡价 港股专用
  158. Iev int64 `xorm:"default 0 BIGINT(20)"` // 平衡量 港股专用
  159. Grepmarketprice int64 `xorm:"default 0 BIGINT(20)"` // 暗盘价 港股专用
  160. Bid6 int64 `xorm:"default 0 BIGINT(20)"` // 买6
  161. Bid7 int64 `xorm:"default 0 BIGINT(20)"` // 买7
  162. Bid8 int64 `xorm:"default 0 BIGINT(20)"` // 买8
  163. Bid9 int64 `xorm:"default 0 BIGINT(20)"` // 买9
  164. Bid10 int64 `xorm:"default 0 BIGINT(20)"` // 买10
  165. Bidvolume6 int64 `xorm:"default 0 BIGINT(20)"` // 买量6
  166. Bidvolume7 int64 `xorm:"default 0 BIGINT(20)"` // 买量7
  167. Bidvolume8 int64 `xorm:"default 0 BIGINT(20)"` // 买量8
  168. Bidvolume9 int64 `xorm:"default 0 BIGINT(20)"` // 买量9
  169. Bidvolume10 int64 `xorm:"default 0 BIGINT(20)"` // 买量10
  170. Ask6 int64 `xorm:"default 0 BIGINT(20)"` // 卖6
  171. Ask7 int64 `xorm:"default 0 BIGINT(20)"` // 卖7
  172. Ask8 int64 `xorm:"default 0 BIGINT(20)"` // 卖8
  173. Ask9 int64 `xorm:"default 0 BIGINT(20)"` // 卖9
  174. Ask10 int64 `xorm:"default 0 BIGINT(20)"` // 卖10
  175. Askvolume6 int64 `xorm:"default 0 BIGINT(20)"` // 卖量6
  176. Askvolume7 int64 `xorm:"default 0 BIGINT(20)"` // 卖量7
  177. Askvolume8 int64 `xorm:"default 0 BIGINT(20)"` // 卖量8
  178. Askvolume9 int64 `xorm:"default 0 BIGINT(20)"` // 卖量9
  179. Askvolume10 int64 `xorm:"default 0 BIGINT(20)"` // 卖量10
  180. Bidordervolume int64 `xorm:"default 0 BIGINT(20)"` // 买单量1
  181. Bidordervolume2 int64 `xorm:"default 0 BIGINT(20)"` // 买单量2
  182. Bidordervolume3 int64 `xorm:"default 0 BIGINT(20)"` // 买单量3
  183. Bidordervolume4 int64 `xorm:"default 0 BIGINT(20)"` // 买单量4
  184. Bidordervolume5 int64 `xorm:"default 0 BIGINT(20)"` // 买单量5
  185. Bidordervolume6 int64 `xorm:"default 0 BIGINT(20)"` // 买单量6
  186. Bidordervolume7 int64 `xorm:"default 0 BIGINT(20)"` // 买单量7
  187. Bidordervolume8 int64 `xorm:"default 0 BIGINT(20)"` // 买单量8
  188. Bidordervolume9 int64 `xorm:"default 0 BIGINT(20)"` // 买单量9
  189. Bidordervolume10 int64 `xorm:"default 0 BIGINT(20)"` // 买单量10
  190. Askordervolume int64 `xorm:"default 0 BIGINT(20)"` // 卖单量1
  191. Askordervolume2 int64 `xorm:"default 0 BIGINT(20)"` // 卖单量2
  192. Askordervolume3 int64 `xorm:"default 0 BIGINT(20)"` // 卖单量3
  193. Askordervolume4 int64 `xorm:"default 0 BIGINT(20)"` // 卖单量4
  194. Askordervolume5 int64 `xorm:"default 0 BIGINT(20)"` // 卖单量5
  195. Askordervolume6 int64 `xorm:"default 0 BIGINT(20)"` // 卖单量6
  196. Askordervolume7 int64 `xorm:"default 0 BIGINT(20)"` // 卖单量7
  197. Askordervolume8 int64 `xorm:"default 0 BIGINT(20)"` // 卖单量8
  198. Askordervolume9 int64 `xorm:"default 0 BIGINT(20)"` // 卖单量9
  199. Askordervolume10 int64 `xorm:"default 0 BIGINT(20)"` // 卖单量10
  200. }
  201. // TableName is Quoteday
  202. func (*Quoteday) TableName() string {
  203. return "quoteday"
  204. }
  205. // GetHistoryCycleDatas 获取历史数据
  206. // 参数 cycleType CycleType 周期类型
  207. // 参数 goodsCode string 商品代码
  208. // 参数 startTime time.Time 开始时间(闭区间)
  209. // 参数 endTime time.Time 结束时间(闭区间)
  210. // 参数 count int 条数
  211. // 参数 isAscForST bool 是否按时间顺序排序,默认为时间倒序排序
  212. // 返回值 []CycleData 历史数据
  213. // 返回值 error 错误
  214. func GetHistoryCycleDatas(cycleType CycleType, goodsCode string, startTime, endTime *time.Time, count int, isAscForST bool) ([]CycleData, error) {
  215. db := db.GetMongoDB()
  216. // 获取目标Collection
  217. collection := "mincycle"
  218. switch cycleType {
  219. case CycleTypeTik:
  220. collection = "quotetik"
  221. case CycleTypeMinutes1:
  222. collection = "mincycle"
  223. case CycleTypeMinutes5:
  224. collection = "min5cycle"
  225. case CycleTypeMinutes30:
  226. collection = "min30cycle"
  227. case CycleTypeMinutes60:
  228. collection = "min60cycle"
  229. case CycleTypeMinutes240:
  230. collection = "min240cycle"
  231. case CycleTypeMinutesDay:
  232. collection = "daycycle"
  233. case CycleTypeWeek:
  234. collection = "weekcycle"
  235. case CycleTypeMonth:
  236. collection = "monthcycle"
  237. case CycleTypeYear:
  238. collection = "yearcycle"
  239. default:
  240. return nil, errors.New("不支持的周期类型")
  241. }
  242. c := db.C(collection)
  243. // 按时间排序
  244. sort := "-ST"
  245. if isAscForST {
  246. sort = "ST"
  247. }
  248. // 查询数据
  249. var cycleDatas []CycleData
  250. m := bson.M{"GC": goodsCode}
  251. if startTime != nil && endTime == nil {
  252. m["ST"] = bson.M{"$gte": startTime.Unix()}
  253. } else if startTime == nil && endTime != nil {
  254. m["ST"] = bson.M{"$lte": endTime.Unix()}
  255. } else if startTime != nil && endTime != nil {
  256. m["ST"] = bson.M{"$gte": startTime.Unix(), "$lte": endTime.Unix()}
  257. }
  258. query := c.Find(m)
  259. if count > 0 {
  260. query = query.Limit(count)
  261. }
  262. if err := query.Sort(sort).All(&cycleDatas); err != nil {
  263. return nil, err
  264. }
  265. return cycleDatas, nil
  266. }
  267. // GetHistoryTikDatas 获取历史数据
  268. // 参数 goodsCode string 商品代码
  269. // 参数 startTime time.Time 开始时间(闭区间)
  270. // 参数 endTime time.Time 结束时间(闭区间)
  271. // 参数 count int 条数
  272. // 参数 isAscForST bool 是否按时间顺序排序,默认为时间倒序排序
  273. // 返回值 []TikData Tik数据
  274. // 返回值 error 错误
  275. func GetHistoryTikDatas(goodsCode string, startTime, endTime *time.Time, count int, isAscForST bool) ([]TikData, error) {
  276. db := db.GetMongoDB()
  277. // 获取目标Collection
  278. collection := "quotetik"
  279. c := db.C(collection)
  280. // 按时间排序
  281. sort := "-AT"
  282. if isAscForST {
  283. sort = "AT"
  284. }
  285. // 查询数据
  286. var tikDatas []TikData
  287. m := bson.M{"GC": goodsCode}
  288. if startTime != nil && endTime == nil {
  289. m["AT"] = bson.M{"$gte": startTime.Unix()}
  290. } else if startTime == nil && endTime != nil {
  291. m["AT"] = bson.M{"$lte": endTime.Unix()}
  292. } else if startTime != nil && endTime != nil {
  293. m["AT"] = bson.M{"$gte": startTime.Unix(), "$lte": endTime.Unix()}
  294. }
  295. query := c.Find(m)
  296. if count > 0 {
  297. query = query.Limit(count)
  298. }
  299. if err := query.Sort(sort).All(&tikDatas); err != nil {
  300. return nil, err
  301. }
  302. return tikDatas, nil
  303. }
  304. // GetQuoteDays 获取目标商品的盘面数据
  305. // 参数 goodsCodes string 商品代码字串,以“,”分隔
  306. // 返回 []Quoteday 盘面数据
  307. // 返回 error error
  308. func GetQuoteDays(goodsCodes string) ([]Quoteday, error) {
  309. engine := db.GetMySQLEngine()
  310. datas := make([]Quoteday, 0)
  311. if len(goodsCodes) > 0 {
  312. // 指定商品代码查询
  313. // 处理商品代码, 让其可作为sql的in条件内容。 例如, 原字符串 ru2201,CU2406, => 处理成 'ru2201','CU2406'
  314. goodsCodes = strings.Trim(goodsCodes, ",")
  315. sCode := strings.Split(goodsCodes, ",")
  316. for i := range sCode {
  317. sCode[i] = "'" + sCode[i] + "'"
  318. }
  319. Instr := strings.Join(sCode, ",")
  320. if err := engine.Where(fmt.Sprintf("goodscode in (%s)", Instr)).Find(&datas); err != nil {
  321. return nil, err
  322. }
  323. } else {
  324. // 不指定则查所有
  325. if err := engine.Find(&datas); err != nil {
  326. return nil, err
  327. }
  328. }
  329. return datas, nil
  330. }