Example #1
0
        //建立交易
        private void Connect_TD()
        {
            lock (_lockTd)
            {
                if (_bWantTdConnect &&
                    (null == m_pTdApi || IntPtr.Zero == m_pTdApi))
                {
                    m_pTdApi = TraderApi.TD_CreateTdApi();
                    TraderApi.CTP_RegOnErrRtnOrderAction(m_pMsgQueue, _fnOnErrRtnOrderAction_Holder);
                    TraderApi.CTP_RegOnErrRtnOrderInsert(m_pMsgQueue, _fnOnErrRtnOrderInsert_Holder);
                    TraderApi.CTP_RegOnRspOrderAction(m_pMsgQueue, _fnOnRspOrderAction_Holder);
                    TraderApi.CTP_RegOnRspOrderInsert(m_pMsgQueue, _fnOnRspOrderInsert_Holder);
                    TraderApi.CTP_RegOnRspQryDepthMarketData(m_pMsgQueue, _fnOnRspQryDepthMarketData_Holder);
                    TraderApi.CTP_RegOnRspQryInstrument(m_pMsgQueue, _fnOnRspQryInstrument_Holder);
                    TraderApi.CTP_RegOnRspQryInstrumentCommissionRate(m_pMsgQueue, _fnOnRspQryInstrumentCommissionRate_Holder);
                    TraderApi.CTP_RegOnRspQryInstrumentMarginRate(m_pMsgQueue, _fnOnRspQryInstrumentMarginRate_Holder);
                    TraderApi.CTP_RegOnRspQryInvestorPosition(m_pMsgQueue, _fnOnRspQryInvestorPosition_Holder);
                    TraderApi.CTP_RegOnRspQryTradingAccount(m_pMsgQueue, _fnOnRspQryTradingAccount_Holder);
                    TraderApi.CTP_RegOnRtnInstrumentStatus(m_pMsgQueue, _fnOnRtnInstrumentStatus_Holder);
                    TraderApi.CTP_RegOnRtnOrder(m_pMsgQueue, _fnOnRtnOrder_Holder);
                    TraderApi.CTP_RegOnRtnTrade(m_pMsgQueue, _fnOnRtnTrade_Holder);
                    TraderApi.TD_RegMsgQueue2TdApi(m_pTdApi, m_pMsgQueue);
                    TraderApi.TD_Connect(m_pTdApi, _newTempPath, string.Join(";", server.Trading.ToArray()),
                                         server.BrokerID, account.InvestorId, account.Password,
                                         ResumeType,
                                         server.UserProductInfo, server.AuthCode);

                    //向单例对象中注入操作用句柄
                    CTPAPI.GetInstance().__RegTdApi(m_pTdApi);
                }
            }
        }
Example #2
0
        private void OnRtnTrade(IntPtr pTraderApi, ref CThostFtdcTradeField pTrade)
        {
            tdlog.Info("时{0},合约{1},方向{2},开平{3},价{4},量{5},引用{6},成交编号{7}",
                       pTrade.TradeTime, pTrade.InstrumentID, pTrade.Direction, pTrade.OffsetFlag,
                       pTrade.Price, pTrade.Volume, pTrade.OrderRef, pTrade.TradeID);

            //找到自己发送的订单,标记成交
            string strSysID = string.Format("{0}:{1}", pTrade.ExchangeID, pTrade.OrderSysID);
            string strKey;

            if (!orderMap.TryGetValue(strSysID, out strKey))
            {
                return;
            }

            GenericOrderItem item;

            if (orderMap.TryGetValue(strKey, out item))
            {
                MultiOrderLeg leg   = item.GetLeg(CTPAPI.FromCTP(pTrade.Direction), pTrade.InstrumentID);
                SingleOrder   order = leg.Order;
#if CTP
                double Price = pTrade.Price;
#elif CTPZQ
                double Price = Convert.ToDouble(pTrade.Price);
#endif
                int Volume = pTrade.Volume;

                int LeavesQty = (int)order.LeavesQty - Volume;
                EmitFilled(order, Price, Volume, CommType.Absolute, 0);

                // 成交完成,清理数据
                OnRtnTradeLastStatus(item, pTrade, strSysID, strKey);
            }
        }
        private void OnRtnInstrumentStatus(IntPtr pTraderApi, ref CThostFtdcInstrumentStatusField pInstrumentStatus)
        {
            tdlog.Info("{0},{1},{2},{3}",
                       pInstrumentStatus.ExchangeID, pInstrumentStatus.InstrumentID,
                       pInstrumentStatus.InstrumentStatus, pInstrumentStatus.EnterReason);

            //通知单例
            CTPAPI.GetInstance().FireOnRtnInstrumentStatus(pInstrumentStatus);
        }
