ermcpGoods.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. package models
  2. // 企业风管期货商品相关
  3. import (
  4. "fmt"
  5. "mtp2_if/db"
  6. "mtp2_if/mtpcache"
  7. "time"
  8. )
  9. // Goodssortbypreposition 合约昨持仓排序表 - 同一品种内按昨持仓量倒排序
  10. // 行情服务清盘前生成此表,供交易服务风控规则使用;生成前先删除此表数据;
  11. type Goodssortbypreposition struct {
  12. Tradedate string `json:"tradedate" xorm:"'TRADEDATE'" binding:"required"` // 交易日
  13. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 合约代码 - 易盛接口:合约代码=品种代码+合约代码
  14. Goodsgroupcode string `json:"goodsgroupcode" xorm:"'GOODSGROUPCODE'"` // 品种代码
  15. Sortindex int64 `json:"sortindex" xorm:"'SORTINDEX'"` // 排序
  16. Prepositionqty int64 `json:"prepositionqty" xorm:"'PREPOSITIONQTY'"` // 昨持仓量
  17. Updatetime time.Time `json:"updatetime" xorm:"'UPDATETIME'"` // 更新时间
  18. }
  19. // TableName is GOODSSORTBYPREPOSITION
  20. func (Goodssortbypreposition) TableName() string {
  21. return "GOODSSORTBYPREPOSITION"
  22. }
  23. type ErmcpGoods struct {
  24. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  25. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  26. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  27. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  28. Goodsgroupid int64 `json:"goodsgroupid" xorm:"'GOODSGROUPID'"` // 所属商品组ID
  29. Goodsstatus int64 `json:"goodsstatus" xorm:"'GOODSSTATUS'"` // 商品状态- 1:待审核 2:未上市 3:上市 4:已注销 5:审核拒绝 6:退市 7:待退市
  30. Currencyid int64 `json:"currencyid" xorm:"'CURRENCYID'"` // 报价货币ID
  31. Goodunitid int64 `json:"goodunitid" xorm:"'GOODUNITID'"` // 报价单位ID
  32. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  33. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  34. Listingdate time.Time `json:"-" xorm:"'LISTINGDATE'"` // 交易开始日期
  35. Lasttradedate time.Time `json:"-" xorm:"'LASTTRADEDATE'"` // 最后交易日期(状态:待退市)
  36. Delistingdate time.Time `json:"-" xorm:"'DELISTINGDATE'"` // 商品退市时间(状态:退市) -- 已作废
  37. Deliveryflag int64 `json:"deliveryflag" xorm:"'DELIVERYFLAG'"` // 交割标志 - 0:不可交割 1:可交割
  38. Hasquoter int64 `json:"-" xorm:"'HASQUOTER'"` // 是否有报价商 - 0:无报价商 1:有报价商
  39. Hqprotecttime int64 `json:"-" xorm:"'HQPROTECTTIME'"` // 行情保护时间(秒)
  40. Quoteshowtype int64 `json:"-" xorm:"'QUOTESHOWTYPE'"` // 行情报价类型: 1:成交价 2:买卖中间价 3:含买价 4:含卖价做市模式固定为3:含买价
  41. Quoteshowtypeinterval int64 `json:"-" xorm:"'QUOTESHOWTYPEINTERVAL'"` // 行情报价间隔时间(秒)(成交价时为0)
  42. Modifystatus int64 `json:"modifystatus" xorm:"'MODIFYSTATUS'"` // 变更状态 - 1:未变更 2:变更中 3:待审核 4:已审核
  43. Goodstradetype int64 `json:"goodstradetype" xorm:"'GOODSTRADETYPE'"` // 商品交易权限类型 - 1:可建可平 3:不可建可平
  44. Creatorid int64 `json:"-" xorm:"'CREATORID'"` // 创建人
  45. Createtime time.Time `json:"-" xorm:"'CREATETIME'"` // 创建时间
  46. Auditaccountid int64 `json:"-" xorm:"'AUDITACCOUNTID'"` // 审核操作员账号
  47. Audittime time.Time `json:"-" xorm:"'AUDITTIME'"` // 审核时间
  48. Modifytime time.Time `json:"-" xorm:"'MODIFYTIME'"` // 修改时间
  49. Modifierid int64 `json:"-" xorm:"'MODIFIERID'"` // 修改人
  50. Cancelaccountid int64 `json:"-" xorm:"'CANCELACCOUNTID'"` // 注销操作员账号
  51. Remark string `json:"-" xorm:"'REMARK'"` // 备注
  52. Canceltime time.Time `json:"-" xorm:"'CANCELTIME'"` // 注销时间
  53. Delistingmode int64 `json:"delistingmode" xorm:"'DELISTINGMODE'"` // 退市方式 - 1:退市平仓 2:退市交收 3:不处理(仅期权\币币兑换)
  54. Forceclosemode int64 `json:"forceclosemode" xorm:"'FORCECLOSEMODE'"` // 定期强平方式 - 1:无 2:每日 3:每周 4:每月[收益权]
  55. Forceclosevalue int64 `json:"forceclosevalue" xorm:"'FORCECLOSEVALUE'"` // 定期强平参数 [收益权]
  56. Cutmode int64 `json:"cutmode" xorm:"'CUTMODE'"` // 斩仓方式 - 1:不斩仓 2:自动斩仓 3:半自动斩仓
  57. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  58. Isbuylimited int64 `json:"isbuylimited" xorm:"'ISBUYLIMITED'"` // 是否限制建仓量 - 0:不限制 1:限制
  59. Innerdealmode int64 `json:"-" xorm:"'INNERDEALMODE'"` // 内部成交方式[通道交易] - 1:净头寸 2:开平 3:平今
  60. Outerdealmode int64 `json:"-" xorm:"'OUTERDEALMODE'"` // 外部成交方式[通道交易]- 1:净头寸 2:开平 3:平今
  61. Closepricemode int64 `json:"closepricemode" xorm:"'CLOSEPRICEMODE'"` // 强平价格方式 - 1:市价 2:最新价 3:涨跌停(未实现)
  62. Closepriceparam float64 `json:"closepriceparam" xorm:"'CLOSEPRICEPARAM'"` // 强平最新价浮动比例 - 方式为2时使用 (<1)买 上浮 (1+x)*最新价卖 下浮 (1-x)*最新价
  63. Qtydecimalplace int64 `json:"qtydecimalplace" xorm:"'QTYDECIMALPLACE'"` // 成交量小数位
  64. Goodscurrencyid int64 `json:"goodscurrencyid" xorm:"'GOODSCURRENCYID'"` // 合约货币ID
  65. Goodsquotetype int64 `json:"-" xorm:"'GOODSQUOTETYPE'"` // 合约报价类型: 1-直接报价 2-间接报价
  66. Quotegear int64 `json:"quotegear" xorm:"'QUOTEGEAR'"` // 行情档位(1-10)
  67. Outgoodscode string `json:"outgoodscode" xorm:"'OUTGOODSCODE'"` // 商品代码(外部)
  68. Isvisible int32 `json:"isvisible" xorm:"ISVISIBLE"` // 游客是否可见 - 0:不可见 1:可见
  69. Areauserid int64 `json:"areauserid" xorm:"AREAUSERID"` // 所属机构
  70. Pictureurl string `json:"pictureurl" xorm:"PICTUREURL"` // 商品图片
  71. Marketmarginalgorithm int64 `json:"marketmarginalgorithm" xorm:"MARKETMARGINALGORITHM"` // 保证金计算方式
  72. Marketmarginvalue float64 `json:"marketmarginvalue" xorm:"MARKETMARGINVALUE"` // 即市保证金值
  73. Mindeliverylot int64 `json:"mindeliverylot" xorm:"MINDELIVERYLOT"` // 最小交收手数(50模式)
  74. PROVIDERUSERID int64 `json:"provideruserid" xorm:"PROVIDERUSERID"` // 发售方用户ID(49)\供货商(50)
  75. PROVIDERACCOUNTID int64 `json:"provideraccountid" xorm:"PROVIDERACCOUNTID"` // 发售方资金账户ID(49)\供货商资金账户ID(50)
  76. MARGINALGORITHM float64 `json:"marginalgorithm" xorm:"MARGINALGORITHM"` // 持仓定金方式(49) - 1:比率 2.固定(52)
  77. TRANSFERDEPOSITRATIO float64 `json:"transferdepositratio" xorm:"TRANSFERDEPOSITRATIO"` // 转让定金比例(49)\持仓定金(52)
  78. THUMURLS string `json:"thumurls" xorm:"THUMURLS"` // 缩略图片(1:1)(逗号分隔)
  79. BANNERURLS string `json:"bannerurls" xorm:"BANNERURLS"` // Banner图片(2:1)(逗号分隔)
  80. Relatedgoodsid int32 `json:"relatedgoodsid" xorm:"REFGOODSID"` // 关联参考商品ID
  81. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  82. TRADEPROPERTY int32 `json:"tradeproperty" xorm:"TRADEPROPERTY"` // 交易属性 - 1:收益权(可做空) 2:所有权(不可做空) 3:期权 4:现货 5:参考行情 6:通道交易 7:币交易 8:场外期权
  83. ENUMDICNAME string `json:"enumdicname"` // 单位名称
  84. MINSPREAD float64 `json:"minspread" xorm:"MINSPREAD"` // 点差下限(46)
  85. MAXSPREAD float64 `json:"maxspread" xorm:"MAXSPREAD"` // 点差上限(46)
  86. GOODSORDER string `json:"goodsorder" xorm:"GOODSORDER"` // 商品显示顺序(99)
  87. GOODSNAMETH string `json:"goodsnameth" xorm:"GOODSNAMETH"` // 期货合约名称泰文)
  88. GOODSNAMEEN string `json:"goodsnameen" xorm:"GOODSNAMEEN"` // 期货合约名称(英文)
  89. GOODSNAMETW string `json:"goodsnametw" xorm:"GOODSNAMETW"` // 期货合约名称(繁体)
  90. BUYPRICEMOVEALGORITHM int32 `json:"buypricemovealgorithm" xorm:"BUYPRICEMOVEALGORITHM"` // 买交收升贴水算法
  91. BUYPRICEMOVEVALUE float64 `json:"buypricemovevalue" xorm:"BUYPRICEMOVEVALUE"` // 买交收升贴水值
  92. BUYSHIPPINGFEEALGORITHM int32 `json:"buyshippingfeealgorithm" xorm:"BUYSHIPPINGFEEALGORITHM"` // 买交收运费算法
  93. BUYSHIPPINGFEEVALUE float64 `json:"buyshippingfeevalue" xorm:"BUYSHIPPINGFEEVALUE"` // 买交收运费值
  94. BUYOTHERFEEALGORITHM int32 `json:"buyotherfeealgorithm" xorm:"BUYOTHERFEEALGORITHM"` // 买交收其它费用算法
  95. BUYOTHERFEEVALUE float64 `json:"buyotherfeevalue" xorm:"BUYOTHERFEEVALUE"` // 买交收其它费用值
  96. SELLPRICEMOVEALGORITHM int32 `json:"sellpricemovealgorithm" xorm:"SELLPRICEMOVEALGORITHM"` // 卖交收升贴水算法
  97. SELLPRICEMOVEVALUE float64 `json:"sellpricemovevalue" xorm:"SELLPRICEMOVEVALUE"` // 卖交收升贴水值
  98. SELLSHIPPINGFEEALGORITHM int32 `json:"sellshippingfeealgorithm" xorm:"SELLSHIPPINGFEEALGORITHM"` // 卖交收运费算法
  99. SELLSHIPPINGFEEVALUE float64 `json:"sellshippingfeevalue" xorm:"SELLSHIPPINGFEEVALUE"` // 卖交收运费值
  100. SELLOTHERFEEALGORITHM int32 `json:"sellotherfeealgorithm" xorm:"SELLOTHERFEEALGORITHM"` // 卖交收其它费用算法
  101. SELLOTHERFEEVALUE float64 `json:"sellotherfeevalue" xorm:"SELLOTHERFEEVALUE"` // 卖交收其它费用值
  102. CANAUTOADDDEPOSIT int32 `json:"canautoadddeposit" xorm:"CANAUTOADDDEPOSIT"` // 是否允许自动追加定金: 0-否 1-是(52)
  103. CANAUTOREFUNDDEPOSIT int32 `json:"canautorefunddeposit" xorm:"CANAUTOREFUNDDEPOSIT"` // 是否允许自动退还定金: 0-否 1-是(52)
  104. GOODSGROUPNAME string `json:"goodsgroupname" xorm:"'GOODSGROUPNAME'"` // 所属商品组名称
  105. RISKCONTROLMODE int32 `json:"riskcontrolmode" xorm:"RISKCONTROLMODE"` // 风控方式(52、10模式) 1:按单风控 2:按账户风控
  106. GOODSNAMEVI string `json:"goodsnamevi" xorm:"GOODSNAMEVI"` // 期货合约名称(越南语)
  107. TPSLFLAG int32 `json:"tpslflag" xorm:"TPSLFLAG"` // 是否开启止盈止损 - 0:不开启 1:开启
  108. TPSLFORCEFLAG int32 `json:"tpslforceflag" xorm:"TPSLFORCEFLAG"` // 是否强制止盈止损 - 0:不强制 1:强制
  109. TPRATIODOWN float64 `json:"tpratiodown" xorm:"TPRATIODOWN"` // 止盈比例下限
  110. TPRATIOUP float64 `json:"tpratioup" xorm:"TPRATIOUP"` // 止盈比例上限
  111. TPRATIODEFAULT float64 `json:"tpratiodefault" xorm:"TPRATIODEFAULT"` // 止盈默认比例
  112. SLRATIODOWN float64 `json:"slratiodown" xorm:"SLRATIODOWN"` // 止损比例下限
  113. SLRATIOUP float64 `json:"slratioup" xorm:"SLRATIOUP"` // 止损比例上限
  114. SLRATIODEFAULT float64 `json:"slratiodefault" xorm:"SLRATIODEFAULT"` // 止损默认比例
  115. }
  116. // GetErmcpGoodses 企业风管专用获取商品信息的方法
  117. func GetErmcpGoodses(userid int64, lastUpdateTime string, loginID int64) ([]ErmcpGoods, error) {
  118. engine := db.GetEngine()
  119. // 对比数据库与终端的更新时间戳
  120. if len(lastUpdateTime) > 0 {
  121. goods := make([]Goods, 0)
  122. engine.Table("GOODS G").Where(fmt.Sprintf("G.MODIFYTIME > to_date('%s','yyyy-MM-dd hh24:mi:ss')", lastUpdateTime)).Find(&goods)
  123. if len(goods) == 0 {
  124. return make([]ErmcpGoods, 0), nil
  125. }
  126. }
  127. // 获取此账号相关有权限的市场
  128. ids := make([]int, 0)
  129. if loginID != 0 {
  130. markets, err := GetMarketsByLoginID(int(loginID))
  131. if err != nil {
  132. return make([]ErmcpGoods, 0), err
  133. }
  134. // 构建市场ID列表
  135. for _, market := range markets {
  136. ids = append(ids, int(market.MARKETID))
  137. }
  138. }
  139. goodses := make([]ErmcpGoods, 0)
  140. session := engine.Table("GOODS G").
  141. Select(`
  142. G.*,
  143. M.TRADEMODE,
  144. M.TRADEPROPERTY,
  145. GM.MARGINALGORITHM MARKETMARGINALGORITHM,
  146. GM.MARKETMARGINVALUE, nvl(EX.MINDELIVERYLOT, 1) MINDELIVERYLOT,
  147. EX.MINSPREAD,
  148. EX.MAXSPREAD,
  149. EX.GOODSORDER,
  150. EX.CANAUTOADDDEPOSIT,
  151. Ex.CANAUTOREFUNDDEPOSIT,
  152. EX.GOODSNAMETH ,
  153. EX.GOODSNAMEEN ,
  154. EX.GOODSNAMETW ,
  155. EX.GOODSNAMEVI ,
  156. EX.BUYPRICEMOVEALGORITHM ,
  157. EX.BUYPRICEMOVEVALUE ,
  158. EX.BUYSHIPPINGFEEALGORITHM ,
  159. EX.BUYSHIPPINGFEEVALUE ,
  160. EX.BUYOTHERFEEALGORITHM ,
  161. EX.BUYOTHERFEEVALUE ,
  162. EX.SELLPRICEMOVEALGORITHM ,
  163. EX.SELLPRICEMOVEVALUE ,
  164. EX.SELLSHIPPINGFEEALGORITHM,
  165. EX.SELLSHIPPINGFEEVALUE ,
  166. EX.SELLOTHERFEEALGORITHM ,
  167. EX.SELLOTHERFEEVALUE ,
  168. GG.GOODSGROUPNAME ,
  169. M.RISKCONTROLMODE ,
  170. EX.TPSLFLAG,
  171. EX.tpslforceflag,
  172. EX.TPRATIODOWN,
  173. EX.TPRATIOUP,
  174. EX.TPRATIODEFAULT,
  175. EX.SLRATIODOWN,
  176. EX.SLRATIOUP,
  177. EX.SLRATIODEFAULT
  178. `).
  179. Join("LEFT", "MARKET M", "M.MARKETID = G.MARKETID").
  180. Join("LEFT", "GOODSMARGINCONFIG GM", "GM.GOODSID = G.GOODSID AND GM.ISDEFAULT = 1").
  181. Join("LEFT", "GOODSEX EX", "EX.GOODSID = G.GOODSID").
  182. Join("LEFT", "GOODSGROUP GG", "GG.GOODSGROUPID = G.GOODSGROUPID").
  183. Where("G.GOODSSTATUS in (3)")
  184. if loginID != 0 {
  185. session = session.In("G.MARKETID", ids)
  186. }
  187. session = session.OrderBy("EX.GOODSORDER, G.GOODSCODE")
  188. if err := session.Find(&goodses); err != nil {
  189. return nil, err
  190. }
  191. // 错误 #3068
  192. //【企业风管-WebPC】期货市场商品应根据已设置的套保品种来显示,未设置套保品种的商品都不要显示出来
  193. if userid > 0 && len(goodses) > 0 {
  194. areaUserId := mtpcache.GetAreaUserId(userid, 0)
  195. sqlId := `
  196. select t.goodsgroupid
  197. from goodsgroup t
  198. where t.groupcategroyid in (
  199. select g.groupcategroyid
  200. from erms_middlegoods t
  201. left join goodsgroup g
  202. on t.goodsgroupid = g.goodsgroupid
  203. where t.areauserid = %v
  204. and t.isvalid = 1)
  205. `
  206. sqlId = fmt.Sprintf(sqlId, areaUserId)
  207. type GoodsGroupId struct {
  208. GoodsGroupId int64 `json:"goodsgroupid" xorm:"'GoodsGroupId'"`
  209. }
  210. sGroupId := make([]GoodsGroupId, 0)
  211. err := engine.SQL(sqlId).Find(&sGroupId)
  212. if err != nil {
  213. return nil, err
  214. }
  215. fIn := func(goodsgroupid int64) bool {
  216. for i := range sGroupId {
  217. if sGroupId[i].GoodsGroupId == goodsgroupid {
  218. return true
  219. }
  220. }
  221. return false
  222. }
  223. sGoods := make([]ErmcpGoods, 0)
  224. for _, v := range goodses {
  225. if fIn(v.Goodsgroupid) {
  226. sGoods = append(sGoods, v)
  227. }
  228. }
  229. goodses = sGoods[:]
  230. }
  231. for i := range goodses {
  232. goodses[i].ENUMDICNAME = mtpcache.GetEnumDicitemName(int32(goodses[i].Goodunitid))
  233. }
  234. return goodses, nil
  235. }
  236. // GetGoodsLastUpdateTime 获取商品表最后更新(Update)时间
  237. func GetGoodsLastUpdateTime() (*time.Time, error) {
  238. engine := db.GetEngine()
  239. var lastUpdateTimes time.Time
  240. sql := `SELECT VERSIONS_STARTTIME LASTUPDATETIME
  241. FROM GOODS VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE WHERE
  242. VERSIONS_STARTTIME IS NOT NULL and VERSIONS_OPERATION = 'U' order by LASTUPDATETIME desc`
  243. has, err := engine.SQL(sql).Get(&lastUpdateTimes)
  244. if err != nil {
  245. return nil, err
  246. }
  247. if !has {
  248. return nil, nil
  249. }
  250. return &lastUpdateTimes, nil
  251. }
  252. // GetGoodsSortByPrePositions 获取查询主力+次主力商品
  253. func GetGoodsSortByPrePositions(sortIndex string) ([]Goodssortbypreposition, error) {
  254. rst := make([]Goodssortbypreposition, 0)
  255. session := db.GetEngine().Table("GOODSSORTBYPREPOSITION T")
  256. if len(sortIndex) > 0 {
  257. session = session.Where(fmt.Sprintf("T.SORTINDEX in (%s)", sortIndex))
  258. }
  259. session = session.Asc("T.SORTINDEX")
  260. if err := session.Find(&rst); err != nil {
  261. return nil, err
  262. }
  263. return rst, nil
  264. }