|
|
@@ -4,88 +4,69 @@ import { QueryErmcpTradePositionRsp } from '@/services/go/ermcp/futures/interfac
|
|
|
import { getQuoteDayInfoByCode } from "@/services/bus/goods";
|
|
|
import { BuyOrSell } from '@/common/constants/enumCommon';
|
|
|
import { getTaAccounts } from '@/services/go/TaAccount';
|
|
|
+import { Taaccount } from "@/services/go/TaAccount/interface";
|
|
|
import { geLoginID_number } from '@/services/bus/login';
|
|
|
import { Systemparam } from '@/services/go/useInfo/interface';
|
|
|
import { getSelectedAccountId } from '@/services/bus/account';
|
|
|
import { TradeAccount, TradePosition } from './interface'
|
|
|
import APP from '@/services';
|
|
|
|
|
|
+// 加载状态
|
|
|
+const loading = ref<boolean>(false);
|
|
|
// 资金账户列表
|
|
|
const tradeAccountList: TradeAccount[] = reactive([]);
|
|
|
-// 期货持仓列表
|
|
|
+// 当前账户期货持仓列表
|
|
|
const tradePositionList: TradePosition[] = reactive([]);
|
|
|
+// 当前资金账户信息
|
|
|
+const tradeAccount = ref<TradeAccount>();
|
|
|
|
|
|
/**
|
|
|
- * 获取资金账户
|
|
|
+ * 资金账户
|
|
|
*/
|
|
|
-export function getTradeAccount() {
|
|
|
- // 加载状态
|
|
|
- const loading = ref<boolean>(false);
|
|
|
-
|
|
|
- const initData = () => {
|
|
|
- tradeAccountList.length = 0;
|
|
|
- tradePositionList.length = 0;
|
|
|
- loading.value = true;
|
|
|
-
|
|
|
- // 系统参数
|
|
|
- const systemParams = <Systemparam[]>APP.get('systemParams');
|
|
|
- // 登录ID
|
|
|
- const loginID = Number(geLoginID_number());
|
|
|
-
|
|
|
- getTaAccounts({ loginID }).then(async (res) => {
|
|
|
- for (let i = 0; i < res.length; i++) {
|
|
|
- const account = res[i];
|
|
|
- const positionList: TradePosition[] = [];
|
|
|
-
|
|
|
- // 获取账户下的期货持仓列表
|
|
|
- await queryErmcpTradePosition({ accountID: account.accountid }).then((res) => {
|
|
|
- res.forEach((item) => {
|
|
|
- positionList.push({
|
|
|
- ...item,
|
|
|
- ...calcPrice(item),
|
|
|
+export function useTradeAccount() {
|
|
|
+ const getTradeAccountList = () => {
|
|
|
+ if (!loading.value) {
|
|
|
+ tradeAccountList.length = 0;
|
|
|
+ loading.value = true;
|
|
|
+
|
|
|
+ // 登录ID
|
|
|
+ const loginID = Number(geLoginID_number());
|
|
|
+
|
|
|
+ getTaAccounts({ loginID }).then(async (res) => {
|
|
|
+ for (let i = 0; i < res.length; i++) {
|
|
|
+ const account = res[i];
|
|
|
+ const positionList: TradePosition[] = [];
|
|
|
+
|
|
|
+ // 获取账户下的期货持仓列表
|
|
|
+ await queryErmcpTradePosition({ accountID: account.accountid }).then((res) => {
|
|
|
+ res.forEach((item) => {
|
|
|
+ positionList.push({
|
|
|
+ ...item,
|
|
|
+ ...calcPositionValue(item),
|
|
|
+ })
|
|
|
})
|
|
|
})
|
|
|
- })
|
|
|
-
|
|
|
- // *系统参数"113"(当日浮动盈利是否可用) 0:不可用 1:可用
|
|
|
- const isAvailable = systemParams.find((e) => e.paramcode === '113')?.paramvalue === '1';
|
|
|
-
|
|
|
- // 计算总浮动盈亏
|
|
|
- const positionProfitAndLoss = computed(() => positionList.reduce((res, item) => res + item.positionProfitAndLoss.value, 0));
|
|
|
-
|
|
|
- // 计算可用资金
|
|
|
- const availableBalance = computed(() => {
|
|
|
- const { currentbalance, usedmargin, freezemargin, freezecharge, otherfreezemargin, outamountfreeze } = account;
|
|
|
- const freeze = currentbalance - usedmargin - freezemargin - otherfreezemargin - freezecharge - outamountfreeze;
|
|
|
-
|
|
|
- if (positionProfitAndLoss.value < 0 || (positionProfitAndLoss.value >= 0 && isAvailable)) {
|
|
|
- // 账户(总浮动盈亏为负) 或(总浮动盈亏为正 且 113 = 1)
|
|
|
- // 可用资金=总浮动盈亏+期末余额-占用-冻结-其它冻结-手续费冻结-出金冻结
|
|
|
- return positionProfitAndLoss.value + freeze;
|
|
|
- } else {
|
|
|
- // 可用资金=期末余额-占用-冻结-其它冻结-手续费冻结-出金冻结
|
|
|
- return freeze;
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- tradeAccountList.push({
|
|
|
- ...account,
|
|
|
- availableBalance,
|
|
|
- positionProfitAndLoss,
|
|
|
- positionList,
|
|
|
- })
|
|
|
- }
|
|
|
|
|
|
- getPositionList();
|
|
|
- loading.value = false;
|
|
|
- })
|
|
|
+ tradeAccountList.push({
|
|
|
+ positionList,
|
|
|
+ ...account,
|
|
|
+ ...calcCapitalValue(account, positionList),
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ selectedTradeAccount();
|
|
|
+ loading.value = false;
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- // 获取当前账户期货持仓列表
|
|
|
- const getPositionList = () => {
|
|
|
- const account = tradeAccountList.find((account) => account.accountid === getSelectedAccountId());
|
|
|
- if (account) {
|
|
|
- tradePositionList.push(...account.positionList);
|
|
|
+ // 设置选中当前账户
|
|
|
+ const selectedTradeAccount = () => {
|
|
|
+ tradePositionList.length = 0;
|
|
|
+ tradeAccount.value = tradeAccountList.find((account) => account.accountid === getSelectedAccountId());
|
|
|
+
|
|
|
+ if (tradeAccount.value) {
|
|
|
+ tradePositionList.push(...tradeAccount.value.positionList);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -93,39 +74,40 @@ export function getTradeAccount() {
|
|
|
loading,
|
|
|
tradeAccountList,
|
|
|
tradePositionList,
|
|
|
- initData,
|
|
|
- getPositionList,
|
|
|
+ tradeAccount,
|
|
|
+ getTradeAccountList,
|
|
|
+ selectedTradeAccount,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 计算价格
|
|
|
- * @param record
|
|
|
+ * 计算持仓数据
|
|
|
+ * @param position
|
|
|
* @returns
|
|
|
*/
|
|
|
-function calcPrice(record: QueryErmcpTradePositionRsp) {
|
|
|
+function calcPositionValue(position: QueryErmcpTradePositionRsp) {
|
|
|
+ // 获取对应的商品行情
|
|
|
+ const quote = getQuoteDayInfoByCode(position.goodscode);
|
|
|
+
|
|
|
// 计算开仓均价
|
|
|
const openAveragePrice = computed(() => {
|
|
|
- const { opencost, curpositionqty, agreeunit } = record
|
|
|
+ const { opencost, curpositionqty, agreeunit } = position
|
|
|
// 开仓成本 ÷ 期末头寸 ÷ 合约单位
|
|
|
return opencost / curpositionqty / agreeunit;
|
|
|
})
|
|
|
|
|
|
// 计算持仓均价
|
|
|
const positionAveragePrice = computed(() => {
|
|
|
- const { positioncost, curpositionqty, agreeunit } = record
|
|
|
+ const { positioncost, curpositionqty, agreeunit } = position
|
|
|
// 持仓成本 ÷ 期末头寸 ÷ 合约单位
|
|
|
return positioncost / curpositionqty / agreeunit;
|
|
|
})
|
|
|
|
|
|
- // 计算浮动盈亏
|
|
|
+ // 计算浮动盈亏 - 对应市场收益权
|
|
|
const positionProfitAndLoss = computed(() => {
|
|
|
- const { goodscode, curpositionqty, agreeunit } = record
|
|
|
- // 获取对应的商品行情
|
|
|
- const quote = getQuoteDayInfoByCode(goodscode);
|
|
|
-
|
|
|
+ const { curpositionqty, agreeunit } = position
|
|
|
if (quote?.last) {
|
|
|
- if (record.buyorsell === BuyOrSell.buy) {
|
|
|
+ if (position.buyorsell === BuyOrSell.buy) {
|
|
|
// 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位
|
|
|
return (quote.last - openAveragePrice.value) * curpositionqty * agreeunit
|
|
|
} else {
|
|
|
@@ -133,12 +115,21 @@ function calcPrice(record: QueryErmcpTradePositionRsp) {
|
|
|
return (positionAveragePrice.value - quote.last) * curpositionqty * agreeunit
|
|
|
}
|
|
|
}
|
|
|
- return record.positionpl
|
|
|
+ return position.positionpl
|
|
|
+ })
|
|
|
+
|
|
|
+ // 计算市值 - 对应市场所有权
|
|
|
+ const capitalization = computed(() => {
|
|
|
+ if (quote?.last) {
|
|
|
+ // 市值 = 最新价 * 持仓数量 * 合约单位
|
|
|
+ return quote.last * position.curpositionqty * position.agreeunit
|
|
|
+ }
|
|
|
+ return 0
|
|
|
})
|
|
|
|
|
|
// 计算盈亏比例
|
|
|
const positionProfitAndLossRate = computed(() => {
|
|
|
- const { opencost } = record
|
|
|
+ const { opencost } = position
|
|
|
// 持仓盈亏 ÷ 开仓成本
|
|
|
const result = positionProfitAndLoss.value / opencost * 100
|
|
|
if (isNaN(result)) {
|
|
|
@@ -149,8 +140,106 @@ function calcPrice(record: QueryErmcpTradePositionRsp) {
|
|
|
|
|
|
return {
|
|
|
openAveragePrice,
|
|
|
+ capitalization,
|
|
|
positionAveragePrice,
|
|
|
positionProfitAndLoss,
|
|
|
positionProfitAndLossRate,
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 计算资金数据
|
|
|
+ * @param account
|
|
|
+ * @param positionList
|
|
|
+ * @returns
|
|
|
+ */
|
|
|
+function calcCapitalValue(account: Taaccount, positionList: TradePosition[]) {
|
|
|
+ // 系统参数
|
|
|
+ const systemParams = <Systemparam[]>APP.get('systemParams');
|
|
|
+
|
|
|
+ // 计算总浮动盈亏
|
|
|
+ const positionProfitAndLoss = computed(() => positionList.reduce((res, item) => res + item.positionProfitAndLoss.value, 0));
|
|
|
+
|
|
|
+ // 计算总市值
|
|
|
+ const marketCap = computed(() => positionList.reduce((res, item) => res + item.capitalization.value, 0));
|
|
|
+
|
|
|
+ // 计算可用资金
|
|
|
+ const availableBalance = computed(() => {
|
|
|
+ // *系统参数"113"(当日浮动盈利是否可用) 0:不可用 1:可用
|
|
|
+ const flag = systemParams.find((e) => e.paramcode === '113')?.paramvalue === '1';
|
|
|
+
|
|
|
+ const { currentbalance, usedmargin, freezemargin, freezecharge, otherfreezemargin, outamountfreeze } = account;
|
|
|
+ const freeze = currentbalance - usedmargin - freezemargin - otherfreezemargin - freezecharge - outamountfreeze;
|
|
|
+
|
|
|
+ if (positionProfitAndLoss.value < 0 || (positionProfitAndLoss.value >= 0 && flag)) {
|
|
|
+ // 账户(总浮动盈亏为负) 或(总浮动盈亏为正 且 113 = 1)
|
|
|
+ // 可用资金 = 总浮动盈亏 + 期末余额 - 占用 - 冻结 - 其它冻结 - 手续费冻结 - 出金冻结
|
|
|
+ return positionProfitAndLoss.value + freeze;
|
|
|
+ } else {
|
|
|
+ // 可用资金 = 期末余额 - 占用 - 冻结 - 其它冻结 - 手续费冻结 - 出金冻结
|
|
|
+ return freeze;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 计算权益/净值
|
|
|
+ const equity = computed(() => {
|
|
|
+ // 根据系统参数“307 账户净值是否减冻结资金 - 0:不减 1:减“
|
|
|
+ const flag = systemParams.find((e) => e.paramcode === '307')?.paramvalue === '1';
|
|
|
+
|
|
|
+ const result = account.currentbalance + marketCap.value + positionProfitAndLoss.value;
|
|
|
+ if (flag) {
|
|
|
+ const { otherfreezemargin, outamountfreeze } = account;
|
|
|
+ // 净值 = 期末余额 + 市值(所有权) + 浮动盈亏(收益权) - 其它冻结 - 出金冻结
|
|
|
+ return result - otherfreezemargin - outamountfreeze;
|
|
|
+ } else {
|
|
|
+ // 净值 = 期末余额 + 市值(所有权) + 浮动盈亏(收益权)
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 计算冻结资金
|
|
|
+ const freezeAmount = computed(() => {
|
|
|
+ const { otherfreezemargin, outamountfreeze, freezecharge } = account;
|
|
|
+ // 冻结资金 = 手续费冻结 + 出金冻结 + 其他冻结保证金
|
|
|
+ return freezecharge + outamountfreeze + otherfreezemargin;
|
|
|
+ })
|
|
|
+
|
|
|
+ // 计算风险净值
|
|
|
+ const valueAtRisk = computed(() => {
|
|
|
+ // 根据系统参数“307 账户净值是否减冻结资金 - 0:不减 1:减“
|
|
|
+ const flag = systemParams.find((e) => e.paramcode === '087')?.paramvalue === '1';
|
|
|
+ const { otherfreezemargin, outamountfreeze } = account;
|
|
|
+
|
|
|
+ const result = account.currentbalance + positionProfitAndLoss.value - otherfreezemargin - outamountfreeze;
|
|
|
+ if (flag) {
|
|
|
+ // 风险净值 = 期末余额 + 市值(所有权) + 浮动盈亏(收益权) - 其他冻结-出金冻结
|
|
|
+ return result + marketCap.value;
|
|
|
+ } else {
|
|
|
+ // 风险净值 = 期末余额 + 浮动盈亏(收益权) - 其他冻结 - 出金冻结
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 计算风险率
|
|
|
+ const hazardRatio = computed(() => {
|
|
|
+ // 根据系统参数“132 风险率计算公式”:
|
|
|
+ const flag = systemParams.find((e) => e.paramcode === '132')?.paramvalue === '1';
|
|
|
+ const { usedmargin, mortgagecredit } = account;
|
|
|
+
|
|
|
+ if (flag) {
|
|
|
+ // 风险率 = 占用 / 风险净值
|
|
|
+ return usedmargin / valueAtRisk.value;
|
|
|
+ } else {
|
|
|
+ // 风险率 = (占用 - 授信金额) / (风险净值 - 授信金额)
|
|
|
+ return (usedmargin - mortgagecredit) / (valueAtRisk.value - mortgagecredit);
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ return {
|
|
|
+ equity,
|
|
|
+ positionProfitAndLoss,
|
|
|
+ availableBalance,
|
|
|
+ freezeAmount,
|
|
|
+ hazardRatio,
|
|
|
+ }
|
|
|
}
|