Example #4
0
        public override void OnStrategyStop()
        {
            CTPAPI.GetInstance().OnRspQryInstrument               -= new CTPAPI.RspQryInstrument(OnRspQryInstrument);
            CTPAPI.GetInstance().OnRspQryInstrumentMarginRate     -= new CTPAPI.RspQryInstrumentMarginRate(OnRspQryInstrumentMarginRate);
            CTPAPI.GetInstance().OnRspQryInstrumentCommissionRate -= new CTPAPI.RspQryInstrumentCommissionRate(OnRspQryInstrumentCommissionRate);

            CTPAPI.GetInstance().OnRtnInstrumentStatus -= new CTPAPI.RtnInstrumentStatus(OnRtnInstrumentStatus);

            CTPAPI.GetInstance().OnRspQryDepthMarketData -= new CTPAPI.RspQryDepthMarketData(OnRspQryDepthMarketData);

            // 此方法已经过期,在插件3.8.2.0中开始废弃
            //CTPAPI.GetInstance().OnRtnDepthMarketData -= new CTPAPI.RtnDepthMarketData(OnRtnDepthMarketData);
        }
Example #5
0
        public override void OnBar(Bar bar)
        {
            //以下四句只是演示,实盘中请保存查询出来的结果,并且一天只查一次
            CTPAPI.GetInstance().ReqQryInstrument("IF1312");

            // 一定得加上TThostFtdcHedgeFlagType
            CTPAPI.GetInstance().ReqQryInstrumentMarginRate("IF1312", TThostFtdcHedgeFlagType.Speculation);

            //目前模拟平台目前查询没有返回,实盘时返回的是产品的手续费,如查"IF1312",返回的是"IF"
            CTPAPI.GetInstance().ReqQryInstrumentCommissionRate("IF1312");

            //通过交易接口查询,主要用来取涨跌停或没有直接订阅的行情
            CTPAPI.GetInstance().ReqQryDepthMarketData("IF1309");
        }
        private void Send(SPOrderItem item)
        {
            if (item == null)
            {
                return;
            }

            SingleOrder order  = item.Leg[0].Order;
            SingleOrder order2 = item.Leg[1].Order;

            string symbol = item.GetSymbol();
            double price  = order.Price - order2.Price;
            int    qty    = (int)order.OrderQty;

            // 是否要做价格调整?
            byte[] bytes            = { (byte)CTPAPI.ToCTP(item.Leg[0].OpenClose), (byte)CTPAPI.ToCTP(item.Leg[1].OpenClose) };
            string szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length);

            byte[] bytes2          = { (byte)HedgeFlagType, (byte)HedgeFlagType };
            string szCombHedgeFlag = System.Text.Encoding.Default.GetString(bytes2, 0, bytes2.Length);

            TThostFtdcDirectionType           Direction           = order.Side == Side.Buy ? TThostFtdcDirectionType.Buy : TThostFtdcDirectionType.Sell;
            TThostFtdcOrderPriceTypeType      OrderPriceType      = TThostFtdcOrderPriceTypeType.LimitPrice;
            TThostFtdcTimeConditionType       TimeCondition       = TThostFtdcTimeConditionType.GFD;
            TThostFtdcContingentConditionType ContingentCondition = TThostFtdcContingentConditionType.Immediately;
            TThostFtdcVolumeConditionType     VolumeCondition     = TThostFtdcVolumeConditionType.AV;

            int nRet = 0;

#if CTP
            nRet = TraderApi.TD_SendOrder(m_pTdApi,
                                          -1,
                                          symbol,
                                          Direction,
                                          szCombOffsetFlag,
                                          szCombHedgeFlag,
                                          qty,
                                          price,
                                          OrderPriceType,
                                          TimeCondition,
                                          ContingentCondition,
                                          0,
                                          VolumeCondition);
#endif
            if (nRet > 0)
            {
                orderMap.CreateNewOrder(string.Format("{0}:{1}:{2}", _RspUserLogin.FrontID, _RspUserLogin.SessionID, nRet), item);
            }
        }
