| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- /**
- * @Author: zou.yingbin
- * @Create : 2021/8/13 10:04
- * @Modify : 2021/8/13 10:04
- */
- package models
- import (
- "fmt"
- "mtp2_if/db"
- "mtp2_if/mtpcache"
- "mtp2_if/utils"
- )
- // TradeGoodsEx 交易商品相关字段
- type TradeGoodsEx struct {
- GOODSNAME string `json:"goodsname" xorm:"'GOODSNAME'"` // 商品名称
- GOODSCODE string `json:"goodscode" xorm:"'GOODSCODE'"` // 商品代码
- DECIMALPLACE int `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 商品价格小数位
- QTYDECIMALPLACE int `json:"qtydecimalplace" xorm:"'QTYDECIMALPLACE'"` // 商品成交量小数位
- AGREEUNIT float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约乘数
- MARKETID int32 `json:"marketid" xorm:"'MARKETID'"` // 市场id
- MARKETNAME string `json:"marketname" xorm:"'MARKETNAME'"` // 市场名称
- GOODUNITID int32 `json:"goodunitid" xorm:"'GOODUNITID'"` // 商品单位id
- CURRENCYID int32 `json:"currencyid" xorm:"'CURRENCYID'"` // 商品币种id
- CURRENCYNAME string `json:"currencyname" xorm:"'CURRENCYNAME'"` // 币种名称
- ENUMDICNAME string `json:"enumdicname" xorm:"'ENUMDICNAME'"` // 商品单位名称
- TRADEMODE int32 `json:"trademode" xorm:"'TRADEMODE'"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价 46:掉期
- REFGOODSID int64 `json:"refgoodsid" xorm:"'REFGOODSID'"` // 标的合约id
- REFGOODSCODE string `json:"refgoodscode" xorm:"'REFGOODSCODE'"` // 标的合约代码
- }
- // TradeAccountEx 交易账户相关字段
- type TradeAccountEx struct {
- TANAME string `json:"taname" xorm:"'TANAME'"` // 资金账号名称
- USERID int64 `json:"userid" xorm:"'USERID'" form:"userid"` // 用户id
- USERNAME string `json:"username" xorm:"'USERNAME'"` // 用户名称
- TaCurrencyid int64 `json:"tacurrencyid" xorm:"'TACURRENCYID'"` // 报价货币ID - taaccount
- }
- // TradePosition 持仓汇总
- type TradePosition struct {
- ACCOUNTID int64 `json:"accountid" xorm:"'ACCOUNTID'"` // 账户id
- GOODSID int32 `json:"goodsid" xorm:"'GOODSID'" form:"goodsid"` // 商品id
- HOLDERTYPE int32 `json:"holdertype" xorm:"'HOLDERTYPE'"` // 持仓类别 - 1:单边持仓 2:双边持仓
- TRADEPROPERTY int32 `json:"tradeproperty" xorm:"'TRADEPROPERTY'"` // 交易属性
- BUYORSELL int32 `json:"buyorsell" xorm:"'BUYORSELL'" form:"buyorsell"` // 买卖方向 0-买 1-卖
- USEDMARGIN SFLOAT64 `json:"usedmargin" xorm:"'USEDMARGIN'"` // 占用保证金
- ORIQTY SFLOAT64 `json:"oriqty" xorm:"'ORIQTY'"` // 期初持仓数量
- QTY SFLOAT64 `json:"qty" xorm:"'QTY'"` // 持仓数量
- FROZENQTY SFLOAT64 `json:"frozenqty" xorm:"'FROZENQTY'"` // 冻结数量
- OTHERFROZENQTY SFLOAT64 `json:"otherfrozenqty" xorm:"'OTHERFROZENQTY'"` // 其它冻结数量
- CUROPENQTY SFLOAT64 `json:"curopenqty" xorm:"'CUROPENQTY'"` // 今日开仓数量
- CURCLOSEQTY SFLOAT64 `json:"curcloseqty" xorm:"'CURCLOSEQTY'"` // 今日平仓数量
- ORIAMOUNT SFLOAT64 `json:"oriamount" xorm:"'ORIAMOUNT'"` // 期初持仓金额
- AMOUNT SFLOAT64 `json:"amount" xorm:"'AMOUNT'"` // 持仓金额
- TradeGoodsEx `xorm:"extends"`
- TradeAccountEx `xorm:"extends"`
- HOLDERPRICE SFLOAT64 `json:"holderprice"` // 持仓均价 = 持仓金额 / 持仓数量 / 合约剩数 保留3位小数
- LASTPRICE SFLOAT64 `json:"lastprice"` // 最新价 从盘面上获取
- POSTIONPL SFLOAT64 `json:"postionpl"` // 持仓盈亏(浮动盈亏)
- ENABLEQTY SFLOAT64 `json:"enableqty"` // 可用数量
- FtAccountIDs string `json:"-" form:"accids"` // 资金账号,逗号隔开
- FtTradeMode string `json:"-" form:"trademodes"` // 交易模式筛选, 逗号隔开
- FtMarketIDs string `json:"-" form:"marketids"` // 市场id, 逗号隔开
- }
- func (r *TradePosition) calc() {
- fNegativePower10 := func(n int, vl ...*SFLOAT64) {
- for i := range vl {
- vl[i].Power10(n * -1)
- }
- }
- r.ENABLEQTY = r.QTY - r.FROZENQTY - r.OTHERFROZENQTY
- // 数量 按成交量小数位缩小
- fNegativePower10(r.QTYDECIMALPLACE, &r.ORIQTY, &r.QTY, &r.FROZENQTY,
- &r.OTHERFROZENQTY, &r.CUROPENQTY, &r.CURCLOSEQTY, &r.ENABLEQTY)
- if r.AGREEUNIT > 1e-8 {
- r.HOLDERPRICE = r.AMOUNT / r.QTY / SFLOAT64(r.AGREEUNIT)
- r.HOLDERPRICE.Round(3)
- }
- if d, ok := mtpcache.GetQuotePrice(r.GOODSCODE); ok {
- r.LASTPRICE.SetByInt64(d, r.DECIMALPLACE)
- r.POSTIONPL = (r.LASTPRICE - r.HOLDERPRICE) * r.QTY * SFLOAT64(r.AGREEUNIT)
- r.POSTIONPL.Round(2)
- }
- }
- func (r *TradePosition) buildSql() string {
- var sqlId utils.SQLVal = `
- with gtmp as
- (select g.goodsid,
- g.goodsname,
- g.goodscode,
- g.decimalplace,
- g.qtydecimalplace,
- g.agreeunit,
- g.marketid,
- g.goodunitid,
- g.currencyid,
- e.enumdicname,
- e2.enumdicname currencyname,
- m.marketname,
- m.trademode
- from goods g
- left join enumdicitem e
- on g.goodunitid = e.enumitemname
- and e.enumdiccode = 'goodsunit'
- left join enumdicitem e2
- on g.currencyid = e2.enumitemname
- and e2.enumdiccode = 'currency'
- left join market m
- on g.marketid = m.marketid),
- utmp as
- (select ta.accountid,
- ta.accountname taname,
- u.userid,
- u.accountname username
- from taaccount ta
- left join useraccount u
- on ta.relateduserid = u.userid)
- select k.*, t1.*, t2.*
- from (select t.accountid,
- t.goodsid,
- t.holdertype,
- t.usedmargin,
- t.tradeproperty,
- 0 as buyorsell,
- t.buypositionqty as oriqty,
- t.buyholderamount as oriamount,
- t.buycurpositionqty as qty,
- t.buycurholderamount as amount,
- t.buyfrozenqty as frozenqty,
- t.buyotherfrozenqty as otherfrozenqty,
- t.buyopentotalqty curopenqty,
- t.buyclosetotalqty curcloseqty
- from tradeposition t
- where t.buycurpositionqty > 0
- union all
- select t.accountid,
- t.goodsid,
- t.holdertype,
- t.usedmargin,
- t.tradeproperty,
- 1 as buyorsell,
- t.sellpositionqty as oriqty,
- t.sellholderamount as oriamount,
- t.sellcurpositionqty as qty,
- t.sellcurholderamount as amount,
- t.sellfrozenqty as frozenqty,
- t.sellotherfrozenqty as otherfrozenqty,
- t.sellopentotalqty as curopenqty,
- t.sellclosetotalqty as curcloseqty
- from tradeposition t
- where t.sellcurpositionqty > 0) k
- left join gtmp t1
- on k.goodsid = t1.goodsid
- left join utmp t2
- on k.accountid = t2.accountid
- where 1 = 1
- `
- sqlId.AndEx("utmp.userid", r.USERID, r.USERID > 0)
- sqlId.AndEx("t.goodsid", r.GOODSID, r.GOODSID > 0)
- sqlId.AndEx("t.BUYORSELL", r.BUYORSELL, r.BUYORSELL != -1)
- sqlId.JoinEx(r.FtTradeMode != "", fmt.Sprintf(" and t1.trademode in(%v)", r.FtTradeMode))
- sqlId.JoinEx(r.FtMarketIDs != "", fmt.Sprintf(" and t1.marketid in(%v)", r.FtMarketIDs))
- sqlId.JoinEx(r.FtAccountIDs != "", fmt.Sprintf(" and k.accountid in(%v)", r.FtAccountIDs))
- return sqlId.String()
- }
- // GetDataEx 获取持仓汇总
- func (r *TradePosition) GetDataEx() (interface{}, error) {
- sData := make([]TradePosition, 0)
- err := db.GetEngine().SQL(r.buildSql()).Find(&sData)
- for i := range sData {
- sData[i].calc()
- }
- return sData, err
- }
- // TradeHolderDetail 持仓明细
- type TradeHolderDetail struct {
- TRADEID string `json:"tradeid" xorm:"TRADEID" form:"tradeid"` // 成交单号(101+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
- TRADEDATE string `json:"tradedate" xorm:"TRADEDATE" form:"tradedate"` // 交易日(yyyyMMdd)
- MARKETID int32 `json:"marketid" xorm:"MARKETID" form:"marketid"` // 市场ID
- GOODSID int32 `json:"goodsid" xorm:"GOODSID" form:"goodsid"` // 商品ID
- ACCOUNTID int64 `json:"accountid" xorm:"ACCOUNTID" form:"accountid"` // 账号ID
- BUYORSELL int32 `json:"buyorsell" xorm:"BUYORSELL" form:"buyorsell"` // 方向 - 0:买 1:卖
- OPENQTY SFLOAT64 `json:"openqty" xorm:"OPENQTY"` // 建仓数量
- HOLDERQTY SFLOAT64 `json:"holderqty" xorm:"HOLDERQTY"` // 持仓数量
- FREEZEQTY SFLOAT64 `json:"freezeqty" xorm:"FREEZEQTY"` // 冻结数量
- OPENPRICE float64 `json:"openprice" xorm:"OPENPRICE"` // 建仓价格
- HOLDERPRICE float64 `json:"holderprice" xorm:"HOLDERPRICE"` // 持仓价格
- TRADEAMOUNT float64 `json:"tradeamount" xorm:"TRADEAMOUNT"` // 成交金额
- HOLDERAMOUNT float64 `json:"holderamount" xorm:"HOLDERAMOUNT"` // 持仓金额
- RELEASEAMOUNT float64 `json:"releaseamount" xorm:"RELEASEAMOUNT"` // 释放持仓金额
- HOLDERDAYS int32 `json:"holderdays" xorm:"HOLDERDAYS"` // 剩余冻结天数
- TRADETIME string `json:"tradetime" xorm:"TRADETIME"` // 交易时间
- TRADEPROPERTY int32 `json:"tradeproperty" xorm:"TRADEPROPERTY"` // 交易属性
- OPTIONTYPE int32 `json:"optiontype" xorm:"OPTIONTYPE"` // 期权类型 - 1:认购(看涨) 2:认沽(看跌)
- PREMIUM float64 `json:"premium" xorm:"PREMIUM"` // 权利金
- EXPIRETYPE int32 `json:"expiretype" xorm:"EXPIRETYPE"` // 行权日类型 - 1:滚动行权 2:固定日行权
- EXPIRECYCLE int32 `json:"expirecycle" xorm:"EXPIRECYCLE"` // 行权周期(天) - 1:滚动行权时填写
- EXPIREDATE string `json:"expiredate" xorm:"EXPIREDATE" form:"expiredate"` // 行权日(yyyyMMdd) - 到期日
- ISPREEXERCISE int32 `json:"ispreexercise" xorm:"ISPREEXERCISE"` // 是否预申报- 0:否 1:是 2:不可行权
- PREEXERCISEPRICE float64 `json:"preexerciseprice" xorm:"PREEXERCISEPRICE"` // 预申报价格
- ISCONFIRMEXERCISE int32 `json:"isconfirmexercise" xorm:"ISCONFIRMEXERCISE"` // 是否确认行权- 0:否 1:是
- HOLDERCREDIT float64 `json:"holdercredit" xorm:"HOLDERCREDIT"` // 持仓授信金额
- RELEASEHOLDERCREDIT float64 `json:"releaseholdercredit" xorm:"RELEASEHOLDERCREDIT"` // 释放持仓授信金额
- TradeGoodsEx `xorm:"extends"`
- TradeAccountEx `xorm:"extends"`
- FtAccountIDs string `json:"-" form:"accids"` // 资金账号,逗号隔开
- FtTradeMode string `json:"-" form:"trademodes"` // 交易模式筛选, 逗号隔开
- FtMarketIDs string `json:"-" form:"marketids"` // 市场id, 逗号隔开
- RISKCONTROLMODE int32 `json:"riskcontrolmode" form:"riskcontrolmode" xorm:"RISKCONTROLMODE"` // 风控方式(52模式) 1:按单风控 2:按账户风控
- }
- func (r *TradeHolderDetail) calc() {
- if r.QTYDECIMALPLACE != 0 {
- r.OPENQTY.Power10(r.QTYDECIMALPLACE * -1)
- r.HOLDERQTY.Power10(r.QTYDECIMALPLACE * -1)
- r.FREEZEQTY.Power10(r.QTYDECIMALPLACE * -1)
- }
- }
- func (r *TradeHolderDetail) buildSql() string {
- var sqlId utils.SQLVal = `
- with gtmp as
- (select g.goodsid,
- g.goodsname,
- g.goodscode,
- g.decimalplace,
- g.qtydecimalplace,
- g.agreeunit,
- g.marketid,
- g.goodunitid,
- g.currencyid,
- g.refgoodsid,
- g.refgoodscode,
- e.enumdicname,
- e2.enumdicname currencyname,
- m.marketname,
- m.trademode,
- m.riskcontrolmode
- from goods g
- left join enumdicitem e
- on g.goodunitid = e.enumitemname
- and e.enumdiccode = 'goodsunit'
- left join enumdicitem e2
- on g.currencyid = e2.enumitemname
- and e2.enumdiccode = 'currency'
- left join market m
- on g.marketid = m.marketid
- where g.GOODSSTATUS <> 7 ),
- utmp as
- (select ta.accountid,
- ta.accountname taname,
- u.userid,
- u.accountname username,
- TA.CURRENCYID TACURRENCYID
- from taaccount ta
- left join useraccount u
- on ta.relateduserid = u.userid)
- SELECT to_char(t.TRADEID) TRADEID,
- t.TRADEDATE,
- t.MARKETID,
- t.GOODSID,
- t.ACCOUNTID,
- t.BUYORSELL,
- t.OPENQTY,
- t.HOLDERQTY,
- t.FREEZEQTY,
- t.OPENPRICE,
- t.HOLDERPRICE,
- t.TRADEAMOUNT,
- t.HOLDERAMOUNT,
- t.RELEASEAMOUNT,
- t.HOLDERDAYS,
- to_char(t.TRADETIME, 'yyyy-mm-dd hh24:mi:ss') TRADETIME,
- t.TRADEPROPERTY,
- t.OPTIONTYPE,
- t.PREMIUM,
- t.EXPIRETYPE,
- t.EXPIRECYCLE,
- t.EXPIREDATE,
- t.ISPREEXERCISE,
- t.PREEXERCISEPRICE,
- t.ISCONFIRMEXERCISE,
- t.HOLDERCREDIT,
- t.RELEASEHOLDERCREDIT,
- gtmp.*,
- utmp.*
- FROM TRADE_HOLDERDETAIL t
- INNER JOIN gtmp on t.goodsid=gtmp.goodsid
- LEFT JOIN utmp on t.accountid=utmp.accountid
- WHERE 1 = 1 and t.HOLDERQTY > 0
- `
- sqlId.AndEx("gtmp.riskcontrolmode", r.RISKCONTROLMODE, r.RISKCONTROLMODE > 0)
- sqlId.AndEx("utmp.userid", r.USERID, r.USERID > 0)
- sqlId.AndEx("t.goodsid", r.GOODSID, r.GOODSID > 0)
- sqlId.AndEx("t.BUYORSELL", r.BUYORSELL, r.BUYORSELL != -1)
- sqlId.JoinEx(r.FtTradeMode != "", fmt.Sprintf(" and gtmp.trademode in(%v)", r.FtTradeMode))
- sqlId.JoinEx(r.FtMarketIDs != "", fmt.Sprintf(" and gtmp.marketid in(%v)", r.FtMarketIDs))
- sqlId.JoinEx(r.FtAccountIDs != "", fmt.Sprintf(" and t.accountid in(%v)", r.FtAccountIDs))
- sqlId.OrderByDesc("t.TRADETIME")
- return sqlId.String()
- }
- // GetDataEx 获取持仓明细
- func (r *TradeHolderDetail) GetDataEx() (interface{}, error) {
- sData := make([]TradeHolderDetail, 0)
- err := db.GetEngine().SQL(r.buildSql()).Find(&sData)
- for i := range sData {
- sData[i].calc()
- }
- return sData, err
- }
|