Exemple #1
0
        private void Send(NewOrderSingle order)
        {
            if (!_bTdConnected)
            {
                EmitError(-1, -1, "交易服务器没有连接,无法报单");
                tdlog.Error("交易服务器没有连接,无法报单");
                return;
            }

            Instrument inst        = InstrumentManager.Instruments[order.Symbol];
            string     altSymbol   = inst.GetSymbol(Name);
            string     altExchange = inst.GetSecurityExchange(Name);
            double     tickSize    = inst.TickSize;

            CThostFtdcInstrumentField _Instrument;

            if (_dictInstruments.TryGetValue(altSymbol, out _Instrument))
            {
                //从合约列表中取交易所名与tickSize,不再依赖用户手工设置的参数了
                tickSize    = _Instrument.PriceTick;
                altExchange = _Instrument.ExchangeID;
            }

            //最小变动价格修正
            double price = order.Price;

            //市价修正,如果不连接行情,此修正不执行,得策略层处理
            CThostFtdcDepthMarketDataField DepthMarket;

            //如果取出来了,并且为有效的,涨跌停价将不为0
            _dictDepthMarketData.TryGetValue(altSymbol, out DepthMarket);

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

            //没有设置就直接用
            if (tickSize > 0)
            {
                decimal remainder = ((decimal)price % (decimal)tickSize);
                if (remainder != 0)
                {
                    if (order.Side == Side.Buy)
                    {
                        price = Math.Ceiling(price / tickSize) * tickSize;
                    }
                    else
                    {
                        price = Math.Floor(price / tickSize) * tickSize;
                    }
                }
                else
                {
                    //正好能整除,不操作
                }
            }

            if (0 == DepthMarket.UpperLimitPrice &&
                0 == DepthMarket.LowerLimitPrice)
            {
                //涨跌停无效
            }
            else
            {
                //防止价格超过涨跌停
                if (price >= DepthMarket.UpperLimitPrice)
                {
                    price = DepthMarket.UpperLimitPrice;
                }
                else if (price <= DepthMarket.LowerLimitPrice)
                {
                    price = DepthMarket.LowerLimitPrice;
                }
            }

            int YdPosition    = 0;
            int TodayPosition = 0;

            string szCombOffsetFlag;

            if (order.Side == Side.Buy)
            {
                //买,先看有没有空单,有就平空单,没有空单,直接买开多单
                _dbInMemInvestorPosition.GetPositions(altSymbol,
                                                      TThostFtdcPosiDirectionType.Short, HedgeFlagType, out YdPosition, out TodayPosition);//TThostFtdcHedgeFlagType.Speculation
            }
            else//是否要区分Side.Sell与Side.SellShort呢?
            {
                //卖,先看有没有多单,有就平多单,没有多单,直接买开空单
                _dbInMemInvestorPosition.GetPositions(altSymbol,
                                                      TThostFtdcPosiDirectionType.Long, HedgeFlagType, out YdPosition, out TodayPosition);
            }

            List <SOrderSplitItem> OrderSplitList = new List <SOrderSplitItem>();
            SOrderSplitItem        orderSplitItem;

            //根据 梦翔 与 马不停蹄 的提示,新加在Text域中指定开平标志的功能
            int nOpenCloseFlag = 0;

            if (order.Text.StartsWith(OpenPrefix))
            {
                nOpenCloseFlag = 1;
            }
            else if (order.Text.StartsWith(ClosePrefix))
            {
                nOpenCloseFlag = -1;
            }
            else if (order.Text.StartsWith(CloseTodayPrefix))
            {
                nOpenCloseFlag = -2;
            }
            else if (order.Text.StartsWith(CloseYesterdayPrefix))
            {
                nOpenCloseFlag = -3;
            }

            int leave = (int)order.OrderQty;

            //是否上海?上海先平今,然后平昨,最后开仓
            //使用do主要是想利用break功能
            //平仓部分
            do
            {
                //指定开仓,直接跳过
                if (nOpenCloseFlag > 0)
                {
                    break;
                }

                //表示指定平今与平昨
                if (nOpenCloseFlag < -1)
                {
                    if (-2 == nOpenCloseFlag)
                    {
                        byte[] bytes = { (byte)TThostFtdcOffsetFlagType.CloseToday, (byte)TThostFtdcOffsetFlagType.CloseToday };
                        szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length);
                    }
                    else
                    {
                        //肯定是-3了
                        byte[] bytes = { (byte)TThostFtdcOffsetFlagType.CloseYesterday, (byte)TThostFtdcOffsetFlagType.CloseYesterday };
                        szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length);
                    }

                    orderSplitItem.qty = leave;
                    orderSplitItem.szCombOffsetFlag = szCombOffsetFlag;
                    OrderSplitList.Add(orderSplitItem);

                    leave = 0;

                    break;
                }

                if (SupportCloseToday.Contains(altExchange))
                {
                    //先看平今
                    if (leave > 0 && TodayPosition > 0)
                    {
                        int min = Math.Min(TodayPosition, leave);
                        leave -= min;

                        byte[] bytes = { (byte)TThostFtdcOffsetFlagType.CloseToday, (byte)TThostFtdcOffsetFlagType.CloseToday };
                        szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length);

                        orderSplitItem.qty = min;
                        orderSplitItem.szCombOffsetFlag = szCombOffsetFlag;
                        OrderSplitList.Add(orderSplitItem);
                    }
                    if (leave > 0 && YdPosition > 0)
                    {
                        int min = Math.Min(YdPosition, leave);
                        leave -= min;

                        byte[] bytes = { (byte)TThostFtdcOffsetFlagType.CloseYesterday, (byte)TThostFtdcOffsetFlagType.CloseYesterday };
                        szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length);

                        orderSplitItem.qty = min;
                        orderSplitItem.szCombOffsetFlag = szCombOffsetFlag;
                        OrderSplitList.Add(orderSplitItem);
                    }
                }
                else
                {
                    //平仓
                    int position = TodayPosition + YdPosition;
                    if (leave > 0 && position > 0)
                    {
                        int min = Math.Min(position, leave);
                        leave -= min;

                        byte[] bytes = { (byte)TThostFtdcOffsetFlagType.Close, (byte)TThostFtdcOffsetFlagType.Close };
                        szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length);

                        orderSplitItem.qty = min;
                        orderSplitItem.szCombOffsetFlag = szCombOffsetFlag;
                        OrderSplitList.Add(orderSplitItem);
                    }
                }
            } while (false);

            do
            {
                //指定平仓,直接跳过
                if (nOpenCloseFlag < 0)
                {
                    break;
                }

                if (leave > 0)
                {
                    byte[] bytes = { (byte)TThostFtdcOffsetFlagType.Open, (byte)TThostFtdcOffsetFlagType.Open };
                    szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length);

                    orderSplitItem.qty = leave;
                    orderSplitItem.szCombOffsetFlag = szCombOffsetFlag;
                    OrderSplitList.Add(orderSplitItem);

                    leave = 0;
                }
            } while (false);

            if (leave > 0)
            {
                tdlog.Info("CTP:还剩余{0}手,你应当是强制指定平仓了,但持仓数小于要平手数", leave);
            }

            //将第二腿也设置成一样,这样在使用组合时这地方不用再调整
            byte[] bytes2          = { (byte)HedgeFlagType, (byte)HedgeFlagType };
            string szCombHedgeFlag = System.Text.Encoding.Default.GetString(bytes2, 0, bytes2.Length);

            bool bSupportMarketOrder = SupportMarketOrder.Contains(altExchange);

            tdlog.Info("Side:{0},Price:{1},LastPrice:{2},Qty:{3},Text:{4},YdPosition:{5},TodayPosition:{6}",
                       order.Side, order.Price, DepthMarket.LastPrice, order.OrderQty, order.Text, YdPosition, TodayPosition);

            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;

            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;
            }

            foreach (SOrderSplitItem it in OrderSplitList)
            {
                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;
                }

                nRet = TraderApi.TD_SendOrder(m_pTdApi,
                                              altSymbol,
                                              Direction,
                                              it.szCombOffsetFlag,
                                              szCombHedgeFlag,
                                              it.qty,
                                              price,
                                              OrderPriceType,
                                              TimeCondition,
                                              ContingentCondition,
                                              order.StopPx,
                                              VolumeCondition);

                if (nRet > 0)
                {
                    _OrderRef2Order.Add(string.Format("{0}:{1}:{2}", _RspUserLogin.FrontID, _RspUserLogin.SessionID, nRet), order as SingleOrder);
                }
            }
        }
