예제 #1
0
        /// <summary>
        /// 请求查询合约保证金响应。
        /// </summary>
        /// <param name="replyField">与请求对应的应答信息数据结构。</param>
        /// <param name="resultField">请求的执行结果信息数据结构。</param>
        /// <param name="requestId">标识请求的请求编号。</param>
        /// <param name="isLast">最后一个应答标志。</param>
        public override void OnRspQryInstrumentMarginRate(ref InstrumentMarginRateField?replyField, ref RspInfoField resultField, int requestId, bool isLast)
        {
            try
            {
                Debug.Assert(m_eventDic.ContainsKey(requestId), string.Format("RequestID({0}) didn't exist.", requestId));
                if (m_eventDic.ContainsKey(requestId) == false)
                {
                    return;
                }

                USeResetEvent resetEvent = m_eventDic[requestId];

                if (resultField.ErrorID != 0)
                {
                    resetEvent.Tag = resultField;
                    resetEvent.Set(true);
                }
                else
                {
                    if (replyField.HasValue)
                    {
                        List <InstrumentMarginRateField> marginFields = resetEvent.Tag as List <InstrumentMarginRateField>;
                        Debug.Assert(marginFields != null);
                        marginFields.Add(replyField.Value);
                    }

                    resetEvent.IsFinish = isLast;
                    resetEvent.Set(false);
                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "OnRspQryInstrumentMarginRate(),Error:" + ex.Message);
            }
        }
예제 #2
0
        /// <summary>
        /// 行情变更通知
        /// </summary>
        /// <param name="reportField">回报信息数据结构。</param>
        public void OnRtnDepthMarketData(ref DepthMarketDataField?reportField)
        {
            try
            {
                if (reportField.HasValue == false)
                {
                    return;
                }

                string        instrumentCode = reportField.Value.InstrumentID;
                USeMarketData marketData     = null;

                lock (m_object)
                {
                    marketData = DepthMarketDataFieldToUSeFuture(reportField.Value);
                    m_marketDataDic[instrumentCode] = marketData;
                }

                USeResetEvent resetEvent = GetResetEvent(instrumentCode);
                if (resetEvent != null)
                {
                    resetEvent.Set(false);
                }

                FireOnMarketDataChanged(marketData);
            }
            catch (Exception ex)
            {
                m_logger.WriteError(string.Format("{0}.OnRtnDepthMarketData failed ,Error:{1}.",
                                                  ToString(), ex.Message));
                Debug.Assert(false, ex.Message);
            }
        }
