public int SendOrder( string szInstrument, TThostFtdcDirectionType Direction, string szCombOffsetFlag, string szCombHedgeFlag, int VolumeTotalOriginal, double LimitPrice, TThostFtdcOrderPriceTypeType OrderPriceType, TThostFtdcTimeConditionType TimeCondition, TThostFtdcContingentConditionType ContingentCondition, double StopPrice, TThostFtdcVolumeConditionType VolumeCondition) { if (null == m_pTdApi || IntPtr.Zero == m_pTdApi) { return(0); } return(TraderApi.TD_SendOrder( m_pTdApi, szInstrument, Direction, szCombOffsetFlag, szCombHedgeFlag, VolumeTotalOriginal, LimitPrice, OrderPriceType, TimeCondition, ContingentCondition, StopPrice, VolumeCondition)); }
public int SendOrder( int OrderRef, string szInstrument, TThostFtdcDirectionType Direction, string szCombOffsetFlag, string szCombHedgeFlag, int VolumeTotalOriginal, double LimitPrice, TThostFtdcOrderPriceTypeType OrderPriceType, TThostFtdcTimeConditionType TimeCondition, TThostFtdcContingentConditionType ContingentCondition, double StopPrice, TThostFtdcVolumeConditionType VolumeCondition) { return(m_Api.SendOrder( OrderRef, szInstrument, Direction, szCombOffsetFlag, szCombHedgeFlag, VolumeTotalOriginal, LimitPrice, OrderPriceType, TimeCondition, ContingentCondition, StopPrice, VolumeCondition)); }
protected double GetAnyPrice(double price, TThostFtdcDirectionType direction) { if (direction == TThostFtdcDirectionType.Buy) { return price + InstrumentStrategy.PriceTick * 2; } else { return price - InstrumentStrategy.PriceTick * 2; } }
public static extern int TD_SendOrder(IntPtr pTraderApi, string szInstrument, TThostFtdcDirectionType Direction, string szCombOffsetFlag, string szCombHedgeFlag, int VolumeTotalOriginal, double LimitPrice, TThostFtdcOrderPriceTypeType OrderPriceType, TThostFtdcTimeConditionType TimeCondition, TThostFtdcContingentConditionType ContingentCondition, double StopPrice);
protected double GetAnyPrice(MarketData marketData, TThostFtdcDirectionType direction) { if (direction == TThostFtdcDirectionType.Buy) { return marketData.LastPrice + InstrumentStrategy.PriceTick * 3; } else { return marketData.LastPrice - InstrumentStrategy.PriceTick * 3; } }
//构造开仓单:限价单 public OrderField OpenPositionOrder(string InstrumentID, double OpenPrice, int VolumeToOpen, TThostFtdcDirectionType OrderDirection, TThostFtdcOrderPriceTypeType OrderPriceType) { OrderField orderField = new OrderField(); orderField.InstrumentID = InstrumentID; orderField.OrderPriceType = OrderPriceType; orderField.CombOffsetFlag = new String((char)TThostFtdcOffsetFlagType.THOST_FTDC_OF_Open, 1);; orderField.Direction = OrderDirection; orderField.LimitPrice = OpenPrice; orderField.VolumeTotalOriginal = VolumeToOpen; return(orderField); }
public static Side FromCTP(TThostFtdcDirectionType Direction) { switch (Direction) { case TThostFtdcDirectionType.Buy: return(Side.Buy); case TThostFtdcDirectionType.Sell: return(Side.Sell); default: return(Side.Undefined); } }
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); } }
/// <summary> /// 将TThostFtdcDirectionType枚举型转为Direction枚举型 /// </summary> /// <param name="tfdt">TThostFtdcDirectionType枚举型实例</param> /// <returns></returns> public static Direction TThostFtdcDirectionType_To_Direction(TThostFtdcDirectionType tfdt) { Direction dir = Direction.Buy; switch (tfdt) { case TThostFtdcDirectionType.THOST_FTDC_D_Buy: break; case TThostFtdcDirectionType.THOST_FTDC_D_Sell: dir = Direction.Sell; break; default: break; } return(dir); }
/// <summary> /// Direction枚举型转为TThostFtdcDirectionType枚举型 /// </summary> /// <param name="dir"></param> /// <returns></returns> public static TThostFtdcDirectionType Direction_To_TThostFtdcDirectionType(Direction dir) { TThostFtdcDirectionType tfdt = TThostFtdcDirectionType.THOST_FTDC_D_Buy; switch (dir) { case Direction.Buy: break; case Direction.Sell: tfdt = TThostFtdcDirectionType.THOST_FTDC_D_Sell; break; default: break; } return(tfdt); }
/// <summary> /// 下预埋单 /// </summary> public void SendParkedOrder(OrderField of) { //OrderRef如果没有填(null),则为"" string _orderRef = (of.OrderRef != null ? of.OrderRef : string.Empty); //当日有效(默认) TThostFtdcTimeConditionType _timeCondition = (of.OrderFieldInstance.TimeCondition == 0 ? TThostFtdcTimeConditionType.THOST_FTDC_TC_GFD : of.OrderFieldInstance.TimeCondition); //立即执行 TThostFtdcContingentConditionType _contingentCondition = (of.OrderFieldInstance.ContingentCondition == 0 ? TThostFtdcContingentConditionType.THOST_FTDC_CC_Immediately : of.OrderFieldInstance.ContingentCondition); //是否强平 TThostFtdcForceCloseReasonType _forceCloseReason = (of.OrderFieldInstance.ForceCloseReason == 0 ? TThostFtdcForceCloseReasonType.THOST_FTDC_FCC_NotForceClose : of.OrderFieldInstance.ForceCloseReason); //报单价格类型:默认是限价单 TThostFtdcOrderPriceTypeType _orderPriceTypeType = (of.OrderFieldInstance.OrderPriceType == 0 ? TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice : of.OrderFieldInstance.OrderPriceType); //任何数量 TThostFtdcVolumeConditionType _volumeCondition = (of.OrderFieldInstance.VolumeCondition == 0 ? TThostFtdcVolumeConditionType.THOST_FTDC_VC_AV : of.OrderFieldInstance.VolumeCondition); //方向 TThostFtdcDirectionType _directionType = (of.Direction == 0 ? TThostFtdcDirectionType.THOST_FTDC_D_Buy : of.OrderFieldInstance.Direction); //默认是投机单:1 string _combHedgeFlag = (of.CombHedgeFlag == 0 ? "1" : ((int)of.CombHedgeFlag).ToString()); base.ReqParkedOrderInsert( BrokerID: this._broker, InvestorID: this._investor, InstrumentID: of.InstrumentID, OrderRef: _orderRef, CombHedgeFlag: _combHedgeFlag, CombOffsetFlag: ((int)of.CombOffsetFlag).ToString(), Direction: _directionType, VolumeTotalOriginal: of.VolumeTotalOriginal, ForceCloseReason: _forceCloseReason, ContingentCondition: _contingentCondition, VolumeCondition: _volumeCondition, LimitPrice: of.LimitPrice, IsSwapOrder: 0, MinVolume: 1, UserForceClose: of.UserForceClose, TimeCondition: _timeCondition, OrderPriceType: _orderPriceTypeType ); }
public void CancelOrder(string Instrument, TThostFtdcDirectionType Direction, string OffsetFlag) { m_Api.CancelOrder(Instrument, Direction, OffsetFlag); }
public void OpenOrder(string instrumentId, TThostFtdcDirectionType direction) { var order = new Order(); order.OffsetFlag = TThostFtdcOffsetFlagType.Open; order.Direction = direction; order.InstrumentId = instrumentId; order.Price = 0; order.Volume = 1; order.StrategyType = "Open Order By User"; OrderInsert(order); }
/// <summary> /// 开平仓:市价单 /// </summary> /// <param name="InstrumentID">合约代码</param> /// <param name="OffsetFlag">平仓:仅上期所平今时使用CloseToday/其它情况均使用Close</param> /// <param name="Direction">买卖</param> /// <param name="Price">价格</param> /// <param name="Volume">手数</param> public int OrderInsert(string InstrumentID, TThostFtdcOffsetFlagType OffsetFlag, TThostFtdcDirectionType Direction, int Volume) { return m_Api.SendOrder( ++this.MaxOrderRef, InstrumentID, Direction, OffsetFlag, TThostFtdcHedgeFlagType.Speculation, Volume, 0, TThostFtdcOrderPriceTypeType.AnyPrice, TThostFtdcTimeConditionType.IOC, TThostFtdcContingentConditionType.Immediately, 0, TThostFtdcVolumeConditionType.AV); }
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); } }
/// <summary> /// 预埋单录入请求 /// </summary> /// <param name="InstrumentID"></param> /// <param name="OffsetFlag"></param> /// <param name="Direction"></param> /// <param name="Price"></param> /// <param name="Volume"></param> public int ParkedOrderInsert(string InstrumentID, TThostFtdcOffsetFlagType OffsetFlag, TThostFtdcDirectionType Direction, double Price, int Volume) { CThostFtdcParkedOrderField tmp = new CThostFtdcParkedOrderField(); tmp.BrokerID = this.BrokerID; tmp.BusinessUnit = null; tmp.ContingentCondition = TThostFtdcContingentConditionType.ParkedOrder; tmp.ForceCloseReason = TThostFtdcForceCloseReasonType.NotForceClose; tmp.InvestorID = this.InvestorID; tmp.IsAutoSuspend = (int)TThostFtdcBoolType.No; tmp.MinVolume = 1; tmp.OrderPriceType = TThostFtdcOrderPriceTypeType.LimitPrice; tmp.OrderRef = (++this.MaxOrderRef).ToString(); tmp.TimeCondition = TThostFtdcTimeConditionType.GFD; tmp.UserForceClose = (int)TThostFtdcBoolType.No; tmp.UserID = this.InvestorID; tmp.VolumeCondition = TThostFtdcVolumeConditionType.AV; tmp.CombHedgeFlag_0 = TThostFtdcHedgeFlagType.Speculation; tmp.InstrumentID = InstrumentID; tmp.CombOffsetFlag_0 = OffsetFlag; tmp.Direction = Direction; tmp.LimitPrice = Price; tmp.VolumeTotalOriginal = Volume; return reqParkedOrderInsert(ref tmp); }
//根据持仓和预期手数生成Orders【核心】 public OrderField[] CreateOrders(Position[] currentPositions, Position[] expectedPositions) { List <OrderField> resultOrders = new List <OrderField>(); //1、当前组合中持有的,但是期望中不持有:全部平掉! Position[] curPositionsToClose = currentPositions.Except(expectedPositions, new Position()).ToArray(); for (int i = 0; i < curPositionsToClose.Length; i++) { Position pos = curPositionsToClose[i]; //平昨 if (pos.YdPosition > 0) { resultOrders.Add(ClosePositionOrder(pos.InstrumentID, pos.YdPosition, pos.PosiDirection, TThostFtdcOffsetFlagType.THOST_FTDC_OF_Close, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } //平今 if (pos.TdPosition > 0) { resultOrders.Add(ClosePositionOrder(pos.InstrumentID, pos.TdPosition, pos.PosiDirection, TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } } //2、当前组合中不持有,但是期望中要持有:全部开仓! Position[] expPositionToOpen = expectedPositions.Except(currentPositions, new Position()).ToArray(); for (int i = 0; i < expPositionToOpen.Length; i++) { Position pos = expPositionToOpen[i]; TThostFtdcDirectionType orderDirection = default(TThostFtdcDirectionType); if (pos.PosiDirection == TThostFtdcPosiDirectionType.THOST_FTDC_PD_Long) { orderDirection = TThostFtdcDirectionType.THOST_FTDC_D_Buy; } else if (pos.PosiDirection == TThostFtdcPosiDirectionType.THOST_FTDC_PD_Short) { orderDirection = TThostFtdcDirectionType.THOST_FTDC_D_Sell; } resultOrders.Add(OpenPositionOrder(pos.InstrumentID, pos.AvgOpenPrice, pos.TdPosition, orderDirection, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } //3、当前组合与期望组合重合部分(instrumentID和positionSide相同) Position[] ol_curPosition = currentPositions.Intersect(expectedPositions, new Position()).OrderBy(p => p.InstrumentID).ThenBy(p => p.PosiDirection).ToArray(); Position[] ol_expPosition = expectedPositions.Intersect(currentPositions, new Position()).OrderBy(p => p.InstrumentID).ThenBy(p => p.PosiDirection).ToArray(); if (ol_curPosition.Length != ol_expPosition.Length) { throw new Exception("长度不匹配!"); } for (int i = 0; i < ol_curPosition.Length; i++) { Position curPos = ol_curPosition[i]; Position expPos = ol_expPosition[i]; string instID = curPos.InstrumentID; int x = curPos.TotalPosition; int y = expPos.TotalPosition; if (x < 0) {//当前组合中该合约为“空头” #region if (x > y) {//继续开空x-y手 resultOrders.Add(OpenPositionOrder(instID, expPos.AvgOpenPrice, x - y, TThostFtdcDirectionType.THOST_FTDC_D_Sell, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } else if (x < y) { if (y - x <= -x)//只要平掉y-x手空头 { if (curPos.YdPosition > 0) { resultOrders.Add(ClosePositionOrder(instID, (int)Math.Min(curPos.YdPosition, y - x), TThostFtdcPosiDirectionType.THOST_FTDC_PD_Short, TThostFtdcOffsetFlagType.THOST_FTDC_OF_Close, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } if (curPos.TdPosition > 0 && (y - x) - (int)Math.Min(curPos.YdPosition, y - x) > 0) { resultOrders.Add(ClosePositionOrder(instID, (y - x) - (int)Math.Min(curPos.YdPosition, y - x), TThostFtdcPosiDirectionType.THOST_FTDC_PD_Short, TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } } else//(y-x>-x)先平掉-x手空头(即所有空头),再开y手多头 { //先平掉所有空头 if (curPos.YdPosition > 0) { resultOrders.Add(ClosePositionOrder(instID, curPos.YdPosition, TThostFtdcPosiDirectionType.THOST_FTDC_PD_Short, TThostFtdcOffsetFlagType.THOST_FTDC_OF_Close, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } if (curPos.TdPosition > 0) { resultOrders.Add(ClosePositionOrder(instID, curPos.TdPosition, TThostFtdcPosiDirectionType.THOST_FTDC_PD_Short, TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } //再开y手多头 resultOrders.Add(OpenPositionOrder(instID, expPos.AvgOpenPrice, y, TThostFtdcDirectionType.THOST_FTDC_D_Buy, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } } #endregion } else if (x > 0) {//当前组合中该合约为“多头” #region if (x < y) {//继续开多y-x手 resultOrders.Add(OpenPositionOrder(instID, expPos.AvgOpenPrice, y - x, TThostFtdcDirectionType.THOST_FTDC_D_Buy, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } else if (x > y) { if (x - y <= x)//只要平掉x-y手空头 { if (curPos.YdPosition > 0) { resultOrders.Add(ClosePositionOrder(instID, (int)Math.Min(curPos.YdPosition, x - y), TThostFtdcPosiDirectionType.THOST_FTDC_PD_Long, TThostFtdcOffsetFlagType.THOST_FTDC_OF_Close, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } if (curPos.TdPosition > 0 && (x - y) - (int)Math.Min(curPos.YdPosition, x - y) > 0) { resultOrders.Add(ClosePositionOrder(instID, (x - y) - (int)Math.Min(curPos.YdPosition, x - y), TThostFtdcPosiDirectionType.THOST_FTDC_PD_Long, TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } } else//(x - y > x )先平掉x手多头(即所有多头),再开-y手空头 { //先平掉所有多头 if (curPos.YdPosition > 0) { resultOrders.Add(ClosePositionOrder(instID, curPos.YdPosition, TThostFtdcPosiDirectionType.THOST_FTDC_PD_Long, TThostFtdcOffsetFlagType.THOST_FTDC_OF_Close, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } if (curPos.TdPosition > 0) { resultOrders.Add(ClosePositionOrder(instID, curPos.TdPosition, TThostFtdcPosiDirectionType.THOST_FTDC_PD_Long, TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } //再开-y手空头 resultOrders.Add(OpenPositionOrder(instID, expPos.AvgOpenPrice, -y, TThostFtdcDirectionType.THOST_FTDC_D_Sell, TThostFtdcOrderPriceTypeType.THOST_FTDC_OPT_LimitPrice)); } } #endregion } } return(resultOrders.ToArray()); }
public int SendOrder( string szInstrument, TThostFtdcDirectionType Direction, string szCombOffsetFlag, string szCombHedgeFlag, int VolumeTotalOriginal, double LimitPrice, TThostFtdcOrderPriceTypeType OrderPriceType, TThostFtdcTimeConditionType TimeCondition, TThostFtdcContingentConditionType ContingentCondition, double StopPrice) { if (null == m_pTdApi || IntPtr.Zero == m_pTdApi) { return 0; } return TraderApi.TD_SendOrder( m_pTdApi, szInstrument, Direction, szCombOffsetFlag, szCombHedgeFlag, VolumeTotalOriginal, LimitPrice, OrderPriceType, TimeCondition, ContingentCondition, StopPrice); }
public int SendOrder( int OrderRef, string szInstrument, TThostFtdcDirectionType Direction, TThostFtdcOffsetFlagType OffsetFlag, TThostFtdcHedgeFlagType HedgeFlag, int VolumeTotalOriginal, double LimitPrice, TThostFtdcOrderPriceTypeType OrderPriceType, TThostFtdcTimeConditionType TimeCondition, TThostFtdcContingentConditionType ContingentCondition, double StopPrice, TThostFtdcVolumeConditionType VolumeCondition) { if (null == IntPtrKey || IntPtr.Zero == IntPtrKey) { return 0; } char szOffsetFlag = (char) OffsetFlag; char hedgeFlag = (char) HedgeFlag; return TraderApi.TD_SendOrder( IntPtrKey, OrderRef, szInstrument, Direction, szOffsetFlag.ToString(), hedgeFlag.ToString(), VolumeTotalOriginal, LimitPrice, OrderPriceType, TimeCondition, ContingentCondition, StopPrice, VolumeCondition); }
public static Side FromCTP(TThostFtdcDirectionType Direction) { switch (Direction) { case TThostFtdcDirectionType.Buy: return Side.Buy; case TThostFtdcDirectionType.Sell: return Side.Sell; default: return Side.Undefined; } }
public int SendOrder( int OrderRef, string szInstrument, TThostFtdcDirectionType Direction, string szCombOffsetFlag, string szCombHedgeFlag, int VolumeTotalOriginal, double LimitPrice, TThostFtdcOrderPriceTypeType OrderPriceType, TThostFtdcTimeConditionType TimeCondition, TThostFtdcContingentConditionType ContingentCondition, double StopPrice, TThostFtdcVolumeConditionType VolumeCondition) { return m_Api.SendOrder( OrderRef, szInstrument, Direction, szCombOffsetFlag, szCombHedgeFlag, VolumeTotalOriginal, LimitPrice, OrderPriceType, TimeCondition, ContingentCondition, StopPrice, VolumeCondition); }
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); } } }
public int SendOrder( int OrderRef, string szInstrument, string szExchange, TThostFtdcDirectionType Direction, string szCombOffsetFlag, string szCombHedgeFlag, int VolumeTotalOriginal, double LimitPrice, TThostFtdcOrderPriceTypeType OrderPriceType, TThostFtdcTimeConditionType TimeCondition, TThostFtdcContingentConditionType ContingentCondition, double StopPrice, TThostFtdcVolumeConditionType VolumeCondition) { if (null == IntPtrKey || IntPtr.Zero == IntPtrKey) { return 0; } return TraderApi.TD_SendOrder( IntPtrKey, OrderRef, szInstrument, szExchange, Direction, szCombOffsetFlag, szCombHedgeFlag, VolumeTotalOriginal, LimitPrice, OrderPriceType, TimeCondition, ContingentCondition, StopPrice, VolumeCondition); }
//只收到成交信息时调用 public bool InsertOrReplaceForTrade( string InstrumentID, TThostFtdcPosiDirectionType PosiDirection, TThostFtdcDirectionType Direction, TThostFtdcHedgeFlagType HedgeFlag, TThostFtdcPositionDateType PositionDate, int volume) { lock (this) { // 今天的买入要先冻结 //冲突的可能性大一些,所以要先Update后Insert DataRow[] rows = Select(InstrumentID, PosiDirection, HedgeFlag, PositionDate); if (rows.Count() == 1) { int vol = (int)rows[0][Position]; rows[0][Position] = vol - volume; } else { //假设是新添数据 try { if (Direction == TThostFtdcDirectionType.Buy) { dtInvestorPosition.Rows.Add( InstrumentID, PosiDirection, HedgeFlag, PositionDate, 0, volume, 0); } else { dtInvestorPosition.Rows.Add( InstrumentID, PosiDirection, HedgeFlag, PositionDate, 0, 0, volume); } } catch { return false; } } return true; } }
/// <summary> /// 开平仓:限价单 /// </summary> /// <param name="InstrumentID">合约代码</param> /// <param name="OffsetFlag">平仓:仅上期所平今时使用CloseToday/其它情况均使用Close</param> /// <param name="Direction">买卖</param> /// <param name="Price">价格</param> /// <param name="Volume">手数</param> public int OrderInsert(string InstrumentID, TThostFtdcOffsetFlagType OffsetFlag, TThostFtdcDirectionType Direction, double Price, int Volume) { var priceType = TThostFtdcOrderPriceTypeType.LimitPrice; var conditionType = TThostFtdcTimeConditionType.GFD; if (Price < 0.01) { priceType = TThostFtdcOrderPriceTypeType.AnyPrice; conditionType = TThostFtdcTimeConditionType.IOC; } return m_Api.SendOrder( ++this.MaxOrderRef, InstrumentID, Direction, OffsetFlag, TThostFtdcHedgeFlagType.Speculation, Volume, Price, priceType, conditionType, TThostFtdcContingentConditionType.Immediately, 0, TThostFtdcVolumeConditionType.AV); }
public static extern void TD_CancelOrder(string Instrument, TThostFtdcDirectionType Direction, string OffsetFlag);
private void OpenOrder() { if (MaxLossStop && lossThreshold >= MaxLossThreshold) return; TThostFtdcDirectionType result = Cross(preMarketData, currMarketData); if (result == TThostFtdcDirectionType.Buy) { openCount = true; openDirection = result; openThreshold = 1; GetLog(result.ToString(), preMarketData, currMarketData, openThreshold); } else if (result == TThostFtdcDirectionType.Sell) { openDirection = result; openCount = true; openThreshold = 1; GetLog(result.ToString(), preMarketData, currMarketData, openThreshold); } if (result == TThostFtdcDirectionType.Nothing && openCount) { if (openThreshold >= MaxOpenThreshold) { var neworder = new Order { OffsetFlag = TThostFtdcOffsetFlagType.Open, Direction = openDirection, InstrumentId = currMarketData.InstrumentId, LastPrice = currMarketData.LastPrice, Price = GetAnyPrice(GetAvgPrice(), openDirection), StopProfit = -300 * InstrumentStrategy.Volume, Volume = InstrumentStrategy.Volume, StrategyType = GetType().ToString() }; neworder.StrategyLogs.AddRange(dayAverageLogs); newOrders.Add(neworder); log.Info(String.Format("{0}:{1}:{2}:{3}:{4}", ToString(), currMarketData.InstrumentId, currMarketData.LastPrice, currMarketData.AveragePrice, result)); openThreshold = 0; openCount = false; dayAverageLogs.Clear(); } else { openThreshold++; GetLog(result.ToString(), preMarketData, currMarketData, openThreshold); } } }