| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- import { reactive, ref, computed } from 'vue';
- import { queryErmcpTradePosition } from '@/services/go/ermcp/futures';
- import { QueryErmcpTradePositionRsp } from '@/services/go/ermcp/futures/interface';
- 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, setSelectedAccount } from '@/services/bus/account'; // 为了兼容以前代码,待优化后期废除
- import { subcriteGoodsQuote } from '@/common/setup/table/tableQuote';
- import { TradeAccount, TradePosition } from './interface'
- import APP from '@/services';
- let stopSubcribe: () => void;
- // 加载状态
- const loading = ref<boolean>(false);
- // 资金账户列表
- const tradeAccountList: TradeAccount[] = reactive([]);
- // 当前账户期货持仓列表
- const tradePositionList: TradePosition[] = reactive([]);
- // 当前资金账户信息
- const tradeAccount = ref<TradeAccount>();
- /**
- * 资金账户
- */
- 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),
- })
- })
- })
- tradeAccountList.push({
- positionList,
- ...account,
- ...calcCapitalValue(account, positionList),
- })
- }
- tradeAccountChange(getSelectedAccountId());
- loading.value = false;
- })
- }
- }
- // 切换资金账户
- const tradeAccountChange = (accountId: number) => {
- tradePositionList.length = 0;
- // 停止上次订阅
- stopSubcribe && stopSubcribe();
- const account = tradeAccountList.find((account) => account.accountid === accountId);
- if (account) {
- tradeAccount.value = account;
- tradePositionList.push(...account.positionList);
- setSelectedAccount(account); // 为了兼容以前代码,待优化后期废除
- // 开始行情订阅
- stopSubcribe = subcriteGoodsQuote(account.positionList.map((e) => e.goodscode));
- } else {
- tradeAccount.value = undefined;
- }
- }
- // 期货账户列表
- const futuresAccountList = computed(() => tradeAccountList.filter((account) => account.taaccounttype === 1));
- return {
- loading,
- tradeAccountList,
- tradePositionList,
- tradeAccount,
- futuresAccountList,
- getTradeAccountList,
- tradeAccountChange,
- }
- }
- /**
- * 计算持仓数据
- * @param position
- * @returns
- */
- function calcPositionValue(position: QueryErmcpTradePositionRsp) {
- // 获取对应的商品行情
- const quote = getQuoteDayInfoByCode(position.goodscode);
- // 计算开仓均价
- const openAveragePrice = computed(() => {
- const { opencost, curpositionqty, agreeunit } = position
- // 开仓成本 ÷ 期末头寸 ÷ 合约单位
- return opencost / curpositionqty / agreeunit;
- })
- // 计算持仓均价
- const positionAveragePrice = computed(() => {
- const { positioncost, curpositionqty, agreeunit } = position
- // 持仓成本 ÷ 期末头寸 ÷ 合约单位
- return positioncost / curpositionqty / agreeunit;
- })
- // 计算浮动盈亏 - 对应市场收益权
- const positionProfitAndLoss = computed(() => {
- const { curpositionqty, agreeunit } = position
- if (quote?.last) {
- if (position.buyorsell === BuyOrSell.buy) {
- // 买方向 = (最新价 - 持仓均价) * 买期末头寸 * 合约单位
- return (quote.last - openAveragePrice.value) * curpositionqty * agreeunit
- } else {
- // 卖方向 = (持仓均价 - 最新价) * 卖期末头寸 * 合约单位
- return (positionAveragePrice.value - quote.last) * curpositionqty * agreeunit
- }
- }
- return position.positionpl
- })
- // 计算市值 - 对应市场所有权
- const capitalization = computed(() => {
- if (quote?.last) {
- // 市值 = 最新价 * 持仓数量 * 合约单位
- return quote.last * position.curpositionqty * position.agreeunit
- }
- return 0
- })
- // 计算盈亏比例
- const positionProfitAndLossRate = computed(() => {
- const { opencost } = position
- // 持仓盈亏 ÷ 开仓成本
- const result = positionProfitAndLoss.value / opencost * 100
- if (isNaN(result)) {
- return 0
- }
- return result
- })
- 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(() => {
- // 根据系统参数“087 风险净值是否加上市值 - 0:不加 1:加“
- const flag = systemParams.find((e) => e.paramcode === '087')?.paramvalue === '1';
- if (flag) {
- return positionList.reduce((res, item) => res + item.capitalization.value, 0);
- }
- return 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 { freezemargin, otherfreezemargin, outamountfreeze, freezecharge } = account;
- // 冻结资金 = 冻结保证金 + 手续费冻结 + 出金冻结 + 其他冻结保证金
- return freezemargin + 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;
- let result = 0
- if (flag) {
- // 风险率 = 占用 / 风险净值
- result = usedmargin / valueAtRisk.value;
- } else {
- // 风险率 = (占用 - 授信金额) / (风险净值 - 授信金额)
- result = (usedmargin - mortgagecredit) / (valueAtRisk.value - mortgagecredit);
- }
- return isNaN(result) ? 0 : result;
- })
- return {
- equity,
- positionProfitAndLoss,
- availableBalance,
- freezeAmount,
- hazardRatio,
- }
- }
|