Example #7
0
        public override void OnStrategyStart()
        {
            CTPAPI.GetInstance().OnRspQryInstrument               += new CTPAPI.RspQryInstrument(OnRspQryInstrument);
            CTPAPI.GetInstance().OnRspQryInstrumentMarginRate     += new CTPAPI.RspQryInstrumentMarginRate(OnRspQryInstrumentMarginRate);
            CTPAPI.GetInstance().OnRspQryInstrumentCommissionRate += new CTPAPI.RspQryInstrumentCommissionRate(OnRspQryInstrumentCommissionRate);
            // 交易所状态
            CTPAPI.GetInstance().OnRtnInstrumentStatus += new CTPAPI.RtnInstrumentStatus(OnRtnInstrumentStatus);

            CTPAPI.GetInstance().OnRspQryTradingAccount += new CTPAPI.RspQryTradingAccount(OnRspQryTradingAccount);

            CTPAPI.GetInstance().OnRspReqQryInvestorPosition += new CTPAPI.RspReqQryInvestorPosition(OnRspReqQryInvestorPosition);

            // 此方法已经过期,在插件3.8.2.0中开始废弃
            //CTPAPI.GetInstance().OnRtnDepthMarketData += new CTPAPI.RtnDepthMarketData(OnRtnDepthMarketData);
        }
        private void Disconnect_MD()
        {
            lock (_lockMd)
            {
                if (null != m_pMdApi && IntPtr.Zero != m_pMdApi)
                {
                    MdApi.MD_RegMsgQueue2MdApi(m_pMdApi, IntPtr.Zero);
                    MdApi.MD_ReleaseMdApi(m_pMdApi);
                    m_pMdApi = IntPtr.Zero;

                    CTPAPI.GetInstance().__RegMdApi(m_pMdApi);
                }
                _bMdConnected = false;
            }
        }
        private void Disconnect_TD()
        {
            lock (_lockTd)
            {
                if (null != m_pTdApi && IntPtr.Zero != m_pTdApi)
                {
                    TraderApi.TD_RegMsgQueue2TdApi(m_pTdApi, IntPtr.Zero);
                    TraderApi.TD_ReleaseTdApi(m_pTdApi);
                    m_pTdApi = IntPtr.Zero;

                    CTPAPI.GetInstance().__RegTdApi(m_pTdApi);
                }
                _bTdConnected = false;
            }
        }
        private void OnRspQryInstrumentMarginRate(IntPtr pTraderApi, ref CThostFtdcInstrumentMarginRateField pInstrumentMarginRate, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (0 == pRspInfo.ErrorID)
            {
                _dictMarginRate[pInstrumentMarginRate.InstrumentID] = pInstrumentMarginRate;
                tdlog.Info("已经接收保证金率 {0}", pInstrumentMarginRate.InstrumentID);

                //通知单例
                CTPAPI.GetInstance().FireOnRspQryInstrumentMarginRate(pInstrumentMarginRate);
            }
            else
            {
                tdlog.Error("nRequestID:{0},ErrorID:{1},OnRspQryInstrumentMarginRate:{2}", nRequestID, pRspInfo.ErrorID, pRspInfo.ErrorMsg);
                EmitError(nRequestID, pRspInfo.ErrorID, "OnRspQryInstrumentMarginRate:" + pRspInfo.ErrorMsg);
            }
        }
Example #11
0
        private void EmitCancelReject(GenericOrderItem item, int error_id, string message)
        {
            TextResponse r = new TextResponse()
            {
                Error    = CTPAPI.FromCTP(error_id),
                ErrorID  = error_id,
                ErrorMsg = message,
            };

            foreach (var leg in item.GetLegs())
            {
                r.OpenClose    = leg.OpenClose;
                leg.Order.Text = r.ToString();
                EmitCancelReject(leg.Order, leg.Order.OrdStatus, r.ToString());
            }
        }
        private void OnRspQryInvestorPosition(IntPtr pTraderApi, ref CThostFtdcInvestorPositionField pInvestorPosition, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (0 == pRspInfo.ErrorID)
            {
                string key = GetPositionKey(pInvestorPosition);
                _dictPositions[key] = pInvestorPosition;
                CTPAPI.GetInstance().FireOnRspReqQryInvestorPosition(pInvestorPosition);

                timerPonstion.Enabled = false;
                timerPonstion.Enabled = true;
            }
            else
            {
                tdlog.Error("nRequestID:{0},ErrorID:{1},OnRspQryInvestorPosition:{2}", nRequestID, pRspInfo.ErrorID, pRspInfo.ErrorMsg);
                EmitError(nRequestID, pRspInfo.ErrorID, "OnRspQryInvestorPosition:" + pRspInfo.ErrorMsg);
            }
        }
        private void OnRtnInstrumentStatus(IntPtr pTraderApi, ref CThostFtdcInstrumentStatusField pInstrumentStatus)
        {
            tdlog.Info("{0},{1},{2},{3},{4},{5},{6},{7}",
                       pInstrumentStatus.ExchangeID, pInstrumentStatus.InstrumentID,
                       pInstrumentStatus.InstrumentStatus, pInstrumentStatus.EnterReason,
                       pInstrumentStatus.EnterTime, pInstrumentStatus.TradingSegmentSN,
                       pInstrumentStatus.ExchangeInstID, pInstrumentStatus.SettlementGroupID);

            //通知单例
            CTPAPI.GetInstance().FireOnRtnInstrumentStatus(pInstrumentStatus);

            // 到IF的交割日,是否会收到两个有关IF的记录?如果在此进行清理是否会有问题?
            // 只会收到一条
            // 遍历是否过期
            if (pInstrumentStatus.InstrumentStatus == TThostFtdcInstrumentStatusType.Closed)
            {
                Dictionary <GenericOrderItem, CThostFtdcOrderField> tmp = new Dictionary <GenericOrderItem, CThostFtdcOrderField>();
                foreach (var pair in orderMap.OrderItem_OrderField)
                {
                    if (pair.Value.ExchangeID == pInstrumentStatus.ExchangeID)
                    {
                        int cnt = pair.Key.GetLegNum();
                        foreach (var pair2 in orderMap.Order_OrderItem)
                        {
                            // 得找到OpenQuant层的单子
                            if (pair.Key == pair2.Value)
                            {
                                --cnt;
                                EmitExpired(pair2.Key);
                                if (cnt <= 0)
                                {
                                    break;
                                }
                            }
                        }
                        tmp[pair.Key] = pair.Value;
                    }
                }

                foreach (var pair in tmp)
                {
                    OnLastStatus(pair.Key, pair.Value.OrderSysID, pair.Value.OrderRef);
                }
                tmp.Clear();
            }
        }
