private USeFundDetail CalculFoundBeforeTrade() { USeOrderDriver orderDriver = USeManager.Instance.OrderDriver; USeQuoteDriver quoteDriver = USeManager.Instance.QuoteDriver; try { List <USeTradeBook> tradeBookList = orderDriver.QueryTradeBooks(); List <USePositionDetail> tradeAccountPosList = orderDriver.QueryPositionDetail(); List <USeOrderBook> orderBookList = orderDriver.QueryOrderBooks(); USeFund accountInfo = orderDriver.QueryFundInfo(); if (tradeBookList == null || tradeAccountPosList == null || orderBookList == null || accountInfo == null) { return(null); } #region 读取 decimal preBalance = accountInfo.PreBalance; //上日客户权益(读取)即上日结算准备金 decimal preCredit = accountInfo.PreCredit; // 上日信用额度 decimal preMortgage = accountInfo.PreMortgage; // 上次质押金额 decimal mortgage = accountInfo.Mortgage; // 质押金额 decimal withDraw = accountInfo.WithDraw; // 今日出金 decimal deposit = accountInfo.Deposit; // 今日入金 decimal deliveryMargin = accountInfo.DeliveryMargin; //交割保证金 #endregion 读取 // 静态权益 = 上日结存 - 上次信用额度 - 上次质押金额 // + 质押金额(可能有延时)- 今日出金(可能有延时) + 今日入金(可能有延时) decimal staticBenefit = preBalance - preCredit - preMortgage + mortgage - withDraw + deposit; #region 成交回报推算 decimal holdHistoryMargin = 0m; decimal holdMargin = 0m; foreach (USePositionDetail posItem in tradeAccountPosList) { USeInstrumentDetail detail = orderDriver.QueryInstrumentDetail(posItem.Instrument); int volumeMultiple = detail.VolumeMultiple; USeMargin productMargin = orderDriver.QueryInstrumentMargin(posItem.Instrument); USeMarketData marketData = quoteDriver.Query(posItem.Instrument); if (posItem.RemainQty > 0) // 有持仓 { if (posItem.PositionType == USePositionType.Yestorday && posItem.Direction == USeDirection.Long) { // 历史多头持仓保证金 = 上日结算价 × 合约乘数 × 持仓手数 × 交易所多头保证金率 decimal margin = (marketData.PreSettlementPrice * volumeMultiple * posItem.RemainQty * productMargin.BrokerLongMarginRatioByMoney) + (posItem.RemainQty * productMargin.BrokerLongMarginRatioByVolume); holdHistoryMargin += margin; } else if (posItem.PositionType == USePositionType.Yestorday && posItem.Direction == USeDirection.Short) { decimal margin = (marketData.PreSettlementPrice * volumeMultiple * posItem.RemainQty * productMargin.BrokerShortMarginRatioByMoney) + (posItem.RemainQty * productMargin.BrokerLongMarginRatioByVolume); holdHistoryMargin += margin; } else { Debug.Assert(false); } } } holdMargin = holdHistoryMargin; #endregion // 动态权益 = 静态权益 decimal dynamicBenefit = staticBenefit; decimal frozon = 0; decimal closeProfit = 0m; decimal holdProfit = 0m; decimal tradeFee = 0m; decimal available = dynamicBenefit - holdMargin - frozon - deliveryMargin; //风险度 = (占用保证金 + 交割保证金) / 动态权益 decimal risk = decimal.Divide((holdMargin + deliveryMargin), dynamicBenefit); decimal preferCash = available; if (tradeBookList.Count != 0 || tradeAccountPosList.Count != 0) { preferCash = (decimal)(preferCash * 7 / 10); } USeFundDetail fundDetail = new USeFundDetail(); fundDetail.AccountID = string.Empty; fundDetail.Available = available; fundDetail.Deposit = deposit; fundDetail.Mortgage = mortgage; fundDetail.PreBalance = preBalance; fundDetail.PreCredit = preCredit; fundDetail.PreMortgage = preMortgage; fundDetail.WithDraw = withDraw; fundDetail.StaticBenefit = staticBenefit; fundDetail.CloseProfit = closeProfit; fundDetail.TradeFee = tradeFee; fundDetail.HoldProfit = holdProfit; fundDetail.HoldMargin = holdMargin; fundDetail.DynamicBenefit = dynamicBenefit; fundDetail.FrozonMargin = 0; fundDetail.AccountID = string.Empty; fundDetail.Available = available; fundDetail.Deposit = deposit; fundDetail.Mortgage = mortgage; fundDetail.PreBalance = preBalance; fundDetail.PreCredit = preCredit; fundDetail.PreMortgage = preMortgage; fundDetail.WithDraw = withDraw; fundDetail.StaticBenefit = staticBenefit; fundDetail.CloseProfit = closeProfit; fundDetail.TradeFee = tradeFee; fundDetail.HoldProfit = holdProfit; fundDetail.HoldMargin = holdMargin; fundDetail.DynamicBenefit = dynamicBenefit; fundDetail.FrozonMargin = 0; fundDetail.FrozonFee = 0; fundDetail.Fronzon = frozon; fundDetail.Risk = risk; fundDetail.PreferCash = preferCash; return(fundDetail); } catch (Exception ex) { Debug.Assert(false, ex.Message); return(null); } }
/// <summary> /// 计算帐户数据。 /// </summary> private USeFundDetail CalculateFundInfo() { USeOrderDriver orderDriver = USeManager.Instance.OrderDriver; USeQuoteDriver quoteDriver = USeManager.Instance.QuoteDriver; try { List <TradeBookCalcItem> tradeBookList = QueryTradeBooks();; List <PositionDetailCalcItem> tradeAccountPosList = QueryPositonDetails(); List <OrderBookCalcItem> orderBookList = QueryOrderBooks(); USeFund accountInfo = orderDriver.QueryFundInfo(); //if (tradeBookList == null || tradeAccountPosList == null || orderBookList == null || accountInfo == null) return null; #region 读取 decimal preBalance = accountInfo.PreBalance; //上日客户权益(读取)即上日结算准备金 decimal preCredit = accountInfo.PreCredit; // 上日信用额度 decimal preMortgage = accountInfo.PreMortgage; // 上次质押金额 decimal mortgage = accountInfo.Mortgage; // 质押金额 decimal withDraw = accountInfo.WithDraw; // 今日出金 decimal deposit = accountInfo.Deposit; // 今日入金 decimal deliveryMargin = accountInfo.DeliveryMargin; //交割保证金 #endregion 读取 // 静态权益 = 上日结存 - 上次信用额度 - 上次质押金额 // + 质押金额(可能有延时)- 今日出金(可能有延时) + 今日入金(可能有延时) decimal staticBenefit = preBalance - preCredit - preMortgage + mortgage - withDraw + deposit; #region 成交回报推算 // 手续费 = SUM(成交回报手续费) decimal tradeFee = tradeBookList.Sum(t => t.Fee); // 平历史仓盈亏 = SUM((平仓价 - 上日结算价) × 多头合约平仓量 × 合约乘数+ (上日结算价-平仓价)× 空头合约平仓量 × 合约乘数)) // 平当日仓盈亏 = SUM((平仓价 - 开仓价)× 多头合约持仓量 × 合约乘数 + (开仓价-平仓价)× 空头合约平仓量 × 合约乘数) // 历史持仓盈亏 = SUM((最新价 - 上日结算价) × 多头合约持仓量× 合约乘数 + (上日结算价-最新价)× 空头合约持仓量 × 合约乘数) // 当日持仓盈亏 = SUM((最新价 - 开仓价) × 多头合约持仓量 × 合约乘数 + (开仓价-最新价) × 空头合约持仓量 × 合约乘数) // 历史持仓保证金 = SUM(上日结算价 × 合约乘数 × 持仓手数 × 保证金率) // 当日持仓保证金 = SUM(开仓价×合约乘数×持仓手数×保证金率) decimal closeProfit = 0m; decimal holdProfit = 0m; decimal holdMargin = 0m; decimal frozonMargin = 0m; decimal frozonFee = 0m; #region 计算持仓盈亏 holdProfit = tradeAccountPosList.Sum((p) => CalcHoldingProfit(p)); closeProfit = tradeAccountPosList.Sum((p) => CalcCloseProfit(p)); #endregion #region 计算持仓占用保证金 List <MarginCalcResultByProductAndDirection> holdMarginList = (tradeAccountPosList.Where(p => p.RemainQty > 0) .GroupBy(p => new { p.InstrumentDetail.Varieties, p.Instrument.Market, p.Direction }) .Select(g => new MarginCalcResultByProductAndDirection { Product = g.Key.Varieties, Market = g.Key.Market, Direction = g.Key.Direction, HoldMargin = g.Sum((i) => CalcHoldingPositonMargin(i)), })).ToList(); List <MarginCalcResultByProductAndDirection> fronzonMarginList = (orderBookList.Where(o => (o.IsFinish == false && o.OffsetType == USeOffsetType.Open)) .GroupBy(o => new { o.InstrumentDetail.Varieties, o.Instrument.Market, o.Direction }) .Select(g => new MarginCalcResultByProductAndDirection { Product = g.Key.Varieties, Market = g.Key.Market, Direction = g.Key.Direction, HoldMargin = g.Sum((i) => CalcOrderFronzonMargin(i)) })).ToList(); List <MarginCalcResultByProduct> holdProductMargin = (holdMarginList.GroupBy(p => new { p.Product, p.Market }) .Select(g => new MarginCalcResultByProduct { Product = g.Key.Product, Market = g.Key.Market, HoldLongMargin = g.Where(i => i.Direction == USeDirection.Long).Sum(i => i.HoldMargin), HoldShortMargin = g.Where(i => i.Direction == USeDirection.Short).Sum(i => i.HoldMargin) })).ToList(); List <MarginCalcResultByProduct> fronzonProductMargin = (fronzonMarginList.GroupBy(p => new { p.Product, p.Market }) .Select(g => new MarginCalcResultByProduct { Product = g.Key.Product, Market = g.Key.Market, FrozonLongMargin = g.Where(i => i.Direction == USeDirection.Long).Sum(i => i.HoldMargin), FrozonShortMargin = g.Where(i => i.Direction == USeDirection.Short).Sum(i => i.HoldMargin) })).ToList(); List <MarginCalcResultByProduct> marginList = new List <MarginCalcResultByProduct>(); marginList.AddRange(holdProductMargin); marginList.AddRange(fronzonProductMargin); holdMargin = CalculateHoldMargin(marginList); frozonMargin = CalculateFronzonMargin(marginList); frozonFee = orderBookList.Where(o => o.IsFinish == false).Sum((i) => CalcOrderFronzonFee(i)); #endregion #endregion // 动态权益 = 静态权益 + 持仓盈亏 + 平仓盈亏 - 手续费(取成交回报手续费) decimal dynamicBenefit = staticBenefit + holdProfit + closeProfit - tradeFee; #region 委托回报推算 // 买冻结保证金 = SUM(委托价格 * 合约乘数 * 委托手数 * 多头保证金率) // 卖冻结保证金 = SUM(委托价格 * 合约乘数 * 委托手数 * 空头保证金率) // 买冻结手续费 = SUM(委托价格 * 合约乘数 * 委托手数 * 期货多头手续费率) // 卖冻结手续费 = SUM(委托价格 * 合约乘数 * 委托手数 * 期货空头手续费率) decimal frozon = frozonMargin + frozonFee; #endregion decimal available = 0m; // 可用资金(当持仓盈亏>=0时) = 动态权益 - 持仓盈亏 – 占用保证金 – 下单冻结 - 交割保证金 //[yangming]新版本好似可用资金要减去平仓盈亏 // 可用资金(当持仓盈亏 <0时) = 动态权益 – 占用保证金 – 下单冻结 - 交割保证金 available = dynamicBenefit - holdMargin - frozon - deliveryMargin; if (holdProfit > 0) { available = available - holdProfit; } if (closeProfit > 0) { available = available - closeProfit; } //风险度 = (占用保证金 + 交割保证金 + 买冻结保证金 + 卖冻结保证金) / 动态权益 //decimal risk = decimal.Divide((holdMargin + deliveryMargin + frozonMargin),(dynamicBenefit)); decimal risk = decimal.Divide(holdMargin, (dynamicBenefit)); decimal preferCash = available; if (tradeBookList.Count != 0 || tradeAccountPosList.Count != 0) { preferCash = (decimal)(preferCash * 7 / 10); } USeFundDetail fundDetail = new USeFundDetail(); fundDetail.AccountID = string.Empty; fundDetail.Available = available; fundDetail.Deposit = deposit; fundDetail.Mortgage = mortgage; fundDetail.PreBalance = preBalance; fundDetail.PreCredit = preCredit; fundDetail.PreMortgage = preMortgage; fundDetail.WithDraw = withDraw; fundDetail.StaticBenefit = staticBenefit; fundDetail.CloseProfit = closeProfit; fundDetail.TradeFee = tradeFee; fundDetail.HoldProfit = holdProfit; fundDetail.HoldMargin = holdMargin; fundDetail.DynamicBenefit = dynamicBenefit; fundDetail.FrozonMargin = frozonMargin; fundDetail.FrozonFee = frozonFee; fundDetail.Fronzon = frozon; fundDetail.Risk = risk; fundDetail.PreferCash = preferCash; return(fundDetail); } catch (Exception ex) { //Debug.Assert(false, ex.Message); return(null); } }