Explorar el Código

1.查资金增加融资额、总市值字段
2.查持仓增加市值、盈亏、盈亏比例、最新价字段

zou.yingbin hace 4 años
padre
commit
05a82e10e2

+ 3 - 3
config/config.xml

@@ -36,10 +36,10 @@
     <Password value="123456"/>
   </MongoDBSetting>
   <MySQLSetting>
-    <Host value="192.168.30.140"/>
+    <Host value="192.168.30.72"/>
     <Port value="3306"/>
-    <DBName value="historyquote_test175"/>
-    <Username value="quote_test175"/>
+    <DBName value="historyquote_test176"/>
+    <Username value="quote_test176"/>
     <Password value="123456"/>
   </MySQLSetting>
 </Configuration>

+ 68 - 7
controllers/order/order.go

@@ -10,7 +10,9 @@ import (
 	"mtp2_if/logger"
 	"mtp2_if/models"
 	"mtp2_if/mtpcache"
+	"mtp2_if/utils"
 	"net/http"
+	"strconv"
 	"time"
 
 	"github.com/gin-gonic/gin"
@@ -73,6 +75,10 @@ type QueryTradePositionRsp struct {
 	AveragePrice    float64 `json:"averageprice" xorm:"AVERAGEPRICE"`             // 持仓均价
 	Usedmargin      float64 `json:"usedmargin"  xorm:"'USEDMARGIN'"`              // 占用保证金[商品币种]
 	QTYDECIMALPLACE int32   `json:"qtydecimalplace"`                              // 成交量小数位
+	PositionPL      float64 `json:"positionpl"`                                   // 持仓盈亏 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位;卖方向 = (持仓均价 - 最新价) * 卖期末头寸 * 合约单位
+	PositionPLRate  float64 `json:"positionplrate"`                               // 持仓盈亏比例【实时行情更新】 = 持仓盈亏 / 开仓成本
+	MarketAmount    float64 `json:"marketamount"`                                 // 市值
+	LastPrice       float64 `json:"lastprice"`                                    // 最新价
 }
 
 // QueryTradePosition 持仓汇总查询(合约市场)
@@ -96,7 +102,17 @@ func QueryTradePosition(c *gin.Context) {
 		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
 		return
 	}
+	rst, ret := GetTradePosition(req.AccountID, req.TradeMode)
+	if ret {
+		appG.Response(http.StatusOK, e.SUCCESS, rst)
+	} else {
+		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
+	}
+}
 