Example #14
0
        //建立行情
        private void Connect_MD()
        {
            lock (_lockMd)
            {
                if (_bWantMdConnect &&
                    (null == m_pMdApi || IntPtr.Zero == m_pMdApi))
                {
                    m_pMdApi = MdApi.MD_CreateMdApi();
                    MdApi.CTP_RegOnRtnDepthMarketData(m_pMsgQueue, _fnOnRtnDepthMarketData_Holder);
                    MdApi.MD_RegMsgQueue2MdApi(m_pMdApi, m_pMsgQueue);
                    MdApi.MD_Connect(m_pMdApi, _newTempPath, string.Join(";", server.MarketData.ToArray()), server.BrokerID, account.InvestorId, account.Password);

                    //向单例对象中注入操作用句柄
                    CTPAPI.GetInstance().__RegMdApi(m_pMdApi);
                }
            }
        }
        private void Send(QuoteOrderItem item)
        {
            if (item == null)
            {
                return;
            }

            SingleOrder AskOrder = item.Sell.Order;
            SingleOrder BidOrder = item.Buy.Order;

            string symbol = item.Buy.Order.Symbol;

            double AskPrice  = AskOrder.Price;
            double BidPrice  = BidOrder.Price;
            int    AskVolume = (int)AskOrder.OrderQty;
            int    BidVolume = (int)BidOrder.OrderQty;

            TThostFtdcOffsetFlagType AskOffsetFlag = CTPAPI.ToCTP(item.Sell.OpenClose);
            TThostFtdcOffsetFlagType BidOffsetFlag = CTPAPI.ToCTP(item.Buy.OpenClose);

            TThostFtdcHedgeFlagType AskHedgeFlag = HedgeFlagType;
            TThostFtdcHedgeFlagType BidHedgeFlag = HedgeFlagType;

            int nRet = 0;

#if CTP
            nRet = TraderApi.TD_SendQuote(m_pTdApi,
                                          -1,
                                          symbol,
                                          AskPrice,
                                          BidPrice,
                                          AskVolume,
                                          BidVolume,
                                          AskOffsetFlag,
                                          BidOffsetFlag,
                                          AskHedgeFlag,
                                          BidHedgeFlag);
#endif
            if (nRet > 0)
            {
                orderMap.CreateNewOrder(string.Format("{0}:{1}:{2}", _RspUserLogin.FrontID, _RspUserLogin.SessionID, nRet), item);
            }
        }
        private void OnRspQryTradingAccount(IntPtr pTraderApi, ref CThostFtdcTradingAccountField pTradingAccount, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLastt)
        {
            if (0 == pRspInfo.ErrorID)
            {
                m_TradingAccount = pTradingAccount;

                //有资金信息过来了,重新计时
                timerAccount.Enabled = false;
                timerAccount.Enabled = true;

                //通知单例,还是使用GetBrokerInfo来取呢?
                CTPAPI.GetInstance().__RegTradingAccount(m_TradingAccount);
                CTPAPI.GetInstance().FireOnRspQryTradingAccount(pTradingAccount);
            }
            else
            {
                tdlog.Error("nRequestID:{0},ErrorID:{1},OnRspQryTradingAccount:{2}", nRequestID, pRspInfo.ErrorID, pRspInfo.ErrorMsg);
                EmitError(nRequestID, pRspInfo.ErrorID, "OnRspQryTradingAccount:" + pRspInfo.ErrorMsg);
            }
        }
        public void OnRspQryDepthMarketData(IntPtr pTraderApi, ref CThostFtdcDepthMarketDataField pDepthMarketData, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (0 == pRspInfo.ErrorID)
            {
                CThostFtdcDepthMarketDataField DepthMarket;
                if (!_dictDepthMarketData.TryGetValue(pDepthMarketData.InstrumentID, out DepthMarket))
                {
                    //没找到此元素,保存一下
                    _dictDepthMarketData[pDepthMarketData.InstrumentID] = pDepthMarketData;
                }

                tdlog.Info("已经接收查询深度行情 {0}", pDepthMarketData.InstrumentID);
                //通知单例
                CTPAPI.GetInstance().FireOnRspQryDepthMarketData(pDepthMarketData);
            }
            else
            {
                tdlog.Error("nRequestID:{0},ErrorID:{1},OnRspQryDepthMarketData:{2}", nRequestID, pRspInfo.ErrorID, pRspInfo.ErrorMsg);
                EmitError(nRequestID, pRspInfo.ErrorID, "OnRspQryDepthMarketData:" + pRspInfo.ErrorMsg);
            }
        }
