trade_analysis.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. package trade_analysis
  2. import (
  3. "eta/eta_api/utils"
  4. "fmt"
  5. "github.com/beego/beego/v2/client/orm"
  6. "time"
  7. )
  8. // 上期能源持仓榜单表
  9. type TradePositionTop struct {
  10. Id uint64 `gorm:"primaryKey;column:id" json:"id"`
  11. ClassifyName string `gorm:"column:classify_name" json:"classify_name"` //分类名称
  12. ClassifyType string `gorm:"column:classify_type" json:"classify_type"` //分类名称下的类型
  13. DealShortName string `gorm:"column:deal_short_name" json:"deal_short_name"` //成交量公司简称
  14. DealValue int `gorm:"column:deal_value" json:"deal_value"` //成交量
  15. DealChange int `gorm:"column:deal_change" json:"deal_change"` //成交变化量
  16. DataTime time.Time `gorm:"column:data_time" json:"data_time"` //数据日期
  17. CreateTime time.Time `gorm:"column:create_time" json:"create_time"` //插入时间
  18. ModifyTime time.Time `gorm:"column:modify_time" json:"modify_time"` //修改时间
  19. DealType int `gorm:"column:deal_type" json:"deal_type"` //交易类型:1多单,2空单,3净多单,4净空单
  20. SourceType int `gorm:"column:source_type" json:"source_type"` //数据来源,0是原始数据的值,1是由T+1日推算出的值,2是由T日的榜单数据推算出的值
  21. Rank int `gorm:"column:rank" json:"rank"` //排名
  22. }
  23. type TradeClassifyNameList struct {
  24. Exchange string `description:"交易所"`
  25. ExchangeEn string `description:"交易所英文"`
  26. Sort int `description:"排序字段" `
  27. Num int `description:"品种数量"`
  28. DataTime string `description:"最新更新时间"`
  29. CurrDate string `description:"当前日期"`
  30. Items []TradeClassifyNameListItem `description:"子类"`
  31. }
  32. type TradeClassifyNameListSort []TradeClassifyNameList
  33. func (v TradeClassifyNameListSort) Len() int {
  34. return len(v)
  35. }
  36. func (v TradeClassifyNameListSort) Swap(i, j int) {
  37. v[i], v[j] = v[j], v[i]
  38. }
  39. func (v TradeClassifyNameListSort) Less(i, j int) bool {
  40. return v[i].Sort < v[j].Sort
  41. }
  42. type TradeClassifyNameListItemSort []TradeClassifyNameListItem
  43. func (v TradeClassifyNameListItemSort) Len() int {
  44. return len(v)
  45. }
  46. func (v TradeClassifyNameListItemSort) Swap(i, j int) {
  47. v[i], v[j] = v[j], v[i]
  48. }
  49. func (v TradeClassifyNameListItemSort) Less(i, j int) bool {
  50. return v[i].ClassifyName < v[j].ClassifyName
  51. }
  52. type TradeClassifyNameListItem struct {
  53. ClassifyName string `description:"交易分类"`
  54. Items []TradeClassifyNameListItemItem `description:"合约代码"`
  55. }
  56. type TradeClassifyNameListItemItemSort []TradeClassifyNameListItemItem
  57. func (v TradeClassifyNameListItemItemSort) Len() int {
  58. return len(v)
  59. }
  60. func (v TradeClassifyNameListItemItemSort) Swap(i, j int) {
  61. v[i], v[j] = v[j], v[i]
  62. }
  63. func (v TradeClassifyNameListItemItemSort) Less(i, j int) bool {
  64. return v[i].ClassifyType < v[j].ClassifyType
  65. }
  66. type TradeClassifyNameListItemItem struct {
  67. ClassifyType string `description:"分类名称下的类型"`
  68. }
  69. type TradeClassifyName struct {
  70. ClassifyName string //分类名称
  71. ClassifyType string //分类名称下的类型
  72. LatestDate string //分类下最晚日期
  73. }
  74. // GetExchangeClassify 获取交易所分类列表
  75. func GetExchangeClassify(exchange string) (list []TradeClassifyName, err error) {
  76. tableName := "base_from_trade_" + exchange + "_index"
  77. orderStr := "classify_name DESC, classify_type asc"
  78. if exchange == "zhengzhou" {
  79. orderStr = "classify_name asc"
  80. }
  81. sql := "SELECT classify_name, classify_type FROM " + tableName + " WHERE `rank` <=20 and `rank` > 0 GROUP BY classify_name, classify_type "
  82. sql += ` ORDER BY ` + orderStr
  83. o := orm.NewOrmUsingDB("data")
  84. _, err = o.Raw(sql).QueryRows(&list)
  85. return
  86. }
  87. type LastTimeItem struct {
  88. CreateTime time.Time
  89. }
  90. // GetExchangeLastTime 获取交易所数据最晚的时间
  91. func GetExchangeLastTime(exchange string) (item LastTimeItem, err error) {
  92. tableName := "base_from_trade_" + exchange + "_index"
  93. sql := `SELECT create_time FROM ` + tableName + ` ORDER BY create_time desc`
  94. o := orm.NewOrmUsingDB("data")
  95. err = o.Raw(sql).QueryRow(&item)
  96. return
  97. }
  98. type GetPositionTopReq struct {
  99. Exchange string `json:"exchange" form:"exchange"` //交易所
  100. ClassifyName string `json:"classify_name" form:"classify_name"` //分类名称
  101. ClassifyType string `json:"classify_type" form:"classify_type"` //具体合约名称
  102. DataTime string `json:"data_time" form:"data_time"` //请求日期,如果为空,则返回最新的榜单日期
  103. }
  104. type GetPositionTopResp struct {
  105. BuyList GetPositionTopList `description:"多单列表"`
  106. SoldList GetPositionTopList `description:"空单列表"`
  107. CleanBuyList GetPositionTopList `description:"净多单列表"`
  108. CleanSoldList GetPositionTopList `description:"净空单列表"`
  109. DataTime string `description:"最新日期或者请求日期"`
  110. LastDataTime string `description:"最新日期"`
  111. }
  112. type GetPositionTopList struct {
  113. TotalDealValue int `description:"总计成交量"`
  114. TotalDealChange int `description:"校昨日变化"`
  115. List []GetPositionTopListItem `description:"榜单详情列表"`
  116. }
  117. type GetPositionTopListItem struct {
  118. DealShortName string `description:"成交量公司简称"`
  119. DealValue int `description:"成交量"`
  120. DealChange int `description:"成交变化量"`
  121. Rank int `description:"当前名次"`
  122. Rate string `description:"当前占比"`
  123. BeforeAllRate string `description:"排在前面的成交量总计占比(包含)"`
  124. BeforeAllValue int `description:"排在前面的成交量总计"`
  125. BeforeAllChange int `description:"排在前面的成交量增减总计"`
  126. }
  127. func GetTradePositionTop(exchange string, classifyName, classifyType, dataTime string) (list []TradePositionTop, err error) {
  128. tableName := "trade_position_" + exchange + "_top"
  129. sql := `SELECT * FROM ` + tableName + " WHERE classify_name=? and classify_type=? and data_time=? and `rank` <=20 and `rank` > 0 ORDER BY deal_value desc"
  130. o := orm.NewOrmUsingDB("data")
  131. _, err = o.Raw(sql, classifyName, classifyType, dataTime).QueryRows(&list)
  132. return
  133. }
  134. type OriginTradeData struct {
  135. Rank int `description:"排名"`
  136. CompanyName string `description:"期货公司名称"`
  137. Val int `description:"持仓量"`
  138. ValChange int `description:"持仓增减"`
  139. DataTime time.Time `description:"数据日期"`
  140. ClassifyName string `description:"品种名称"`
  141. ClassifyType string `description:"合约代码"`
  142. ValType int `description:"数据类型: 1-多单; 2-空单"`
  143. }
  144. // GetTradeDataByClassifyAndCompany 根据品种和公司名称获取持仓数据
  145. func GetTradeDataByClassifyAndCompany(exchange, classifyName string, contracts, companies []string) (items []*OriginTradeData, err error) {
  146. if exchange == "" {
  147. err = fmt.Errorf("数据表名称有误")
  148. return
  149. }
  150. if len(contracts) == 0 || len(companies) == 0 {
  151. return
  152. }
  153. tableName := fmt.Sprintf("base_from_trade_%s_index", exchange)
  154. sql := `SELECT
  155. rank,
  156. buy_short_name AS company_name,
  157. buy_value AS val,
  158. buy_change AS val_change,
  159. classify_name,
  160. classify_type,
  161. data_time,
  162. 1 AS val_type
  163. FROM
  164. %s
  165. WHERE
  166. classify_name = ? AND classify_type IN (%s) AND buy_short_name IN (%s)
  167. UNION ALL
  168. (
  169. SELECT
  170. rank,
  171. sold_short_name,
  172. sold_value,
  173. sold_change,
  174. classify_name,
  175. classify_type,
  176. data_time,
  177. 2 AS val_type
  178. FROM
  179. %s
  180. WHERE
  181. classify_name = ? AND classify_type IN (%s) AND sold_short_name IN (%s)
  182. )`
  183. sql = fmt.Sprintf(sql, tableName, utils.GetOrmInReplace(len(contracts)), utils.GetOrmInReplace(len(companies)), tableName, utils.GetOrmInReplace(len(contracts)), utils.GetOrmInReplace(len(companies)))
  184. o := orm.NewOrmUsingDB("data")
  185. _, err = o.Raw(sql, classifyName, contracts, companies, classifyName, contracts, companies).QueryRows(&items)
  186. return
  187. }
  188. // GetTradeZhengzhouDataByClassifyAndCompany 郑商所-根据品种和公司名称获取持仓数据
  189. func GetTradeZhengzhouDataByClassifyAndCompany(exchange string, contracts, companies []string) (items []*OriginTradeData, err error) {
  190. if exchange == "" {
  191. err = fmt.Errorf("数据表名称有误")
  192. return
  193. }
  194. if len(contracts) == 0 || len(companies) == 0 {
  195. return
  196. }
  197. tableName := fmt.Sprintf("base_from_trade_%s_index", exchange)
  198. sql := `SELECT
  199. rank,
  200. buy_short_name AS company_name,
  201. buy_value AS val,
  202. buy_change AS val_change,
  203. classify_name AS classify_type,
  204. data_time,
  205. 1 AS val_type
  206. FROM
  207. %s
  208. WHERE
  209. classify_name IN (%s) AND buy_short_name IN (%s)
  210. UNION ALL
  211. (
  212. SELECT
  213. rank,
  214. sold_short_name,
  215. sold_value,
  216. sold_change,
  217. classify_name AS classify_type,
  218. data_time,
  219. 2 AS val_type
  220. FROM
  221. %s
  222. WHERE
  223. classify_name IN (%s) AND sold_short_name IN (%s)
  224. )`
  225. sql = fmt.Sprintf(sql, tableName, utils.GetOrmInReplace(len(contracts)), utils.GetOrmInReplace(len(companies)), tableName, utils.GetOrmInReplace(len(contracts)), utils.GetOrmInReplace(len(companies)))
  226. o := orm.NewOrmUsingDB("data")
  227. _, err = o.Raw(sql, contracts, companies, contracts, companies).QueryRows(&items)
  228. return
  229. }
  230. // ContractCompanyTradeData [合约-期货公司]持仓数据
  231. type ContractCompanyTradeData struct {
  232. CompanyName string `description:"期货公司名称"`
  233. ClassifyType string `description:"合约代码"`
  234. StartDate time.Time `description:"数据开始日期"`
  235. EndDate time.Time `description:"数据结束日期"`
  236. DataList []*ContractCompanyTradeDataList `description:"数据序列"`
  237. }
  238. const (
  239. TradeDataTypeNull = 0 // 无值
  240. TradeDataTypeOrigin = 1 // 原始值
  241. TradeDataTypeCalculate = 2 // 推算值
  242. WarehouseBuyChartType = 1 // 多单图
  243. WarehouseSoldChartType = 2 // 空单图
  244. WarehousePureBuyChartType = 3 // 净多单图
  245. WarehouseDefaultUnit = "手"
  246. WarehouseDefaultFrequency = "日度"
  247. GuangZhouTopCompanyAliasName = "日成交持仓排名" // 广期所TOP20对应的公司名称
  248. GuangZhouSeatNameBuy = "持买单量" // 广期所指标名称中的多单名称
  249. GuangZhouSeatNameSold = "持卖单量" // 广期所指标名称中的空单名称
  250. GuangZhouTopSeatNameBuy = "持买单量总计" // 广期所指标名称中的TOP20多单名称
  251. GuangZhouTopSeatNameSold = "持卖单量总计" // 广期所指标名称中的TOP20空单名称
  252. )
  253. const (
  254. TradeExchangeZhengzhou = "zhengzhou"
  255. TradeExchangeGuangzhou = "guangzhou"
  256. )
  257. var WarehouseTypeSuffixNames = map[int]string{
  258. WarehouseBuyChartType: "席位多单",
  259. WarehouseSoldChartType: "席位空单",
  260. WarehousePureBuyChartType: "席位净多单",
  261. }
  262. // GuangzhouSeatNameValType 广期所数据名称对应的席位方向
  263. var GuangzhouSeatNameValType = map[string]int{
  264. GuangZhouSeatNameBuy: 1,
  265. GuangZhouSeatNameSold: 2,
  266. GuangZhouTopSeatNameBuy: 1,
  267. GuangZhouTopSeatNameSold: 2,
  268. }
  269. // ContractCompanyTradeDataList [合约-期货公司]持仓数据详情
  270. type ContractCompanyTradeDataList struct {
  271. Date time.Time `description:"数据日期"`
  272. BuyVal int `description:"多单持仓量"`
  273. BuyValType int `description:"多单数据类型: 0-无值; 1-原始值; 2-推算值"`
  274. BuyChange int `description:"多单持仓增减"`
  275. BuyChangeType int `description:"多单持仓增减类型: 0-无值; 1-原始值; 2-推算值"`
  276. SoldVal int `description:"空单持仓量"`
  277. SoldValType int `description:"空单数据类型: 0-无值; 1-原始值; 2-推算值"`
  278. SoldChange int `description:"空单持仓增减"`
  279. SoldChangeType int `description:"空单持仓增减类型: 0-无值; 1-原始值; 2-推算值"`
  280. PureBuyVal int `description:"净多单持仓量"`
  281. PureBuyValType int `description:"净多单数据类型: 0-无值; 1-原始值; 2-推算值"`
  282. PureBuyChange int `description:"净多单持仓增减"`
  283. PureBuyChangeType int `description:"净多单持仓增减类型: 0-无值; 1-原始值; 2-推算值"`
  284. }
  285. // GetLastTradeDataByClassify 获取[合约]末位多空单数据
  286. func GetLastTradeDataByClassify(exchange, classifyName string, contracts []string) (items []*OriginTradeData, err error) {
  287. if exchange == "" {
  288. err = fmt.Errorf("数据表名称有误")
  289. return
  290. }
  291. if len(contracts) == 0 {
  292. return
  293. }
  294. contractReplacer := utils.GetOrmInReplace(len(contracts))
  295. tableName := fmt.Sprintf("base_from_trade_%s_index", exchange)
  296. sql := `SELECT
  297. tpt.rank,
  298. tpt.buy_short_name AS company_name,
  299. tpt.buy_value AS val,
  300. tpt.buy_change AS val_change,
  301. tpt.classify_name,
  302. tpt.classify_type,
  303. tpt.data_time,
  304. 1 AS val_type
  305. FROM
  306. %s tpt
  307. JOIN
  308. (
  309. SELECT
  310. data_time, classify_type, MAX(rank) AS max_rank
  311. FROM
  312. %s
  313. WHERE
  314. classify_name = ? AND classify_type IN (%s) AND buy_short_name <> ''
  315. GROUP BY
  316. data_time,
  317. classify_type
  318. ) sub
  319. ON
  320. tpt.data_time = sub.data_time AND tpt.classify_type = sub.classify_type AND tpt.rank = sub.max_rank
  321. WHERE
  322. tpt.classify_name = ? AND tpt.classify_type IN (%s)
  323. UNION ALL
  324. (
  325. SELECT
  326. tpt.rank, tpt.sold_short_name, tpt.sold_value, tpt.sold_change, tpt.classify_name, tpt.classify_type, tpt.data_time, 2 AS val_type
  327. FROM
  328. %s tpt
  329. JOIN
  330. (
  331. SELECT
  332. data_time, classify_type, MAX(rank) AS max_rank
  333. FROM
  334. %s
  335. WHERE
  336. classify_name = ? AND classify_type IN (%s) AND sold_short_name <> ''
  337. GROUP BY
  338. data_time, classify_type
  339. ) sub
  340. ON
  341. tpt.data_time = sub.data_time AND tpt.classify_type = sub.classify_type AND tpt.rank = sub.max_rank
  342. WHERE
  343. tpt.classify_name = ? AND tpt.classify_type IN (%s)
  344. )`
  345. sql = fmt.Sprintf(sql, tableName, tableName, contractReplacer, contractReplacer, tableName, tableName, contractReplacer, contractReplacer)
  346. o := orm.NewOrmUsingDB("data")
  347. _, err = o.Raw(sql, classifyName, contracts, classifyName, contracts, classifyName, contracts, classifyName, contracts).QueryRows(&items)
  348. return
  349. }
  350. // GetLastTradeZhengzhouDataByClassify 郑商所-获取[合约]末位多空单数据
  351. func GetLastTradeZhengzhouDataByClassify(exchange string, contracts []string) (items []*OriginTradeData, err error) {
  352. if exchange == "" {
  353. err = fmt.Errorf("数据表名称有误")
  354. return
  355. }
  356. if len(contracts) == 0 {
  357. return
  358. }
  359. contractReplacer := utils.GetOrmInReplace(len(contracts))
  360. tableName := fmt.Sprintf("base_from_trade_%s_index", exchange)
  361. sql := `SELECT
  362. tpt.rank,
  363. tpt.buy_short_name AS company_name,
  364. tpt.buy_value AS val,
  365. tpt.buy_change AS val_change,
  366. tpt.classify_name AS classify_type,
  367. tpt.data_time,
  368. 1 AS val_type
  369. FROM
  370. %s tpt
  371. JOIN
  372. (
  373. SELECT
  374. data_time, classify_name, MAX(rank) AS max_rank
  375. FROM
  376. %s
  377. WHERE
  378. classify_name IN (%s) AND buy_short_name <> ''
  379. GROUP BY
  380. data_time,
  381. classify_name
  382. ) sub
  383. ON
  384. tpt.data_time = sub.data_time AND tpt.classify_name = sub.classify_name AND tpt.rank = sub.max_rank
  385. WHERE
  386. tpt.classify_name IN (%s)
  387. UNION ALL
  388. (
  389. SELECT
  390. tpt.rank, tpt.sold_short_name, tpt.sold_value, tpt.sold_change, tpt.classify_name AS classify_type, tpt.data_time, 2 AS val_type
  391. FROM
  392. %s tpt
  393. JOIN
  394. (
  395. SELECT
  396. data_time, classify_name, MAX(rank) AS max_rank
  397. FROM
  398. %s
  399. WHERE
  400. classify_name IN (%s) AND sold_short_name <> ''
  401. GROUP BY
  402. data_time, classify_name
  403. ) sub
  404. ON
  405. tpt.data_time = sub.data_time AND tpt.classify_name = sub.classify_name AND tpt.rank = sub.max_rank
  406. WHERE
  407. tpt.classify_name IN (%s)
  408. )`
  409. sql = fmt.Sprintf(sql, tableName, tableName, contractReplacer, contractReplacer, tableName, tableName, contractReplacer, contractReplacer)
  410. o := orm.NewOrmUsingDB("data")
  411. _, err = o.Raw(sql, contracts, contracts, contracts, contracts).QueryRows(&items)
  412. return
  413. }
  414. type BaseFromTradeGuangzhouIndex struct {
  415. BaseFromTradeGuangzhouIndexId int `orm:"column(base_from_trade_guangzhou_index_id);pk"`
  416. BaseFromTradeGuangzhouClassifyId int `description:"分类id"`
  417. IndexCode string `description:"指标编码"`
  418. IndexName string `description:"指标名称"`
  419. Frequency string `description:"频率"`
  420. Unit string `description:"单位"`
  421. StartDate string `description:"开始日期"`
  422. EndDate string `description:"结束日期"`
  423. CreateTime time.Time `description:"创建日期"`
  424. ModifyTime time.Time `description:"修改日期"`
  425. }
  426. func GetBaseFromTradeGuangzhouIndexByClassifyId(classifyId int) (list []*BaseFromTradeGuangzhouIndex, err error) {
  427. o := orm.NewOrmUsingDB("data")
  428. sql := `SELECT * FROM base_from_trade_guangzhou_index WHERE base_from_trade_guangzhou_classify_id = ?`
  429. _, err = o.Raw(sql, classifyId).QueryRows(&list)
  430. return
  431. }
  432. type BaseFromTradeGuangzhouData struct {
  433. BaseFromTradeGuangzhouDataId int `orm:"column(base_from_trade_guangzhou_data_id);pk"`
  434. BaseFromTradeGuangzhouIndexId int `description:"指标id"`
  435. IndexCode string `description:"指标编码"`
  436. DataTime time.Time `description:"数据日期"`
  437. Value float64 `description:"数据值"`
  438. QtySub float64 `description:"增减"`
  439. CreateTime time.Time `description:"创建日期"`
  440. ModifyTime time.Time `description:"修改日期"`
  441. }
  442. // GetBaseFromTradeGuangzhouDataByIndexIds 获取指标数据
  443. func GetBaseFromTradeGuangzhouDataByIndexIds(indexIds []int) (list []*BaseFromTradeGuangzhouData, err error) {
  444. if len(indexIds) == 0 {
  445. return
  446. }
  447. o := orm.NewOrmUsingDB("data")
  448. sql := fmt.Sprintf(`SELECT * FROM base_from_trade_guangzhou_data WHERE base_from_trade_guangzhou_index_id IN (%s) ORDER BY base_from_trade_guangzhou_index_id`, utils.GetOrmInReplace(len(indexIds)))
  449. _, err = o.Raw(sql, indexIds).QueryRows(&list)
  450. return
  451. }
  452. // GetBaseFromTradeGuangzhouMinDataByIndexIds 获取指标中的末位数据
  453. func GetBaseFromTradeGuangzhouMinDataByIndexIds(indexIds []int) (list []*BaseFromTradeGuangzhouData, err error) {
  454. indexLen := len(indexIds)
  455. if indexLen == 0 {
  456. return
  457. }
  458. o := orm.NewOrmUsingDB("data")
  459. sql := fmt.Sprintf(`SELECT
  460. t1.data_time,
  461. t1.min_value AS value
  462. FROM
  463. (
  464. SELECT
  465. data_time,
  466. MIN(value) AS min_value
  467. FROM
  468. base_from_trade_guangzhou_data
  469. WHERE
  470. base_from_trade_guangzhou_index_id IN (%s)
  471. GROUP BY
  472. data_time
  473. ) t1
  474. JOIN
  475. base_from_trade_guangzhou_data t2
  476. ON
  477. t1.data_time = t2.data_time AND t1.min_value = t2.value AND t2.base_from_trade_guangzhou_index_id IN (%s)
  478. GROUP BY
  479. t1.data_time`, utils.GetOrmInReplace(indexLen), utils.GetOrmInReplace(indexLen))
  480. _, err = o.Raw(sql, indexIds, indexIds).QueryRows(&list)
  481. return
  482. }