/// <summary> /// 计算平仓损益。 /// </summary> /// <param name="arbitrageOrder"></param> /// <returns></returns> private ProfitResult CalculatCloseProfit(USeArbitrageOrder arbitrageOrder) { USeOrderDriver orderDriver = USeManager.Instance.OrderDriver; USeQuoteDriver quoteDriver = USeManager.Instance.QuoteDriver; Debug.Assert(orderDriver != null); Debug.Assert(quoteDriver != null); ArbitrageTaskGroup closeTaskGroup = arbitrageOrder.CloseTaskGroup; List <USeOrderBook> orderBookList = arbitrageOrder.GetAllOrderBooks(); USeMarketData buyMarketData = USeManager.Instance.QuoteDriver.Query(closeTaskGroup.BuyInstrument); USeMarketData sellMarketData = USeManager.Instance.QuoteDriver.Query(closeTaskGroup.SellInstrument); USeInstrumentDetail buyInstrumentDetail = USeManager.Instance.OrderDriver.QueryInstrumentDetail(closeTaskGroup.BuyInstrument); USeInstrumentDetail sellInstrumentDetail = USeManager.Instance.OrderDriver.QueryInstrumentDetail(closeTaskGroup.SellInstrument); decimal buyProfit = CalculateProfitByOrderBook(orderBookList, buyInstrumentDetail, buyMarketData); decimal sellProfit = CalculateProfitByOrderBook(orderBookList, sellInstrumentDetail, sellMarketData); decimal totalProfit = buyProfit + sellProfit; ProfitResult result = new ProfitResult() { BuyProfit = buyProfit, SellProfit = sellProfit }; return(result); }
/// <summary> /// 初始化。 /// </summary> /// <param name="orderDriver">交易驱动。</param> /// <param name="quoteDriver">行情驱动。</param> /// <param name="autoTraderManager">自动下单机管理类。</param> public void Initialize(USeOrderDriver orderDriver, USeQuoteDriver quoteDriver) { m_orderDriver = orderDriver; m_quoteDriver = quoteDriver; m_updateTimer = new System.Threading.Timer(QueryAndUpdate, false, Timeout.Infinite, Timeout.Infinite); }
/// <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> public override void Initialize() { this.btnChangeProduct.Text = "选择品种"; USeOrderDriver orderDriver = USeManager.Instance.OrderDriver; USeQuoteDriver quoteDriver = USeManager.Instance.QuoteDriver; quoteDriver.OnDriverStateChanged += QuoteDriver_OnDriverStateChanged; orderDriver.OnDriverStateChanged += OrderDriver_OnDriverStateChanged; USeManager.Instance.AutoTraderManager.OnAutoTraderNotify += AutoTraderManager_OnAutoTraderNotify; SetQuoteDriverState(quoteDriver.DriverState); SetOrderDriverState(orderDriver.DriverState); }
/// <summary> /// 预启动。 /// </summary> /// <param name="orderDriver"></param> /// <param name="quoteDriver"></param> public void PreStart(USeOrderDriver orderDriver, USeQuoteDriver quoteDriver) { if (orderDriver.DriverState != USeOrderDriverState.Ready) { throw new Exception("交易服务未登录"); } if (quoteDriver.DriverState != USeQuoteDriverState.Ready) { throw new Exception("行情服务未登录"); } m_loginUser = new InvestorAccount(orderDriver.BrokerId, orderDriver.Account, orderDriver.Password); m_orderDriver = orderDriver; m_quoteDriver = quoteDriver; m_orderDriver.SetAppLogger(m_eventLogger); }
/// <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="arbitrageOrderList">套利单信息。</param> /// <param name="orderDriver">交易驱动。</param> /// <param name="quoteDriver">行情驱动。</param> /// <param name="alarmManager">预警管理类。</param> /// <param name="systemConfigManager">系统配置管理类。</param> public void Initialize(List <USeArbitrageOrder> arbitrageOrderList, USeOrderDriver orderDriver, USeQuoteDriver quoteDriver, AlarmManager alarmManager, SystemConfigManager systemConfigManager) { m_orderDriver = orderDriver; m_quoteDriver = quoteDriver; m_alarmManager = alarmManager; m_systemConfigManager = systemConfigManager; m_systemConfigManager.OnSystemSettingChanged += M_systemConfigManager_OnSystemSettingChanged1; if (arbitrageOrderList == null || arbitrageOrderList.Count <= 0) { return; } lock (m_syncObj) { int maxAliasNum = 0; // 当日别名最大号码 TaskOrderSetting taskOrderSetting = m_systemConfigManager.GetTaskOrderSetting(); foreach (USeArbitrageOrder arbitrageOrder in arbitrageOrderList) { AutoTrader autoTrader = new AutoTrader(); autoTrader.SetRecordLogger(USeManager.Instance.CommandLogger); autoTrader.SetTryOrderCondition(taskOrderSetting.TaskMaxTryCount, taskOrderSetting.TryOrderMinInterval); autoTrader.Initialize(arbitrageOrder, m_orderDriver, m_quoteDriver, m_alarmManager); autoTrader.OnNotify += AutoTrader_OnNotify; autoTrader.OnAlarm += AutoTrader_OnAlarm; autoTrader.OnStateChanged += AutoTrader_OnStateChanged; autoTrader.OnArbitrageOrderChanged += AutoTrader_OnArbitrageOrderChanged; m_autoTraderDic.Add(autoTrader.TraderIdentify, autoTrader); if (arbitrageOrder.CreateTime.Date == DateTime.Today && arbitrageOrder.AliasNum > maxAliasNum) { maxAliasNum = arbitrageOrder.AliasNum; } } m_aliasIdCrateor.Set(maxAliasNum); } }
/// <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); } }
/// <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); } }
/// <summary> /// 初始化套利下单机。 /// </summary> /// <param name="arbitrageOrder">套利单信息。</param> /// <param name="orderDriver">下单驱动。</param> /// <param name="quoteDriver">行情驱动。</param> /// <param name="alarmManager">预警管理类。</param> public void Initialize(USeArbitrageOrder arbitrageOrder, USeOrderDriver orderDriver, USeQuoteDriver quoteDriver, AlarmManager alarmManager) { if (m_initialized) { throw new ApplicationException(string.Format("{0} already initialized.", this)); } if (arbitrageOrder == null) { throw new ArgumentNullException("arbitrageOrder", "arbitrageOrder is null"); } if (orderDriver == null) { throw new ArgumentNullException("orderDriver", "orderDriver is null"); } if (quoteDriver == null) { throw new ArgumentNullException("quoteDrvier", "quoteDrvier is null"); } if (alarmManager == null) { throw new ArgumentNullException("alarmManager", "alarmManager is null"); } try { lock (m_syncObj) { m_arbitrageOrder = arbitrageOrder.Clone(); m_orderDriver = orderDriver; m_quoteDriver = quoteDriver; } m_orderDriver.OnOrderBookChanged += OrderDriver_OnOrderBookChanged; m_quoteDriver.OnMarketDataChanged += QuoteDriver_OnMarketDataChanged; if (arbitrageOrder.OpenArgument != null) { m_quoteDriver.Subscribe(arbitrageOrder.OpenArgument.BuyInstrument); m_quoteDriver.Subscribe(arbitrageOrder.OpenArgument.SellInstrument); } string text = string.Format("初始化套利单完成,当前状态为[{0}]", arbitrageOrder.State.ToDescription()); AutoTraderNotice notice = CreateTraderNotice(text); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); } catch (Exception ex) { string text = string.Format("初始化套利单失败,原因:{0}", ex.Message); AutoTraderNotice notice = CreateTraderNotice(text); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); throw new Exception("初始化自定下单机失败"); } m_initialized = true; }