Example #18
0
        private void _Disconnect()
        {
            timerConnect.Enabled    = false;
            timerDisconnect.Enabled = false;
            timerAccount.Enabled    = false;
            timerPonstion.Enabled   = false;

            CTPAPI.GetInstance().__RegInstrumentDictionary(null);
            CTPAPI.GetInstance().__RegInstrumentCommissionRateDictionary(null);
            CTPAPI.GetInstance().__RegInstrumentMarginRateDictionary(null);
            CTPAPI.GetInstance().__RegDepthMarketDataDictionary(null);

            Disconnect_MD();
            Disconnect_TD();
            Disconnect_MsgQueue();

            Clear();
            ChangeStatus(ProviderStatus.Disconnected);
            isConnected = false;
            EmitDisconnectedEvent();
        }
Example #19
0
        private void Send(CommonOrderItem item)
        {
            if (item == null)
            {
                return;
            }

            SingleOrder order = item.Leg.Order;

            string apiSymbol;
            string apiExchange;
            double apiTickSize;
            string altSymbol;

#if CTP
            GetInstrumentInfoForCTP(order.Instrument, out apiSymbol, out apiExchange, out apiTickSize);
            altSymbol = apiSymbol;
#elif CTPZQ
            GetInstrumentInfoForCTPZQ(order.Instrument, out apiSymbol, out apiExchange, out apiTickSize, out altSymbol);
#endif
            double price = order.Price;
            int    qty   = (int)order.OrderQty;

            //市价修正,如果不连接行情,此修正不执行,得策略层处理
            CThostFtdcDepthMarketDataField DepthMarket;
            //如果取出来了,并且为有效的,涨跌停价将不为0
            _dictDepthMarketData.TryGetValue(altSymbol, out DepthMarket);

            //市价单模拟
            if (OrdType.Market == order.OrdType)
            {
                //按买卖调整价格
                if (order.Side == Side.Buy)
                {
                    price = DepthMarket.LastPrice + LastPricePlusNTicks * apiTickSize;
                }
                else
                {
                    price = DepthMarket.LastPrice - LastPricePlusNTicks * apiTickSize;
                }
            }

            price = FixPrice(price, order.Side, apiTickSize, DepthMarket.LowerLimitPrice, DepthMarket.UpperLimitPrice);

            // 是否要做价格调整?
            byte[] bytes            = { (byte)CTPAPI.ToCTP(item.Leg.OpenClose) };
            string szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length);

            byte[] bytes2          = { (byte)HedgeFlagType };
            string szCombHedgeFlag = System.Text.Encoding.Default.GetString(bytes2, 0, bytes2.Length);

            TThostFtdcDirectionType           Direction           = order.Side == Side.Buy ? TThostFtdcDirectionType.Buy : TThostFtdcDirectionType.Sell;
            TThostFtdcOrderPriceTypeType      OrderPriceType      = TThostFtdcOrderPriceTypeType.LimitPrice;
            TThostFtdcTimeConditionType       TimeCondition       = TThostFtdcTimeConditionType.GFD;
            TThostFtdcContingentConditionType ContingentCondition = TThostFtdcContingentConditionType.Immediately;
            TThostFtdcVolumeConditionType     VolumeCondition     = TThostFtdcVolumeConditionType.AV;


#if CTP
            bool bSupportMarketOrder = SupportMarketOrder.Contains(apiExchange);
#elif CTPZQ
            bool bSupportMarketOrder = true;
#endif

            switch (order.TimeInForce)
            {
            case TimeInForce.IOC:
                TimeCondition   = TThostFtdcTimeConditionType.IOC;
                VolumeCondition = TThostFtdcVolumeConditionType.AV;
                break;

            case TimeInForce.FOK:
                TimeCondition   = TThostFtdcTimeConditionType.IOC;
                VolumeCondition = TThostFtdcVolumeConditionType.CV;
                break;

            default:
                break;
            }

            int nRet = 0;

            switch (order.OrdType)
            {
            case OrdType.Limit:
                break;

            case OrdType.Market:
                if (SwitchMakertOrderToLimitOrder || !bSupportMarketOrder)
                {
                }
                else
                {
                    price          = 0;
                    OrderPriceType = TThostFtdcOrderPriceTypeType.AnyPrice;
                    TimeCondition  = TThostFtdcTimeConditionType.IOC;
                }
                break;

            default:
                tdlog.Warn("没有实现{0}", order.OrdType);
                return;
            }

