| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756 |
- package ermcp
- import (
- "mtp2_if/global/app"
- "mtp2_if/global/e"
- "mtp2_if/logger"
- "mtp2_if/models"
- "mtp2_if/utils"
- "net/http"
- "strconv"
- "github.com/gin-gonic/gin"
- )
- // QueryErmcpTradePositionReq 获取企业风管期货持仓头寸信息请求参数
- type QueryErmcpTradePositionReq struct {
- AccountID int `form:"accountID" binding:"required"`
- MarketID int `form:"marketID"`
- }
- // QueryErmcpTradePositionRsp 获取企业风管期货持仓头寸信息返回模型
- type QueryErmcpTradePositionRsp struct {
- Goodsname string `json:"goodsname"` // 商品名称
- BuyOrSell int64 `json:"buyorsell"` // 方向 - 0:买 1:卖
- EnableQTY int64 `json:"enableqty"` // 可用(总仓可用)
- CurPositionQTY int64 `json:"curpositionqty"` // 持仓(总仓数量, 期末头寸)
- Last float64 `json:"last"` // 现价
- CurTDPosition int64 `json:"curtdposition"` // 今仓数量(期末今日头寸)
- CurTDPositionEnabled int64 `json:"curtdpositionenabled"` // 今仓可用
- PositionAveragePrice float64 `json:"positionaverageprice"` // 持仓均价【头寸变化更新】= 持仓成本 / 期末头寸 / 合约单位
- OpenAveragePrice float64 `json:"openaverageprice" ` // 开仓均价【头寸变化更新】 = 开仓成本 / 期末头寸 / 合约单位
- PositionPL float64 `json:"positionpl"` // 盯市浮盈【实时行情更新】(MTP:浮动盈亏、持仓盈亏) 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位;卖方向 = (持仓均价 - 最新价) * 卖期末头寸 * 合约单位
- OpenPL float64 `json:"openpl"` // 逐笔浮盈【实时行情更新】(MTP:开仓盈亏、平仓盈亏) 买方向 = (最新价 - 开仓均价) * 买期末头寸 * 合约单位;卖方向 = (开仓均价 - 最新价) * 卖期末头寸 * 合约单位
- PositionPLRate float64 `json:"positionplrate"` // 持仓盈亏比例【实时行情更新】 = 持仓盈亏 / 开仓成本
- UsedMargin float64 `json:"usedmargin"` // 占用保证金
- ExExehangeName string `json:"exexchangename"` // 外部交易所名称
- OpenCost float64 `json:"opencost"` // 开仓成本
- PositionCost float64 `json:"positioncost"` // 持仓成本
- Goodsid int64 `json:"goodsid"` // 商品ID(自增ID SEQ_GOODS)
- Goodscode string `json:"goodscode"` // 商品代码(内部)
- Outgoodscode string `json:"outgoodscode"` // 商品代码(外部)
- Agreeunit float64 `json:"agreeunit"` // 合约单位
- Decimalplace int64 `json:"decimalplace"` // 报价小数位
- Marketid int64 `json:"marketid"` // 所属市场ID
- }
- // QueryErmcpTradePosition 获取企业风管期货持仓头寸信息
- // @Summary 获取企业风管期货持仓头寸信息
- // @Description 本接口只使用于通道交易相关头寸查询;子账户持仓头寸占用保证金为0;
- // @Produce json
- // @Security ApiKeyAuth
- // @Param accountID query int true "资金账户ID"
- // @Param marketID query int false "所属市场ID"
- // @Success 200 {object} QueryErmcpTradePositionRsp
- // @Failure 500 {object} app.Response
- // @Router /Ermcp/QueryErmcpTradePosition [get]
- // @Tags 企业风险管理(app)
- func QueryErmcpTradePosition(c *gin.Context) {
- appG := app.Gin{C: c}
- // 获取请求参数
- var req QueryErmcpTradePositionReq
- if err := appG.C.ShouldBindQuery(&req); err != nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
- return
- }
- rsp := make([]QueryErmcpTradePositionRsp, 0)
- // 获取资金账户信息
- taAccount, err := models.GetTaAccountByID(req.AccountID)
- if err != nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- if taAccount == nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- if taAccount.Ismain == 1 {
- // 母账户,从HEDGE_OUTTRADEPOSITION表查询持仓头寸(未生成内部头寸)
- hedgeOutTradePositions, err := models.GetHedgeOutTradePositions(req.AccountID, req.MarketID)
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- // 分解买卖方向的头寸
- for _, v := range hedgeOutTradePositions {
- // 分解买卖方向的头寸
- if v.Curbuyposition > 0 {
- // 买方向
- item := QueryErmcpTradePositionRsp{
- BuyOrSell: 0,
- EnableQTY: v.Curbuyposition - v.Fretdbuyposition - v.Freydbuyposition, // 买可用 = 期末买头寸 - 冻结今日买头寸 - 冻结上日买头寸
- CurPositionQTY: v.Curbuyposition,
- CurTDPosition: v.Curtdbuyposition,
- CurTDPositionEnabled: v.Curtdbuyposition - v.Fretdbuyposition, // 今仓买可用 = 期末今日买头寸 - 冻结今日买头寸
- UsedMargin: v.Buyusemargin,
- OpenCost: v.Buyopencost,
- PositionCost: v.Buypositioncost,
- Goodsid: v.Hedgegoodsid,
- Marketid: int64(v.Marketid),
- }
- // 获取对应商品信息
- goods, err := models.GetGoods(int(v.Hedgegoodsid))
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
- return
- }
- if goods == nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
- appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
- return
- }
- item.Goodscode = goods.Goodscode
- item.Outgoodscode = goods.Outgoodscode
- item.Goodsname = goods.Goodsname
- item.Agreeunit = goods.Agreeunit
- // 获取对应外部交易所名称
- exchange, err := models.GetExternalexchangeByGoodsGroupID(int(goods.Goodsgroupid))
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
- return
- }
- if exchange == nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
- appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
- return
- }
- item.ExExehangeName = exchange.Exchangefullname
- // 获取对应商品盘面信息
- quoteDays, err := models.GetQuoteDays("'" + goods.Outgoodscode + "'")
- if err != nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_QUOTE_FAILED, nil)
- return
- }
- if len(quoteDays) > 0 {
- if quoteDays[0].Last != 0 {
- item.Last = utils.IntToFloat64(int(quoteDays[0].Last), int(goods.Decimalplace))
- }
- // 没有现价则尝试用昨结
- if item.Last == 0 && quoteDays[0].Presettle != 0 {
- item.Last = utils.IntToFloat64(int(quoteDays[0].Presettle), int(goods.Decimalplace))
- }
- }
- // 计算价格与盈亏
- // 开仓均价 = 开仓成本 / 期末头寸 / 合约单位
- item.OpenAveragePrice = v.Buyopencost / float64(v.Curbuyposition) / goods.Agreeunit
- item.OpenAveragePrice, _ = strconv.ParseFloat(utils.FormatFloat(item.OpenAveragePrice, int(goods.Decimalplace)), 64)
- // 持仓均价 = 持仓成本 / 期末头寸 / 合约单位
- item.PositionAveragePrice = v.Buypositioncost / float64(v.Curbuyposition) / goods.Agreeunit
- item.PositionAveragePrice, _ = strconv.ParseFloat(utils.FormatFloat(item.PositionAveragePrice, int(goods.Decimalplace)), 64)
- // 盯市浮盈(MTP:浮动盈亏、持仓盈亏) 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位
- if item.Last != 0 {
- item.PositionPL = (item.Last - item.PositionAveragePrice) * float64(v.Curbuyposition) * goods.Agreeunit
- }
- // 逐笔浮盈(MTP:开仓盈亏、平仓盈亏)买方向 = (最新价 - 开仓均价) * 买期末头寸 * 合约单位
- if item.Last != 0 {
- item.OpenPL = (item.Last - item.OpenAveragePrice) * float64(v.Curbuyposition) * goods.Agreeunit
- }
- // 持仓盈亏比例 = 持仓盈亏 / 开仓成本
- if item.PositionPL != 0 && v.Buyopencost != 0 {
- item.PositionPLRate = item.PositionPL / v.Buyopencost
- item.PositionPLRate, _ = strconv.ParseFloat(utils.FormatFloat(item.PositionPLRate, 4), 64)
- }
- rsp = append(rsp, item)
- }
- if v.Cursellposition > 0 {
- // 卖方向
- item := QueryErmcpTradePositionRsp{
- BuyOrSell: 1,
- EnableQTY: v.Cursellposition - v.Fretdsellposition - v.Freydsellposition,
- CurPositionQTY: v.Cursellposition,
- CurTDPosition: v.Curtdsellposition,
- CurTDPositionEnabled: v.Curtdsellposition - v.Fretdsellposition,
- UsedMargin: v.Sellusemargin,
- OpenCost: v.Sellopencost,
- PositionCost: v.Sellpositioncost,
- Goodsid: v.Hedgegoodsid,
- Marketid: int64(v.Marketid),
- }
- // 获取对应商品信息
- goods, err := models.GetGoods(int(v.Hedgegoodsid))
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
- return
- }
- if goods == nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
- appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
- return
- }
- item.Goodscode = goods.Goodscode
- item.Outgoodscode = goods.Outgoodscode
- item.Goodsname = goods.Goodsname
- item.Agreeunit = goods.Agreeunit
- // 获取对应外部交易所名称
- exchange, err := models.GetExternalexchangeByGoodsGroupID(int(goods.Goodsgroupid))
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
- return
- }
- if exchange == nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
- appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
- return
- }
- item.ExExehangeName = exchange.Exchangefullname
- // 获取对应商品盘面信息
- quoteDays, err := models.GetQuoteDays("'" + goods.Outgoodscode + "'")
- if err != nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_QUOTE_FAILED, nil)
- return
- }
- if len(quoteDays) > 0 {
- if quoteDays[0].Last != 0 {
- item.Last = utils.IntToFloat64(int(quoteDays[0].Last), int(goods.Decimalplace))
- }
- // 没有现价则尝试用昨结
- if item.Last == 0 && quoteDays[0].Presettle != 0 {
- item.Last = utils.IntToFloat64(int(quoteDays[0].Presettle), int(goods.Decimalplace))
- }
- }
- // 计算价格与盈亏
- // 开仓均价 = 开仓成本 / 期末头寸 / 合约单位
- item.OpenAveragePrice = v.Sellopencost / float64(v.Cursellposition) / goods.Agreeunit
- item.OpenAveragePrice, _ = strconv.ParseFloat(utils.FormatFloat(item.OpenAveragePrice, int(goods.Decimalplace)), 64)
- // 持仓均价 = 持仓成本 / 期末头寸 / 合约单位
- item.PositionAveragePrice = v.Sellpositioncost / float64(v.Cursellposition) / goods.Agreeunit
- item.PositionAveragePrice, _ = strconv.ParseFloat(utils.FormatFloat(item.PositionAveragePrice, int(goods.Decimalplace)), 64)
- // 盯市浮盈(MTP:浮动盈亏、持仓盈亏) 卖方向 = (持仓均价 - 最新价) * 卖期末头寸 * 合约单位
- if item.Last != 0 {
- item.PositionPL = (item.PositionAveragePrice - item.Last) * float64(v.Cursellposition) * goods.Agreeunit
- }
- // 逐笔浮盈(MTP:开仓盈亏、平仓盈亏)买方向 = (开仓均价 - 最新价) * 卖期末头寸 * 合约单位
- if item.Last != 0 {
- item.OpenPL = (item.Last - item.OpenAveragePrice) * float64(v.Cursellposition) * goods.Agreeunit
- }
- // 持仓盈亏比例 = 持仓盈亏 / 开仓成本
- if item.PositionPL != 0 && v.Sellopencost != 0 {
- item.PositionPLRate = item.PositionPL / v.Sellopencost
- item.PositionPLRate, _ = strconv.ParseFloat(utils.FormatFloat(item.PositionPLRate, 4), 64)
- }
- rsp = append(rsp, item)
- }
- }
- } else {
- // 子账户
- tradePositions, err := models.GetTradePositions(req.AccountID, req.MarketID)
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- // 分解买卖方向的头寸
- for _, v := range tradePositions {
- if v.Buycurpositionqty > 0 {
- // 买方向
- item := QueryErmcpTradePositionRsp{
- BuyOrSell: 0,
- EnableQTY: v.Buycurpositionqty - v.Buyfrozenqty, // 买可用 = 买当前持仓总数量 - 买持仓冻结数量
- CurPositionQTY: v.Buycurpositionqty,
- CurTDPosition: v.Buycurtdposition,
- CurTDPositionEnabled: v.Buycurtdposition - v.Buyfretdposition, // 今仓买可用 = 期末今日买头寸 - 冻结今日买头寸
- Goodsid: int64(v.Goodsid),
- }
- // 获取对应市场信息
- market, err := models.GetMarketByGoodsID(int(v.Goodsid))
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_MARKET_FAILED, nil)
- return
- }
- if market == nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
- appG.Response(http.StatusBadRequest, e.ERROR_GET_MARKET_FAILED, nil)
- return
- }
- item.Marketid = int64(market.Marketid)
- // 获取对应商品信息
- goods, err := models.GetGoods(int(v.Goodsid))
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
- return
- }
- if goods == nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
- appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
- return
- }
- item.Goodscode = goods.Goodscode
- item.Outgoodscode = goods.Outgoodscode
- item.Goodsname = goods.Goodsname
- item.Agreeunit = goods.Agreeunit
- // 获取对应外部交易所名称
- exchange, err := models.GetExternalexchangeByGoodsGroupID(int(goods.Goodsgroupid))
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
- return
- }
- if exchange == nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
- appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
- return
- }
- item.ExExehangeName = exchange.Exchangefullname
- // 获取对应商品盘面信息
- quoteDays, err := models.GetQuoteDays("'" + goods.Outgoodscode + "'")
- if err != nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_QUOTE_FAILED, nil)
- return
- }
- if len(quoteDays) > 0 {
- if quoteDays[0].Last != 0 {
- item.Last = utils.IntToFloat64(int(quoteDays[0].Last), int(goods.Decimalplace))
- }
- // 没有现价则尝试用昨结
- if item.Last == 0 && quoteDays[0].Presettle != 0 {
- item.Last = utils.IntToFloat64(int(quoteDays[0].Presettle), int(goods.Decimalplace))
- }
- }
- // 子账户需要从内部持仓明细(通道)表汇总计划开仓成本和开仓均价
- hedgeInnerHolderDetails, _ := models.GetHedgeInnerHolderDetails(req.AccountID, int(item.Goodsid), 0)
- for _, detail := range hedgeInnerHolderDetails {
- // 开仓成本 = 建仓价 * 持仓数量 * 合约单位
- item.OpenCost += detail.Openprice * float64(detail.Holderqty) * goods.Agreeunit
- }
- // 开仓均价 = 开仓成本 / 期末头寸 / 合约单位
- item.OpenAveragePrice = item.OpenCost / float64(item.CurPositionQTY) / goods.Agreeunit
- item.OpenAveragePrice, _ = strconv.ParseFloat(utils.FormatFloat(item.OpenAveragePrice, int(goods.Decimalplace)), 64)
- // 持仓成本
- item.PositionCost = v.Buycurholderamount
- // 持仓均价 = 持仓成本 / 期末头寸 / 合约单位
- item.PositionAveragePrice = v.Buycurholderamount / float64(v.Buycurpositionqty) / goods.Agreeunit
- item.PositionAveragePrice, _ = strconv.ParseFloat(utils.FormatFloat(item.PositionAveragePrice, int(goods.Decimalplace)), 64)
- // 盯市浮盈(MTP:浮动盈亏、持仓盈亏) 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位
- if item.Last != 0 {
- item.PositionPL = (item.Last - item.PositionAveragePrice) * float64(v.Buycurpositionqty) * goods.Agreeunit
- }
- // 逐笔浮盈(MTP:开仓盈亏、平仓盈亏)买方向 = (最新价 - 开仓均价) * 买期末头寸 * 合约单位
- if item.Last != 0 {
- item.OpenPL = (item.Last - item.OpenAveragePrice) * float64(v.Buycurpositionqty) * goods.Agreeunit
- }
- // 持仓盈亏比例 = 持仓盈亏 / 开仓成本
- if item.PositionPL != 0 && item.OpenCost != 0 {
- item.PositionPLRate = item.PositionPL / item.OpenCost
- item.PositionPLRate, _ = strconv.ParseFloat(utils.FormatFloat(item.PositionPLRate, 4), 64)
- }
- rsp = append(rsp, item)
- }
- if v.Sellcurpositionqty > 0 {
- // 卖方向
- item := QueryErmcpTradePositionRsp{
- BuyOrSell: 1,
- EnableQTY: v.Sellcurpositionqty - v.Sellfrozenqty, // 买可用 = 买当前持仓总数量 - 买持仓冻结数量
- CurPositionQTY: v.Sellcurpositionqty,
- CurTDPosition: v.Sellcurtdposition,
- CurTDPositionEnabled: v.Sellcurtdposition - v.Sellfretdposition, // 今仓买可用 = 期末今日买头寸 - 冻结今日买头寸
- Goodsid: int64(v.Goodsid),
- }
- // 获取对应市场信息
- market, err := models.GetMarketByGoodsID(int(v.Goodsid))
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_MARKET_FAILED, nil)
- return
- }
- if market == nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
- appG.Response(http.StatusBadRequest, e.ERROR_GET_MARKET_FAILED, nil)
- return
- }
- item.Marketid = int64(market.Marketid)
- // 获取对应商品信息
- goods, err := models.GetGoods(int(v.Goodsid))
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
- return
- }
- if goods == nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
- appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
- return
- }
- item.Goodscode = goods.Goodscode
- item.Outgoodscode = goods.Outgoodscode
- item.Goodsname = goods.Goodsname
- item.Agreeunit = goods.Agreeunit
- // 获取对应外部交易所名称
- exchange, err := models.GetExternalexchangeByGoodsGroupID(int(goods.Goodsgroupid))
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
- return
- }
- if exchange == nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
- appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
- return
- }
- item.ExExehangeName = exchange.Exchangefullname
- // 获取对应商品盘面信息
- quoteDays, err := models.GetQuoteDays("'" + goods.Outgoodscode + "'")
- if err != nil {
- logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_GET_QUOTE_FAILED, nil)
- return
- }
- if len(quoteDays) > 0 {
- if quoteDays[0].Last != 0 {
- item.Last = utils.IntToFloat64(int(quoteDays[0].Last), int(goods.Decimalplace))
- }
- // 没有现价则尝试用昨结
- if item.Last == 0 && quoteDays[0].Presettle != 0 {
- item.Last = utils.IntToFloat64(int(quoteDays[0].Presettle), int(goods.Decimalplace))
- }
- }
- // 子账户需要从内部持仓明细(通道)表汇总计划开仓成本和开仓均价
- hedgeInnerHolderDetails, _ := models.GetHedgeInnerHolderDetails(req.AccountID, int(item.Goodsid), 1)
- for _, detail := range hedgeInnerHolderDetails {
- // 开仓成本 = 建仓价 * 持仓数量 * 合约单位
- item.OpenCost += detail.Openprice * float64(detail.Holderqty) * goods.Agreeunit
- }
- // 开仓均价 = 开仓成本 / 期末头寸 / 合约单位
- item.OpenAveragePrice = item.OpenCost / float64(item.CurPositionQTY) / goods.Agreeunit
- item.OpenAveragePrice, _ = strconv.ParseFloat(utils.FormatFloat(item.OpenAveragePrice, int(goods.Decimalplace)), 64)
- // 持仓成本
- item.PositionCost = v.Sellcurholderamount
- // 持仓均价 = 持仓成本 / 期末头寸 / 合约单位
- item.PositionAveragePrice = v.Sellcurholderamount / float64(v.Sellcurpositionqty) / goods.Agreeunit
- item.PositionAveragePrice, _ = strconv.ParseFloat(utils.FormatFloat(item.PositionAveragePrice, int(goods.Decimalplace)), 64)
- // 盯市浮盈(MTP:浮动盈亏、持仓盈亏) 卖方向 = (持仓均价 - 最新价) * 卖期末头寸 * 合约单位
- if item.Last != 0 {
- item.PositionPL = (item.PositionAveragePrice - item.Last) * float64(v.Sellcurpositionqty) * goods.Agreeunit
- }
- // 逐笔浮盈(MTP:开仓盈亏、平仓盈亏)卖方向 = (开仓均价 - 最新价) * 卖期末头寸 * 合约单位
- if item.Last != 0 {
- item.OpenPL = (item.OpenAveragePrice - item.Last) * float64(v.Sellcurpositionqty) * goods.Agreeunit
- }
- // 持仓盈亏比例 = 持仓盈亏 / 开仓成本
- if item.PositionPL != 0 && item.OpenCost != 0 {
- item.PositionPLRate = item.PositionPL / item.OpenCost
- item.PositionPLRate, _ = strconv.ParseFloat(utils.FormatFloat(item.PositionPLRate, 4), 64)
- }
- rsp = append(rsp, item)
- }
- }
- }
- // 查询成功返回
- logger.GetLogger().Debugln("QueryErmcpTradePosition successed: %v", rsp)
- appG.Response(http.StatusOK, e.SUCCESS, rsp)
- }
- // QueryErmcpOrderDetailsReq 获取企业风管期货委托单信息请求参数
- type QueryErmcpOrderDetailsReq struct {
- AccountID int `form:"accountID" binding:"required"`
- }
- // QueryErmcpOrderDetails 获取企业风管期货委托单信息
- // @Summary 获取企业风管期货委托单信息
- // @Produce json
- // @Security ApiKeyAuth
- // @Param accountID query int true "资金账户ID"
- // @Success 200 {object} models.QueryHedgeOrderDetailRsp
- // @Failure 500 {object} app.Response
- // @Router /Ermcp/QueryErmcpOrderDetails [get]
- // @Tags 企业风险管理(app)
- func QueryErmcpOrderDetails(c *gin.Context) {
- appG := app.Gin{C: c}
- // 获取请求参数
- var req QueryErmcpOrderDetailsReq
- if err := appG.C.ShouldBindQuery(&req); err != nil {
- logger.GetLogger().Errorf("QueryErmcpOrderDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
- return
- }
- // 获取资金账户信息
- taAccount, err := models.GetTaAccountByID(req.AccountID)
- if err != nil {
- logger.GetLogger().Errorf("QueryErmcpOrderDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- if taAccount == nil {
- logger.GetLogger().Errorf("QueryErmcpOrderDetails failed")
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- rst := make([]models.QueryHedgeOrderDetailRsp, 0)
- if taAccount.Ismain == 1 {
- // 母账户 -> 外部委托单
- rst, err = models.GetHedgeOutOrderDetails(req.AccountID)
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpOrderDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- } else {
- // 子账户 -> 内部委托单
- rst, err = models.GetHedgeInnerOrderDetails(req.AccountID)
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpOrderDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- }
- // 查询成功返回
- logger.GetLogger().Debugln("QueryErmcpOrderDetails successed: %v", rst)
- appG.Response(http.StatusOK, e.SUCCESS, rst)
- }
- // QueryErmcpHisOrderDetailsReq 获取企业风管期货历史委托单信息请求参数
- type QueryErmcpHisOrderDetailsReq struct {
- AccountID int `form:"accountID" binding:"required"`
- StartDate string `form:"startDate"` // 开始时间
- EndDate string `form:"endDate"` // 结束时间
- }
- // QueryErmcpHisOrderDetails 获取企业风管期货历史委托单信息
- // @Summary 获取企业风管期货历史委托单信息
- // @Produce json
- // @Security ApiKeyAuth
- // @Param accountID query int true "资金账户ID"
- // @Param startDate query string false "开始时间 - 闭区间,格式:yyyy-MM-dd"
- // @Param endDate query string false "结束时间 - 闭区间,格式:yyyy-MM-dd"
- // @Success 200 {object} models.QueryHedgeOrderDetailRsp
- // @Failure 500 {object} app.Response
- // @Router /Ermcp/QueryErmcpHisOrderDetails [get]
- // @Tags 企业风险管理(app)
- func QueryErmcpHisOrderDetails(c *gin.Context) {
- appG := app.Gin{C: c}
- // 获取请求参数
- var req QueryErmcpHisOrderDetailsReq
- if err := appG.C.ShouldBindQuery(&req); err != nil {
- logger.GetLogger().Errorf("QueryErmcpHisOrderDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
- return
- }
- // 获取资金账户信息
- taAccount, err := models.GetTaAccountByID(req.AccountID)
- if err != nil {
- logger.GetLogger().Errorf("QueryErmcpHisOrderDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- if taAccount == nil {
- logger.GetLogger().Errorf("QueryErmcpHisOrderDetails failed")
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- rst := make([]models.QueryHedgeOrderDetailRsp, 0)
- if taAccount.Ismain == 1 {
- // 母账户 -> 外部历史委托单
- rst, err = models.GetHisHedgeOutOrderDetails(req.AccountID, req.StartDate, req.EndDate)
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpHisOrderDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- } else {
- // 子账户 -> 内部历史委托单
- rst, err = models.GetHisHedgeInnerOrderDetails(req.AccountID, req.StartDate, req.EndDate)
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpHisOrderDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- }
- // 查询成功返回
- logger.GetLogger().Debugln("QueryErmcpHisOrderDetails successed: %v", rst)
- appG.Response(http.StatusOK, e.SUCCESS, rst)
- }
- // QueryHedgeTradeDetailReq 获取企业风管期货成交单信息请求参数
- type QueryHedgeTradeDetailReq struct {
- AccountID int `form:"accountID" binding:"required"`
- GoodsID int `form:"goodsID"`
- BuyOrSell int `form:"buyOrSell"`
- }
- // QueryErmcpTradeDetails 获取企业风管期货成交单信息
- // @Summary 获取企业风管期货成交单信息
- // @Produce json
- // @Security ApiKeyAuth
- // @Param accountID query int true "资金账户ID"
- // @Param goodsID query int false "商品ID"
- // @Param buyOrSell query int false "买卖方向,0:买 1:卖"
- // @Success 200 {object} models.QueryHedgeTradeDetailRsp
- // @Failure 500 {object} app.Response
- // @Router /Ermcp/QueryErmcpTradeDetails [get]
- // @Tags 企业风险管理(app)
- func QueryErmcpTradeDetails(c *gin.Context) {
- appG := app.Gin{C: c}
- // 获取请求参数
- var req QueryHedgeTradeDetailReq
- if err := appG.C.ShouldBindQuery(&req); err != nil {
- logger.GetLogger().Errorf("QueryErmcpTradeDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
- return
- }
- // 获取资金账户信息
- taAccount, err := models.GetTaAccountByID(req.AccountID)
- if err != nil {
- logger.GetLogger().Errorf("QueryErmcpTradeDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- if taAccount == nil {
- logger.GetLogger().Errorf("QueryErmcpTradeDetails failed")
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- rst := make([]models.QueryHedgeTradeDetailRsp, 0)
- if taAccount.Ismain == 1 {
- // 母账户 -> 外部成交单
- rst, err = models.GetHedgeOutTradeDetails(req.AccountID, req.GoodsID, req.BuyOrSell)
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradeDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- } else {
- // 子账户 -> 内部成交单
- rst, err = models.GetHedgeInnerTradeDetails(req.AccountID, req.GoodsID, req.BuyOrSell)
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpTradeDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- }
- // 查询成功返回
- logger.GetLogger().Debugln("QueryErmcpTradeDetails successed: %v", rst)
- appG.Response(http.StatusOK, e.SUCCESS, rst)
- }
- // QueryHedgeHisTradeDetaislReq 获取企业风管期货历史成交单信息请求参数
- type QueryHedgeHisTradeDetaislReq struct {
- AccountID int `form:"accountID" binding:"required"`
- GoodsID int `form:"goodsID"`
- BuyOrSell int `form:"buyOrSell"`
- StartDate string `form:"startDate"` // 开始时间
- EndDate string `form:"endDate"` // 结束时间
- }
- // QueryErmcpHisTradeDetails 获取企业风管期货历史成交单信息
- // @Summary 获取企业风管期货历史成交单信息
- // @Produce json
- // @Security ApiKeyAuth
- // @Param accountID query int true "资金账户ID"
- // @Param goodsID query int false "商品ID"
- // @Param buyOrSell query int false "买卖方向,0:买 1:卖"
- // @Param startDate query string false "开始时间 - 闭区间,格式:yyyy-MM-dd"
- // @Param endDate query string false "结束时间 - 闭区间,格式:yyyy-MM-dd"
- // @Success 200 {object} models.QueryHedgeTradeDetailRsp
- // @Failure 500 {object} app.Response
- // @Router /Ermcp/QueryErmcpHisTradeDetails [get]
- // @Tags 企业风险管理(app)
- func QueryErmcpHisTradeDetails(c *gin.Context) {
- appG := app.Gin{C: c}
- // 获取请求参数
- var req QueryHedgeHisTradeDetaislReq
- if err := appG.C.ShouldBindQuery(&req); err != nil {
- logger.GetLogger().Errorf("QueryErmcpHisTradeDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
- return
- }
- // 获取资金账户信息
- taAccount, err := models.GetTaAccountByID(req.AccountID)
- if err != nil {
- logger.GetLogger().Errorf("QueryErmcpHisTradeDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- if taAccount == nil {
- logger.GetLogger().Errorf("QueryErmcpHisTradeDetails failed")
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- rst := make([]models.QueryHedgeTradeDetailRsp, 0)
- if taAccount.Ismain == 1 {
- // 母账户 -> 外部历史成交单
- rst, err = models.GetHisHedgeOutTradeDetails(req.AccountID, req.GoodsID, req.BuyOrSell, req.StartDate, req.EndDate)
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpHisTradeDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- } else {
- // 子账户 -> 内部历史成交单
- rst, err = models.GetHisHedgeInnerTradeDetails(req.AccountID, req.GoodsID, req.BuyOrSell, req.StartDate, req.EndDate)
- if err != nil {
- // 查询失败
- logger.GetLogger().Errorf("QueryErmcpHisTradeDetails failed: %s", err.Error())
- appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
- return
- }
- }
- // 查询成功返回
- logger.GetLogger().Debugln("QueryErmcpHisTradeDetails successed: %v", rst)
- appG.Response(http.StatusOK, e.SUCCESS, rst)
- }
|