public bool OnTrade(ref SingleOrder order, ref CThostFtdcTradeField pTrade, ref double Price, ref int Volume) { //先保存到两个队例,排序是为了配对 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; } } return false; }
private void OnRtnTrade(IntPtr pTraderApi, ref CThostFtdcTradeField pTrade) { if (OutputLog) { Console.WriteLine("时{0},合约{1},方向{2},开平{3},价{4},量{5},引用{6}", pTrade.TradeTime, pTrade.InstrumentID, pTrade.Direction, pTrade.OffsetFlag, pTrade.Price, pTrade.Volume, pTrade.OrderRef); } //将仓位计算提前,防止在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 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; } } } }