#if CTP
            nRet = TraderApi.TD_SendOrder(m_pTdApi,
                                          apiSymbol,
                                          Direction,
                                          szCombOffsetFlag,
                                          szCombHedgeFlag,
                                          qty,
                                          price,
                                          OrderPriceType,
                                          TimeCondition,
                                          ContingentCondition,
                                          order.StopPx,
                                          VolumeCondition);
#elif CTPZQ
            nRet = TraderApi.TD_SendOrder(m_pTdApi,
                                          apiSymbol,
                                          apiExchange,
                                          Direction,
                                          szCombOffsetFlag,
                                          szCombHedgeFlag,
                                          qty,
                                          string.Format("{0}", price),
                                          OrderPriceType,
                                          TimeCondition,
                                          ContingentCondition,
                                          order.StopPx,
                                          VolumeCondition);
#endif
            if (nRet > 0)
            {
                orderMap.CreateNewOrder(string.Format("{0}:{1}:{2}", _RspUserLogin.FrontID, _RspUserLogin.SessionID, nRet), item);
            }
        }
        private void _Connect()
        {
            // 限制低版本的OpenQuant不能使用,其它产品不做限制
            switch (Framework.Installation.MainProduct)
            {
            case "OpenQuant":
                if (Assembly.GetEntryAssembly().GetName().Version < new Version(3, 9, 3))
                {
                    MessageBox.Show("您的OpenQuant版本过低,请装最新版");
                    return;
                }
                break;

            case "QuantRouter":
                break;

            case "QuantBase":
                break;

            case "QuantTrader":
                break;
            }

            CTPAPI.GetInstance().__RegInstrumentDictionary(_dictInstruments);
            CTPAPI.GetInstance().__RegInstrumentCommissionRateDictionary(_dictCommissionRate);
            CTPAPI.GetInstance().__RegDepthMarketDataDictionary(_dictDepthMarketData);
            CTPAPI.GetInstance().__RegInvestorPositionDictionary(_dictPositions);
#if CTP
            CTPAPI.GetInstance().__RegInstrumentMarginRateDictionary(_dictMarginRate);
#endif

            server  = null;
            account = null;

            bool bCheckOk = false;

            do
            {
                if (0 == serversList.Count)
                {
                    MessageBox.Show("您还没有设置 服务器 信息,目前只选择第一条进行连接");
                    break;
                }
                if (0 == accountsList.Count)
                {
                    MessageBox.Show("您还没有设置 账号 信息,目前只选择第一条进行连接");
                    break;
                }

                server  = serversList[0];
                account = accountsList[0];

                if (string.IsNullOrEmpty(server.BrokerID))
                {
                    MessageBox.Show("BrokerID不能为空");
                    break;
                }

                if (_bWantTdConnect && 0 == server.Trading.Count())
                {
                    MessageBox.Show("交易服务器地址不全");
                    break;
                }

                if (_bWantMdConnect && 0 == server.MarketData.Count())
                {
                    MessageBox.Show("行情服务器信息不全");
                    break;
                }

                if (string.IsNullOrEmpty(account.InvestorId) ||
                    string.IsNullOrEmpty(account.Password))
                {
                    MessageBox.Show("账号信息不全");
                    break;
                }

                bCheckOk = true;
            } while (false);

            if (false == bCheckOk)
            {
                ChangeStatus(ProviderStatus.Disconnected);
                isConnected = false;
                return;
            }

            //新建目录
            _newTempPath = string.Format("{1}{0}{2}{0}{3}{0}{4}", Path.DirectorySeparatorChar, ApiTempPath, this.Name, server.BrokerID, account.InvestorId);
            Directory.CreateDirectory(_newTempPath);

            ChangeStatus(ProviderStatus.Connecting);
            //如果前面一次连接一直连不上,新改地址后也会没响应,所以先删除
            Disconnect_MD();
            Disconnect_TD();

            if (_bWantMdConnect || _bWantTdConnect)
            {
                timerDisconnect.Enabled = true;
                Connect_MsgQueue();
            }
            if (_bWantMdConnect)
            {
                Connect_MD();
            }
            if (_bWantTdConnect)
            {
                Connect_TD();
            }
        }
 private void OnRtnForQuoteRsp(IntPtr pMdUserApi, ref CThostFtdcForQuoteRspField pForQuoteRsp)
 {
     Console.WriteLine("OnRtnForQuoteRsp");
     // 询价请求
     CTPAPI.GetInstance().FireOnRtnForQuoteRsp(pForQuoteRsp);
 }
