qryOrder.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. package ermcp
  2. import (
  3. "mtp2_if/global/app"
  4. "mtp2_if/global/e"
  5. "mtp2_if/logger"
  6. "mtp2_if/models"
  7. "mtp2_if/utils"
  8. "net/http"
  9. "github.com/gin-gonic/gin"
  10. )
  11. // QueryErmcpTradePositionReq 获取企业风管期货持仓头寸信息请求参数
  12. type QueryErmcpTradePositionReq struct {
  13. AccountID int `form:"accountID" binding:"required"`
  14. MarketID int `form:"marketID"`
  15. }
  16. // QueryErmcpTradePositionRsp 获取企业风管期货持仓头寸信息返回模型
  17. type QueryErmcpTradePositionRsp struct {
  18. Goodsname string `json:"goodsname"` // 商品名称
  19. BuyOrSell int64 `json:"buyorsell"` // 方向 - 0:买 1:卖
  20. EnableQTY int64 `json:"enableqty"` // 可用(总仓可用)
  21. CurPositionQTY int64 `json:"curpositionqty"` // 持仓(总仓数量, 期末头寸)
  22. Last float64 `json:"last"` // 现价
  23. CurTDPosition int64 `json:"curtdposition"` // 今仓数量(期末今日头寸)
  24. CurTDPositionEnabled int64 `json:"curtdpositionenabled"` // 今仓可用
  25. PositionAveragePrice float64 `json:"positionaverageprice"` // 持仓均价【头寸变化更新】= 持仓成本 / 期末头寸 / 合约单位
  26. OpenAveragePrice float64 `json:"openaverageprice" ` // 开仓均价【头寸变化更新】 = 开仓成本 / 期末头寸 / 合约单位
  27. PositionPL float64 `json:"positionpl"` // 盯市浮盈【实时行情更新】(MTP:浮动盈亏、持仓盈亏) 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位;卖方向 = (持仓均价 - 最新价) * 买期末头寸 * 合约单位
  28. OpenPL float64 `json:"openpl"` // 逐笔浮盈【实时行情更新】(MTP:开仓盈亏、平仓盈亏) 买方向 = (最新价 - 开仓均价) * 买期末头寸 * 合约单位;卖方向 = (开仓均价 - 最新价) * 买期末头寸 * 合约单位
  29. PositionPLRate float64 `json:"positionplrate"` // 持仓盈亏比例【实时行情更新】 = 持仓盈亏 / 开仓成本
  30. UsedMargin float64 `json:"usedmargin"` // 占用保证金
  31. ExExehangeName string `json:"exexchangename"` // 外部交易所名称
  32. OpenCost float64 `json:"opencost"` // 开仓成本
  33. PositionCost float64 `json:"positioncost"` // 持仓成本
  34. Goodsid int64 `json:"goodsid"` // 商品ID(自增ID SEQ_GOODS)
  35. Goodscode string `json:"goodscode"` // 商品代码(内部)
  36. Outgoodscode string `json:"outgoodscode"` // 商品代码(外部)
  37. Agreeunit float64 `json:"agreeunit"` // 合约单位
  38. Decimalplace int64 `json:"decimalplace"` // 报价小数位
  39. Marketid int64 `json:"marketid"` // 所属市场ID
  40. }
  41. // QueryErmcpTradePosition 获取企业风管期货持仓头寸信息
  42. // @Summary 获取企业风管期货持仓头寸信息
  43. // @Description 本接口只使用于通道交易相关头寸查询;子账户持仓头寸占用保证金为0;
  44. // @Produce json
  45. // @Security ApiKeyAuth
  46. // @Param accountID query int true "资金账户ID"
  47. // @Param marketID query int false "所属市场ID"
  48. // @Success 200 {object} QueryErmcpTradePositionRsp
  49. // @Failure 500 {object} app.Response
  50. // @Router /Ermcp/QueryErmcpTradePosition [get]
  51. // @Tags 企业风险管理(app)
  52. func QueryErmcpTradePosition(c *gin.Context) {
  53. appG := app.Gin{C: c}
  54. // 获取请求参数
  55. var req QueryErmcpTradePositionReq
  56. if err := appG.C.ShouldBindQuery(&req); err != nil {
  57. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  58. appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
  59. return
  60. }
  61. rsp := make([]QueryErmcpTradePositionRsp, 0)
  62. // 获取资金账户信息
  63. taAccount, err := models.GetTaAccountByID(req.AccountID)
  64. if err != nil {
  65. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  66. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  67. return
  68. }
  69. if taAccount == nil {
  70. logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
  71. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  72. return
  73. }
  74. if taAccount.Ismain == 1 {
  75. // 母账户,从HEDGE_OUTTRADEPOSITION表查询持仓头寸(未生成内部头寸)
  76. hedgeOutTradePositions, err := models.GetHedgeOutTradePositions(req.AccountID, req.MarketID)
  77. if err != nil {
  78. // 查询失败
  79. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  80. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  81. return
  82. }
  83. // 分解买卖方向的头寸
  84. for _, v := range hedgeOutTradePositions {
  85. // 分解买卖方向的头寸
  86. if v.Curbuyposition > 0 {
  87. // 买方向
  88. item := QueryErmcpTradePositionRsp{
  89. BuyOrSell: 0,
  90. EnableQTY: v.Curbuyposition - v.Fretdbuyposition - v.Freydbuyposition, // 买可用 = 期末买头寸 - 冻结今日买头寸 - 冻结上日买头寸
  91. CurPositionQTY: v.Curbuyposition,
  92. CurTDPosition: v.Curtdbuyposition,
  93. CurTDPositionEnabled: v.Curtdbuyposition - v.Fretdbuyposition, // 今仓买可用 = 期末今日买头寸 - 冻结今日买头寸
  94. UsedMargin: v.Buyusemargin,
  95. OpenCost: v.Buyopencost,
  96. PositionCost: v.Buypositioncost,
  97. Goodsid: v.Hedgegoodsid,
  98. Marketid: int64(v.Marketid),
  99. }
  100. // 获取对应商品信息
  101. goods, err := models.GetGoods(int(v.Hedgegoodsid))
  102. if err != nil {
  103. // 查询失败
  104. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  105. appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
  106. return
  107. }
  108. if goods == nil {
  109. logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
  110. appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
  111. return
  112. }
  113. item.Goodscode = goods.Goodscode
  114. item.Outgoodscode = goods.Outgoodscode
  115. item.Goodsname = goods.Goodsname
  116. item.Agreeunit = goods.Agreeunit
  117. // 获取对应外部交易所名称
  118. exchange, err := models.GetExternalexchangeByGoodsGroupID(int(goods.Goodsgroupid))
  119. if err != nil {
  120. // 查询失败
  121. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  122. appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
  123. return
  124. }
  125. if exchange == nil {
  126. logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
  127. appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
  128. return
  129. }
  130. item.ExExehangeName = exchange.Exchangefullname
  131. // 获取对应商品盘面信息
  132. quoteDays, err := models.GetQuoteDays("'" + goods.Outgoodscode + "'")
  133. if err != nil {
  134. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  135. appG.Response(http.StatusBadRequest, e.ERROR_GET_QUOTE_FAILED, nil)
  136. return
  137. }
  138. if len(quoteDays) > 0 {
  139. if quoteDays[0].Last != 0 {
  140. item.Last = utils.IntToFloat64(int(quoteDays[0].Last), int(goods.Decimalplace))
  141. }
  142. // 没有现价则尝试用昨结
  143. if item.Last == 0 && quoteDays[0].Presettle != 0 {
  144. item.Last = utils.IntToFloat64(int(quoteDays[0].Presettle), int(goods.Decimalplace))
  145. }
  146. }
  147. // 计算价格与盈亏
  148. // 开仓均价 = 开仓成本 / 期末头寸 / 合约单位
  149. item.OpenAveragePrice = v.Buyopencost / float64(v.Curbuyposition) / goods.Agreeunit
  150. // 持仓均价 = 持仓成本 / 期末头寸 / 合约单位
  151. item.PositionAveragePrice = v.Buypositioncost / float64(v.Curbuyposition) / goods.Agreeunit
  152. // 盯市浮盈(MTP:浮动盈亏、持仓盈亏) 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位
  153. if item.Last != 0 {
  154. item.PositionPL = (item.Last - item.PositionAveragePrice) * float64(v.Curbuyposition) * goods.Agreeunit
  155. }
  156. // 逐笔浮盈(MTP:开仓盈亏、平仓盈亏)买方向 = (最新价 - 开仓均价) * 买期末头寸 * 合约单位
  157. if item.Last != 0 {
  158. item.OpenPL = (item.Last - item.OpenAveragePrice) * float64(v.Curbuyposition) * goods.Agreeunit
  159. }
  160. // 持仓盈亏比例 = 持仓盈亏 / 开仓成本
  161. if item.PositionPL != 0 && v.Buyopencost != 0 {
  162. item.PositionPLRate = item.PositionPL / v.Buyopencost
  163. }
  164. rsp = append(rsp, item)
  165. }
  166. if v.Cursellposition > 0 {
  167. // 卖方向
  168. item := QueryErmcpTradePositionRsp{
  169. BuyOrSell: 1,
  170. EnableQTY: v.Cursellposition - v.Fretdsellposition - v.Freydsellposition,
  171. CurPositionQTY: v.Cursellposition,
  172. CurTDPosition: v.Curtdsellposition,
  173. CurTDPositionEnabled: v.Curtdsellposition - v.Fretdsellposition,
  174. UsedMargin: v.Sellusemargin,
  175. OpenCost: v.Sellopencost,
  176. PositionCost: v.Sellpositioncost,
  177. Goodsid: v.Hedgegoodsid,
  178. Marketid: int64(v.Marketid),
  179. }
  180. // 获取对应商品信息
  181. goods, err := models.GetGoods(int(v.Hedgegoodsid))
  182. if err != nil {
  183. // 查询失败
  184. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  185. appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
  186. return
  187. }
  188. if goods == nil {
  189. logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
  190. appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
  191. return
  192. }
  193. item.Goodscode = goods.Goodscode
  194. item.Outgoodscode = goods.Outgoodscode
  195. item.Goodsname = goods.Goodsname
  196. item.Agreeunit = goods.Agreeunit
  197. // 获取对应外部交易所名称
  198. exchange, err := models.GetExternalexchangeByGoodsGroupID(int(goods.Goodsgroupid))
  199. if err != nil {
  200. // 查询失败
  201. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  202. appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
  203. return
  204. }
  205. if exchange == nil {
  206. logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
  207. appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
  208. return
  209. }
  210. item.ExExehangeName = exchange.Exchangefullname
  211. // 获取对应商品盘面信息
  212. quoteDays, err := models.GetQuoteDays("'" + goods.Outgoodscode + "'")
  213. if err != nil {
  214. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  215. appG.Response(http.StatusBadRequest, e.ERROR_GET_QUOTE_FAILED, nil)
  216. return
  217. }
  218. if len(quoteDays) > 0 {
  219. if quoteDays[0].Last != 0 {
  220. item.Last = utils.IntToFloat64(int(quoteDays[0].Last), int(goods.Decimalplace))
  221. }
  222. // 没有现价则尝试用昨结
  223. if item.Last == 0 && quoteDays[0].Presettle != 0 {
  224. item.Last = utils.IntToFloat64(int(quoteDays[0].Presettle), int(goods.Decimalplace))
  225. }
  226. }
  227. // 计算价格与盈亏
  228. // 开仓均价 = 开仓成本 / 期末头寸 / 合约单位
  229. item.OpenAveragePrice = v.Sellopencost / float64(v.Cursellposition) / goods.Agreeunit
  230. // 持仓均价 = 持仓成本 / 期末头寸 / 合约单位
  231. item.PositionAveragePrice = v.Sellpositioncost / float64(v.Cursellposition) / goods.Agreeunit
  232. // 盯市浮盈(MTP:浮动盈亏、持仓盈亏) 卖方向 = (持仓均价 - 最新价) * 卖期末头寸 * 合约单位
  233. if item.Last != 0 {
  234. item.PositionPL = (item.PositionAveragePrice - item.Last) * float64(v.Cursellposition) * goods.Agreeunit
  235. }
  236. // 逐笔浮盈(MTP:开仓盈亏、平仓盈亏)买方向 = (开仓均价 - 最新价) * 卖期末头寸 * 合约单位
  237. if item.Last != 0 {
  238. item.OpenPL = (item.Last - item.OpenAveragePrice) * float64(v.Cursellposition) * goods.Agreeunit
  239. }
  240. // 持仓盈亏比例 = 持仓盈亏 / 开仓成本
  241. if item.PositionPL != 0 && v.Sellopencost != 0 {
  242. item.PositionPLRate = item.PositionPL / v.Sellopencost
  243. }
  244. rsp = append(rsp, item)
  245. }
  246. }
  247. } else {
  248. // 子账户
  249. tradePositions, err := models.GetTradePositions(req.AccountID, req.MarketID)
  250. if err != nil {
  251. // 查询失败
  252. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  253. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  254. return
  255. }
  256. // 分解买卖方向的头寸
  257. for _, v := range tradePositions {
  258. if v.Buycurpositionqty > 0 {
  259. // 买方向
  260. item := QueryErmcpTradePositionRsp{
  261. BuyOrSell: 0,
  262. EnableQTY: v.Buycurpositionqty - v.Buyfrozenqty, // 买可用 = 买当前持仓总数量 - 买持仓冻结数量
  263. CurPositionQTY: v.Buycurpositionqty,
  264. CurTDPosition: v.Buycurtdposition,
  265. CurTDPositionEnabled: v.Buycurtdposition - v.Buyfretdposition, // 今仓买可用 = 期末今日买头寸 - 冻结今日买头寸
  266. Goodsid: int64(v.Goodsid),
  267. }
  268. // 获取对应市场信息
  269. market, err := models.GetMarketByGoodsID(int(v.Goodsid))
  270. if err != nil {
  271. // 查询失败
  272. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  273. appG.Response(http.StatusBadRequest, e.ERROR_GET_MARKET_FAILED, nil)
  274. return
  275. }
  276. if market == nil {
  277. logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
  278. appG.Response(http.StatusBadRequest, e.ERROR_GET_MARKET_FAILED, nil)
  279. return
  280. }
  281. item.Marketid = int64(market.Marketid)
  282. // 获取对应商品信息
  283. goods, err := models.GetGoods(int(v.Goodsid))
  284. if err != nil {
  285. // 查询失败
  286. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  287. appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
  288. return
  289. }
  290. if goods == nil {
  291. logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
  292. appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
  293. return
  294. }
  295. item.Goodscode = goods.Goodscode
  296. item.Outgoodscode = goods.Outgoodscode
  297. item.Goodsname = goods.Goodsname
  298. item.Agreeunit = goods.Agreeunit
  299. // 获取对应外部交易所名称
  300. exchange, err := models.GetExternalexchangeByGoodsGroupID(int(goods.Goodsgroupid))
  301. if err != nil {
  302. // 查询失败
  303. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  304. appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
  305. return
  306. }
  307. if exchange == nil {
  308. logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
  309. appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
  310. return
  311. }
  312. item.ExExehangeName = exchange.Exchangefullname
  313. // 获取对应商品盘面信息
  314. quoteDays, err := models.GetQuoteDays("'" + goods.Outgoodscode + "'")
  315. if err != nil {
  316. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  317. appG.Response(http.StatusBadRequest, e.ERROR_GET_QUOTE_FAILED, nil)
  318. return
  319. }
  320. if len(quoteDays) > 0 {
  321. if quoteDays[0].Last != 0 {
  322. item.Last = utils.IntToFloat64(int(quoteDays[0].Last), int(goods.Decimalplace))
  323. }
  324. // 没有现价则尝试用昨结
  325. if item.Last == 0 && quoteDays[0].Presettle != 0 {
  326. item.Last = utils.IntToFloat64(int(quoteDays[0].Presettle), int(goods.Decimalplace))
  327. }
  328. }
  329. // 子账户需要从内部持仓明细(通道)表汇总计划开仓成本和开仓均价
  330. hedgeInnerHolderDetails, _ := models.GetHedgeInnerHolderDetails(int(item.Goodsid), 0)
  331. for _, detail := range hedgeInnerHolderDetails {
  332. // 开仓成本 = 建仓价 * 持仓数量 * 合约单位
  333. item.OpenCost += detail.Openprice * float64(detail.Holderqty) * goods.Agreeunit
  334. }
  335. // 开仓均价 = 开仓成本 / 期末头寸 / 合约单位
  336. item.OpenAveragePrice = item.OpenCost / float64(item.CurPositionQTY) / goods.Agreeunit
  337. // 持仓成本
  338. item.PositionCost = v.Buycurholderamount
  339. // 持仓均价 = 持仓成本 / 期末头寸 / 合约单位
  340. item.PositionAveragePrice = v.Buycurholderamount / float64(v.Buycurpositionqty) / goods.Agreeunit
  341. // 盯市浮盈(MTP:浮动盈亏、持仓盈亏) 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位
  342. if item.Last != 0 {
  343. item.PositionPL = (item.Last - item.PositionAveragePrice) * float64(v.Buycurpositionqty) * goods.Agreeunit
  344. }
  345. // 逐笔浮盈(MTP:开仓盈亏、平仓盈亏)买方向 = (最新价 - 开仓均价) * 买期末头寸 * 合约单位
  346. if item.Last != 0 {
  347. item.OpenPL = (item.Last - item.OpenAveragePrice) * float64(v.Buycurpositionqty) * goods.Agreeunit
  348. }
  349. // 持仓盈亏比例 = 持仓盈亏 / 开仓成本
  350. if item.PositionPL != 0 && item.OpenCost != 0 {
  351. item.PositionPLRate = item.PositionPL / item.OpenCost
  352. }
  353. rsp = append(rsp, item)
  354. }
  355. if v.Sellcurpositionqty > 0 {
  356. // 卖方向
  357. item := QueryErmcpTradePositionRsp{
  358. BuyOrSell: 1,
  359. EnableQTY: v.Sellcurpositionqty - v.Sellfrozenqty, // 买可用 = 买当前持仓总数量 - 买持仓冻结数量
  360. CurPositionQTY: v.Sellcurpositionqty,
  361. CurTDPosition: v.Sellcurtdposition,
  362. CurTDPositionEnabled: v.Sellcurtdposition - v.Sellfretdposition, // 今仓买可用 = 期末今日买头寸 - 冻结今日买头寸
  363. Goodsid: int64(v.Goodsid),
  364. }
  365. // 获取对应市场信息
  366. market, err := models.GetMarketByGoodsID(int(v.Goodsid))
  367. if err != nil {
  368. // 查询失败
  369. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  370. appG.Response(http.StatusBadRequest, e.ERROR_GET_MARKET_FAILED, nil)
  371. return
  372. }
  373. if market == nil {
  374. logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
  375. appG.Response(http.StatusBadRequest, e.ERROR_GET_MARKET_FAILED, nil)
  376. return
  377. }
  378. item.Marketid = int64(market.Marketid)
  379. // 获取对应商品信息
  380. goods, err := models.GetGoods(int(v.Goodsid))
  381. if err != nil {
  382. // 查询失败
  383. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  384. appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
  385. return
  386. }
  387. if goods == nil {
  388. logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
  389. appG.Response(http.StatusBadRequest, e.ERROR_GET_GOODS_FAILED, nil)
  390. return
  391. }
  392. item.Goodscode = goods.Goodscode
  393. item.Outgoodscode = goods.Outgoodscode
  394. item.Goodsname = goods.Goodsname
  395. item.Agreeunit = goods.Agreeunit
  396. // 获取对应外部交易所名称
  397. exchange, err := models.GetExternalexchangeByGoodsGroupID(int(goods.Goodsgroupid))
  398. if err != nil {
  399. // 查询失败
  400. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  401. appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
  402. return
  403. }
  404. if exchange == nil {
  405. logger.GetLogger().Errorf("QueryErmcpTradePosition failed")
  406. appG.Response(http.StatusBadRequest, e.ERROR_GET_EXEXCHANGE_FAILED, nil)
  407. return
  408. }
  409. item.ExExehangeName = exchange.Exchangefullname
  410. // 获取对应商品盘面信息
  411. quoteDays, err := models.GetQuoteDays("'" + goods.Outgoodscode + "'")
  412. if err != nil {
  413. logger.GetLogger().Errorf("QueryErmcpTradePosition failed: %s", err.Error())
  414. appG.Response(http.StatusBadRequest, e.ERROR_GET_QUOTE_FAILED, nil)
  415. return
  416. }
  417. if len(quoteDays) > 0 {
  418. if quoteDays[0].Last != 0 {
  419. item.Last = utils.IntToFloat64(int(quoteDays[0].Last), int(goods.Decimalplace))
  420. }
  421. // 没有现价则尝试用昨结
  422. if item.Last == 0 && quoteDays[0].Presettle != 0 {
  423. item.Last = utils.IntToFloat64(int(quoteDays[0].Presettle), int(goods.Decimalplace))
  424. }
  425. }
  426. // 子账户需要从内部持仓明细(通道)表汇总计划开仓成本和开仓均价
  427. hedgeInnerHolderDetails, _ := models.GetHedgeInnerHolderDetails(int(item.Goodsid), 1)
  428. for _, detail := range hedgeInnerHolderDetails {
  429. // 开仓成本 = 建仓价 * 持仓数量 * 合约单位
  430. item.OpenCost += detail.Openprice * float64(detail.Holderqty) * goods.Agreeunit
  431. }
  432. // 开仓均价 = 开仓成本 / 期末头寸 / 合约单位
  433. item.OpenAveragePrice = item.OpenCost / float64(item.CurPositionQTY) / goods.Agreeunit
  434. // 持仓成本
  435. item.PositionCost = v.Sellcurholderamount
  436. // 持仓均价 = 持仓成本 / 期末头寸 / 合约单位
  437. item.PositionAveragePrice = v.Sellcurholderamount / float64(v.Sellcurpositionqty) / goods.Agreeunit
  438. // 盯市浮盈(MTP:浮动盈亏、持仓盈亏) 卖方向 = (持仓均价 - 最新价) * 买期末头寸 * 合约单位
  439. if item.Last != 0 {
  440. item.PositionPL = (item.PositionAveragePrice - item.Last) * float64(v.Sellcurpositionqty) * goods.Agreeunit
  441. }
  442. // 逐笔浮盈(MTP:开仓盈亏、平仓盈亏)卖方向 = (开仓均价 - 最新价) * 买期末头寸 * 合约单位
  443. if item.Last != 0 {
  444. item.OpenPL = (item.OpenAveragePrice - item.Last) * float64(v.Sellcurpositionqty) * goods.Agreeunit
  445. }
  446. // 持仓盈亏比例 = 持仓盈亏 / 开仓成本
  447. if item.PositionPL != 0 && item.OpenCost != 0 {
  448. item.PositionPLRate = item.PositionPL / item.OpenCost
  449. }
  450. rsp = append(rsp, item)
  451. }
  452. }
  453. }
  454. // 查询成功返回
  455. logger.GetLogger().Debugln("QueryErmcpTradePosition successed: %v", rsp)
  456. appG.Response(http.StatusOK, e.SUCCESS, rsp)
  457. }
  458. // QueryErmcpOrderDetailReq 获取企业风管期货委托单信息请求参数
  459. type QueryErmcpOrderDetailReq struct {
  460. AccountID int `form:"accountID" binding:"required"`
  461. MarketID int `form:"marketID"`
  462. }
  463. type QueryErmcpOrderDetailRsp struct {
  464. OrderType int `json:"ordertype"` //
  465. }