瀏覽代碼

1.修改 敞口报表/合同明细接口
2.增加 查询敞口关联的主力合约接口
3.#95593 计算期末/期初 均价
4.增加 查询敞口报表/期货明细接口
5.更新手机端菜单(mobile_menu.json)

zou.yingbin 4 年之前
父節點
當前提交
682a31bff1
共有 9 個文件被更改,包括 5626 次插入5973 次删除
  1. 2 2
      config/mobile_menu.json
  2. 19 0
      controllers/ermcp/qryExposure.go
  3. 29 0
      controllers/ermcp3/qryErmcp3Report.go
  4. 2400 2505
      docs/docs.go
  5. 2400 2505
      docs/swagger.json
  6. 181 938
      docs/swagger.yaml
  7. 531 23
      models/ermcp3Report.go
  8. 62 0
      models/ermcpExposure.go
  9. 2 0
      routers/router.go

+ 2 - 2
config/mobile_menu.json

@@ -314,7 +314,7 @@
                 "sort": 2,
                 "type": 1,
                 "rulekey": "client_report_futures",
-                "isshow": false,
+                "isshow": true,
                 "remark": "报表查询-期货报表",
                 "children": [
                     {
@@ -323,7 +323,7 @@
                         "sort": 1,
                         "type": 1,
                         "rulekey": "client_report_futures_account",
-                        "isshow": false,
+                        "isshow": true,
                         "remark": "报表查询-期货报表-账户明细",
                         "children": [] 
                     }

+ 19 - 0
controllers/ermcp/qryExposure.go

@@ -297,3 +297,22 @@ func QueryExposureHedgePositionDetail(c *gin.Context) {
 	m := models.ErmcpHedgePositionDetail{AREAUSERID: req.AreaUserId, HEDGEGOODSID: req.GoodsId}
 	appG.DoGetDataEx(&m)
 }
+
+// QueryExposureGoods
+// @Summary 查询敞口主力合约
+// @Produce json
+// @Security ApiKeyAuth
+// @Param middlegoodsid query int true "套保商品id"
+// @Success 200 {array} models.ErmcpMiddlegoodsRelateGoods
+// @Failure 500 {object} app.Response
+// @Router /Ermcp/QueryExposureGoods [get]
+// @Tags 企业风险管理(app)
+func QueryExposureGoods(c *gin.Context) {
+	a := app.GinUtils{Gin: app.Gin{C: c}}
+	req := struct {
+		MIDDLEGOODSID int32 `form:"middlegoodsid" binding:"required"` // 用户id
+	}{}
+	a.DoBindReq(&req)
+	m := models.ErmcpMiddlegoodsRelateGoods{MIDDLEGOODSID: req.MIDDLEGOODSID}
+	a.DoGetDataI(&m)
+}

+ 29 - 0
controllers/ermcp3/qryErmcp3Report.go

@@ -303,6 +303,35 @@ func QryAreaExpourseHedgeplanDetail(c *gin.Context) {
 	a.DoGetDataI(&m)
 }
 
+// QryAreaExpourseFutuDetail
+// @Summary 查询敞口期货明细(敞口报表/期货明细)
+// @Produce json
+// @Security ApiKeyAuth
+// @Param userid query int true "用户ID"
+// @Param middlegoodsid query int true "套保商品id"
+// @Param cycletype query int true "周期类型 - 0:日 1:月 2:季 3:年 4:周 5:全报表【原值】"
+// @Param cycletime query string true "周期时间 日(YYYYMMDD) 月(YYYYMM)  季(YYYYQ) 年(YYYY) 周(YYYYMMDD周内任意一天) 全(0)【原值】"
+// @Success 200 {array} models.Ermcp3ExposureFutuDetail
+// @Failure 500 {object} app.Response
+// @Router /Ermcp3/QryAreaExpourseFutuDetail [get]
+// @Tags 企业风险管理v3(app)
+func QryAreaExpourseFutuDetail(c *gin.Context) {
+	a := app.GinUtils{Gin: app.Gin{C: c}}
+	tmp := struct {
+		USERID        int64  `form:"userid" binding:"required"`        // 用户id
+		MIDDLEGOODSID int32  `form:"middlegoodsid" binding:"required"` // 套保商品id
+		CYCLETYPE     int32  `form:"cycletype"`
+		CYCLETIME     string `form:"cycletime"`
+	}{}
+	a.DoBindReq(&tmp)
+	req := QryReportReq{USERID: tmp.USERID, QUERYTYPE: 2, CYCLETYPE: tmp.CYCLETYPE, CYCLETIME: tmp.CYCLETIME}
+	a.CheckParam(&req)
+	req.CovertRequest()
+	m := models.Ermcp3ExposureFutuDetail{USERID: req.USERID,
+		MIDDLEGOODSID: tmp.MIDDLEGOODSID, RECKONDATE: req.TRADEDATE, BeginDate: req.BEGINDATE, EndDate: req.ENDDATE}
+	a.DoGetDataI(&m)
+}
+
 // QryAreaSpotplReport
 // @Summary 查询现货报表
 // @Produce json

File diff suppressed because it is too large
+ 2400 - 2505
docs/docs.go


File diff suppressed because it is too large
+ 2400 - 2505
docs/swagger.json


File diff suppressed because it is too large
+ 181 - 938
docs/swagger.yaml


+ 531 - 23
models/ermcp3Report.go

@@ -671,12 +671,16 @@ type Ermcp3ExposureContractDetail struct {
 	BRANDNAME          string  `json:"brandname"  xorm:"'BRANDNAME'"`                   // 品牌名称
 	DELIVERYGOODSCODE  string  `json:"deliverygoodscode"  xorm:"'DELIVERYGOODSCODE'"`   // 现货商品代码
 	DELIVERYGOODSNAME  string  `json:"deliverygoodsname"  xorm:"'DELIVERYGOODSNAME'"`   // 现货商品名称
+	CONVERTFACTOR      float64 `json:"convertfactor"  xorm:"'CONVERTFACTOR'"`           // 标仓系数
+	TODAYPRICEDQTY     float64 `json:"todaypricedqty"  xorm:"'TODAYPRICEDQTY'"`         // 今定价量
 
-	EnumdicName  string  `json:"enumdicname"`  // 单位名称
-	BUYUSERNAME  string  `json:"buyusername"`  // 采购方名称
-	SELLUSERNAME string  `json:"sellusername"` // 销售方名称
-	CurQty       float64 `json:"curqty"`       // 今定价量
-	DiffQty      float64 `json:"diffqty"`      // 套保品种今变动量
+	EnumdicName      string  `json:"enumdicname"`      // 单位名称
+	BUYUSERNAME      string  `json:"buyusername"`      // 采购方名称
+	SELLUSERNAME     string  `json:"sellusername"`     // 销售方名称
+	CurQty           float64 `json:"curqty"`           // 今定价量
+	DiffQty          float64 `json:"diffqty"`          // 套保品种今变动量
+	DiffHedgeQty     float64 `json:"diffhedgeqty"`     // 套保变动量
+	DiffNeedHedgeQty float64 `json:"diffneedhedgeqty"` // 应套保变动量
 
 	BeginDate string `json:"-"` // 开始交易日
 	EndDate   string `json:"-"` // 结束交易日
@@ -685,6 +689,12 @@ type Ermcp3ExposureContractDetail struct {
 func (r *Ermcp3ExposureContractDetail) calc() {
 	r.CurQty = r.QTY
 	r.DiffQty = r.QTY * r.CONVERTRATIO
+	r.DiffHedgeQty = r.TODAYPRICEDQTY * r.CONVERTRATIO * r.CONVERTFACTOR
+	if r.BIZTYPE == 1 {
+		r.DiffNeedHedgeQty = r.TODAYPRICEDQTY * r.CONVERTRATIO * r.CONVERTFACTOR * r.NEEDHEDGERATIO
+	} else {
+		r.DiffNeedHedgeQty = r.TODAYPRICEDQTY * r.CONVERTRATIO * r.CONVERTFACTOR * r.NEEDARBITRAGERATIO
+	}
 	r.EnumdicName = mtpcache.GetEnumDicitemName(r.UNITID)
 	r.BUYUSERNAME = mtpcache.GetUserNameByUserId(r.BUYUSERID)
 	r.SELLUSERNAME = mtpcache.GetUserNameByUserId(r.SELLUSERID)
@@ -704,10 +714,12 @@ func (r *Ermcp3ExposureContractDetail) buildSql() string {
 		"       s.qty," +
 		"       s.pricedqty," +
 		"       s.wrstandardid," +
-		"       s.audittradedate tradedate," +
+		"       s.reckondate tradedate," +
+		"       s.todaypricedqty," +
 		"       w.wrstandardname," +
 		"       w.wrstandardcode," +
 		"       w.unitid," +
+		"       w.convertfactor," +
 		"       mg.middlegoodsname," +
 		"       mg.middlegoodscode," +
 		"       mg.goodsunitid," +
@@ -718,7 +730,7 @@ func (r *Ermcp3ExposureContractDetail) buildSql() string {
 		"       g.deliverygoodscode," +
 		"       g.deliverygoodsname" +
 		"  from erms2_wrsconvertdetail t" +
-		" inner join ermcp_spotcontract s" +
+		" inner join reckon_ermcp_spotcontract s" +
 		"    on t.deliverygoodsid = s.deliverygoodsid" +
 		"  left join erms_middlegoods mg" +
 		"    on t.middlegoodsid = mg.middlegoodsid" +
@@ -726,12 +738,13 @@ func (r *Ermcp3ExposureContractDetail) buildSql() string {
 		"    on s.wrstandardid = w.wrstandardid" +
 		"  left join dgfactoryitem dg" +
 		"    on s.spotgoodsbrandid = dg.dgfactoryitemid" +
-		"  left join deliverygoods g on s.deliverygoodsid=g.deliverygoodsid" +
+		"  left join deliverygoods g" +
+		"    on s.deliverygoodsid = g.deliverygoodsid" +
 		" where t.wrstandardid = 0" +
 		"   and s.contractstatus in (2, 3)"
-	sqlId.AndEx("s.audittradedate", r.TRADEDATE, len(r.TRADEDATE) > 0)
+	sqlId.AndEx("s.reckondate", r.TRADEDATE, len(r.TRADEDATE) > 0)
 	if len(r.BeginDate) > 0 && len(r.EndDate) > 0 {
-		sqlId.Join(fmt.Sprintf(" and s.audittradedate >= '%v' and s.audittradedate <= '%v'", r.BeginDate, r.EndDate))
+		sqlId.Join(fmt.Sprintf(" and s.reckondate >= '%v' and s.reckondate <= '%v'", r.BeginDate, r.EndDate))
 	}
 	sqlId.And("t.middlegoodsid", r.MIDDLEGOODSID)
 	sqlId.Join(fmt.Sprintf(" and %v in(s.userid, s.tradeuserid)", r.USERID))
@@ -911,6 +924,18 @@ func (r *Ermcp3AreaSpotPLReport) calc() {
 	r.UNITIDNAME = mtpcache.GetEnumDicitemName(r.UNITID)
 	r.ACCOUNTNAME = mtpcache.GetUserNameByUserId(r.AREAUSERID)
 	r.CURRENCYNAME = mtpcache.GetCurrencyName(r.CURRENCYID)
+	if r.CURQTY > 0 {
+		r.CURAVERAGEPRICE = r.CURAMOUNT / r.CURQTY
+	}
+	if r.ORIQTY > 0 {
+		r.ORIAVERAGEPRICE = r.ORIAMOUNT / r.ORIQTY
+	}
+	if r.TODAYBUYQTY > 0 {
+		r.TODAYBUYAVERAGEPRICE = r.TODAYBUYAMOUNT / r.TODAYBUYQTY
+	}
+	if r.TODAYSELLQTY > 0 {
+		r.TODAYSELLAVERAGEPRICE = r.TODAYSELLAMOUNT / r.TODAYSELLQTY
+	}
 }
 
 func (r *Ermcp3AreaSpotPLReport) buildSql() string {
@@ -940,20 +965,16 @@ func (r *Ermcp3AreaSpotPLReport) buildSqlDay() string {
 		"               sum(t.ORISELLQTY) ORISELLQTY," +
 		"               sum(t.ORISELLAMOUNT) ORISELLAMOUNT," +
 		"               sum(t.ORIQTY) ORIQTY," +
-		"               sum(t.ORIAVERAGEPRICE) ORIAVERAGEPRICE," +
 		"               sum(t.ORIAMOUNT) ORIAMOUNT," +
 		"               sum(t.TODAYBUYQTY) TODAYBUYQTY," +
 		"               sum(t.TODAYBUYAMOUNT) TODAYBUYAMOUNT," +
-		"               sum(t.TODAYBUYAVERAGEPRICE) TODAYBUYAVERAGEPRICE," +
 		"               sum(t.TODAYSELLQTY) TODAYSELLQTY," +
 		"               sum(t.TODAYSELLAMOUNT) TODAYSELLAMOUNT," +
-		"               sum(t.TODAYSELLAVERAGEPRICE) TODAYSELLAVERAGEPRICE," +
 		"               sum(t.CURBUYQTY) CURBUYQTY," +
 		"               sum(t.CURBUYAMOUNT) CURBUYAMOUNT," +
 		"               sum(t.CURSELLQTY) CURSELLQTY," +
 		"               sum(t.CURSELLAMOUNT) CURSELLAMOUNT," +
 		"               sum(t.CURQTY) CURQTY," +
-		"               sum(t.CURAVERAGEPRICE) CURAVERAGEPRICE," +
 		"               sum(t.CURAMOUNT) CURAMOUNT," +
 		"               max(t.CURSPOTPRICE) CURSPOTPRICE," +
 		"               sum(t.CURMARKETVALUE) CURMARKETVALUE," +
@@ -1000,20 +1021,16 @@ func (r *Ermcp3AreaSpotPLReport) buildSqlDayDetail() string {
 		"               sum(t.ORISELLQTY) ORISELLQTY," +
 		"               sum(t.ORISELLAMOUNT) ORISELLAMOUNT," +
 		"               sum(t.ORIQTY) ORIQTY," +
-		"               sum(t.ORIAVERAGEPRICE) ORIAVERAGEPRICE," +
 		"               sum(t.ORIAMOUNT) ORIAMOUNT," +
 		"               sum(t.TODAYBUYQTY) TODAYBUYQTY," +
 		"               sum(t.TODAYBUYAMOUNT) TODAYBUYAMOUNT," +
-		"               sum(t.TODAYBUYAVERAGEPRICE) TODAYBUYAVERAGEPRICE," +
 		"               sum(t.TODAYSELLQTY) TODAYSELLQTY," +
 		"               sum(t.TODAYSELLAMOUNT) TODAYSELLAMOUNT," +
-		"               sum(t.TODAYSELLAVERAGEPRICE) TODAYSELLAVERAGEPRICE," +
 		"               sum(t.CURBUYQTY) CURBUYQTY," +
 		"               sum(t.CURBUYAMOUNT) CURBUYAMOUNT," +
 		"               sum(t.CURSELLQTY) CURSELLQTY," +
 		"               sum(t.CURSELLAMOUNT) CURSELLAMOUNT," +
 		"               sum(t.CURQTY) CURQTY," +
-		"               sum(t.CURAVERAGEPRICE) CURAVERAGEPRICE," +
 		"               sum(t.CURAMOUNT) CURAMOUNT," +
 		"               max(t.CURSPOTPRICE) CURSPOTPRICE," +
 		"               sum(t.CURMARKETVALUE) CURMARKETVALUE," +
@@ -1063,20 +1080,16 @@ func (r *Ermcp3AreaSpotPLReport) buildSqlCycle() string {
 		"               sum(t.ORISELLQTY) ORISELLQTY," +
 		"               sum(t.ORISELLAMOUNT) ORISELLAMOUNT," +
 		"               sum(t.ORIQTY) ORIQTY," +
-		"               sum(t.ORIAVERAGEPRICE) ORIAVERAGEPRICE," +
 		"               sum(t.ORIAMOUNT) ORIAMOUNT," +
 		"               sum(t.TODAYBUYQTY) TODAYBUYQTY," +
 		"               sum(t.TODAYBUYAMOUNT) TODAYBUYAMOUNT," +
-		"               sum(t.TODAYBUYAVERAGEPRICE) TODAYBUYAVERAGEPRICE," +
 		"               sum(t.TODAYSELLQTY) TODAYSELLQTY," +
 		"               sum(t.TODAYSELLAMOUNT) TODAYSELLAMOUNT," +
-		"               sum(t.TODAYSELLAVERAGEPRICE) TODAYSELLAVERAGEPRICE," +
 		"               sum(t.CURBUYQTY) CURBUYQTY," +
 		"               sum(t.CURBUYAMOUNT) CURBUYAMOUNT," +
 		"               sum(t.CURSELLQTY) CURSELLQTY," +
 		"               sum(t.CURSELLAMOUNT) CURSELLAMOUNT," +
 		"               sum(t.CURQTY) CURQTY," +
-		"               sum(t.CURAVERAGEPRICE) CURAVERAGEPRICE," +
 		"               sum(t.CURAMOUNT) CURAMOUNT," +
 		"               max(t.CURSPOTPRICE) CURSPOTPRICE," +
 		"               sum(t.CURMARKETVALUE) CURMARKETVALUE," +
@@ -1927,7 +1940,7 @@ type Ermcp3TaFutuReDataReport struct {
 	MIDDLEGOODSQTY         float64 `json:"middlegoodsqty"  xorm:"MIDDLEGOODSQTY"`                 // 套保品种期末量 (=交易品种期末量 * 期货品种折算系数)
 	TODAYMIDDLEGOODSQTY    float64 `json:"todaymiddlegoodsqty"  xorm:"TODAYMIDDLEGOODSQTY"`       // 套保品种变化量 (= 交易品种变化量*期货品种折算系数)
 	RECKONPL2              float64 `json:"reckonpl2"  xorm:"RECKONPL2"`                           // 结算逐笔盈亏
-	OUTERGROUPCODE         string  `json:"outergroupcode"  xorm:"'OUTERGROUPCODE'"`               //  交易品种代码
+	OUTERGROUPCODE         string  `json:"outergroupcode"  xorm:"'OUTERGROUPCODE'"`               // 交易品种代码
 	GOODSGROUPNAME         string  `json:"goodsgroupname"  xorm:"'GOODSGROUPNAME'"`               // 交易品种名称
 	GOODSCODE              string  `json:"goodscode"  xorm:"'GOODSCODE'"`                         // 交易合约代码
 	GOODSNAME              string  `json:"goodsname"  xorm:"'GOODSNAME'"`                         // 交易合约名称
@@ -2185,3 +2198,498 @@ func (r *Ermcp3TaFutuReDataReport) GetDataEx() (interface{}, error) {
 	}
 	return sData, err
 }
+
+// ReckonDayPosition 持仓头寸日照
+type ReckonDayPosition struct {
+	ACCOUNTID           int64   `json:"accountid"  xorm:"ACCOUNTID"`                     // 账号Id
+	GOODSID             int32   `json:"goodsid"  xorm:"GOODSID"`                         // 商品Id
+	RECKONDATE          string  `json:"reckondate"  xorm:"RECKONDATE"`                   // 日照日期(yyyyMMdd)
+	BUYPOSITIONQTY      int32   `json:"buypositionqty"  xorm:"BUYPOSITIONQTY"`           // 买期初持仓数量
+	BUYHOLDERAMOUNT     float64 `json:"buyholderamount"  xorm:"BUYHOLDERAMOUNT"`         // 买持仓期初总金额
+	BUYCURPOSITIONQTY   int32   `json:"buycurpositionqty"  xorm:"BUYCURPOSITIONQTY"`     // 买当前持仓总数量
+	BUYCURHOLDERAMOUNT  float64 `json:"buycurholderamount"  xorm:"BUYCURHOLDERAMOUNT"`   // 买当前持仓总金额
+	BUYFROZENQTY        int32   `json:"buyfrozenqty"  xorm:"BUYFROZENQTY"`               // 买持仓冻结
+	BUYOTHERFROZENQTY   int32   `json:"buyotherfrozenqty"  xorm:"BUYOTHERFROZENQTY"`     // 买持仓其他冻结(交割冻结)
+	BUYOPENREQQTY       int32   `json:"buyopenreqqty"  xorm:"BUYOPENREQQTY"`             // 买开仓申请数量
+	BUYRECKONPL         float64 `json:"buyreckonpl"  xorm:"BUYRECKONPL"`                 // 买结算盈亏
+	BUYINTEREST         float64 `json:"buyinterest"  xorm:"BUYINTEREST"`                 // 买递延费(仓储费)
+	BUYUSEDMARGIN       float64 `json:"buyusedmargin"  xorm:"BUYUSEDMARGIN"`             // 占用保证金
+	BUYOPENTOTALQTY     int32   `json:"buyopentotalqty"  xorm:"BUYOPENTOTALQTY"`         // 今日买开仓总数量
+	BUYCLOSETOTALQTY    int32   `json:"buyclosetotalqty"  xorm:"BUYCLOSETOTALQTY"`       // 今日买平仓总数量
+	BUYCLOSETOTALPL     float64 `json:"buyclosetotalpl"  xorm:"BUYCLOSETOTALPL"`         // 买平仓总盈亏
+	SELLPOSITIONQTY     int32   `json:"sellpositionqty"  xorm:"SELLPOSITIONQTY"`         // 卖期初持仓数量
+	SELLHOLDERAMOUNT    float64 `json:"sellholderamount"  xorm:"SELLHOLDERAMOUNT"`       // 卖持仓期初总金额
+	SELLCURPOSITIONQTY  int32   `json:"sellcurpositionqty"  xorm:"SELLCURPOSITIONQTY"`   // 卖当前持仓数量
+	SELLCURHOLDERAMOUNT float64 `json:"sellcurholderamount"  xorm:"SELLCURHOLDERAMOUNT"` // 卖当前持仓总金额
+	SELLFROZENQTY       int32   `json:"sellfrozenqty"  xorm:"SELLFROZENQTY"`             // 卖持仓冻结
+	SELLOTHERFROZENQTY  int32   `json:"sellotherfrozenqty"  xorm:"SELLOTHERFROZENQTY"`   // 卖持仓其他冻结(交割冻结)
+	SELLOPENREQQTY      int32   `json:"sellopenreqqty"  xorm:"SELLOPENREQQTY"`           // 卖开仓申请数量
+	SELLRECKONPL        float64 `json:"sellreckonpl"  xorm:"SELLRECKONPL"`               // 卖结算盈亏
+	SELLINTEREST        float64 `json:"sellinterest"  xorm:"SELLINTEREST"`               // 卖递延费
+	SELLUSEDMARGIN      float64 `json:"sellusedmargin"  xorm:"SELLUSEDMARGIN"`           // 卖占用保证金-作废
+	SELLOPENTOTALQTY    int32   `json:"sellopentotalqty"  xorm:"SELLOPENTOTALQTY"`       // 卖开仓总数量
+	SELLCLOSETOTALQTY   int32   `json:"sellclosetotalqty"  xorm:"SELLCLOSETOTALQTY"`     // 卖平仓总数量
+	SELLCLOSETOTALPL    float64 `json:"sellclosetotalpl"  xorm:"SELLCLOSETOTALPL"`       // 卖平仓总盈亏
+	TRADEPROPERTY       int32   `json:"tradeproperty"  xorm:"TRADEPROPERTY"`             // 交易属性
+	MARGINALGORITHM     int32   `json:"marginalgorithm"  xorm:"MARGINALGORITHM"`         // 保证金收取方式 - 1:比率 2:固定
+	MARGINVALUE         float64 `json:"marginvalue"  xorm:"MARGINVALUE"`                 // 保证金设置值(投资管理系统-多LongMarginValue)
+	BUYFEEALGORITHM     int32   `json:"buyfeealgorithm"  xorm:"BUYFEEALGORITHM"`         // 买递延费收取方式 - 1:比率  2:固定
+	BUYMEMBERFEEVALUE   float64 `json:"buymemberfeevalue"  xorm:"BUYMEMBERFEEVALUE"`     // 买会员递延费设置值
+	BUYEXCHAGEFEEVALUE  float64 `json:"buyexchagefeevalue"  xorm:"BUYEXCHAGEFEEVALUE"`   // 买交易所递延费设置值
+	SELLFEEALGORITHM    int32   `json:"sellfeealgorithm"  xorm:"SELLFEEALGORITHM"`       // 卖递延费收取方式 - 1:比率  2:固定
+	SELLMEMBERFEEVALUE  float64 `json:"sellmemberfeevalue"  xorm:"SELLMEMBERFEEVALUE"`   // 卖会员递延费设置值
+	SELLEXCHAGEFEEVALUE float64 `json:"sellexchagefeevalue"  xorm:"SELLEXCHAGEFEEVALUE"` // 卖交易所递延费设置值
+	INTEREST2           float64 `json:"interest2"  xorm:"INTEREST2"`                     // 过夜费
+	ACCOUNTCURRENCYID   int32   `json:"accountcurrencyid"  xorm:"ACCOUNTCURRENCYID"`     // 账户币种ID
+	GOODSCURRENCYID     int32   `json:"goodscurrencyid"  xorm:"GOODSCURRENCYID"`         // 商品币种ID
+	CUREXCHANGERATE     float64 `json:"curexchangerate"  xorm:"CUREXCHANGERATE"`         // 当前汇率
+	BUYRECKONPL2        float64 `json:"buyreckonpl2"  xorm:"BUYRECKONPL2"`               // 买结算盈亏(逐笔) - 根据持仓单日照表字段汇率
+	SELLRECKONPL2       float64 `json:"sellreckonpl2"  xorm:"SELLRECKONPL2"`             // 结算盈亏(逐笔) - 根据持仓单日照表字段汇率
+	BUYCURTDPOSITION    int32   `json:"buycurtdposition"  xorm:"BUYCURTDPOSITION"`       // 买期末今日头寸
+	BUYFRETDPOSITION    int32   `json:"buyfretdposition"  xorm:"BUYFRETDPOSITION"`       // 买冻结今日头寸
+	SELLCURTDPOSITION   int32   `json:"sellcurtdposition"  xorm:"SELLCURTDPOSITION"`     // 卖期末今日头寸
+	SELLFRETDPOSITION   int32   `json:"sellfretdposition"  xorm:"SELLFRETDPOSITION"`     // 卖冻结今日头寸
+	INTERESTCHARGE      float64 `json:"interestcharge"  xorm:"INTERESTCHARGE"`           // 利息(110)
+	SHORTMARGINVALUE    float64 `json:"shortmarginvalue"  xorm:"SHORTMARGINVALUE"`       // 保证金设置值(投资管理系统-空)
+	BUYDEFERCHARGE      float64 `json:"buydefercharge"  xorm:"BUYDEFERCHARGE"`           // 买递延费2(仓储费2)
+	SELLDEFERCHARGE     float64 `json:"selldefercharge"  xorm:"SELLDEFERCHARGE"`         // 卖递延费2
+
+	RELATEDUSERID      int64   `json:"relateduserid"  xorm:"'RELATEDUSERID'"`           // 关联用户id
+	MIDDLEGOODSID      int32   `json:"middlegoodsid"  xorm:"'MIDDLEGOODSID'"`           // 套保商品id
+	MIDDLEGOODSCODE    string  `json:"middlegoodscode"  xorm:"'MIDDLEGOODSCODE'"`       // 套保商品代码
+	MIDDLEGOODSNAME    string  `json:"middlegoodsname"  xorm:"'MIDDLEGOODSNAME'"`       // 套保商品名称
+	NEEDHEDGERATIO     float64 `json:"needhedgeratio"  xorm:"'NEEDHEDGERATIO'"`         // 应套保比例
+	NEEDARBITRAGERATIO float64 `json:"needarbitrageratio"  xorm:"'NEEDARBITRAGERATIO'"` // 应套利比例
+	GOODSGROUPID       int32   `json:"goodsgroupid"  xorm:"'GOODSGROUPID'"`             // 交易品种id
+	CONVERTRATIO       float64 `json:"convertratio"  xorm:"'CONVERTRATIO'"`             // 折算系数
+	GOODSCODE          string  `json:"goodscode"  xorm:"'GOODSCODE'"`                   // 交易商品代码
+	GOODSNAME          string  `json:"goodsname"  xorm:"'GOODSNAME'"`                   // 交易商品名称
+	GOODUNITID         int32   `json:"goodunitid"  xorm:"'GOODUNITID'"`                 // 交易商品单位id
+	AGREEUNIT          float64 `json:"agreeunit"  xorm:"'AGREEUNIT'"`                   // 合约乘数
+	ENUMDICNAME        string  `json:"enumdicname"`                                     // 单位名称(交易商品)
+	ACCOUNTNAME        string  `json:"accountname"  xorm:"'ACCOUNTNAME'"`               // 交易账户
+
+	DiffBuyQty        float64 `json:"diffbuyqty"`        // 交易品种今变化量(买)
+	DiffMgBuyQty      float64 `json:"diffmgbuyqty"`      // 套保品种今变化量(买)
+	DiffNeedMgBuyQty  float64 `json:"diffneedmgbuyqty"`  // 应套保总量变化量(买)
+	DiffSellQty       float64 `json:"diffsellqty"`       // 交易品种今变化量(卖)
+	DiffMgSellQty     float64 `json:"diffmgsellqty"`     // 套保品种今变化量(卖)
+	DiffNeedMgSellQty float64 `json:"diffneedmgsellqty"` // 应套保总量变化量(卖)
+
+	BeginDate string `json:"begindate"` // 开始交易日
+	EndDate   string `json:"enddate"`   // 结束交易日
+}
+
+func (r *ReckonDayPosition) calc() {
+	r.ENUMDICNAME = mtpcache.GetEnumDicitemName(r.GOODUNITID)
+	if r.BUYPOSITIONQTY > 0 || r.BUYCURPOSITIONQTY > 0 {
+		r.DiffBuyQty = float64(r.BUYCURPOSITIONQTY) * r.AGREEUNIT
+		r.DiffMgBuyQty = float64(r.BUYCURPOSITIONQTY) * r.AGREEUNIT * r.CONVERTRATIO
+		r.DiffNeedMgBuyQty = float64(r.BUYCURPOSITIONQTY) * r.AGREEUNIT * r.CONVERTRATIO * r.NEEDHEDGERATIO
+	}
+	if r.SELLPOSITIONQTY > 0 || r.SELLCURPOSITIONQTY > 0 {
+		r.DiffBuyQty = float64(r.SELLCURPOSITIONQTY) * r.AGREEUNIT
+		r.DiffMgBuyQty = float64(r.SELLCURPOSITIONQTY) * r.AGREEUNIT * r.CONVERTRATIO
+		r.DiffNeedMgBuyQty = float64(r.SELLCURPOSITIONQTY) * r.AGREEUNIT * r.CONVERTRATIO * r.NEEDHEDGERATIO
+	}
+}
+
+func (r *ReckonDayPosition) buildSql() string {
+	var sqlId utils.SQLVal = "with tmp as" +
+		" (select t.middlegoodsid," +
+		"         t.middlegoodscode," +
+		"         t.middlegoodsname," +
+		"         t.needhedgeratio," +
+		"         t.needarbitrageratio," +
+		"         t.goodsgroupid," +
+		"         c.convertratio," +
+		"         g.goodsid," +
+		"         g.goodscode," +
+		"         g.goodsname," +
+		"         g.agreeunit," +
+		"         g.goodunitid" +
+		"    from erms_middlegoods t" +
+		"   inner join ermcp_ggconvertconfig c" +
+		"      on t.goodsgroupid = c.destgoodsgroupid" +
+		"   inner join goods g" +
+		"      on g.goodsgroupid = c.srcgoodsgroupid)" +
+		"SELECT t.ACCOUNTID," +
+		"       t.GOODSID," +
+		"       t.RECKONDATE," +
+		"       t.BUYPOSITIONQTY," +
+		"       t.BUYHOLDERAMOUNT," +
+		"       t.BUYCURPOSITIONQTY," +
+		"       t.BUYCURHOLDERAMOUNT," +
+		"       t.BUYFROZENQTY," +
+		"       t.BUYOTHERFROZENQTY," +
+		"       t.BUYOPENREQQTY," +
+		"       t.BUYRECKONPL," +
+		"       t.BUYINTEREST," +
+		"       t.BUYUSEDMARGIN," +
+		"       t.BUYOPENTOTALQTY," +
+		"       t.BUYCLOSETOTALQTY," +
+		"       t.BUYCLOSETOTALPL," +
+		"       t.SELLPOSITIONQTY," +
+		"       t.SELLHOLDERAMOUNT," +
+		"       t.SELLCURPOSITIONQTY," +
+		"       t.SELLCURHOLDERAMOUNT," +
+		"       t.SELLFROZENQTY," +
+		"       t.SELLOTHERFROZENQTY," +
+		"       t.SELLOPENREQQTY," +
+		"       t.SELLRECKONPL," +
+		"       t.SELLINTEREST," +
+		"       t.SELLUSEDMARGIN," +
+		"       t.SELLOPENTOTALQTY," +
+		"       t.SELLCLOSETOTALQTY," +
+		"       t.SELLCLOSETOTALPL," +
+		"       t.TRADEPROPERTY," +
+		"       t.MARGINALGORITHM," +
+		"       t.MARGINVALUE," +
+		"       t.BUYFEEALGORITHM," +
+		"       t.BUYMEMBERFEEVALUE," +
+		"       t.BUYEXCHAGEFEEVALUE," +
+		"       t.SELLFEEALGORITHM," +
+		"       t.SELLMEMBERFEEVALUE," +
+		"       t.SELLEXCHAGEFEEVALUE," +
+		"       t.INTEREST2," +
+		"       t.ACCOUNTCURRENCYID," +
+		"       t.GOODSCURRENCYID," +
+		"       t.CUREXCHANGERATE," +
+		"       t.BUYRECKONPL2," +
+		"       t.SELLRECKONPL2," +
+		"       t.BUYCURTDPOSITION," +
+		"       t.BUYFRETDPOSITION," +
+		"       t.SELLCURTDPOSITION," +
+		"       t.SELLFRETDPOSITION," +
+		"       t.INTERESTCHARGE," +
+		"       t.SHORTMARGINVALUE," +
+		"       t.BUYDEFERCHARGE," +
+		"       t.SELLDEFERCHARGE," +
+		"       ta.relateduserid," +
+		"       ta.accountname," +
+		"       tmp.*" +
+		"  FROM RECKON_DAYPOSITION t" +
+		" INNER JOIN tmp" +
+		"    on t.goodsid = tmp.goodsid" +
+		" INNER JOIN TAACCOUNT ta" +
+		"    on t.accountid = ta.accountid" +
+		" WHERE 1 = 1" +
+		"   and (t.buypositionqty > 0 or t.buycurpositionqty > 0 or t.SELLPOSITIONQTY > 0 or t.SELLCURPOSITIONQTY > 0)"
+	sqlId.And("ta.RELATEDUSERID", r.RELATEDUSERID)
+	sqlId.And("tmp.MIDDLEGOODSID", r.MIDDLEGOODSID)
+	sqlId.AndEx("t.RECKONDATE", r.RECKONDATE, len(r.RECKONDATE) > 0)
+	if len(r.BeginDate) > 0 && len(r.EndDate) > 0 {
+		sqlId.Join(fmt.Sprintf(" and t.RECKONDATE >= '%v' and t.RECKONDATE <= '%v' ", r.BeginDate, r.EndDate))
+	}
+	return sqlId.String()
+}
+
+// GetDataEx 获取持仓头寸日照
+func (r *ReckonDayPosition) GetDataEx() ([]ReckonDayPosition, error) {
+	sData := make([]ReckonDayPosition, 0)
+	err := db.GetEngine().SQL(r.buildSql()).Find(&sData)
+	for i := range sData {
+		sData[i].calc()
+	}
+	return sData, err
+}
+
+// HISOUTTRADEPOSITION 外部头寸日照
+type HISOUTTRADEPOSITION struct {
+	HISTRADEDATE      string  `json:"histradedate"  xorm:"'HISTRADEDATE'"`         // 日期
+	ISVALIDDATA       int32   `json:"isvaliddata"  xorm:"'ISVALIDDATA'"`           // 是否有效
+	ACCOUNTID         int64   `json:"accountid"  xorm:"ACCOUNTID"`                 // 资金账号[外部母账户]
+	HEDGEGOODSID      int32   `json:"hedgegoodsid"  xorm:"HEDGEGOODSID"`           // 对冲合约ID
+	HEDGEACCOUNTCODE  string  `json:"hedgeaccountcode"  xorm:"HEDGEACCOUNTCODE"`   // 对冲账号
+	TRADEDATE         string  `json:"tradedate"  xorm:"TRADEDATE"`                 // 交易日(yyyyMMdd)
+	MARKETID          int32   `json:"marketid"  xorm:"MARKETID"`                   // 市场ID
+	YDBUYPOSITION     int32   `json:"ydbuyposition"  xorm:"YDBUYPOSITION"`         // 期初买头寸
+	CURBUYPOSITION    int32   `json:"curbuyposition"  xorm:"CURBUYPOSITION"`       // 期末买头寸
+	CURYDBUYPOSITION  int32   `json:"curydbuyposition"  xorm:"CURYDBUYPOSITION"`   // 期末上日买头寸
+	CURTDBUYPOSITION  int32   `json:"curtdbuyposition"  xorm:"CURTDBUYPOSITION"`   // 期末今日买头寸
+	FREYDBUYPOSITION  int32   `json:"freydbuyposition"  xorm:"FREYDBUYPOSITION"`   // 冻结上日买头寸
+	FRETDBUYPOSITION  int32   `json:"fretdbuyposition"  xorm:"FRETDBUYPOSITION"`   // 冻结今日买头寸
+	YDSELLPOSITION    int32   `json:"ydsellposition"  xorm:"YDSELLPOSITION"`       // 期初卖头寸
+	CURSELLPOSITION   int32   `json:"cursellposition"  xorm:"CURSELLPOSITION"`     // 期末卖头寸
+	CURYDSELLPOSITION int32   `json:"curydsellposition"  xorm:"CURYDSELLPOSITION"` // 期末上日卖头寸
+	CURTDSELLPOSITION int32   `json:"curtdsellposition"  xorm:"CURTDSELLPOSITION"` // 期末今日卖头寸
+	FREYDSELLPOSITION int32   `json:"freydsellposition"  xorm:"FREYDSELLPOSITION"` // 冻结上日卖头寸
+	FRETDSELLPOSITION int32   `json:"fretdsellposition"  xorm:"FRETDSELLPOSITION"` // 冻结今日卖头寸
+	BUYOPENCOST       float64 `json:"buyopencost"  xorm:"BUYOPENCOST"`             // 买开仓成本
+	BUYPOSITIONCOST   float64 `json:"buypositioncost"  xorm:"BUYPOSITIONCOST"`     // 买持仓成本
+	BUYUSEMARGIN      float64 `json:"buyusemargin"  xorm:"BUYUSEMARGIN"`           // 买占用保证金
+	SELLOPENCOST      float64 `json:"sellopencost"  xorm:"SELLOPENCOST"`           // 卖开仓成本
+	SELLPOSITIONCOST  float64 `json:"sellpositioncost"  xorm:"SELLPOSITIONCOST"`   // 卖持仓成本
+	SELLUSEMARGIN     float64 `json:"sellusemargin"  xorm:"SELLUSEMARGIN"`         // 卖占用保证金
+
+	RELATEDUSERID      int64   `json:"relateduserid"  xorm:"'RELATEDUSERID'"`           // 关联用户id
+	MIDDLEGOODSID      int32   `json:"middlegoodsid"  xorm:"'MIDDLEGOODSID'"`           // 套保商品id
+	MIDDLEGOODSCODE    string  `json:"middlegoodscode"  xorm:"'MIDDLEGOODSCODE'"`       // 套保商品代码
+	MIDDLEGOODSNAME    string  `json:"middlegoodsname"  xorm:"'MIDDLEGOODSNAME'"`       // 套保商品名称
+	NEEDHEDGERATIO     float64 `json:"needhedgeratio"  xorm:"'NEEDHEDGERATIO'"`         // 应套保比例
+	NEEDARBITRAGERATIO float64 `json:"needarbitrageratio"  xorm:"'NEEDARBITRAGERATIO'"` // 应套利比例
+	GOODSGROUPID       int32   `json:"goodsgroupid"  xorm:"'GOODSGROUPID'"`             // 交易品种id
+	CONVERTRATIO       float64 `json:"convertratio"  xorm:"'CONVERTRATIO'"`             // 折算系数
+	GOODSCODE          string  `json:"goodscode"  xorm:"'GOODSCODE'"`                   // 交易商品代码
+	GOODSNAME          string  `json:"goodsname"  xorm:"'GOODSNAME'"`                   // 交易商品名称
+	GOODUNITID         int32   `json:"goodunitid"  xorm:"'GOODUNITID'"`                 // 交易商品单位id
+	AGREEUNIT          float64 `json:"agreeunit"  xorm:"'AGREEUNIT'"`                   // 合约乘数
+	ENUMDICNAME        string  `json:"enumdicname"`                                     // 单位名称(交易商品)
+	ACCOUNTNAME        string  `json:"accountname"  xorm:"'ACCOUNTNAME'"`               // 交易账户
+
+	DiffBuyQty        float64 `json:"diffbuyqty"`        // 交易品种今变化量(买)
+	DiffMgBuyQty      float64 `json:"diffmgbuyqty"`      // 套保品种今变化量(买)
+	DiffNeedMgBuyQty  float64 `json:"diffneedmgbuyqty"`  // 应套保总量变化量(买)
+	DiffSellQty       float64 `json:"diffsellqty"`       // 交易品种今变化量(卖)
+	DiffMgSellQty     float64 `json:"diffmgsellqty"`     // 套保品种今变化量(卖)
+	DiffNeedMgSellQty float64 `json:"diffneedmgsellqty"` // 应套保总量变化量(卖)
+
+	BeginDate string `json:"begindate"` // 开始交易日
+	EndDate   string `json:"enddate"`   // 结束交易日
+}
+
+func (r *HISOUTTRADEPOSITION) calc() {
+	r.ENUMDICNAME = mtpcache.GetEnumDicitemName(r.GOODUNITID)
+	if r.YDBUYPOSITION > 0 || r.CURBUYPOSITION > 0 {
+		r.DiffBuyQty = float64(r.CURBUYPOSITION) * r.AGREEUNIT
+		r.DiffMgBuyQty = float64(r.CURBUYPOSITION) * r.AGREEUNIT * r.CONVERTRATIO
+		r.DiffNeedMgBuyQty = float64(r.CURBUYPOSITION) * r.AGREEUNIT * r.CONVERTRATIO * r.NEEDHEDGERATIO
+	}
+	if r.YDSELLPOSITION > 0 || r.CURSELLPOSITION > 0 {
+		r.DiffBuyQty = float64(r.CURSELLPOSITION) * r.AGREEUNIT
+		r.DiffMgBuyQty = float64(r.CURSELLPOSITION) * r.AGREEUNIT * r.CONVERTRATIO
+		r.DiffNeedMgBuyQty = float64(r.CURSELLPOSITION) * r.AGREEUNIT * r.CONVERTRATIO * r.NEEDHEDGERATIO
+	}
+}
+
+func (r *HISOUTTRADEPOSITION) buildSql() string {
+	var sqlId utils.SQLVal = "with tmp as" +
+		" (select t.middlegoodsid," +
+		"         t.middlegoodscode," +
+		"         t.middlegoodsname," +
+		"         t.needhedgeratio," +
+		"         t.needarbitrageratio," +
+		"         t.goodsgroupid," +
+		"         c.convertratio," +
+		"         g.goodsid," +
+		"         g.goodscode," +
+		"         g.goodsname," +
+		"         g.agreeunit," +
+		"         g.goodunitid" +
+		"    from erms_middlegoods t" +
+		"   inner join ermcp_ggconvertconfig c" +
+		"      on t.goodsgroupid = c.destgoodsgroupid" +
+		"   inner join goods g" +
+		"      on g.goodsgroupid = c.srcgoodsgroupid)" +
+		"SELECT t.HISTRADEDATE," +
+		"       t.ISVALIDDATA," +
+		"       t.ACCOUNTID," +
+		"       t.HEDGEGOODSID," +
+		"       t.HEDGEACCOUNTCODE," +
+		"       t.TRADEDATE," +
+		"       t.MARKETID," +
+		"       t.YDBUYPOSITION," +
+		"       t.CURBUYPOSITION," +
+		"       t.CURYDBUYPOSITION," +
+		"       t.CURTDBUYPOSITION," +
+		"       t.FREYDBUYPOSITION," +
+		"       t.FRETDBUYPOSITION," +
+		"       t.YDSELLPOSITION," +
+		"       t.CURSELLPOSITION," +
+		"       t.CURYDSELLPOSITION," +
+		"       t.CURTDSELLPOSITION," +
+		"       t.FREYDSELLPOSITION," +
+		"       t.FRETDSELLPOSITION," +
+		"       t.BUYOPENCOST," +
+		"       t.BUYPOSITIONCOST," +
+		"       t.BUYUSEMARGIN," +
+		"       t.SELLOPENCOST," +
+		"       t.SELLPOSITIONCOST," +
+		"       t.SELLUSEMARGIN," +
+		"       ta.relateduserid," +
+		"       ta.accountname," +
+		"       tmp.*" +
+		"  FROM HIS_HEDGE_OUTTRADEPOSITION t" +
+		" INNER JOIN tmp" +
+		"    on t.HEDGEGOODSID = tmp.goodsid" +
+		" INNER JOIN TAACCOUNT ta" +
+		"    on t.accountid = ta.accountid" +
+		" WHERE 1 = 1" +
+		"   and (t.YDBUYPOSITION > 0 or t.CURBUYPOSITION > 0 or t.YDSELLPOSITION > 0 or t.CURSELLPOSITION > 0)"
+	sqlId.And("ta.RELATEDUSERID", r.RELATEDUSERID)
+	sqlId.And("tmp.MIDDLEGOODSID", r.MIDDLEGOODSID)
+	sqlId.AndEx("t.HISTRADEDATE", r.HISTRADEDATE, len(r.HISTRADEDATE) > 0)
+	if len(r.BeginDate) > 0 && len(r.EndDate) > 0 {
+		sqlId.Join(fmt.Sprintf(" and t.HISTRADEDATE >= '%v' and t.HISTRADEDATE <= '%v' ", r.BeginDate, r.EndDate))
+	}
+	return sqlId.String()
+}
+
+// GetDataEx 获取外部头寸日照
+func (r *HISOUTTRADEPOSITION) GetDataEx() ([]HISOUTTRADEPOSITION, error) {
+	sData := make([]HISOUTTRADEPOSITION, 0)
+	err := db.GetEngine().SQL(r.buildSql()).Find(&sData)
+	for i := range sData {
+		sData[i].calc()
+	}
+	return sData, err
+}
+
+// Ermcp3ExposureFutuDetail 敞口报表期货明细
+type Ermcp3ExposureFutuDetail struct {
+	ACCOUNTID       int64   `json:"accountid"`       // 交易账户id
+	ACCOUNTNAME     string  `json:"accountname"`     // 交易账户
+	GOODSID         int32   `json:"goodsid"`         // 商品id
+	GOODSCODE       string  `json:"goodscode"`       // 商品代码
+	GOODSNAME       string  `json:"goodsname"`       // 商品名称
+	BUYORSELL       int32   `json:"buyorsell"`       // 方向 0-买 1-卖
+	ORIHOLDQTY      float64 `json:"oriholdqty"`      // 期初持仓量
+	HOLDQTY         float64 `json:"holdqty"`         // 期末持仓量
+	TODAYOPENQTY    float64 `json:"todayopenqty"`    // 今开仓量
+	TODAYCLOSEQTY   float64 `json:"todaycloseqty"`   // 今平仓量
+	DiffTradeQty    float64 `json:"difftradeqty"`    // 交易品种今变化量
+	DiffMgQty       float64 `json:"diffmgqty"`       // 套保品种今变化量
+	DiffNeedQty     float64 `json:"diffneedqty"`     // 应套保总量变化量
+	MIDDLEGOODSID   int32   `json:"middlegoodsid"`   // 套保商品id
+	MIDDLEGOODSCODE string  `json:"middlegoodscode"` // 套保商品代码
+	MIDDLEGOODSNAME string  `json:"middlegoodsname"` // 套保商品名称
+	ENUMDICNAME     string  `json:"enumdicname"`     // 单位名称
+
+	USERID     int64  `json:"-"`         // 用户id
+	RECKONDATE string `json:"tradedate"` // 交易日
+	BeginDate  string `json:"begindate"` // 开始交易日
+	EndDate    string `json:"enddate"`   // 结束交易日
+}
+
+func (r *Ermcp3ExposureFutuDetail) fromOutPositionBuy(v *HISOUTTRADEPOSITION) {
+	r.ACCOUNTID = v.ACCOUNTID
+	r.ACCOUNTNAME = v.ACCOUNTNAME
+	r.GOODSID = v.HEDGEGOODSID
+	r.GOODSCODE = v.GOODSCODE
+	r.GOODSNAME = v.GOODSNAME
+	r.BUYORSELL = 0
+	r.ORIHOLDQTY = float64(v.YDBUYPOSITION)
+	r.HOLDQTY = float64(v.CURBUYPOSITION)
+	r.TODAYOPENQTY = 0
+	r.TODAYCLOSEQTY = 0
+	r.DiffTradeQty = v.DiffBuyQty
+	r.DiffMgQty = v.DiffMgBuyQty
+	r.DiffNeedQty = v.DiffNeedMgBuyQty
+	r.MIDDLEGOODSID = v.MIDDLEGOODSID
+	r.MIDDLEGOODSCODE = v.MIDDLEGOODSCODE
+	r.MIDDLEGOODSNAME = v.MIDDLEGOODSNAME
+	r.ENUMDICNAME = v.ENUMDICNAME
+	r.RECKONDATE = v.HISTRADEDATE
+}
+
+func (r *Ermcp3ExposureFutuDetail) fromOutPositionSell(v *HISOUTTRADEPOSITION) {
+	r.ACCOUNTID = v.ACCOUNTID
+	r.ACCOUNTNAME = v.ACCOUNTNAME
+	r.GOODSID = v.HEDGEGOODSID
+	r.GOODSCODE = v.GOODSCODE
+	r.GOODSNAME = v.GOODSNAME
+	r.BUYORSELL = 1
+	r.ORIHOLDQTY = float64(v.YDSELLPOSITION)
+	r.HOLDQTY = float64(v.CURSELLPOSITION)
+	r.TODAYOPENQTY = 0
+	r.TODAYCLOSEQTY = 0
+	r.DiffTradeQty = v.DiffSellQty
+	r.DiffMgQty = v.DiffMgSellQty
+	r.DiffNeedQty = v.DiffNeedMgSellQty
+	r.MIDDLEGOODSID = v.MIDDLEGOODSID
+	r.MIDDLEGOODSCODE = v.MIDDLEGOODSCODE
+	r.MIDDLEGOODSNAME = v.MIDDLEGOODSNAME
+	r.ENUMDICNAME = v.ENUMDICNAME
+	r.RECKONDATE = v.HISTRADEDATE
+}
+
+func (r *Ermcp3ExposureFutuDetail) fromTradePositionBuy(v *ReckonDayPosition) {
+	r.ACCOUNTID = v.ACCOUNTID
+	r.ACCOUNTNAME = v.ACCOUNTNAME
+	r.GOODSID = v.GOODSID
+	r.GOODSCODE = v.GOODSCODE
+	r.GOODSNAME = v.GOODSNAME
+	r.BUYORSELL = 0
+	r.ORIHOLDQTY = float64(v.BUYPOSITIONQTY)
+	r.HOLDQTY = float64(v.BUYCURPOSITIONQTY)
+	r.TODAYOPENQTY = 0
+	r.TODAYCLOSEQTY = 0
+	r.DiffTradeQty = v.DiffBuyQty
+	r.DiffMgQty = v.DiffMgBuyQty
+	r.DiffNeedQty = v.DiffNeedMgBuyQty
+	r.MIDDLEGOODSID = v.MIDDLEGOODSID
+	r.MIDDLEGOODSCODE = v.MIDDLEGOODSCODE
+	r.MIDDLEGOODSNAME = v.MIDDLEGOODSNAME
+	r.ENUMDICNAME = v.ENUMDICNAME
+	r.RECKONDATE = v.RECKONDATE
+}
+
+func (r *Ermcp3ExposureFutuDetail) fromTradePositionSell(v *ReckonDayPosition) {
+	r.ACCOUNTID = v.ACCOUNTID
+	r.ACCOUNTNAME = v.ACCOUNTNAME
+	r.GOODSID = v.GOODSID
+	r.GOODSCODE = v.GOODSCODE
+	r.GOODSNAME = v.GOODSNAME
+	r.BUYORSELL = 1
+	r.ORIHOLDQTY = float64(v.SELLPOSITIONQTY)
+	r.HOLDQTY = float64(v.SELLCURPOSITIONQTY)
+	r.TODAYOPENQTY = 0
+	r.TODAYCLOSEQTY = 0
+	r.DiffTradeQty = v.DiffSellQty
+	r.DiffMgQty = v.DiffMgSellQty
+	r.DiffNeedQty = v.DiffNeedMgSellQty
+	r.MIDDLEGOODSID = v.MIDDLEGOODSID
+	r.MIDDLEGOODSCODE = v.MIDDLEGOODSCODE
+	r.MIDDLEGOODSNAME = v.MIDDLEGOODSNAME
+	r.ENUMDICNAME = v.ENUMDICNAME
+	r.RECKONDATE = v.RECKONDATE
+}
+
+// GetDataEx 获取敞口报表期货明细
+func (r *Ermcp3ExposureFutuDetail) GetDataEx() (interface{}, error) {
+	sData := make([]Ermcp3ExposureFutuDetail, 0)
+	if mtpcache.IsAreaUserId(r.USERID) {
+		// 查母账户头寸
+		m := HISOUTTRADEPOSITION{RELATEDUSERID: r.USERID, HISTRADEDATE: r.RECKONDATE,
+			BeginDate: r.BeginDate, EndDate: r.EndDate, MIDDLEGOODSID: r.MIDDLEGOODSID}
+		d, _ := m.GetDataEx()
+		for _, v := range d {
+			if v.YDBUYPOSITION > 0 || v.CURBUYPOSITION > 0 {
+				val := Ermcp3ExposureFutuDetail{}
+				val.fromOutPositionBuy(&v)
+				val.BeginDate = r.BeginDate
+				val.EndDate = r.EndDate
+				sData = append(sData, val)
+			}
+			if v.YDSELLPOSITION > 0 || v.CURSELLPOSITION > 0 {
+				val := Ermcp3ExposureFutuDetail{}
+				val.fromOutPositionSell(&v)
+				val.BeginDate = r.BeginDate
+				val.EndDate = r.EndDate
+				sData = append(sData, val)
+			}
+		}
+	} else {
+		// 查子账户头寸
+		m := ReckonDayPosition{RELATEDUSERID: r.USERID, RECKONDATE: r.RECKONDATE,
+			BeginDate: r.BeginDate, EndDate: r.EndDate, MIDDLEGOODSID: r.MIDDLEGOODSID}
+		d, _ := m.GetDataEx()
+		for _, v := range d {
+			if v.BUYPOSITIONQTY > 0 || v.BUYCURPOSITIONQTY > 0 {
+				val := Ermcp3ExposureFutuDetail{}
+				val.fromTradePositionBuy(&v)
+				val.BeginDate = r.BeginDate
+				val.EndDate = r.EndDate
+				sData = append(sData, val)
+			}
+			if v.SELLPOSITIONQTY > 0 || v.SELLCURPOSITIONQTY > 0 {
+				val := Ermcp3ExposureFutuDetail{}
+				val.fromTradePositionSell(&v)
+				val.BeginDate = r.BeginDate
+				val.EndDate = r.EndDate
+				sData = append(sData, val)
+			}
+		}
+	}
+	return sData, nil
+}

+ 62 - 0
models/ermcpExposure.go

@@ -904,3 +904,65 @@ func (r *ErmcpHedgePositionDetail) GetDataEx() (interface{}, error) {
 	}
 	return sData, err
 }
+
+// ErmcpMiddlegoodsRelateGoods 套保商品关联主动合约
+type ErmcpMiddlegoodsRelateGoods struct {
+	MIDDLEGOODSID      int32   `json:"middlegoodsid"  xorm:"'MIDDLEGOODSID'"`           // 套保商品id
+	MIDDLEGOODSCODE    string  `json:"middlegoodsswcode"  xorm:"'MIDDLEGOODSCODE'"`     // 套保商品代码
+	MIDDLEGOODSNAME    string  `json:"middlegoodsname"  xorm:"'MIDDLEGOODSNAME'"`       // 套保商品名称
+	NEEDHEDGERATIO     float64 `json:"needhedgeratio"  xorm:"'NEEDHEDGERATIO'"`         // 应套保比例
+	NEEDARBITRAGERATIO float64 `json:"needarbitrageratio"  xorm:"'NEEDARBITRAGERATIO'"` // 应套利比例
+	GOODSGROUPID       int32   `json:"goodsgroupid"  xorm:"'GOODSGROUPID'"`             // 交易品种id
+	CONVERTRATIO       float64 `json:"convertratio"  xorm:"'CONVERTRATIO'"`             // 折算系数
+	GOODSID            int32   `json:"goodsid"  xorm:"GOODSID"`                         // 商品Id
+	GOODSCODE          string  `json:"goodscode"  xorm:"'GOODSCODE'"`                   // 交易商品代码
+	GOODSNAME          string  `json:"goodsname"  xorm:"'GOODSNAME'"`                   // 交易商品名称
+	GOODUNITID         int32   `json:"goodunitid"  xorm:"'GOODUNITID'"`                 // 交易商品单位id
+	AGREEUNIT          float64 `json:"agreeunit"  xorm:"'AGREEUNIT'"`                   // 合约乘数
+	ENUMDICNAME        string  `json:"enumdicname"`                                     // 单位名称(交易商品)
+}
+
+func (r *ErmcpMiddlegoodsRelateGoods) calc() {
+	r.ENUMDICNAME = mtpcache.GetEnumDicitemName(r.GOODUNITID)
+}
+
+func (r *ErmcpMiddlegoodsRelateGoods) buildSql() string {
+	var sqlId utils.SQLVal = "with tmp as" +
+		" (select a.*, g.goodsid, g.goodscode, g.goodsname" +
+		"    from (select row_number() over(partition by t.goodscode order by t.tradedate desc, t.sortindex) cn," +
+		"                 t.*" +
+		"            from GoodsSortByPrePosition t) a" +
+		"    left join goods g" +
+		"      on a.goodscode = g.goodscode" +
+		"   where cn = 1)" +
+		"select t.middlegoodsid," +
+		"       t.middlegoodscode," +
+		"       t.middlegoodsname," +
+		"       t.needhedgeratio," +
+		"       t.needarbitrageratio," +
+		"       t.goodsgroupid," +
+		"       c.convertratio," +
+		"       g.goodsid," +
+		"       g.goodscode," +
+		"       g.goodsname," +
+		"       g.agreeunit," +
+		"       g.goodunitid" +
+		"  from erms_middlegoods t" +
+		" inner join ermcp_ggconvertconfig c" +
+		"    on t.goodsgroupid = c.destgoodsgroupid" +
+		" inner join goods g" +
+		"    on g.goodsgroupid = c.srcgoodsgroupid" +
+		" where 1 = 1 and g.goodsid in (select goodsid from tmp)"
+	sqlId.And("t.MIDDLEGOODSID", r.MIDDLEGOODSID)
+	return sqlId.String()
+}
+
+// GetDataEx 获取套保商品关联主动合约
+func (r *ErmcpMiddlegoodsRelateGoods) GetDataEx() (interface{}, error) {
+	sData := make([]ErmcpMiddlegoodsRelateGoods, 0)
+	err := db.GetEngine().SQL(r.buildSql()).Find(&sData)
+	for i := range sData {
+		sData[i].calc()
+	}
+	return sData, err
+}

+ 2 - 0
routers/router.go

@@ -378,6 +378,7 @@ func InitRouter() *gin.Engine {
 		ermcpR.GET("/QuerySpotGoodsPriceLog", ermcp.QuerySpotGoodsPriceLog)
 		ermcpR.GET("/QueryFuturesCompany", ermcp.QueryFuturesCompany)
 		ermcpR.GET("/QueryTradeConfigTMP", ermcp.QueryTradeConfigTMP)
+		ermcpR.GET("/QueryExposureGoods", ermcp.QueryExposureGoods)
 
 		// 期货相关
 		// 查询企业风管期货商品信息
@@ -439,6 +440,7 @@ func InitRouter() *gin.Engine {
 		ermcp3R.GET("/QryAreaExpourseReport", ermcp3.QryAreaExpourseReport)
 		ermcp3R.GET("/QryAreaExpourseContractDetail", ermcp3.QryAreaExpourseContractDetail)
 		ermcp3R.GET("/QryAreaExpourseHedgeplanDetail", ermcp3.QryAreaExpourseHedgeplanDetail)
+		ermcp3R.GET("/QryAreaExpourseFutuDetail", ermcp3.QryAreaExpourseFutuDetail)
 		ermcp3R.GET("/QryAreaStockReport", ermcp3.QryAreaStockReport)
 		ermcp3R.GET("/QryFinanceReport", ermcp3.QryFinanceReport)
 		ermcp3R.GET("/QryAreaSumPL", ermcp3.QryAreaSumPL)

Some files were not shown because too many files changed in this diff