Example #22
0
        private void _Connect()
        {
            CTPAPI.GetInstance().__RegInstrumentDictionary(_dictInstruments);
            CTPAPI.GetInstance().__RegInstrumentCommissionRateDictionary(_dictCommissionRate);
            CTPAPI.GetInstance().__RegInstrumentMarginRateDictionary(_dictMarginRate);
            CTPAPI.GetInstance().__RegDepthMarketDataDictionary(_dictDepthMarketData);

            server  = null;
            account = null;

            bool bCheckOk = false;

            do
            {
                if (0 == serversList.Count)
                {
                    MessageBox.Show("您还没有设置 服务器 信息,目前只选择第一条进行连接");
                    break;
                }
                if (0 == accountsList.Count)
                {
                    MessageBox.Show("您还没有设置 账号 信息,目前只选择第一条进行连接");
                    break;
                }

                server  = serversList[0];
                account = accountsList[0];

                if (string.IsNullOrEmpty(server.BrokerID))
                {
                    MessageBox.Show("BrokerID不能为空");
                    break;
                }

                if (_bWantTdConnect && 0 == server.Trading.Count())
                {
                    MessageBox.Show("交易服务器地址不全");
                    break;
                }

                if (_bWantMdConnect && 0 == server.MarketData.Count())
                {
                    MessageBox.Show("行情服务器信息不全");
                    break;
                }

                if (string.IsNullOrEmpty(account.InvestorId) ||
                    string.IsNullOrEmpty(account.Password))
                {
                    MessageBox.Show("账号信息不全");
                    break;
                }

                bCheckOk = true;
            } while (false);

            if (false == bCheckOk)
            {
                ChangeStatus(ProviderStatus.Disconnected);
                isConnected = false;
                return;
            }

            //新建目录
            _newTempPath = ApiTempPath + Path.DirectorySeparatorChar + server.BrokerID + Path.DirectorySeparatorChar + account.InvestorId;
            Directory.CreateDirectory(_newTempPath);

            ChangeStatus(ProviderStatus.Connecting);
            //如果前面一次连接一直连不上,新改地址后也会没响应,所以先删除
            Disconnect_MD();
            Disconnect_TD();

            if (_bWantMdConnect || _bWantTdConnect)
            {
                timerDisconnect.Enabled = true;
                Connect_MsgQueue();
            }
            if (_bWantMdConnect)
            {
                Connect_MD();
            }
            if (_bWantTdConnect)
            {
                Connect_TD();
            }
        }
        private void OnRtnDepthMarketData(IntPtr pApi, ref CThostFtdcDepthMarketDataField pDepthMarketData)
        {
            DataRecord record;

            if (!_dictAltSymbol2Instrument.TryGetValue(pDepthMarketData.InstrumentID, out record))
            {
                mdlog.Warn("合约{0}不在订阅列表中却收到了数据", pDepthMarketData.InstrumentID);
                return;
            }

            Instrument instrument = record.Instrument;

            CThostFtdcDepthMarketDataField DepthMarket;

            _dictDepthMarketData.TryGetValue(pDepthMarketData.InstrumentID, out DepthMarket);

            //将更新字典的功能提前,因为如果一开始就OnTrade中下单,涨跌停没有更新
            _dictDepthMarketData[pDepthMarketData.InstrumentID] = pDepthMarketData;

            if (TimeMode.LocalTime == _TimeMode)
            {
                //为了生成正确的Bar,使用本地时间
                _dateTime = Clock.Now;
            }
            else
            {
                //直接按HH:mm:ss来解析,测试过这种方法目前是效率比较高的方法
                try
                {
                    // 只有使用交易所行情时才需要处理跨天的问题
                    ChangeTradingDay(pDepthMarketData.TradingDay);

                    int HH = int.Parse(pDepthMarketData.UpdateTime.Substring(0, 2));
                    int mm = int.Parse(pDepthMarketData.UpdateTime.Substring(3, 2));
                    int ss = int.Parse(pDepthMarketData.UpdateTime.Substring(6, 2));

                    _dateTime = new DateTime(_yyyy, _MM, _dd, HH, mm, ss, pDepthMarketData.UpdateMillisec);
                }
                catch (Exception)
                {
                    _dateTime = Clock.Now;
                }
            }

            if (record.TradeRequested)
            {
                //通过测试,发现IB的Trade与Quote在行情过来时数量是不同的,在这也做到不同
                if (DepthMarket.LastPrice == pDepthMarketData.LastPrice &&
                    DepthMarket.Volume == pDepthMarketData.Volume)
                {
                }
                else
                {
                    //行情过来时是今天累计成交量,得转换成每个tick中成交量之差
                    int volume = pDepthMarketData.Volume - DepthMarket.Volume;
                    if (0 == DepthMarket.Volume)
                    {
                        //没有接收到最开始的一条,所以这计算每个Bar的数据时肯定超大,强行设置为0
                        volume = 0;
                    }
                    else if (volume < 0)
                    {
                        //如果隔夜运行,会出现今早成交量0-昨收盘成交量,出现负数,所以当发现为负时要修改
                        volume = pDepthMarketData.Volume;
                    }

                    Trade trade = new Trade(_dateTime,
                                            pDepthMarketData.LastPrice == double.MaxValue ? 0 : pDepthMarketData.LastPrice,
                                            volume);

                    EmitNewTradeEvent(instrument, trade);
                }
            }

            if (record.QuoteRequested)
            {
                //if (
                //DepthMarket.BidVolume1 == pDepthMarketData.BidVolume1
                //&& DepthMarket.AskVolume1 == pDepthMarketData.AskVolume1
                //&& DepthMarket.BidPrice1 == pDepthMarketData.BidPrice1
                //&& DepthMarket.AskPrice1 == pDepthMarketData.AskPrice1
                //)
                //{ }
                //else
                {
                    Quote quote = new Quote(_dateTime,
                                            pDepthMarketData.BidPrice1 == double.MaxValue ? 0 : pDepthMarketData.BidPrice1,
                                            pDepthMarketData.BidVolume1,
                                            pDepthMarketData.AskPrice1 == double.MaxValue ? 0 : pDepthMarketData.AskPrice1,
                                            pDepthMarketData.AskVolume1
                                            );

                    EmitNewQuoteEvent(instrument, quote);
                }
            }

            if (record.MarketDepthRequested)
            {
                EmitNewMarketDepth(instrument, _dateTime, 0, MDSide.Ask, pDepthMarketData.AskPrice1, pDepthMarketData.AskVolume1);
                EmitNewMarketDepth(instrument, _dateTime, 0, MDSide.Bid, pDepthMarketData.BidPrice1, pDepthMarketData.BidVolume1);

                //EmitNewMarketDepth(instrument, _dateTime, 1, MDSide.Ask, pDepthMarketData.AskPrice2, pDepthMarketData.AskVolume2);
                //EmitNewMarketDepth(instrument, _dateTime, 1, MDSide.Bid, pDepthMarketData.BidPrice2, pDepthMarketData.BidVolume2);

                //EmitNewMarketDepth(instrument, _dateTime, 2, MDSide.Ask, pDepthMarketData.AskPrice3, pDepthMarketData.AskVolume3);
                //EmitNewMarketDepth(instrument, _dateTime, 2, MDSide.Bid, pDepthMarketData.BidPrice3, pDepthMarketData.BidVolume3);

                //EmitNewMarketDepth(instrument, _dateTime, 3, MDSide.Ask, pDepthMarketData.AskPrice4, pDepthMarketData.AskVolume4);
                //EmitNewMarketDepth(instrument, _dateTime, 3, MDSide.Bid, pDepthMarketData.BidPrice4, pDepthMarketData.BidVolume4);

                //EmitNewMarketDepth(instrument, _dateTime, 4, MDSide.Ask, pDepthMarketData.AskPrice5, pDepthMarketData.AskVolume5);
                //EmitNewMarketDepth(instrument, _dateTime, 4, MDSide.Bid, pDepthMarketData.BidPrice5, pDepthMarketData.BidVolume5);
            }

            // 价差生成功能
            do
            {
                if (null == CTPAPI.GetInstance().SpreadMarketData)
                {
                    break;
                }

                ISpreadMarketData SpreadMarketData = CTPAPI.GetInstance().SpreadMarketData;
                var ticks = SpreadMarketData.CalculateSpread(pDepthMarketData);
                if (null == ticks)
                {
                    break;
                }

                foreach (var tick in ticks)
                {
                    Instrument inst = InstrumentManager.Instruments[tick.Symbol];
                    if (null == inst)
                    {
                        continue;
                    }

                    if (!double.IsNaN(tick.Price))
                    {
                        Trade trade = new Trade(_dateTime, tick.Price, tick.Size);
                        trade.ProviderId = tick.ProviderId;

                        EmitNewTradeEvent(inst, trade);
                    }
                    if (!double.IsNaN(tick.Ask) && !double.IsNaN(tick.Bid))
                    {
                        Quote quote = new Quote(_dateTime,
                                                tick.Bid, tick.BidSize,
                                                tick.Ask, tick.AskSize);
                        quote.ProviderId = tick.ProviderId;

                        EmitNewQuoteEvent(inst, quote);
                    }
                }
            } while (false);

            // 直接回报CTP的行情信息
            if (EmitOnRtnDepthMarketData)
            {
                CTPAPI.GetInstance().FireOnRtnDepthMarketData(pDepthMarketData);
            }
        }