예제 #3
0
        /// <summary>
        /// 登录CTP。
        /// </summary>
        /// <param name="account">交易帐号。</param>
        /// <param name="password">交易密码(明文)。</param>
        /// <param name="brokerID">所属经纪商ID。</param>
        public void Login(string account, string password, string brokerID)
        {
            m_investorID = account;
            m_brokerID   = brokerID;
            int requestID = m_requetSeqIDCreator.Next();

            try
            {
                m_loginEvent = new USeResetEvent(requestID);

                m_ctpUser.LoginAsync(m_brokerID, account, password, "", requestID);
                if (m_loginEvent.WaitOne(5000) == false)
                {
                    throw new Exception("登录超时");
                }
                else
                {
                    if (m_loginEvent.IsError)
                    {
                        Debug.Assert(m_loginEvent.Tag != null);
                        RspInfoField rspInfo = (RspInfoField)m_loginEvent.Tag;
                        Debug.Assert(rspInfo.ErrorID != 0);
                        throw new Exception(string.Format("({0}){1}", rspInfo.ErrorID, rspInfo.ErrorMsg));
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                m_loginEvent = null;
            }
        }
예제 #4
0
        /// <summary>
        /// 查询账户基本信息
        /// </summary>
        ///<param name="error">查询结果信息。</param>
        /// <returns>查询账户基本信息。</returns>
        private InvestorField QueryInvestorBaseInfoFromCtp()
        {
            int requestID = m_requetSeqIDCreator.Next();
            List <InvestorField> investorInfos = new List <InvestorField>();

            try
            {
                USeResetEvent queryEvent = new USeResetEvent(requestID);
                queryEvent.Tag = investorInfos;
                m_eventDic.Add(queryEvent.EventID, queryEvent);

                QryInvestorField requestField = new QryInvestorField();
                requestField.BrokerID   = m_brokerID;
                requestField.InvestorID = m_investorID;

                m_ctpUser.ReqQryInvestor(ref requestField, requestID);

                while (true)
                {
                    if (queryEvent.IsError)
                    {
                        Debug.Assert(queryEvent.Tag != null);
                        RspInfoField rspInfo = (RspInfoField)queryEvent.Tag;
                        throw new Exception(string.Format("({0}){1}", rspInfo.ErrorID, rspInfo.ErrorMsg));
                    }

                    if (queryEvent.IsFinish)
                    {
                        break;
                    }

                    if (queryEvent.WaitOne(m_queryTimeOut) == false)
                    {
                        throw new Exception(string.Format("({0}){1}", "99", "time out"));
                    }
                }
            }
            catch (Exception ex)
            {
                m_logger.WriteError(string.Format("{0}.QueryInvestorBaseInfoFromCtp() failed,Error:{1}.",
                                                  ToString(), ex.Message));
                throw new Exception(string.Format("Query investor base info failed,Error:{0}.", ex.Message));
            }
            finally
            {
                m_eventDic.Remove(requestID);
            }

            if (investorInfos.Count > 0)
            {
                Debug.Assert(investorInfos.Count == 1);
                return(investorInfos[0]);
            }
            else
            {
                throw new Exception(string.Format("Query investor base info failed,Error:{0}.", "no record"));
            }
        }
예제 #5
0
        /// <summary>
        /// 从Ctp查询是否需要投资者结算信息确认。
        /// </summary>
        /// <returns></returns>
        private bool QueryNeedSettlementInfoConfirmFromCtp()
        {
            List <SettlementInfoConfirmField> replyFields = new List <SettlementInfoConfirmField>();
            int requestID = m_requetSeqIDCreator.Next();

            try
            {
                USeResetEvent queryEvent = new USeResetEvent(requestID);
                queryEvent.Tag = replyFields;
                m_eventDic.Add(queryEvent.EventID, queryEvent);

                QrySettlementInfoConfirmField requestFields = new QrySettlementInfoConfirmField();
                requestFields.BrokerID   = m_brokerID;
                requestFields.InvestorID = m_investorID;

                m_ctpUser.ReqQrySettlementInfoConfirm(ref requestFields, requestID);

                while (true)
                {
                    if (queryEvent.IsError)
                    {
                        Debug.Assert(queryEvent.Tag != null);
                        RspInfoField rspInfo = (RspInfoField)queryEvent.Tag;
                        throw new Exception(string.Format("({0}){1}", rspInfo.ErrorID, rspInfo.ErrorMsg));
                    }

                    if (queryEvent.IsFinish)
                    {
                        break;
                    }

                    if (queryEvent.WaitOne(m_queryTimeOut) == false)
                    {
                        throw new Exception(string.Format("({0}){1}", "99", "time out"));
                    }
                }
            }
            catch (Exception ex)
            {
                m_logger.WriteError(string.Format("{0}.QueryNeedSettlementInfoConfirmFromCtp() failed,Error:{1}.",
                                                  ToString(), ex.Message));
                throw new Exception(string.Format("Query settlementInfo confirm failed,Error:{0}.", ex.Message));
            }
            finally
            {
                m_eventDic.Remove(requestID);
            }

            if (replyFields.Count <= 0)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        /// <summary>
        /// 期货公司认证
        /// </summary>
        public override void AuthorT(string brokerID, string userId, string authCode, string userProductInfo)
        {
            FireOrderDriverStateChanged(USeOrderDriverState.Authoring, "");

            Debug.Assert(m_ctpUser != null, "m_ctpUser is null");

            int requestID = m_requetSeqIDCreator.Next();

            try
            {
                USeResetEvent resetEvent = new USeResetEvent(requestID);
                m_eventDic.Add(resetEvent.EventID, resetEvent);

                ReqAuthenticateField field = new ReqAuthenticateField()
                {
                    BrokerID        = brokerID,
                    UserID          = userId,
                    AuthCode        = authCode,
                    UserProductInfo = userProductInfo
                };

                m_ctpUser.ReqAuthenticate(ref field, requestID);

                if (resetEvent.WaitOne(m_connectTimeOut) == false)
                //if (resetEvent.WaitOne(50000) == false)
                {
                    throw new Exception("AuthorT time out.");
                }
                else
                {
                    if (resetEvent.IsError)
                    {
                        Debug.Assert(resetEvent.Tag != null);
                        ReqAuthenticateField rspInfo = (ReqAuthenticateField)resetEvent.Tag;
                        Debug.Assert(rspInfo.UserProductInfo != null && rspInfo.UserProductInfo != "");
                        throw new Exception(string.Format("({0}){1}", rspInfo.AuthCode, rspInfo.UserProductInfo));
                    }
                }
            }
            catch (Exception ex)
            {
                FireOrderDriverStateChanged(USeOrderDriverState.AuthorFieldOut, ex.Message);
                m_logger.WriteError(string.Format("{0} AuthorT failed,Error: {1}.", ToString(), ex.Message));
                throw ex;
            }
            finally
            {
                m_eventDic.Remove(requestID);
            }

            FireOrderDriverStateChanged(USeOrderDriverState.AuthorSuccessOn, "");
        }
예제 #7
0
        /// <summary>
        /// 查询账户持仓信息。
        /// </summary>
        ///<param name="error">查询结果信息。</param>
        /// <returns>查询持仓信息是否成功。</returns>
        private List <InvestorPositionField> QueryInvestorPositionFromCtp()
        {
            List <InvestorPositionField> positionsFields = new List <InvestorPositionField>();
            int requestID = m_requetSeqIDCreator.Next();

            try
            {
                USeResetEvent queryEvent = new USeResetEvent(requestID);
                queryEvent.Tag = positionsFields;
                m_eventDic.Add(queryEvent.EventID, queryEvent);

                QryInvestorPositionField requestField = new QryInvestorPositionField();
                requestField.BrokerID     = m_brokerID;
                requestField.InvestorID   = m_investorID;
                requestField.InstrumentID = null;

                m_ctpUser.ReqQryInvestorPosition(ref requestField, requestID);

                while (true)
                {
                    if (queryEvent.IsError)
                    {
                        Debug.Assert(queryEvent.Tag != null);
                        RspInfoField rspInfo = (RspInfoField)queryEvent.Tag;
                        throw new Exception(string.Format("({0}){1}", rspInfo.ErrorID, rspInfo.ErrorMsg));
                    }

                    if (queryEvent.IsFinish)
                    {
                        break;
                    }

                    if (queryEvent.WaitOne(m_queryTimeOut) == false)
                    {
                        throw new Exception(string.Format("({0}){1}", "99", "time out"));
                    }
                }
            }
            catch (Exception ex)
            {
                m_logger.WriteError(string.Format("{0}.QueryInvestorPositionFromCtp() failed,Error:{1}.",
                                                  ToString(), ex.Message));
                throw new Exception(string.Format("Query position failed,Error:{0}.", ex.Message));
            }
            finally
            {
                m_eventDic.Remove(requestID);
            }

            return(positionsFields);
        }
예제 #8
0
        /// <summary>
        /// 查询所有合约深度行情数据。
        /// </summary>
        /// <returns></returns>
        public List <DepthMarketDataField> QueryDepthMarketData()
        {
            int requestID = m_requetSeqIDCreator.Next();

            try
            {
                List <DepthMarketDataField> marketList = new List <DepthMarketDataField>();
                USeResetEvent queryEvent = new USeResetEvent(requestID);
                queryEvent.Tag = marketList;
                m_eventDic.Add(queryEvent.EventID, queryEvent);

                QryDepthMarketDataField field = new QryDepthMarketDataField();
                m_ctpUser.ReqQryDepthMarketData(ref field, requestID);

                if (queryEvent.WaitOne(m_queryTimeOut) == false)
                {
                    throw new Exception("查询超时");
                }
                else
                {
                    if (queryEvent.IsError)
                    {
                        Debug.Assert(queryEvent.Tag != null);
                        RspInfoField rspInfo = (RspInfoField)queryEvent.Tag;
                        throw new Exception(string.Format("({0}){1}", rspInfo.ErrorID, rspInfo.ErrorMsg));
                    }
                    while (true)
                    {
                        if (queryEvent.IsFinish)
                        {
                            break;
                        }
                        // 继续等待应答结果
                        if (queryEvent.WaitOne(m_queryTimeOut) == false)
                        {
                            throw new Exception(string.Format("({0}){1}", "99", "time out"));
                        }
                    }
                }

                return(marketList);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                m_eventDic.Remove(requestID);
            }
        }
        /// <summary>
        /// 登录行情服务器
        /// </summary>
        /// <param name="account">账号</param>
        /// <param name="password">密码</param>
        public override void Login(string brokerId, string account, string password)
        {
            FireDriverStateChanged(USeQuoteDriverState.LoggingOn, "");

            try
            {
                USeResetEvent loginEvent = new USeResetEvent();
                m_eventDic.Add(LOGIN_EVENT_KEY, loginEvent);

                m_ctpFeed.LoginAsync(brokerId, account, password, "", -1);
                if (loginEvent.WaitOne(m_connectTimeOut) == false)
                {
                    throw new Exception("login time out.");
                }
                else
                {
                    if (loginEvent.IsError)
                    {
                        Debug.Assert(loginEvent.Tag != null);
                        RspInfoField rspInfo = (RspInfoField)loginEvent.Tag;
                        Debug.Assert(rspInfo.ErrorID != 0);
                        throw new Exception(string.Format("({0}){1}", rspInfo.ErrorID, rspInfo.ErrorMsg));
                    }
                    else
                    {
                        FireDriverStateChanged(USeQuoteDriverState.LoggedOn, "");
                    }
                }
            }
            catch (Exception ex)
            {
                FireDriverStateChanged(USeQuoteDriverState.DisConnected, ex.Message);
                m_logger.WriteError(string.Format("{0} login failed,Error: {1}.", ToString(), ex.Message));
                throw ex;
            }
            finally
            {
                m_eventDic.Remove(LOGIN_EVENT_KEY);
            }
            m_brokerID   = brokerId;
            m_investorID = account;
            m_password   = password;

            FireDriverStateChanged(USeQuoteDriverState.Ready, "");
        }
예제 #10
0
        /// <summary>
        /// 与前置机连接成功时的回调方法。
        /// </summary>
        public void OnFrontConnect()
        {
            m_logger.WriteInformation(string.Format("{0}.OnFrontConnect ok.", ToString()));
            USeResetEvent resetEvent = GetResetEvent(CONNECT_EVENT_KEY);

            if (resetEvent != null)
            {
                resetEvent.Set(false);
            }
            else
            {
                if (string.IsNullOrEmpty(m_password) == false)
                {
                    FireDriverStateChanged(USeQuoteDriverState.Connected, "Reconnect");

                    //1秒后重新登录
                    m_autoLoginTimer.Change(1000, Timeout.Infinite);
                }
            }
        }
예제 #11
0
        /// <summary>
        /// 登录响应
        /// </summary>
        /// <param name="replyField">与请求对应的应答信息数据结构。</param>
        /// <param name="resultField">请求的执行结果信息数据结构。</param>
        /// <param name="requestId">标识请求的请求编号。</param>
        /// <param name="isLast">最后一个应答标志。</param>
        public void OnRspUserLogin(ref RspUserLoginField?replyField, ref RspInfoField resultField, int requestId, bool isLast)
        {
            m_logger.WriteInformation(string.Format("{0}.OnRspUserLogin ok.", ToString()));
            USeResetEvent resetEvent = GetResetEvent(LOGIN_EVENT_KEY);

            if (resetEvent == null)
            {
                return;
            }

            if (resultField.ErrorID != 0 || replyField.HasValue == false)
            {
                resetEvent.Tag = resultField;
                resetEvent.Set(true);
            }
            else
            {
                resetEvent.Set(false);
            }
        }
        /// <summary>
        /// 连接行情服务器
        /// </summary>
        public override void ConnectServer()
        {
            if (m_eventDic.ContainsKey(CONNECT_EVENT_KEY))
            {
                throw new Exception(string.Format("{0} is connecting.", ToString()));
            }

            FireDriverStateChanged(USeQuoteDriverState.Connecting, "");

            Debug.Assert(string.IsNullOrEmpty(m_ctpFeedStreamFilePath) == false);
            m_ctpFeed = new CtpFeed(m_ctpFeedStreamFilePath);
            m_ctpFeed.SetApplication(this);
            Debug.Assert(m_ctpFeed != null, "m_ctpFeed is null");

            try
            {
                USeResetEvent connectEvent = new USeResetEvent(0);
                m_eventDic.Add(CONNECT_EVENT_KEY, connectEvent);

                m_ctpFeed.ConnectAsync(string.Format(@"tcp://{0}:{1}", m_address, m_port));

                if (connectEvent.WaitOne(m_connectTimeOut) == false)
                {
                    throw new Exception("connect time out.");
                }

                FireDriverStateChanged(USeQuoteDriverState.Connected, "");
            }
            catch (Exception ex)
            {
                FireDriverStateChanged(USeQuoteDriverState.DisConnected, ex.Message);
                m_logger.WriteError(string.Format("{0} connect failed,Error: {1}.", ToString(), ex.Message));
                throw ex;
            }
            finally
            {
                m_eventDic.Remove(CONNECT_EVENT_KEY);
            }
        }
예제 #13
0
        /// <summary>
        /// 连接CTP交易服务器。
        /// </summary>
        /// <param name="address">交易服务器地址。</param>
        /// <param name="port">交易服务器地址端口。</param>
        public void Connect(string address, int port, int loginTimeout, int queryTimeout)
        {
            if (loginTimeout <= 0)
            {
                throw new ArgumentNullException("loginTimeout", "loginTimeout can not be null or empty.");
            }
            if (queryTimeout <= 0)
            {
                throw new ArgumentNullException("queryTimeout", "queryTimeout can not be null or empty.");
            }
            Debug.Assert(m_connectEvent == null, "ConnectEvent is not null.");

            m_loginTimeOut = loginTimeout;
            m_queryTimeOut = queryTimeout;

            m_ctpUser = new CtpUser("");
            m_ctpUser.SetApplication(this);

            Debug.Assert(m_ctpUser != null);
            try
            {
                m_connectEvent = new USeResetEvent();
                m_ctpUser.ConnectAsync(string.Format(@"tcp://{0}:{1}", address, port));

                if (m_connectEvent.WaitOne(m_loginTimeOut) == false)
                {
                    throw new Exception("连接超时");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                m_connectEvent = null;
            }
        }
예제 #14
0
        /// <summary>
        /// 从Ctp查询保证金。
        /// </summary>
        /// <param name="instrumentCode"></param>
        /// <returns></returns>
        private InstrumentMarginRateField QueryMarginFromCtp(string instrumentCode)
        {
            List <InstrumentMarginRateField> marginFields = new List <InstrumentMarginRateField>();
            int requestID = m_requetSeqIDCreator.Next();

            try
            {
                USeResetEvent queryEvent = new USeResetEvent(requestID);
                queryEvent.Tag = marginFields;
                m_eventDic.Add(queryEvent.EventID, queryEvent);

                QryInstrumentMarginRateField requestField = new QryInstrumentMarginRateField();
                requestField.BrokerID     = m_brokerID;
                requestField.InvestorID   = m_investorID;
                requestField.InstrumentID = instrumentCode;
                requestField.HedgeFlag    = HedgeFlagType.Speculation;

                m_ctpUser.ReqQryInstrumentMarginRate(ref requestField, requestID);

                while (true)
                {
                    if (queryEvent.IsError)
                    {
                        Debug.Assert(queryEvent.Tag != null);
                        RspInfoField rspInfo = (RspInfoField)queryEvent.Tag;
                        throw new Exception(string.Format("({0}){1}", rspInfo.ErrorID, rspInfo.ErrorMsg));
                    }

                    if (queryEvent.IsFinish)
                    {
                        break;
                    }

                    if (queryEvent.WaitOne(m_queryTimeOut) == false)
                    {
                        throw new Exception(string.Format("({0}){1}", "99", "time oute"));
                    }
                }
            }
            catch (Exception ex)
            {
                m_logger.WriteError(string.Format("{0}.QueryMarginFromCtp() failed,Error:{1}.",
                                                  ToString(), ex.Message));
                throw new Exception(string.Format("Query [{0}]margin failed,Error:{1}.", instrumentCode, ex.Message));
            }
            finally
            {
                m_eventDic.Remove(requestID);
            }

            if (marginFields.Count > 0)
            {
                Debug.Assert(marginFields.Count == 1);
                return(marginFields[0]);
            }
            else
            {
                //查询有应答但无值,构造一个空的保证金
                InstrumentMarginRateField marginField = new InstrumentMarginRateField();
                marginField.BrokerID                 = m_brokerID;
                marginField.HedgeFlag                = HedgeFlagType.Speculation;
                marginField.InstrumentID             = instrumentCode;
                marginField.InvestorID               = m_investorID;
                marginField.InvestorRange            = InvestorRangeType.All;
                marginField.IsRelative               = IntBoolType.Yes;
                marginField.LongMarginRatioByMoney   = 0d;
                marginField.LongMarginRatioByVolume  = 0d;
                marginField.ShortMarginRatioByMoney  = 0d;
                marginField.ShortMarginRatioByVolume = 0d;

                return(marginField);
            }
        }
예제 #15
0
        /// <summary>
        /// 从Ctp查询手续费。
        /// </summary>
        /// <param name="instrumentCode">合约代码。</param>
        /// <returns></returns>
        private InstrumentCommissionRateField QueryCommissionRateFieldFromCtp(string instrumentCode)
        {
            List <InstrumentCommissionRateField> commissionFields = new List <InstrumentCommissionRateField>();
            int requestID = m_requetSeqIDCreator.Next();

            try
            {
                USeResetEvent queryEvent = new USeResetEvent(requestID);
                queryEvent.Tag = commissionFields;
                m_eventDic.Add(queryEvent.EventID, queryEvent);

                QryInstrumentCommissionRateField requestFields = new QryInstrumentCommissionRateField();
                requestFields.BrokerID     = m_brokerID;
                requestFields.InvestorID   = m_investorID;
                requestFields.InstrumentID = instrumentCode;

                m_ctpUser.ReqQryInstrumentCommissionRate(ref requestFields, requestID);

                while (true)
                {
                    if (queryEvent.IsError)
                    {
                        Debug.Assert(queryEvent.Tag != null);
                        RspInfoField rspInfo = (RspInfoField)queryEvent.Tag;
                        throw new Exception(string.Format("({0}){1}", rspInfo.ErrorID, rspInfo.ErrorMsg));
                    }

                    if (queryEvent.IsFinish)
                    {
                        break;
                    }

                    if (queryEvent.WaitOne(m_queryTimeOut) == false)
                    {
                        throw new Exception(string.Format("({0}){1}", "99", "time out"));
                    }
                }
            }
            catch (Exception ex)
            {
                m_logger.WriteError(string.Format("{0}.QueryCommissionRateFieldFromCtp() failed,Error:{1}.",
                                                  ToString(), ex.Message));
                throw new Exception(string.Format("Query [{0}] commission rate failed,Error:{1}.", instrumentCode, ex.Message));
            }
            finally
            {
                m_eventDic.Remove(requestID);
            }

            if (commissionFields.Count > 0)
            {
                Debug.Assert(commissionFields.Count == 1);
                return(commissionFields[0]);
            }
            else
            {
                //查询有应答但无值,构造一个空的手续费
                USeInstrumentDetail instrumentDetail = m_dataBuffer.GetInstrumentDetail(instrumentCode);
                Debug.Assert(instrumentDetail != null);
                InstrumentCommissionRateField rateField = new InstrumentCommissionRateField();
                rateField.BrokerID                = m_brokerID;
                rateField.CloseRatioByMoney       = 0d;
                rateField.CloseRatioByVolume      = 0d;
                rateField.CloseTodayRatioByMoney  = 0d;
                rateField.CloseTodayRatioByVolume = 0d;
                rateField.InstrumentID            = instrumentDetail.Varieties;
                rateField.InvestorID              = m_investorID;
                rateField.InvestorRange           = InvestorRangeType.All;
                rateField.OpenRatioByMoney        = 0d;
                rateField.OpenRatioByVolume       = 0d;

                return(rateField);
            }
        }
예제 #16
0
        /// <summary>
        /// 查询合约保证金。
        /// </summary>
        /// <param name="instrumentCode"></param>
        /// <returns></returns>
        public InstrumentMarginRateField?QueryInstrumentMargin(string instrumentCode)
        {
            int requestID = m_requetSeqIDCreator.Next();

            try
            {
                List <InstrumentMarginRateField> marginList = new List <InstrumentMarginRateField>();
                USeResetEvent queryEvent = new USeResetEvent(requestID);
                queryEvent.Tag = marginList;
                m_eventDic.Add(queryEvent.EventID, queryEvent);

                QryInstrumentMarginRateField field = new QryInstrumentMarginRateField();
                field.BrokerID     = m_brokerID;
                field.InvestorID   = m_investorID;
                field.InstrumentID = instrumentCode;
                field.HedgeFlag    = HedgeFlagType.Speculation;
                m_ctpUser.ReqQryInstrumentMarginRate(ref field, requestID);

                if (queryEvent.WaitOne(m_queryTimeOut) == false)
                {
                    throw new Exception("查询超时");
                }
                else
                {
                    if (queryEvent.IsError)
                    {
                        Debug.Assert(queryEvent.Tag != null);
                        RspInfoField rspInfo = (RspInfoField)queryEvent.Tag;
                        throw new Exception(string.Format("({0}){1}", rspInfo.ErrorID, rspInfo.ErrorMsg));
                    }
                    while (true)
                    {
                        if (queryEvent.IsFinish)
                        {
                            break;
                        }
                        // 继续等待应答结果
                        if (queryEvent.WaitOne(m_queryTimeOut) == false)
                        {
                            throw new Exception(string.Format("({0}){1}", "99", "超时"));
                        }
                    }
                }

                if (marginList.Count > 0)
                {
                    Debug.Assert(marginList.Count == 1);
                    return(marginList[0]);
                }
                else
                {
                    return(null);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                m_eventDic.Remove(requestID);
            }
        }
        /// <summary>
        /// 查询产品行情
        /// </summary>
        /// <param name="product">被查询产品</param>
        /// <returns>被查询产品行情信息</returns>
        public override USeMarketData Query(USeInstrument product)
        {
            try
            {
                if (m_marketDataDic.ContainsKey(product.InstrumentCode))
                {
                    return(m_marketDataDic[product.InstrumentCode]);
                }
                else
                {
                    USeResetEvent queryEvent = new USeResetEvent();
                    lock (m_object)
                    {
                        if (!m_eventDic.ContainsKey(product.InstrumentCode))
                        {
                            m_eventDic.Add(product.InstrumentCode, queryEvent);
                        }
                    }

                    m_ctpFeed.SubscribeMarketData(new string[] { product.InstrumentCode });

                    while (true)
                    {
                        if (queryEvent.WaitOne(m_queryTimeOut) == false)
                        {
                            USeMarketData nullMarketData = new USeMarketData();
                            nullMarketData.Instrument = product.Clone();
                            return(nullMarketData);
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (m_marketDataDic.ContainsKey(product.InstrumentCode))
                    {
                        return(m_marketDataDic[product.InstrumentCode]);
                    }
                    else
                    {
                        USeMarketData nullMarketData = new USeMarketData();
                        nullMarketData.Instrument = product.Clone();
                        return(nullMarketData);
                    }
                }
            }
            catch (Exception ex)
            {
                m_logger.WriteError(string.Format("{0} Query failed,Error: {1}.", ToString(), ex.Message));

                USeMarketData nullMarketData = new USeMarketData();
                nullMarketData.Instrument = product.Clone();
                return(nullMarketData);
            }
            finally
            {
                lock (m_object)
                {
                    m_eventDic.Remove(product.InstrumentCode);
                }
            }
        }
        /// <summary>
        /// 登录交易服务器。
        /// </summary>
        /// <param name="brokerId">经纪商ID。</param>
        /// <param name="account">帐号。</param>
        /// <param name="password">密码。</param>
        public override void Login(string brokerId, string account, string password)
        {
            FireOrderDriverStateChanged(USeOrderDriverState.LoggingOn, "");

            m_dataBuffer.Clear();

            m_brokerID   = brokerId;
            m_investorID = account;
            int requestID = m_requetSeqIDCreator.Next();

            try
            {
                USeResetEvent resetEvent = new USeResetEvent(requestID);
                m_eventDic.Add(resetEvent.EventID, resetEvent);

                m_ctpUser.LoginAsync(m_brokerID, account, password, "", requestID);
                if (resetEvent.WaitOne(m_connectTimeOut) == false)
                //if (resetEvent.WaitOne(50000) == false)
                {
                    throw new Exception("Login time out.");
                }
                else
                {
                    if (resetEvent.IsError)
                    {
                        Debug.Assert(resetEvent.Tag != null);
                        RspInfoField rspInfo = (RspInfoField)resetEvent.Tag;
                        Debug.Assert(rspInfo.ErrorID != 0);
                        throw new Exception(string.Format("({0}){1}", rspInfo.ErrorID, rspInfo.ErrorMsg));
                    }
                }
            }
            catch (Exception ex)
            {
                FireOrderDriverStateChanged(USeOrderDriverState.DisConnected, ex.Message);
                m_logger.WriteError(string.Format("{0} login failed,Error: {1}.", ToString(), ex.Message));
                throw ex;
            }
            finally
            {
                m_eventDic.Remove(requestID);
            }
            FireOrderDriverStateChanged(USeOrderDriverState.LoggingOn, "");

            List <InstrumentField>       instrumentList = null;
            List <OrderField>            orderBookList  = null;
            List <TradeField>            tradeBookList  = null;
            List <InvestorPositionField> positionList   = null;
            TradingAccountField          tradeAccountField;
            InvestorField investorField;

            try
            {
                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "正在查询投资者信息");
                investorField = QueryInvestorBaseInfoFromCtp();
                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "查询投资者信息完成");
                Thread.Sleep(1000);

                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "正在查询合约信息");
                instrumentList = QueryAllInstrumentFromCtp();
                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "查询合约信息完成");
                Thread.Sleep(1000);

                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "正在查询委托单信息");
                orderBookList = QueryAllOrderFieldFromCtp();
                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "查询委托单信息完成");
                Thread.Sleep(1000);

                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "正在查询成交回报信息");
                tradeBookList = QueryAllTradeFieldFromCtp();
                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "查询成交回报信息完成");
                Thread.Sleep(1000);

                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "正在查询持仓信息");
                positionList = QueryInvestorPositionFromCtp();
                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "查询持仓信息完成");
                Thread.Sleep(1000);

                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "正在查询资金帐号信息");
                tradeAccountField = QueryTradingAccountFromCtp();
                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "查询资金帐号信息完成");
                Thread.Sleep(1000);

                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "正在查询结算单信息");
                m_needSettlementConfirm = QueryNeedSettlementInfoConfirmFromCtp();
                FireOrderDriverStateChanged(USeOrderDriverState.Loading, "查询结算单信息完成");
                Thread.Sleep(1000);
            }
            catch (Exception ex)
            {
                m_logger.WriteError(ex.Message);
                FireOrderDriverStateChanged(USeOrderDriverState.DisConnected, ex.Message);
                throw ex;
            }

            try
            {
                m_dataBuffer.InitializeInstrumentInfo(instrumentList);
                m_dataBuffer.InitializeData(orderBookList, tradeBookList, positionList, tradeAccountField, investorField);
            }
            catch (Exception ex)
            {
                m_logger.WriteError(ex.Message);
                m_dataBuffer.Clear();
                FireOrderDriverStateChanged(USeOrderDriverState.DisConnected, ex.Message);
                throw ex;
            }

            m_password = password;
            FireOrderDriverStateChanged(USeOrderDriverState.Ready, "");

            m_queryTimer.Change(2000, Timeout.Infinite);                               // 启动手续费保证金查询
            m_queryAccountTimer.Change(QUERY_ACCOUNT_INFO_INTERVAL, Timeout.Infinite); // 启动帐号资金定时查询
        }