trade_position_analysis.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. package data_manage
  2. import (
  3. sql2 "database/sql"
  4. "eta/eta_task/global"
  5. "eta/eta_task/utils"
  6. "fmt"
  7. "gorm.io/gorm"
  8. "time"
  9. "unsafe"
  10. )
  11. // 持仓榜单表
  12. type TradePositionTop struct {
  13. Id uint64 `orm:"column(id);pk" gorm:"primaryKey"`
  14. ClassifyName string //分类名称
  15. ClassifyType string //分类名称下的类型
  16. DataTime string //数据日期
  17. CreateTime time.Time //插入时间
  18. ModifyTime time.Time //修改时间
  19. DealShortName string //成交量公司简称
  20. DealValue int //成交量
  21. DealChange int //成交变化量
  22. DealType int //交易类型:1多单,2空单,3净多单,4净空单
  23. SourceType int //数据来源,0是原始数据的值,1是由T+1日推算出的值,2是由T日的榜单数据推算出的值
  24. Rank int //排名
  25. }
  26. func (m *TradePositionTop) AfterFind(db *gorm.DB) (err error) {
  27. m.DataTime = utils.GormDateStrToDateStr(m.DataTime)
  28. return
  29. }
  30. func (m *TradePositionTop) ConvertTimeStr() {
  31. m.DataTime = utils.GormDateStrToDateStr(m.DataTime)
  32. return
  33. }
  34. type TradePositionDalianTop struct {
  35. TradePositionTop
  36. }
  37. type TradePositionZhengzhouTop struct {
  38. TradePositionTop
  39. }
  40. type TradePositionCffexTop struct {
  41. TradePositionTop
  42. }
  43. type TradePositionShanghaiTop struct {
  44. TradePositionTop
  45. }
  46. type TradePositionIneTop struct {
  47. TradePositionTop
  48. }
  49. type TradePositionGuangzhouTop struct {
  50. TradePositionTop
  51. }
  52. func InsertMultiTradePositionTop(exchange string, items []*TradePositionTop) (err error) {
  53. o := global.DbMap[utils.DbNameIndex]
  54. if exchange == "dalian" {
  55. list := make([]*TradePositionDalianTop, 0)
  56. for _, v := range items {
  57. tmp := (*TradePositionDalianTop)(unsafe.Pointer(v))
  58. list = append(list, tmp)
  59. }
  60. err = o.CreateInBatches(list, utils.MultiAddNum).Error
  61. return
  62. } else if exchange == "zhengzhou" {
  63. list := make([]*TradePositionZhengzhouTop, 0)
  64. for _, v := range items {
  65. tmp := (*TradePositionZhengzhouTop)(unsafe.Pointer(v))
  66. list = append(list, tmp)
  67. }
  68. err = o.CreateInBatches(list, utils.MultiAddNum).Error
  69. return
  70. } else if exchange == "cffex" {
  71. list := make([]*TradePositionCffexTop, 0)
  72. for _, v := range items {
  73. tmp := (*TradePositionCffexTop)(unsafe.Pointer(v))
  74. list = append(list, tmp)
  75. }
  76. err = o.CreateInBatches(list, utils.MultiAddNum).Error
  77. return
  78. } else if exchange == "shanghai" {
  79. list := make([]*TradePositionShanghaiTop, 0)
  80. for _, v := range items {
  81. tmp := (*TradePositionShanghaiTop)(unsafe.Pointer(v))
  82. list = append(list, tmp)
  83. }
  84. err = o.CreateInBatches(list, utils.MultiAddNum).Error
  85. return
  86. } else if exchange == "ine" {
  87. list := make([]*TradePositionIneTop, 0)
  88. for _, v := range items {
  89. tmp := (*TradePositionIneTop)(unsafe.Pointer(v))
  90. list = append(list, tmp)
  91. }
  92. err = o.CreateInBatches(list, utils.MultiAddNum).Error
  93. return
  94. } else if exchange == "guangzhou" {
  95. list := make([]*TradePositionGuangzhouTop, 0)
  96. for _, v := range items {
  97. tmp := (*TradePositionGuangzhouTop)(unsafe.Pointer(v))
  98. list = append(list, tmp)
  99. }
  100. err = o.CreateInBatches(list, utils.MultiAddNum).Error
  101. return
  102. }
  103. return
  104. }
  105. func GetTradePositionTopByExchangeDataTime(exchange string, startDate, endDate string) (list []*TradePositionTop, err error) {
  106. o := global.DbMap[utils.DbNameIndex]
  107. sql := "SELECT * FROM trade_position_" + exchange + "_top where data_time >= ? and data_time <= ? and deal_type in (1,2) ORDER BY classify_name, classify_type, deal_type, data_time, deal_value desc"
  108. err = o.Raw(sql, startDate, endDate).Find(&list).Error
  109. return
  110. }
  111. func GetTradePositionTopByExchangeDataTimeByClassify(exchange string, startDate, endDate string, classifyNames, classifyTypes []string) (list []*TradePositionTop, err error) {
  112. o := global.DbMap[utils.DbNameIndex]
  113. sql := `SELECT * FROM trade_position_` + exchange + `_top where data_time >= ? and data_time <= ? and deal_type in (1,2) and classify_name in (` + utils.GetOrmInReplace(len(classifyNames)) + `) and classify_type in (` + utils.GetOrmInReplace(len(classifyTypes)) + `) ORDER BY classify_name, classify_type, deal_type, data_time, deal_value desc`
  114. err = o.Raw(sql, startDate, endDate, classifyNames, classifyTypes).Find(&list).Error
  115. return
  116. }
  117. func GetTradePositionTopCountByExchangeDataTime(exchange string, startDate, endDate string) (count int64, err error) {
  118. o := global.DbMap[utils.DbNameIndex]
  119. sql := "SELECT count(*) FROM trade_position_" + exchange + "_top where data_time >= ? and data_time <= ? and deal_type in (1,2) ORDER BY classify_name, classify_type, deal_type, data_time, deal_value desc"
  120. err = o.Raw(sql, startDate, endDate).Scan(&count).Error
  121. return
  122. }
  123. func GetTradePositionTopByExchangeSourceType(exchange string, dataTime string, sourceType int) (list []*TradePositionTop, err error) {
  124. o := global.DbMap[utils.DbNameIndex]
  125. sql := "SELECT * FROM trade_position_" + exchange + "_top where data_time= ? and source_type = ? ORDER BY classify_name, classify_type, deal_type, deal_value desc"
  126. err = o.Raw(sql, dataTime, sourceType).Find(&list).Error
  127. return
  128. }
  129. func GetTradePositionTopByExchangeSourceTypeClassify(exchange string, dataTime string, sourceType int, classifyNames, classifyTypes []string) (list []*TradePositionTop, err error) {
  130. o := global.DbMap[utils.DbNameIndex]
  131. sql := `SELECT * FROM trade_position_` + exchange + `_top where data_time= ? and source_type = ? and classify_name in (` + utils.GetOrmInReplace(len(classifyNames)) + `) and classify_type in (` + utils.GetOrmInReplace(len(classifyTypes)) + `) ORDER BY classify_name, classify_type, deal_type, deal_value desc`
  132. err = o.Raw(sql, dataTime, sourceType, classifyNames, classifyTypes).Find(&list).Error
  133. return
  134. }
  135. type TradeTopClassify struct {
  136. ClassifyName string //分类名称
  137. ClassifyType string //分类名称下的类型
  138. }
  139. type TradePositionSub struct {
  140. ClassifyName string //分类名称
  141. ClassifyType string //分类名称下的类型
  142. DataTime string //数据日期
  143. DealShortName string //成交量公司简称
  144. SubValue int //差值
  145. DealType int
  146. }
  147. type TradePositionSubList []*TradePositionSub
  148. func (v TradePositionSubList) Len() int {
  149. return len(v)
  150. }
  151. func (v TradePositionSubList) Swap(i, j int) {
  152. v[i], v[j] = v[j], v[i]
  153. }
  154. func (v TradePositionSubList) Less(i, j int) bool {
  155. return v[i].SubValue > v[j].SubValue
  156. }
  157. type UpdateDealValueChange struct {
  158. Id uint64
  159. DealValue int //成交量
  160. DealChange int
  161. SourceType int
  162. ModifyTime time.Time //修改时间
  163. }
  164. type UpdateChangeVal struct {
  165. Id uint64
  166. DealChange int
  167. ModifyTime time.Time //修改时间
  168. }
  169. func MultiUpdatePositionTop(exchange string, updates []UpdateDealValueChange) (err error) {
  170. o := global.DbMap[utils.DbNameIndex]
  171. sql := "UPDATE trade_position_" + exchange + "_top SET deal_value=?, deal_change=?, source_type=?, modify_time=? WHERE id = ?"
  172. for _, v := range updates {
  173. err = o.Exec(sql, v.DealValue, v.DealChange, v.SourceType, v.ModifyTime, v.Id).Error
  174. if err != nil {
  175. return
  176. }
  177. }
  178. return
  179. }
  180. func DeletePositionTopByDataTime(exchange string, dataTime string, dealType int) (err error) {
  181. o := global.DbMap[utils.DbNameIndex]
  182. sql := "delete from trade_position_" + exchange + "_top WHERE data_time=? and deal_type=?"
  183. err = o.Exec(sql, dataTime, dealType).Error
  184. return
  185. }
  186. func DeletePositionTopByDataTimeClassify(exchange string, dataTime string, dealType int, classifyNames, classifyTypes []string) (err error) {
  187. o := global.DbMap[utils.DbNameIndex]
  188. sql := `delete from trade_position_` + exchange + `_top WHERE data_time=? and deal_type=? and classify_name in (` + utils.GetOrmInReplace(len(classifyNames)) + `) and classify_type in (` + utils.GetOrmInReplace(len(classifyTypes)) + `)`
  189. err = o.Exec(sql, dataTime, dealType, classifyNames, classifyTypes).Error
  190. return
  191. }
  192. func GetTradePositionTopByExchangeDataTimeType(exchange string, dataTime string, dealType int) (list []*TradePositionTop, err error) {
  193. o := global.DbMap[utils.DbNameIndex]
  194. sql := "select * from trade_position_" + exchange + "_top WHERE data_time=? and deal_type=?"
  195. err = o.Raw(sql, dataTime, dealType).Find(&list).Error
  196. return
  197. }
  198. func GetTradePositionTopByExchangeDataTimeTypeClassify(exchange string, dataTime string, dealType int, classifyNames, classifyTypes []string) (list []*TradePositionTop, err error) {
  199. o := global.DbMap[utils.DbNameIndex]
  200. sql := `select * from trade_position_` + exchange + `_top WHERE data_time=? and deal_type=? and classify_name in (` + utils.GetOrmInReplace(len(classifyNames)) + `) and classify_type in (` + utils.GetOrmInReplace(len(classifyTypes)) + `)`
  201. err = o.Raw(sql, dataTime, dealType, classifyNames, classifyTypes).Find(&list).Error
  202. return
  203. }
  204. func MultiInsertTradeBaseDataToTop(exchange string, startDate, endDate string) (err error) {
  205. o := global.DbMap[utils.DbNameIndex]
  206. now := time.Now().Format(utils.FormatDateTime)
  207. sql1 := "INSERT INTO trade_position_" + exchange + "_top(classify_name,classify_type,deal_short_name,deal_value,deal_change,data_time,deal_type,source_type,rank,create_time,modify_time) " +
  208. "SELECT classify_name,classify_type,buy_short_name,buy_value,buy_change,data_time,1,0,rank,?,? FROM base_from_trade_" + exchange + "_index where rank <50 and buy_short_name !='' and buy_short_name !=' ' and data_time between ? and ?"
  209. err = o.Exec(sql1, now, now, startDate, endDate).Error
  210. if err != nil {
  211. return
  212. }
  213. sql2 := "INSERT INTO trade_position_" + exchange + "_top(classify_name,classify_type,deal_short_name,deal_value,deal_change,data_time,deal_type,source_type,rank,create_time,modify_time) " +
  214. "SELECT classify_name,classify_type,sold_short_name,sold_value,sold_change,data_time,2,0,rank,?,? FROM base_from_trade_" + exchange + "_index where rank <50 and sold_short_name !='' and sold_short_name !=' ' and data_time between ? and ?"
  215. err = o.Exec(sql2, now, now, startDate, endDate).Error
  216. return
  217. }
  218. func MultiInsertTradeBaseDataToTopByClassify(exchange string, startDate, endDate string, classifyNames, classifyTypes []string) (err error) {
  219. o := global.DbMap[utils.DbNameIndex]
  220. now := time.Now().Format(utils.FormatDateTime)
  221. sql1 := "INSERT INTO trade_position_" + exchange + "_top(classify_name,classify_type,deal_short_name,deal_value,deal_change,data_time,deal_type,source_type,rank,create_time,modify_time)" +
  222. "SELECT classify_name,classify_type,buy_short_name,buy_value,buy_change,data_time,1,0,rank,?,? FROM base_from_trade_" + exchange + "_index where rank <50 and buy_short_name !='' and buy_short_name !=' ' and data_time between ? and ? and classify_name in (" + utils.GetOrmInReplace(len(classifyNames)) + ") and classify_type in (" + utils.GetOrmInReplace(len(classifyTypes)) + ")"
  223. err = o.Exec(sql1, now, now, startDate, endDate, classifyNames, classifyTypes).Error
  224. if err != nil {
  225. return
  226. }
  227. sql2 := "INSERT INTO trade_position_" + exchange + "_top(classify_name,classify_type,deal_short_name,deal_value,deal_change,data_time,deal_type,source_type,rank,create_time,modify_time)" +
  228. "SELECT classify_name,classify_type,sold_short_name,sold_value,sold_change,data_time,2,0,rank,?,? FROM base_from_trade_" + exchange + "_index where rank <50 and sold_short_name !='' and sold_short_name !=' ' and data_time between ? and ? and classify_name in (" + utils.GetOrmInReplace(len(classifyNames)) + ") and classify_type in (" + utils.GetOrmInReplace(len(classifyTypes)) + ")"
  229. err = o.Exec(sql2, now, now, startDate, endDate, classifyNames, classifyTypes).Error
  230. return
  231. }
  232. // GetTradePositionTopOriginDataTimes 获取榜单原始数据日期-正序
  233. func GetTradePositionTopOriginDataTimes(exchange string) (dates []string, err error) {
  234. o := global.DbMap[utils.DbNameIndex]
  235. sql := `SELECT DISTINCT data_time FROM base_from_trade_%s_index ORDER BY data_time ASC`
  236. sql = fmt.Sprintf(sql, exchange)
  237. var originDates []string
  238. err = o.Raw(sql).Scan(&originDates).Error
  239. if err != nil {
  240. return
  241. }
  242. for _, v := range originDates {
  243. if v == "" {
  244. continue
  245. }
  246. v = utils.GormDateStrToDateStr(v)
  247. dates = append(dates, v)
  248. }
  249. return
  250. }
  251. // BaseFromTradeClassify 交易所分类表
  252. type BaseFromTradeClassify struct {
  253. Id uint64 `orm:"column(id);pk" gorm:"primaryKey"`
  254. ClassifyName string //分类名称
  255. ClassifyType string //分类名称下的类型
  256. Exchange string //交易所
  257. LatestDate time.Time //数据最近的日期
  258. CreateTime time.Time //插入时间
  259. ModifyTime time.Time //修改时间
  260. }
  261. // GetAllBaseFromTradeClassify 获取所有的交易所分类列表
  262. func GetAllBaseFromTradeClassify() (list []*BaseFromTradeClassify, err error) {
  263. sql := `SELECT * FROM base_from_trade_classify `
  264. o := global.DbMap[utils.DbNameIndex]
  265. err = o.Raw(sql).Find(&list).Error
  266. return
  267. }
  268. // Update 更新
  269. func (m *BaseFromTradeClassify) Update(cols []string) (err error) {
  270. o := global.DbMap[utils.DbNameIndex]
  271. err = o.Select(cols).Updates(m).Error
  272. return
  273. }
  274. // MultiAddBaseFromTradeClassify 批量插入交易所分类
  275. func MultiAddBaseFromTradeClassify(items []*BaseFromTradeClassify) (err error) {
  276. if len(items) == 0 {
  277. return
  278. }
  279. o := global.DbMap[utils.DbNameIndex]
  280. err = o.CreateInBatches(items, utils.MultiAddNum).Error
  281. return
  282. }
  283. type TradeClassifyName struct {
  284. ClassifyName string //分类名称
  285. ClassifyType string //分类名称下的类型
  286. DataTime time.Time //数据最近的日期
  287. ModifyTime time.Time //数据最近的日期
  288. }
  289. // GetExchangeClassify 获取交易所分类列表
  290. func GetExchangeClassify(exchange string) (list []TradeClassifyName, err error) {
  291. tableName := "trade_position_" + exchange + "_top"
  292. orderStr := "classify_name DESC, classify_type asc"
  293. if exchange == "zhengzhou" {
  294. orderStr = "classify_name asc"
  295. }
  296. sql := `SELECT classify_name, classify_type,MAX(data_time) as data_time,MAX(modify_time) as modify_time FROM ` + tableName + ` GROUP BY classify_name, classify_type `
  297. sql += ` ORDER BY ` + orderStr
  298. o := global.DbMap[utils.DbNameIndex]
  299. err = o.Raw(sql).Find(&list).Error
  300. return
  301. }
  302. // GetTradePositionTopCleanByExchangeDataTime 根据时间查询净多单和净空单的值
  303. func GetTradePositionTopCleanByExchangeDataTime(exchange string, startDate, endDate string) (list []*TradePositionTop, err error) {
  304. o := global.DbMap[utils.DbNameIndex]
  305. sql := "SELECT * FROM trade_position_" + exchange + "_top where data_time >= ? and data_time <= ? and deal_type in (3,4) ORDER BY classify_name, classify_type, deal_type, data_time, deal_value desc"
  306. err = o.Raw(sql, startDate, endDate).Find(&list).Error
  307. return
  308. }
  309. // GetTradePositionTopCleanByExchangeDataTimeClassify 根据时间查询净多单和净空单的值
  310. func GetTradePositionTopCleanByExchangeDataTimeClassify(exchange string, startDate, endDate string, classifyNames, classifyTypes []string) (list []*TradePositionTop, err error) {
  311. o := global.DbMap[utils.DbNameIndex]
  312. sql := `SELECT * FROM trade_position_` + exchange + `_top where data_time >= ? and data_time <= ? and deal_type in (3,4) and classify_name in (` + utils.GetOrmInReplace(len(classifyNames)) + `) and classify_type in (` + utils.GetOrmInReplace(len(classifyTypes)) + `) ORDER BY classify_name, classify_type, deal_type, data_time, deal_value desc`
  313. err = o.Raw(sql, startDate, endDate, classifyNames, classifyTypes).Find(&list).Error
  314. return
  315. }
  316. // MultiUpdatePositionTopChangeVal 批量更新榜单里变化量的值
  317. func MultiUpdatePositionTopChangeVal(exchange string, updates []UpdateChangeVal) (err error) {
  318. o := global.DbMap[utils.DbNameIndex]
  319. sql := "UPDATE trade_position_" + exchange + "_top SET deal_change=?, modify_time=? WHERE id = ?"
  320. for _, v := range updates {
  321. err = o.Exec(sql, v.DealChange, v.ModifyTime, v.Id).Error
  322. if err != nil {
  323. return
  324. }
  325. }
  326. return
  327. }
  328. func GetTradePositionOriginClassifyCountByExchangeDataTime(exchange string, startDate, endDate string) (count int64, err error) {
  329. o := global.DbMap[utils.DbNameIndex]
  330. var pars []interface{}
  331. var sql string
  332. if utils.DbDriverName == utils.DbDriverByDm {
  333. // DM不支持COUNT(DISTINCT column1, column2)这种写法
  334. sql = `SELECT COUNT(*)
  335. FROM (
  336. SELECT DISTINCT classify_name, classify_type
  337. FROM base_from_trade_ine_index
  338. WHERE rank < 50
  339. AND (buy_short_name != '' OR sold_short_name != '')
  340. AND (buy_short_name != ' ' OR sold_short_name != ' ')
  341. AND data_time >= ?
  342. AND data_time <= ?
  343. )`
  344. pars = append(pars, startDate, endDate)
  345. } else {
  346. sql = "SELECT COUNT(DISTINCT classify_name, classify_type) FROM base_from_trade_" + exchange + "_index where rank <50 and (buy_short_name !='' or sold_short_name !='' ) and (buy_short_name !=' ' or sold_short_name !=' ' ) and data_time >= ? and data_time <= ?"
  347. pars = append(pars, startDate, endDate)
  348. }
  349. err = o.Raw(sql, pars...).Scan(&count).Error
  350. return
  351. }
  352. func GetTradePositionTopClassifyCountByExchangeDataTime(exchange string, startDate, endDate string) (count int64, err error) {
  353. o := global.DbMap[utils.DbNameIndex]
  354. var pars []interface{}
  355. var sql string
  356. if utils.DbDriverName == utils.DbDriverByDm {
  357. sql = `SELECT COUNT(*)
  358. FROM (
  359. SELECT DISTINCT classify_name, classify_type
  360. FROM trade_position_ine_top
  361. WHERE data_time >= ?
  362. AND data_time <= ?
  363. AND deal_type IN (1, 2)
  364. )`
  365. pars = append(pars, startDate, endDate)
  366. } else {
  367. sql = "SELECT COUNT(DISTINCT classify_name, classify_type) FROM trade_position_" + exchange + "_top where data_time >= ? and data_time <= ? and deal_type in (1,2) "
  368. pars = append(pars, startDate, endDate)
  369. }
  370. err = o.Raw(sql, pars...).Scan(&count).Error
  371. return
  372. }
  373. type TradePositionClassifyInfo struct {
  374. ClassifyName string //分类名称
  375. ClassifyType string //分类名称下的类型
  376. }
  377. func GetTradePositionOriginClassifyByExchangeDataTime(exchange string, startDate, endDate string) (list []TradePositionClassifyInfo, err error) {
  378. o := global.DbMap[utils.DbNameIndex]
  379. sql := "SELECT DISTINCT classify_name, classify_type FROM base_from_trade_" + exchange + "_index where rank <50 and (buy_short_name !='' or sold_short_name !='' ) and (buy_short_name !=' ' or sold_short_name !=' ' ) and data_time >= ? and data_time <= ?"
  380. err = o.Raw(sql, startDate, endDate).Find(&list).Error
  381. return
  382. }
  383. func GetTradePositionTopClassifyByExchangeDataTime(exchange string, startDate, endDate string) (list []TradePositionClassifyInfo, err error) {
  384. o := global.DbMap[utils.DbNameIndex]
  385. sql := "SELECT DISTINCT classify_name, classify_type FROM trade_position_" + exchange + "_top where data_time >= ? and data_time <= ? and deal_type in (1,2) "
  386. err = o.Raw(sql, startDate, endDate).Find(&list).Error
  387. return
  388. }
  389. // DeleteTradePositionTopAllByExchangeDataTime 删除计算数据
  390. func DeleteTradePositionTopAllByExchangeDataTime(exchange string, startDate, endDate string) (err error) {
  391. o := global.DbMap[utils.DbNameIndex]
  392. sql := "DELETE FROM trade_position_" + exchange + "_top where data_time >= ? and data_time <= ? "
  393. err = o.Exec(sql, startDate, endDate).Error
  394. return
  395. }
  396. type GetFirstBaseFromTradeIndeDate struct {
  397. DataTime string
  398. }
  399. func GetFirstBaseFromTradeIndexByDate(exchange string) (item *GetFirstBaseFromTradeIndeDate, err error) {
  400. o := global.DbMap[utils.DbNameIndex]
  401. sql := "SELECT * FROM base_from_trade_" + exchange + "_index where rank < 50 order by data_time asc"
  402. err = o.Raw(sql).First(&item).Error
  403. if err != nil {
  404. return
  405. }
  406. item.DataTime = utils.GormDateStrToDateStr(item.DataTime)
  407. return
  408. }
  409. // 获取持仓分析的最新数据
  410. func GetTradePositionTopLastedDataTime(exchange string) (dataTime time.Time, err error) {
  411. o := global.DbMap[utils.DbNameIndex]
  412. sql := "SELECT max(data_time) FROM trade_position_" + exchange + "_top"
  413. var timeNull sql2.NullTime
  414. err = o.Raw(sql).Scan(&timeNull).Error
  415. if err != nil {
  416. return
  417. }
  418. if timeNull.Valid {
  419. dataTime = timeNull.Time
  420. }
  421. return
  422. }