/** * @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'"` // 用户名称 } // 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, 逗号隔开 } 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 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 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 LEFT JOIN gtmp on t.goodsid=gtmp.goodsid LEFT JOIN utmp on t.accountid=utmp.accountid WHERE 1 = 1 and t.HOLDERQTY > 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 }