public bool OnTrade(ref SingleOrder order, ref CThostFtdcTradeField pTrade, ref double Price, ref int Volume) { #if CTP //先保存到两个队例,排序是为了配对 if (TThostFtdcDirectionType.Buy == pTrade.Direction) { qBuy.Add(pTrade); qBuy.Sort(SortCThostFtdcTradeField); } else { qSell.Add(pTrade); qSell.Sort(SortCThostFtdcTradeField); } //取已经配对好的 if (qBuy.Count > 0 && qSell.Count > 0) { // 有网友说可能成交时不成对,这地方是否改动一下 if (qBuy[0].Volume == qSell[0].Volume)//如果不等就有问题了 { Volume = qBuy[0].Volume; if (order.Side == Side.Buy) { Price = qBuy[0].Price - qSell[0].Price; } else { Price = qSell[0].Price - qBuy[0].Price; } //用完就清除 qBuy.RemoveAt(0); qSell.RemoveAt(0); return true; } } #endif return false; }
private void OnRtnTrade_callback(IntPtr pTraderApi, ref CThostFtdcTradeField pTrade) { if (null != OnRtnTrade) { OnRtnTrade(this, new OnRtnTradeArgs(pTraderApi, ref pTrade)); } }
private void OnRspQryTrade_callback(IntPtr pTraderApi, ref CThostFtdcTradeField pTrade, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast) { if (null != OnRspQryTrade) { OnRspQryTrade(this, new OnRspQryTradeArgs(pTraderApi, ref pTrade, ref pRspInfo, nRequestID, bIsLast)); } }
public bool UpdateByTrade(CThostFtdcTradeField pTrade) { /* * Q:向非上海市场发送平今指今,系统能自动处理成平今,接到的回报是平今还是平仓? * A:上海市场的昨仓用Close和CloseYesterday都能平,报单回报不会改变,而成交回报会修改成CloseYesterday * * Q:是否不同市场收到的成交回报都分为了今天与历史。非上海市场不时用Close时,返回数据能区分CloseToday和CloseYesterday吗?还是只回Close * * Q:上海强平今仓与昨仓会收到什么结果? * * Q:非上海市场,一手今,一手昨,同时平,收到的回报会如何? * */ //如果是开仓,查找唯一的那条记录,不存在就插入 //如果是平今,只查找今天的记录,直接修改 //如果是平昨,只处理昨天 //如果是平仓,从历史开始处理 lock(this) { TThostFtdcPosiDirectionType PosiDirection = TThostFtdcPosiDirectionType.Short; TThostFtdcPositionDateType PositionDate = TThostFtdcPositionDateType.Today; if (TThostFtdcOffsetFlagType.Open == pTrade.OffsetFlag) { if (TThostFtdcDirectionType.Buy == pTrade.Direction) { PosiDirection = TThostFtdcPosiDirectionType.Long; } return InsertOrReplaceForOpen(pTrade.InstrumentID, PosiDirection, pTrade.HedgeFlag, PositionDate, pTrade.Volume); } else { if (TThostFtdcDirectionType.Sell == pTrade.Direction) { PosiDirection = TThostFtdcPosiDirectionType.Long; } if (TThostFtdcOffsetFlagType.CloseToday == pTrade.OffsetFlag) { return ReplaceForClose(pTrade.InstrumentID, PosiDirection, pTrade.HedgeFlag, PositionDate, pTrade.Volume) == 0; } else if (TThostFtdcOffsetFlagType.CloseYesterday == pTrade.OffsetFlag) { PositionDate = TThostFtdcPositionDateType.History; return ReplaceForClose(pTrade.InstrumentID, PosiDirection, pTrade.HedgeFlag, PositionDate, pTrade.Volume) == 0; } else if (TThostFtdcOffsetFlagType.Close == pTrade.OffsetFlag) { return ReplaceForClose(pTrade.InstrumentID, PosiDirection, pTrade.HedgeFlag, pTrade.Volume) == 0; } else { //无法计算的开平类型,要求直接发送查询请求 return false; } } } }
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 OnRtnTradeLastStatus(GenericOrderItem item, CThostFtdcTradeField pTrade, string OrderSysID, string Key) { OnLastStatus(item,OrderSysID,Key); }
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); //将仓位计算提前,防止在OnPositionOpened中下平仓时与“C|”配合出错 if (_dbInMemInvestorPosition.UpdateByTrade(pTrade)) { } else { //本地计算更新失败,重查一次 TraderApi.TD_ReqQryInvestorPosition(m_pTdApi, pTrade.InstrumentID); } SingleOrder order; //找到自己发送的订单,标记成交 if (_OrderRef2Order.TryGetValue(string.Format("{0}:{1}:{2}", _RspUserLogin.FrontID, _RspUserLogin.SessionID, pTrade.OrderRef), out order)) { if (TThostFtdcTradeTypeType.CombinationDerived == pTrade.TradeType) { //组合,得特别处理 DbInMemTrade _trade;//用此对象维护组合对 if (!_Orders4Combination.TryGetValue(order, out _trade)) { _trade = new DbInMemTrade(); _Orders4Combination[order] = _trade; } double Price = 0; int Volume = 0; //找到成对交易的,得出价差 if (_trade.OnTrade(ref order, ref pTrade, ref Price, ref Volume)) { EmitFilled(order, Price, Volume); //完成使命了,删除 if (_trade.isEmpty()) { _Orders4Combination.Remove(order); } } } else { //普通订单,直接通知即可 EmitFilled(order, pTrade.Price, pTrade.Volume); } } }
private static int SortCThostFtdcTradeField(CThostFtdcTradeField a1, CThostFtdcTradeField a2) { return a1.TradeID.CompareTo(a2.TradeID); }
public OnRtnTradeArgs(IntPtr pTraderApi, ref CThostFtdcTradeField pTrade) { this.pTraderApi = pTraderApi; this.pTrade = pTrade; }
public OnRspQryTradeArgs(IntPtr pTraderApi, ref CThostFtdcTradeField pTrade, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast) { this.pTraderApi = pTraderApi; this.pTrade = pTrade; this.pRspInfo = pRspInfo; this.nRequestID = nRequestID; this.bIsLast = bIsLast; }
private void InsertToMock(Order order) { if (order.CloseOrders.Count == 0) { OnRspQryOrder(this, new OrderEventArgs(() => Add(order))); order.RemainVolume = order.Volume; order.OrderRef = tradeApi.MaxOrderRef++.ToString(); order.FrontID = tradeApi.FrontID; order.SessionID = tradeApi.SessionID; order.TradePrice = order.Price; order.TradeDate = tradeApi.TradingDay; order.TradeTime = DateTime.Now.ToString("HH:mm:ss"); order.StatusType = EnumOrderStatus.已开仓; } else { foreach (var closeOrder in order.GetClosingOrders()) { closeOrder.OrderRef = tradeApi.MaxOrderRef++.ToString(); closeOrder.FrontID = tradeApi.FrontID; closeOrder.SessionID = tradeApi.SessionID; closeOrder.StatusType = EnumOrderStatus.平仓中; closeOrder.OrderSysID = tradeApi.MaxOrderRef++.ToString(); var tradeField = new CThostFtdcTradeField(); tradeField.TradeID = tradeApi.MaxOrderRef++.ToString(); tradeField.OrderSysID = closeOrder.OrderSysID; tradeField.Price = closeOrder.Price; tradeField.TradeDate = tradeApi.TradingDay; tradeField.TradeTime = DateTime.Now.ToString("HH:mm:ss"); var o = UpdateTradeID(tradeField); if (o == null || o.StatusType != EnumOrderStatus.已平仓) continue; OnRspQryOrder(this, new OrderEventArgs(() => HandleOrderClose(o))); if (!HasMoney) HasMoney = true; } } }
public Order UpdateTradeID(CThostFtdcTradeField pTrade) { string orderSysID = pTrade.OrderSysID.Trim(); sw.EnterWriteLock(); Order order = orders.FirstOrDefault( o => o.OrderSysID == orderSysID && o.TradeID == null); if (order != null) { order.TradeID = pTrade.TradeID; order.TradePrice = pTrade.Price; order.TradeDate = pTrade.TradeDate; order.TradeTime = pTrade.TradeTime; order.StatusType = EnumOrderStatus.已开仓; OrderRepository.Update(order); } else { foreach (var o in orders) { var closeorder = o.CloseOrders.FirstOrDefault(c => c.OrderSysID == orderSysID && c.TradeID == null); if (closeorder == null) continue; closeorder.TradeID = pTrade.TradeID; closeorder.TradePrice = pTrade.Price; closeorder.TradeDate = pTrade.TradeDate; closeorder.TradeTime = pTrade.TradeTime; closeorder.StatusType = EnumOrderStatus.已平仓; o.RemainVolume -= closeorder.Volume; o.StatusType = o.IsClosed() ? EnumOrderStatus.已平仓 : EnumOrderStatus.已开仓; var profit = (o.Direction == TThostFtdcDirectionType.Buy) ? closeorder.TradePrice - o.TradePrice : o.TradePrice - closeorder.TradePrice; closeorder.CloseProfit = profit * closeorder.Volume * o.Unit; o.CloseProfit += closeorder.CloseProfit; //o.PositionProfit -= closeorder.CloseProfit; OrderRepository.Update(o); order = o; break; } } sw.ExitWriteLock(); return order; }
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); //将仓位计算提前,防止在OnPositionOpened中下平仓时与“C|”配合出错 if (_dbInMemInvestorPosition.UpdateByTrade(pTrade)) { } else { //本地计算更新失败,重查一次 TraderApi.TD_ReqQryInvestorPosition(m_pTdApi, pTrade.InstrumentID); } SingleOrder order; //找到自己发送的订单,标记成交 string strSysID = string.Format("{0}:{1}", pTrade.ExchangeID, pTrade.OrderSysID); string strKey; if (!_OrderSysID2OrderRef.TryGetValue(strSysID,out strKey)) { return; } if (_OrderRef2Order.TryGetValue(strKey, out order)) { double Price = 0; int Volume = 0; if (TThostFtdcTradeTypeType.CombinationDerived == pTrade.TradeType) { //组合,得特别处理 DbInMemTrade _trade;//用此对象维护组合对 if (!_Orders4Combination.TryGetValue(order, out _trade)) { _trade = new DbInMemTrade(); _Orders4Combination[order] = _trade; } //找到成对交易的,得出价差 if (_trade.OnTrade(ref order, ref pTrade, ref Price, ref Volume)) { //完成使命了,删除 //if (_trade.isEmpty()) //{ // _Orders4Combination.Remove(order); //} } } else { //普通订单,直接通知即可 Price = pTrade.Price; Volume = pTrade.Volume; } int LeavesQty = (int)order.LeavesQty - Volume; EmitFilled(order, Price, Volume); //成交完全,清理 if (LeavesQty <= 0) { _OrderRef2Order.Remove(strKey); _OrderSysID2OrderRef.Remove(strSysID); _Orders4Combination.Remove(order); _Orders4Cancel.Remove(order); } } }