/// <summary> /// 评估创建套利单需要保证金。 /// </summary> /// <param name="openArg"></param> /// <returns></returns> public decimal EvaluateMargin(ArbitrageOpenArgument openArg) { USeOrderDriver orderDriver = USeManager.Instance.OrderDriver; USeQuoteDriver quoteDriver = USeManager.Instance.QuoteDriver; USeInstrumentDetail buyInstrumentDetail = orderDriver.QueryInstrumentDetail(openArg.BuyInstrument); USeInstrumentDetail sellInstrumentDetail = orderDriver.QueryInstrumentDetail(openArg.SellInstrument); USeMarketData buyMarketData = quoteDriver.Query(openArg.BuyInstrument); USeMarketData sellMarketData = quoteDriver.Query(openArg.SellInstrument); USeMargin buyMarginRate = orderDriver.QueryInstrumentMargin(openArg.BuyInstrument); USeMargin sellMarginRate = orderDriver.QueryInstrumentMargin(openArg.SellInstrument); decimal buyMargin = (openArg.TotalOrderQty * buyMarginRate.BrokerLongMarginRatioByVolume) + (buyMarketData.LastPrice * openArg.TotalOrderQty * buyInstrumentDetail.VolumeMultiple * buyMarginRate.BrokerLongMarginRatioByMoney); decimal sellMargin = (openArg.TotalOrderQty * sellMarginRate.BrokerShortMarginRatioByVolume) + (sellMarketData.LastPrice * openArg.TotalOrderQty * sellInstrumentDetail.VolumeMultiple * sellMarginRate.BrokerShortMarginRatioByMoney); if (openArg.BuyInstrument.Market == USeMarket.SHFE && openArg.SellInstrument.Market == USeMarket.SHFE) { return(Math.Max(buyMargin, sellMargin)); } else { return(buyMargin + sellMargin); } }
/// <summary> /// 计算冻结保证金。 /// </summary> /// <param name="orderBook"></param> /// <returns></returns> private decimal CalcOrderFronzonMargin(OrderBookCalcItem orderBook) { if (orderBook.IsFinish) { return(0m); } ; if (orderBook.OffsetType != USeOffsetType.Open) { return(0m); } int volumeMultiple = orderBook.InstrumentDetail.VolumeMultiple; USeMargin productMargin = orderBook.MarginRate; decimal frozonMargin = 0; if (orderBook.OrderSide == USeOrderSide.Buy) { frozonMargin = ((orderBook.OrderQty - orderBook.TradeQty) * productMargin.BrokerLongMarginRatioByVolume) + (orderBook.OrderPrice * (orderBook.OrderQty - orderBook.TradeQty) * volumeMultiple * productMargin.BrokerLongMarginRatioByMoney); } else if (orderBook.OrderSide == USeOrderSide.Sell) { frozonMargin += ((orderBook.OrderQty - orderBook.TradeQty) * productMargin.BrokerShortMarginRatioByVolume) + (orderBook.OrderPrice * (orderBook.OrderQty - orderBook.TradeQty) * volumeMultiple * productMargin.BrokerShortMarginRatioByMoney); } else { Debug.Assert(false); } return(frozonMargin); }
private void UpddateMarketData(object sender, USeMarketDataChangedEventArgs e) { USeOrderSide orderSide = GetChoiceDirection(); this.labelUpper.Text = e.MarketData.AskPrice.ToString(); this.labelLower.Text = e.MarketData.BidPrice.ToString(); USeFundDetail fundDetail = USeManager.Instance.FundCalculator.FundDetail; Debug.Assert(fundDetail != null); decimal available = fundDetail.Available; decimal priceScole = USeManager.Instance.OrderDriver.QueryInstrumentVolumeMultiple(m_selectedInstrument); USeMargin useMargin = USeManager.Instance.OrderDriver.QueryInstrumentMargin(m_selectedInstrument); decimal margin = 0m; if (orderSide == USeOrderSide.Buy) { this.numericUpDownPrice.Value = e.MarketData.AskPrice; margin = (useMargin.BrokerLongMarginRatioByMoney * priceScole * this.numericUpDownPrice.Value) + useMargin.BrokerLongMarginRatioByVolume; } else if (orderSide == USeOrderSide.Sell) { this.numericUpDownPrice.Value = e.MarketData.BidPrice; margin = (useMargin.BrokerShortMarginRatioByMoney * priceScole * this.numericUpDownPrice.Value) + useMargin.BrokerShortMarginRatioByVolume; } else { Debug.Assert(false); } decimal miniVolumnMoney = margin > 0 ? decimal.Divide(available, margin) : 0; this.Label_CanVolumn.Text = (Math.Floor(miniVolumnMoney)).ToString(); }
/// <summary> /// 克隆USeMargin对象。 /// </summary> /// <returns></returns> public USeMargin Clone() { USeMargin margin = new USeMargin(); margin.Instrument = this.Instrument.Clone(); margin.ExchangeLongMarginRatio = this.ExchangeLongMarginRatio; margin.ExchangeShortMarginRatio = this.ExchangeShortMarginRatio; margin.BrokerLongMarginRatioByMoney = this.BrokerLongMarginRatioByMoney; margin.BrokerLongMarginRatioByVolume = this.BrokerLongMarginRatioByVolume; margin.BrokerShortMarginRatioByMoney = this.BrokerShortMarginRatioByMoney; margin.BrokerShortMarginRatioByVolume = this.BrokerShortMarginRatioByVolume; return(margin); }
/// <summary> /// 查询合约保证金。 /// </summary> /// <param name="instrument"></param> /// <returns></returns> public override USeMargin QueryInstrumentMargin(USeInstrument instrument) { USeMargin margin = new USeMargin() { Instrument = instrument.Clone(), ExchangeLongMarginRatio = 0.09m, ExchangeShortMarginRatio = 0.09m, BrokerLongMarginRatioByMoney = 0.09m, BrokerLongMarginRatioByVolume = 0, BrokerShortMarginRatioByMoney = 0.09m, BrokerShortMarginRatioByVolume = 0 }; return(margin); }
/// <summary> /// 计算保证金。 /// </summary> /// <param name="instrument">合约。</param> /// <param name="direction">方向。</param> /// <param name="qty">数量。</param> /// <param name="price">价格。</param> /// <returns></returns> private decimal CalculateMargin(USeInstrument instrument, USeDirection direction, int qty, decimal price) { USeMargin margin = m_dataBuffer.GetMargin(instrument); int volumeMultiple = m_dataBuffer.GetVolumeMultiple(instrument); switch (direction) { case USeDirection.Long: return(margin.BrokerLongMarginRatioByMoney * price * qty * volumeMultiple + margin.BrokerLongMarginRatioByVolume * qty); case USeDirection.Short: return(margin.BrokerShortMarginRatioByMoney * price * qty * volumeMultiple + margin.BrokerShortMarginRatioByVolume * qty); default: Debug.Assert(false, "CalculateMargin(),invalid direction"); return(0m); } }
/// <summary> /// 查询委托回报。 /// </summary> /// <returns></returns> private List <OrderBookCalcItem> QueryOrderBooks() { USeOrderDriver orderDriver = USeManager.Instance.OrderDriver; List <USeOrderBook> orderBookList = orderDriver.QueryOrderBooks(); List <OrderBookCalcItem> list = new List <OrderBookCalcItem>(); if (orderBookList == null) { return(list); } foreach (USeOrderBook orderBookItem in orderBookList) { USeInstrumentDetail detail = orderDriver.QueryInstrumentDetail(orderBookItem.Instrument); USeMargin productMargin = orderDriver.QueryInstrumentMargin(orderBookItem.Instrument); USeFee productFee = orderDriver.QueryInstrumentFee(orderBookItem.Instrument); OrderBookCalcItem calcItem = new OrderBookCalcItem() { InstrumentDetail = detail, MarginRate = productMargin, FeeRate = productFee, OrderNum = orderBookItem.OrderNum, Account = orderBookItem.Account, Instrument = orderBookItem.Instrument, OrderQty = orderBookItem.OrderQty, OrderPrice = orderBookItem.OrderPrice, TradeQty = orderBookItem.TradeQty, TradeAmount = orderBookItem.TradeAmount, TradePrice = orderBookItem.TradePrice, TradeFee = orderBookItem.TradeFee, OrderStatus = orderBookItem.OrderStatus, CancelQty = orderBookItem.CancelQty, OrderSide = orderBookItem.OrderSide, OffsetType = orderBookItem.OffsetType, Memo = orderBookItem.Memo, OrderTime = orderBookItem.OrderTime }; list.Add(calcItem); } return(list); }
/// <summary> /// CTP InstrumentMarginRateField To USeMargin。 /// </summary> /// <param name="field"></param> /// <returns></returns> private USeMargin CtpMarginRateFieldToUSeProductMarginInfo(InstrumentMarginRateField filed) { USeMargin margin = new USeMargin(); margin.Instrument = m_dataBuffer.GetInstrumnetByCode(filed.InstrumentID); try { margin.BrokerLongMarginRatioByMoney = filed.LongMarginRatioByMoney == double.MaxValue ? 0m : Convert.ToDecimal(filed.LongMarginRatioByMoney); margin.BrokerLongMarginRatioByVolume = filed.LongMarginRatioByVolume == double.MaxValue ? 0m : Convert.ToDecimal(filed.LongMarginRatioByVolume); margin.BrokerShortMarginRatioByMoney = filed.ShortMarginRatioByMoney == double.MaxValue ? 0m : Convert.ToDecimal(filed.ShortMarginRatioByMoney); margin.BrokerShortMarginRatioByVolume = filed.ShortMarginRatioByVolume == double.MaxValue ? 0m : Convert.ToDecimal(filed.ShortMarginRatioByVolume); } catch (Exception ex) { Debug.Assert(false, "InstrumentMarginRateFieldToFulcProductMarginInfo() convet failed," + ex.Message); } return(margin); }
/// <summary> /// 查询持仓明细。 /// </summary> /// <returns></returns> private List <PositionDetailCalcItem> QueryPositonDetails() { USeOrderDriver orderDriver = USeManager.Instance.OrderDriver; USeQuoteDriver quoteDriver = USeManager.Instance.QuoteDriver; List <USePositionDetail> positonList = orderDriver.QueryPositionDetail(); List <PositionDetailCalcItem> list = new List <PositionDetailCalcItem>(); if (positonList == null) { return(list); } foreach (USePositionDetail posItem in positonList) { USeInstrumentDetail detail = orderDriver.QueryInstrumentDetail(posItem.Instrument); USeMargin productMargin = orderDriver.QueryInstrumentMargin(posItem.Instrument); USeMarketData marketData = quoteDriver.Query(posItem.Instrument); PositionDetailCalcItem calcItem = new PositionDetailCalcItem() { InstrumentDetail = detail, Margin = productMargin, MarketData = marketData, ID = posItem.ID, Instrument = posItem.Instrument.Clone(), Direction = posItem.Direction, PositionType = posItem.PositionType, OpenQty = posItem.OpenQty, OpenPrice = posItem.OpenPrice, OpenTime = posItem.OpenTime, CloseQty = posItem.CloseQty, CloseAmount = posItem.CloseAmount, ClosePrice = posItem.ClosePrice }; list.Add(calcItem); } return(list); }
/// <summary> /// 查询合约保证金。 /// </summary> /// <param name="instrument"></param> /// <returns></returns> public override USeMargin QueryInstrumentMargin(USeInstrument instrument) { if (m_dataBuffer.ExistInstrument(instrument.InstrumentCode) == false) { throw new Exception(string.Format("Unsupport instrument[{0}]", instrument)); } USeMargin margin = m_dataBuffer.GetMargin(instrument); if (margin != null) { return(margin); } else { int index = 3; while (index > 0) { index--; try { InstrumentMarginRateField field = QueryMarginFromCtp(instrument.InstrumentCode); m_dataBuffer.UpdateInstrumentMagin(field); margin = m_dataBuffer.GetMargin(instrument); Debug.Assert(margin != null, "QueryInstrumentMargin(),margin is null"); return(margin); } catch { } Thread.Sleep(1200); } Debug.Assert(false, "QueryInstrumentMargin(),margin is null"); // 如果还查不到则抛出异常 throw new Exception(string.Format("Query instrument[{0}] margin failed", instrument)); } }
/// <summary> /// 计算当前套利单占用的保证金。 /// </summary> /// <returns></returns> public decimal CalculatUseMargin() { ArbitrageOpenArgument openArg = null; lock (m_syncObj) { if (m_arbitrageOrder.State == ArbitrageOrderState.Finish || m_arbitrageOrder.State == ArbitrageOrderState.Closed) { //平仓完成套利单不占用保证金 return(0m); } openArg = m_arbitrageOrder.OpenArgument.Clone(); } USeOrderDriver orderDriver = USeManager.Instance.OrderDriver; USeQuoteDriver quoteDriver = USeManager.Instance.QuoteDriver; USeInstrumentDetail buyInstrumentDetail = orderDriver.QueryInstrumentDetail(openArg.BuyInstrument); USeInstrumentDetail sellInstrumentDetail = orderDriver.QueryInstrumentDetail(openArg.SellInstrument); USeMarketData buyMarketData = quoteDriver.Query(openArg.BuyInstrument); USeMarketData sellMarketData = quoteDriver.Query(openArg.SellInstrument); USeMargin buyMarginRate = orderDriver.QueryInstrumentMargin(openArg.BuyInstrument); USeMargin sellMarginRate = orderDriver.QueryInstrumentMargin(openArg.SellInstrument); decimal buyMargin = (openArg.TotalOrderQty * buyMarginRate.BrokerLongMarginRatioByVolume) + (buyMarketData.LastPrice * openArg.TotalOrderQty * buyInstrumentDetail.VolumeMultiple * buyMarginRate.BrokerLongMarginRatioByMoney); decimal sellMargin = (openArg.TotalOrderQty * sellMarginRate.BrokerShortMarginRatioByVolume) + (sellMarketData.LastPrice * openArg.TotalOrderQty * sellInstrumentDetail.VolumeMultiple * sellMarginRate.BrokerShortMarginRatioByMoney); if (openArg.BuyInstrument.Market == USeMarket.SHFE && openArg.SellInstrument.Market == USeMarket.SHFE) { return(Math.Max(buyMargin, sellMargin)); } else { return(buyMargin + sellMargin); } }
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); } }