Exemple #2
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 Send(NewOrderSingle order)
        {
            if (order == null)
            {
                return;
            }

            if (!_bTdConnected)
            {
                EmitError(-1, -1, "交易服务器没有连接,无法报单");
                tdlog.Error("交易服务器没有连接,无法报单");
                return;
            }

            Instrument inst        = InstrumentManager.Instruments[order.Symbol];
            string     altSymbol   = inst.GetSymbol(Name);
            string     altExchange = inst.GetSecurityExchange(Name);
            double     tickSize    = inst.TickSize;
            string     type        = inst.SecurityType;

            //    CThostFtdcInstrumentField _Instrument;
            //    if (_dictInstruments.TryGetValue(altSymbol, out _Instrument))
            //    {
            //        //从合约列表中取交易所名与tickSize,不再依赖用户手工设置的参数了
            //        tickSize = _Instrument.PriceTick;
            //        altExchange = _Instrument.ExchangeID;
            //    }

            //最小变动价格修正
            double price = order.Price;

            //市价修正,如果不连接行情,此修正不执行,得策略层处理
            DFITCDepthMarketDataField DepthMarket;

            //如果取出来了,并且为有效的,涨跌停价将不为0
            _dictDepthMarketData.TryGetValue(altSymbol, out DepthMarket);

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

            //没有设置就直接用
            if (tickSize > 0)
            {
                decimal remainder = ((decimal)price % (decimal)tickSize);
                if (remainder != 0)
                {
                    if (order.Side == Side.Buy)
                    {
                        price = Math.Ceiling(price / tickSize) * tickSize;
                    }
                    else
                    {
                        price = Math.Floor(price / tickSize) * tickSize;
                    }
                }
                else
                {
                    //正好能整除,不操作
                }
            }

            if (0 == DepthMarket.UpperLimitPrice &&
                0 == DepthMarket.LowerLimitPrice)
            {
                //涨跌停无效
            }
            else
            {
                //防止价格超过涨跌停
                if (price >= DepthMarket.UpperLimitPrice)
                {
                    price = DepthMarket.UpperLimitPrice;
                }
                else if (price <= DepthMarket.LowerLimitPrice)
                {
                    price = DepthMarket.LowerLimitPrice;
                }
            }


            DFITCOpenCloseTypeType szCombOffsetFlag;

            //根据 梦翔 与 马不停蹄 的提示,新加在Text域中指定开平标志的功能
            if (order.Text.StartsWith(OpenPrefix))
            {
                szCombOffsetFlag = DFITCOpenCloseTypeType.OPEN;
            }
            else if (order.Text.StartsWith(ClosePrefix))
            {
                szCombOffsetFlag = DFITCOpenCloseTypeType.CLOSE;
            }
            else if (order.Text.StartsWith(CloseTodayPrefix))
            {
                szCombOffsetFlag = DFITCOpenCloseTypeType.CLOSETODAY;
            }
            else if (order.Text.StartsWith(CloseYesterdayPrefix))
            {
                szCombOffsetFlag = DFITCOpenCloseTypeType.CLOSE;
            }
            else if (order.Text.StartsWith(ExecutePrefix))
            {
                szCombOffsetFlag = DFITCOpenCloseTypeType.EXECUTE;
            }
            else
            {
                szCombOffsetFlag = DFITCOpenCloseTypeType.OPEN;
            }

            int leave = (int)order.OrderQty;

            DFITCSpeculatorType szCombHedgeFlag = SpeculatorType;

            bool bSupportMarketOrder = SupportMarketOrder.Contains(altExchange);

            tdlog.Info("Side:{0},Price:{1},LastPrice:{2},Qty:{3},Text:{4}",
                       order.Side, order.Price, DepthMarket.LastPrice, order.OrderQty, order.Text);

            DFITCBuySellTypeType    sBuySellType    = order.Side == Side.Buy ? DFITCBuySellTypeType.BUY : DFITCBuySellTypeType.SELL;
            DFITCOrderTypeType      orderType       = DFITCOrderTypeType.LIMITORDER;
            DFITCOrderPropertyType  orderProperty   = DFITCOrderPropertyType.NON;
            DFITCInstrumentTypeType nInstrumentType = (FIXSecurityType.FutureOption == type) ? DFITCInstrumentTypeType.OPT_TYPE : DFITCInstrumentTypeType.COMM_TYPE;

            switch (order.TimeInForce)
            {
            case TimeInForce.IOC:
                orderProperty = DFITCOrderPropertyType.FAK;
                break;

            case TimeInForce.FOK:
                orderProperty = DFITCOrderPropertyType.FOK;
                break;

            default:
                break;
            }

            int nRet = 0;

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

            case OrdType.Market:
                if (SwitchMakertOrderToLimitOrder || !bSupportMarketOrder)
                {
                }
                else
                {
                    //price = 0;
                    orderType = DFITCOrderTypeType.MKORDER;
                }
                break;

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

            nRet = TraderApi.TD_SendOrder(m_pTdApi, -1,
                                          altSymbol,
                                          sBuySellType,
                                          szCombOffsetFlag,
                                          szCombHedgeFlag,
                                          leave,
                                          price,
                                          orderType,
                                          orderProperty,
                                          nInstrumentType);

            if (nRet > 0)
            {
                _OrderRef2Order[string.Format("{0}:{1}", _RspUserLogin.sessionID, nRet)] = order as SingleOrder;
            }
        }