| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- import { computed, toRefs, shallowReadonly } from 'vue'
- import { v4 } from 'uuid'
- import { formatDecimal } from '@/filters'
- import { BuyOrSell } from '@/constants/buyorsell'
- import { queryTaAccounts } from '@/services/api/account'
- import { queryErmcpTradePosition } from '@/services/api/trade'
- import subscribe from '@/services/subscribe'
- import { useLoginStore } from './login'
- import { useFuturesStore } from './futures'
- import { VueStore } from '../base'
- import eventBus from '@/services/bus'
- interface StoreState {
- loading: boolean;
- accountId: number; // 当前资金账户ID
- accountList: Ermcp.TaAccountsRsp[]; // 资金账户列表
- accountPositionList: Ermcp.TradePositionRsp[]; // 资金账户持仓列表
- }
- function useFormula(item: Ermcp.TradePositionRsp) {
- const { getGoodsPriceByCode } = useFuturesStore()
- const { goodscode, buyorsell, curpositionqty, agreeunit, positionpl, opencost, positioncost, decimalplace } = item
- // 计算开仓均价
- const calcOpenAveragePrice = () => {
- // 开仓成本 ÷ 期末头寸 ÷ 合约单位
- return opencost / curpositionqty / agreeunit
- }
- // 计算持仓均价
- const calcPositionAveragePrice = () => {
- // 持仓成本 ÷ 期末头寸 ÷ 合约单位
- return positioncost / curpositionqty / agreeunit
- }
- // 计算浮动盈亏 - 对应市场收益权
- const calcProfitLoss = () => {
- const last = getGoodsPriceByCode(goodscode)
- let result = positionpl
- if (last.value) {
- const positionAveragePrice = calcPositionAveragePrice()
- // 收益权 = (最新价 - 持仓均价) * 持仓数量 * 合约单位 * 方向(买1卖-1)
- const rightToEarnings = (last.value - positionAveragePrice) * curpositionqty * agreeunit
- result = rightToEarnings * (buyorsell === BuyOrSell.Buy ? 1 : -1)
- }
- return formatDecimal(result, decimalplace)
- }
- return {
- calcOpenAveragePrice,
- calcPositionAveragePrice,
- calcProfitLoss
- }
- }
- /**
- * 账户存储类
- */
- const store = new (class extends VueStore<StoreState>{
- constructor() {
- const state: StoreState = {
- loading: false,
- accountId: 0,
- accountList: [],
- accountPositionList: [],
- }
- super(state)
- // 接收资金变动通知
- eventBus.$on('MoneyChangedNotify', () => {
- this.actions.getAccountList()
- })
- }
- private uuid = v4()
- private pending = Promise.resolve() // 请求等待状态,防止重复请求
- /** 当前资金账户信息 */
- private accountInfo = computed(() => {
- const account = this.state.accountList.find((e) => e.accountid === this.state.accountId)
- // 总浮动盈亏
- const totalProfitLoss = this.futuresPositionList.value.reduce((res, cur) => res + cur.positionpl, 0)
- return {
- ...account,
- totalProfitLoss,
- }
- })
- /** 期货持仓列表 */
- private futuresPositionList = computed(() => {
- const positionList = this.state.accountPositionList
- return positionList.reduce((res, item) => {
- const { calcProfitLoss } = useFormula(item)
- res.push({
- ...item,
- positionpl: Number(calcProfitLoss()),
- })
- return res
- }, [] as Ermcp.TradePositionRsp[])
- })
- getters = {
- accountInfo: this.accountInfo,
- futuresPositionList: this.futuresPositionList
- }
- actions = {
- /** 获取资金账户列表 */
- getAccountList: async () => {
- await this.pending
- const { getLoginId } = useLoginStore()
- this.state.loading = true
- this.pending = queryTaAccounts({
- data: {
- loginID: getLoginId()
- },
- success: (res) => {
- const dataList = res.data
- if (dataList.length) {
- this.state.accountList = dataList
- // 查找当前选中的资金账户
- const account = dataList.find((e) => e.accountid === this.state.accountId)
- if (account) {
- this.state.loading = false
- } else {
- // 如果不存在,默认选中第一个账户
- this.state.accountId = dataList[0].accountid
- this.actions.getAccountPositionList()
- }
- } else {
- this.state.loading = false
- this.actions.reset()
- }
- },
- fail: () => {
- this.state.loading = false
- }
- })
- return this.pending
- },
- /** 获取资金账户持仓列表 */
- getAccountPositionList: async (marketID?: number) => {
- await this.pending
- subscribe.removeQuoteSubscribe(this.uuid)
- this.state.loading = true
- this.pending = queryErmcpTradePosition({
- data: {
- accountID: this.state.accountId,
- ...marketID ? { marketID } : {}
- },
- success: (res) => {
- const codes = res.data.map((e) => e.goodscode)
- this.state.accountPositionList = res.data
- if (codes.length) {
- // 行情订阅
- subscribe.addQuoteSubscribe(codes, this.uuid).start()
- }
- },
- complete: () => {
- this.state.loading = false
- }
- })
- return this.pending
- },
- /** 重置数据 */
- reset: () => {
- this.state.accountId = 0
- this.state.accountList = []
- this.state.accountPositionList = []
- }
- }
- })
- export function useAccountStore() {
- return shallowReadonly({
- ...toRefs(store.state),
- ...store.getters,
- ...store.actions,
- ...store.methods,
- })
- }
|