示例#1
0
        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);
            }
        }
示例#2
0
        /// <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);
            }
        }