+// GetTradePosition 获取持仓汇总数据, 成功返回true, 失败返回false
+func GetTradePosition(accIds string, tradeModes string) (rst []QueryTradePositionRsp, ret bool) {
+	rst = make([]QueryTradePositionRsp, 0)
 	// 查询数据
 	type tradePosition struct {
 		models.Tradeposition `xorm:"extends"`
@@ -119,18 +135,52 @@ func QueryTradePosition(c *gin.Context) {
 		Join("LEFT", "MARKET", "GOODS.MARKETID = MARKET.MARKETID").
 		Join("LEFT", "ENUMDICITEM", "GOODS.GOODUNITID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'goodsunit'").
 		Select("TRADEPOSITION.*, GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.CURRENCYID, GOODS.GOODUNITID,GOODS.QTYDECIMALPLACE, ENUMDICITEM.ENUMDICNAME as GOODUNIT, GOODS.AGREEUNIT, GOODS.DECIMALPLACE, MARKET.MARKETID, MARKET.TRADEMODE").
-		Where(fmt.Sprintf(`TRADEPOSITION.ACCOUNTID in (%s)`, req.AccountID))
-	if len(req.TradeMode) > 0 {
-		s = s.And(fmt.Sprintf(`MARKET.TRADEMODE in (%s)`, req.TradeMode))
+		Where(fmt.Sprintf(`TRADEPOSITION.ACCOUNTID in (%s)`, accIds))
+	if len(tradeModes) > 0 {
+		s = s.And(fmt.Sprintf(`MARKET.TRADEMODE in (%s)`, tradeModes))
 	}
 	if err := s.Find(&datas); err != nil {
 		// 查询失败
 		logger.GetLogger().Errorf("QueryTradePosition failed: %s", err.Error())
-		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
+		return rst, false
+	}
+
+	// 获取盘面
+	goodGuotes := make([]models.Quoteday, 0)
+	if len(datas) > 0 {
+		var a models.InStrBuilder
+		for i := range datas {
+			a.Add(datas[i].Goodscode)
+		}
+		goodGuotes, _ = models.GetQuoteDays(a.InStr())
+	}
+
+	fCalcPL := func(goodsCode string, buyOrSell int64, qty, holderPrice,
+		agreeUnit float64, decimalPlace int64) (positionPL float64, marketAmount float64, lastPrice float64) {
+		positionPL = 0
+		for _, q := range goodGuotes {
+			if goodsCode == q.Goodscode {
+				if q.Last != 0 {
+					lastPrice = utils.IntToFloat64(int(q.Last), int(decimalPlace))
+				} else if q.Presettle != 0 {
+					lastPrice = utils.IntToFloat64(int(q.Presettle), int(decimalPlace))
+				} else {
+					return
+				}
+				positionPL = (lastPrice - holderPrice) * qty * agreeUnit
+				positionPL, _ = strconv.ParseFloat(utils.FormatFloat(positionPL, 2), 64)
+				if buyOrSell == 1 {
+					// 卖方向 *-1
+					positionPL *= -1.0
+				}
+				marketAmount = lastPrice * qty * agreeUnit
+				marketAmount, _ = strconv.ParseFloat(utils.FormatFloat(marketAmount, 2), 64)
+			}
+		}
 		return
 	}
+
 	// 构建返回数据
-	rst := make([]QueryTradePositionRsp, 0)
 	for _, v := range datas {
 		// 构建买方向持仓汇总
 		if v.Buycurpositionqty > 0 {
@@ -161,6 +211,12 @@ func QueryTradePosition(c *gin.Context) {
 				//tradePosition.AveragePrice, _ = strconv.ParseFloat(utils.FormatFloat(averagePrice, int(v.Decimalplace)), 64)
 				// #96004 改为固定3位小数
 				tradePosition.AveragePrice, _ = decimal.NewFromFloat(averagePrice).Round(3).Float64()
+				tradePosition.PositionPL, tradePosition.MarketAmount, tradePosition.LastPrice = fCalcPL(tradePosition.GoodsCode, tradePosition.BuyOrSell, tradePosition.CurPositionQTY,
+					tradePosition.AveragePrice, tradePosition.AgreeUnit, tradePosition.DecimalPlace)
+				if tradePosition.CurHolderAmount > 1e-10 {
+					tradePosition.PositionPLRate = tradePosition.PositionPL / tradePosition.CurHolderAmount
+					tradePosition.PositionPLRate, _ = strconv.ParseFloat(utils.FormatFloat(tradePosition.PositionPLRate, 4), 64)
+				}
 				rst = append(rst, tradePosition)
 			}
 		}
@@ -194,7 +250,12 @@ func QueryTradePosition(c *gin.Context) {
 				//tradePosition.AveragePrice, _ = strconv.ParseFloat(utils.FormatFloat(averagePrice, int(v.Decimalplace)), 64)
 				// #96004 改为固定3位小数
 				tradePosition.AveragePrice, _ = decimal.NewFromFloat(averagePrice).Round(3).Float64()
-
+				tradePosition.PositionPL, tradePosition.MarketAmount, tradePosition.LastPrice = fCalcPL(tradePosition.GoodsCode, tradePosition.BuyOrSell, tradePosition.CurPositionQTY,
+					tradePosition.AveragePrice, tradePosition.AgreeUnit, tradePosition.DecimalPlace)
+				if tradePosition.CurHolderAmount > 1e-10 {
+					tradePosition.PositionPLRate = tradePosition.PositionPL / tradePosition.CurHolderAmount
+					tradePosition.PositionPLRate, _ = strconv.ParseFloat(utils.FormatFloat(tradePosition.PositionPLRate, 4), 64)
+				}
 				rst = append(rst, tradePosition)
 			}
 		}
@@ -202,7 +263,7 @@ func QueryTradePosition(c *gin.Context) {
 
 	// 查询成功
 	logger.GetLogger().Debugln("QueryTradePosition successed: %v", rst)
-	appG.Response(http.StatusOK, e.SUCCESS, rst)
+	return rst, true
 }
 
 // QueryTradeOrderDetailReq 委托单查询请求参数(合约市场)

+ 31 - 1
controllers/taaccount/taaccount.go

@@ -2,6 +2,7 @@ package taaccount
 
 import (
 	"fmt"
+	"mtp2_if/controllers/order"
 	"mtp2_if/db"
 	"mtp2_if/global/app"
 	"mtp2_if/global/e"
@@ -49,7 +50,7 @@ func GetTaAccounts(c *gin.Context) {
 	}
 
 	// 如果是母账户,要从对冲外部资金账户表获取资金信息
-	for i, _ := range taAccounts {
+	for i := range taAccounts {
 		item := &taAccounts[i]
 		if item.Ismain == 1 {
 			hedgeOutTaAccount, _ := models.GetHedgeOutTaAccount(int(item.Accountid))
@@ -68,6 +69,35 @@ func GetTaAccounts(c *gin.Context) {
 		}
 	}
 
+	if len(taAccounts) > 0 {
+		// 查融资额
+		var a models.InStrBuilder
+		for i := range taAccounts {
+			a.Add(taAccounts[i].Accountid)
+		}
+		mRemainAmount := models.QhjContractRemainAmount{FilterAccId: a.InStr()}
+		if d, err := mRemainAmount.GetData(); err == nil {
+			for _, v := range d {
+				for i := range taAccounts {
+					if v.ACCOUNTID == taAccounts[i].Accountid {
+						taAccounts[i].REMAINAMOUNT = v.REMAINACOUNT
+					}
+				}
+			}
+		}
+
+		// 查总市值
+		if rst, bRet := order.GetTradePosition(a.InStr(), ""); bRet {
+			for i := range taAccounts {
+				for _, v := range rst {
+					if taAccounts[i].Accountid == v.AccountID {
+						taAccounts[i].CURAMOUNT += v.MarketAmount
+					}
+				}
+			}
+		}
+	}
+
 	// 查询成功
 	logger.GetLogger().Debugln("GetTaAccounts successed: %v", taAccounts)
 	appG.Response(http.StatusOK, e.SUCCESS, taAccounts)

+ 24 - 0
docs/docs.go

@@ -27318,6 +27318,10 @@ var doc = `{
                     "description": "今日授信增加",
                     "type": "number"
                 },
+                "curamount": {
+                    "description": "总市值(从持仓中统计)",
+                    "type": "number"
+                },
                 "currencyid": {
                     "description": "货币ID",
                     "type": "integer"
@@ -27438,6 +27442,10 @@ var doc = `{
                     "description": "关联用户",
                     "type": "integer"
                 },
+                "remainacount": {
+                    "description": "融资额(从融资合同中统计)",
+                    "type": "number"
+                },
                 "serivcegroup": {
                     "description": "服务分组",
                     "type": "integer"
@@ -29332,6 +29340,14 @@ var doc = `{
                     "description": "期初持仓总金额[商品币种]",
                     "type": "number"
                 },
+                "lastprice": {
+                    "description": "最新价",
+                    "type": "number"
+                },
+                "marketamount": {
+                    "description": "市值",
+                    "type": "number"
+                },
                 "marketid": {
                     "description": "所属市场ID",
                     "type": "integer"
@@ -29348,6 +29364,14 @@ var doc = `{
                     "description": "持仓其他冻结数量(交割冻结)",
                     "type": "number"
                 },
+                "positionpl": {
+                    "description": "持仓盈亏 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位;卖方向 = (持仓均价 - 最新价) * 卖期末头寸 * 合约单位",
+                    "type": "number"
+                },
+                "positionplrate": {
+                    "description": "持仓盈亏比例【实时行情更新】 = 持仓盈亏 / 开仓成本",
+                    "type": "number"
+                },
                 "positionqty": {
                     "description": "期初持仓数量",
                     "type": "number"

+ 24 - 0
docs/swagger.json

@@ -27302,6 +27302,10 @@
                     "description": "今日授信增加",
                     "type": "number"
                 },
+                "curamount": {
+                    "description": "总市值(从持仓中统计)",
+                    "type": "number"
+                },
                 "currencyid": {
                     "description": "货币ID",
                     "type": "integer"
@@ -27422,6 +27426,10 @@
                     "description": "关联用户",
                     "type": "integer"
                 },
+                "remainacount": {
+                    "description": "融资额(从融资合同中统计)",
+                    "type": "number"
+                },
                 "serivcegroup": {
                     "description": "服务分组",
                     "type": "integer"
@@ -29316,6 +29324,14 @@
                     "description": "期初持仓总金额[商品币种]",
                     "type": "number"
                 },
+                "lastprice": {
+                    "description": "最新价",
+                    "type": "number"
+                },
+                "marketamount": {
+                    "description": "市值",
+                    "type": "number"
+                },
                 "marketid": {
                     "description": "所属市场ID",
                     "type": "integer"
@@ -29332,6 +29348,14 @@
                     "description": "持仓其他冻结数量(交割冻结)",
                     "type": "number"
                 },
+                "positionpl": {
+                    "description": "持仓盈亏 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位;卖方向 = (持仓均价 - 最新价) * 卖期末头寸 * 合约单位",
+                    "type": "number"
+                },
+                "positionplrate": {
+                    "description": "持仓盈亏比例【实时行情更新】 = 持仓盈亏 / 开仓成本",
+                    "type": "number"
+                },
                 "positionqty": {
                     "description": "期初持仓数量",
                     "type": "number"

+ 19 - 0
docs/swagger.yaml

@@ -12340,6 +12340,9 @@ definitions:
       creditincrease:
         description: 今日授信增加
         type: number
+      curamount:
+        description: 总市值(从持仓中统计)
+        type: number
       currencyid:
         description: 货币ID
         type: integer
@@ -12430,6 +12433,9 @@ definitions:
       relateduserid:
         description: 关联用户
         type: integer
+      remainacount:
+        description: 融资额(从融资合同中统计)
+        type: number
       serivcegroup:
         description: 服务分组
         type: integer
@@ -13868,6 +13874,12 @@ definitions:
       holderamount:
         description: 期初持仓总金额[商品币种]
         type: number
+      lastprice:
+        description: 最新价
+        type: number
+      marketamount:
+        description: 市值
+        type: number
       marketid:
         description: 所属市场ID
         type: integer
@@ -13880,6 +13892,13 @@ definitions:
       otherfrozenqty:
         description: 持仓其他冻结数量(交割冻结)
         type: number
+      positionpl:
+        description: 持仓盈亏 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位;卖方向 = (持仓均价 - 最新价) * 卖期末头寸
+          * 合约单位
+        type: number
+      positionplrate:
+        description: 持仓盈亏比例【实时行情更新】 = 持仓盈亏 / 开仓成本
+        type: number
       positionqty:
         description: 期初持仓数量
         type: number

+ 3 - 0
models/account.go

@@ -96,6 +96,9 @@ type Taaccount struct {
 	Serivcegroup          int64     `json:"serivcegroup"  xorm:"'SERIVCEGROUP'"`                   // 服务分组
 	Accountname           string    `json:"accountname"  xorm:"'ACCOUNTNAME'"`                     // 账户名称
 	Accountflag           int32     `json:"accountflag"  xorm:"'ACCOUNTFLAG'"`                     // 账户标识 - 0\1 (默认为0, 当上级账户与本账户的关联用户均为自己时更新为1)
+
+	REMAINAMOUNT float64 `json:"remainamount" xorm:"-"` // 融资额(从融资合同中统计)
+	CURAMOUNT    float64 `json:"curamount" xorm:"-"`    // 总市值(从持仓中统计)
 }
 
 // TableName is TAACCOUNT

+ 26 - 0
models/ermcpCommon.go

@@ -59,6 +59,32 @@ func DecodeStr(condition bool, strTrue, strFalse string) string {
 	return strFalse
 }
 
+// InStrBuilder 构建InStr字串
+type InStrBuilder struct {
+	Value []interface{}
+}
+
+// Add 增加元素
+func (r *InStrBuilder) Add(v interface{}) {
+	r.Value = append(r.Value, v)
+}
+
+// InStr 返回逗号隔开的字串
+func (r *InStrBuilder) InStr() string {
+	var str string
+	for _, v := range r.Value {
+		if len(str) > 0 {
+			str += ","
+		}
+		if _, ok := v.(string); ok {
+			str += fmt.Sprintf("'%v'", v)
+		} else {
+			str += fmt.Sprintf("%v", v)
+		}
+	}
+	return str
+}
+
 // InStr
 func InStr(param ...interface{}) string {
 	var str string

+ 33 - 0
models/qhj.go

@@ -2210,3 +2210,36 @@ func (r *QhjScoreLog) GetDataEx() (interface{}, error) {
 	}
 	return sData, err
 }
+
+// QhjContractRemainAmount 融资额
+type QhjContractRemainAmount struct {
+	ACCOUNTID    int64   `json:"accountid"  xorm:"'ACCOUNTID'"`       // 资金账号
+	REMAINACOUNT float64 `json:"remainacount"  xorm:"'REMAINACOUNT'"` // 融资额(合同剩余金额)
+
+	FilterAccId string `json:"-"` // 资金账号列表
+}
+
+func (r *QhjContractRemainAmount) calc() {
+
+}
+
+func (r *QhjContractRemainAmount) buildSql() string {
+	var sqlId utils.SQLVal = "select t.borroweraccountid accountid, sum(s.remainamount) remainamount" +
+		"  from scf_contract t" +
+		" inner join scf_contractinfo s" +
+		"    on t.scfcontractid = s.scfcontractid" +
+		" where 1 = 1 and t.scfcontracttype=5"
+	sqlId.JoinEx(r.FilterAccId != "", fmt.Sprintf(" and t.borroweraccountid in (%v)", r.FilterAccId))
+	sqlId.Join(" group by t.borroweraccountid")
+	return sqlId.String()
+}
+
+// GetDataEx 获取融资额
+func (r *QhjContractRemainAmount) GetData() ([]QhjContractRemainAmount, error) {
+	sData := make([]QhjContractRemainAmount, 0)
+	err := db.GetEngine().SQL(r.buildSql()).Find(&sData)
+	for i := range sData {
+		sData[i].calc()
+	}
+	return sData, err
+}