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; }
public void AddTraderResult(CThostFtdcTradeField pTrade) { try { sqlConnection.Open(); } finally { sqlConnection.Close(); } }
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); } 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); } } if (_dbInMemInvestorPosition.UpdateByTrade(pTrade)) { } else { //本地计算更新失败,重查一次 TraderApi.TD_ReqQryInvestorPosition(m_pTdApi, pTrade.InstrumentID); } }
private void OnRspQryTrade_callback(object sender, ref CThostFtdcTradeField pTrade, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast) { if (null != OnRspQryTrade) { try { OnRspQryTrade(this, new OnRspQryTradeArgs(ref pTrade, ref pRspInfo, nRequestID, bIsLast)); } catch (Exception ex) { MessageBox.Show("TraderApiWrapper::OnRspQryTrade_callback:" + ex.ToString()); } } }
/// <summary> /// 成交回报 /// </summary> private void CTradeApi_OnRtnTrade(ref CThostFtdcTradeField pTrade) { Trade t = new Trade(pTrade); var key = new Tuple <string, Direction>(t.TradeID, t.Direction); var value = this._DictTrade.AddOrUpdate(key, t, (k, v) => { v = t; return(v); }); //对于第一次登陆,由于先返回的是trade,所以不能调用UpdatePositionFromRtnTrade;只有当Position查询过后,才可以调用! if (this._isFirstTimeLogin) { this._OnTrade?.Invoke(value); } else { UpdatePositionFromRtnTrade(new Trade(pTrade)); this._OnTrade?.Invoke(value); } }
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)) { tdlog.Warn("找不到对应OrderSysID: {0},{1},{2}", strSysID, pTrade.BrokerOrderSeq, pTrade.OrderLocalID); 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); } else { tdlog.Warn("找不到对应Key: {0}", strKey); } }
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_3(IntPtr pTraderApi, ref CThostFtdcTradeField pTrade) { OnRtnTrade_1(this, pTraderApi, ref pTrade); }
private void OnRspQryTrade_3(IntPtr pTraderApi, ref CThostFtdcTradeField pTrade, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast) { OnRspQryTrade_1(this, pTraderApi, ref pTrade, ref pRspInfo, nRequestID, bIsLast); }
private static int SortCThostFtdcTradeField(CThostFtdcTradeField a1, CThostFtdcTradeField a2) { return(a1.TradeID.CompareTo(a2.TradeID)); }
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); } } }
public OnRtnTradeArgs(IntPtr pTraderApi, ref CThostFtdcTradeField pTrade) { this.pTraderApi = pTraderApi; this.pTrade = pTrade; }
private void OnRtnTradeLastStatus(GenericOrderItem item, CThostFtdcTradeField pTrade, string OrderSysID, string Key) { OnLastStatus(item, OrderSysID, Key); }
private void OnRspQryTrade_3(ref CThostFtdcTradeField pTrade, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast) { OnRspQryTrade_1(this, ref pTrade, ref pRspInfo, nRequestID, bIsLast); }
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 OnRtnTradeArgs(ref CThostFtdcTradeField pTrade) { this.pTrade = pTrade; }
public override void OnRtnTrade(CThostFtdcTradeField pTrade) { _callbackApi.OnRtnTrade(pTrade); }
public override void OnRspQryTrade(CThostFtdcTradeField pTrade, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast) { _callbackApi.OnRspQryTrade(pTrade, pRspInfo, nRequestID, bIsLast); }
///成交通知 public void OnRtnTrade(CThostFtdcTradeField pTrade) { Console.WriteLine("OnRtnTrade"); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(CThostFtdcTradeField obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
///请求查询成交响应 public void OnRspQryTrade(CThostFtdcTradeField pTrade, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast) { Console.WriteLine("OnRspQryTrade"); }
public void AddTrader(string investorID, string instrumentID, string tradeTime, string orderRef, string tradeID, double price, int volume, EnumOffsetFlagType offsetFlag, EnumDirectionType direction, CThostFtdcTradeField pTrade) { try { sqlConnection.Open(); string sql = "insert into trader(investorID, instrumentID, tradeTime, orderRef, tradeID, price, volume" + ",offsetFlag,direction) values ('" + investorID + "','" + instrumentID + "','" + tradeTime + "', '" + orderRef + "','" + tradeID + "'," + price + "," + volume + "," + (offsetFlag == EnumOffsetFlagType.Open ? 0 : 1) + "," + (direction == EnumDirectionType.Buy ? 0 : 1) + ")"; //Console.WriteLine(sql); MySqlCommand command = new MySqlCommand(sql, sqlConnection); command.ExecuteNonQuery(); } finally { sqlConnection.Close(); } }
private void OnRtnTrade_3(ref CThostFtdcTradeField pTrade) { OnRtnTrade_1(this, ref pTrade); }
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_callback(IntPtr pTraderApi, ref CThostFtdcTradeField pTrade) { if (null != OnRtnTrade) { OnRtnTrade(this, new OnRtnTradeArgs(pTraderApi, ref pTrade)); } }
private void CTPOnRtnTrade(ref CThostFtdcTradeField pTrade) { if (!IsLogin) { _rtnOrderTime = DateTime.Now; } string id; OrderField of = null; if (!(_dicSysidSfrId.TryGetValue(pTrade.OrderSysID, out id) && DicOrderField.TryGetValue(id, out of))) { CThostFtdcTradeField fReTrade = pTrade; var list = _sysidTrade.GetOrAdd(pTrade.OrderSysID, new List <CThostFtdcTradeField>()); list.Add(fReTrade); return; } TradeField f = new TradeField { Hedge = pTrade.HedgeFlag == TThostFtdcHedgeFlagType.THOST_FTDC_HF_Speculation ? HedgeType.Speculation : pTrade.HedgeFlag == TThostFtdcHedgeFlagType.THOST_FTDC_HF_Arbitrage ? HedgeType.Arbitrage : HedgeType.Hedge, Direction = pTrade.Direction == TThostFtdcDirectionType.THOST_FTDC_D_Buy ? DirectionType.Buy : DirectionType.Sell, //ExchangeID = pTrade.ExchangeID, InstrumentID = pTrade.InstrumentID, Offset = pTrade.OffsetFlag == TThostFtdcOffsetFlagType.THOST_FTDC_OF_Open ? OffsetType.Open : pTrade.OffsetFlag == TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday ? OffsetType.CloseToday : OffsetType.Close, Price = pTrade.Price, TradeID = pTrade.TradeID + (char)pTrade.Direction, TradeTime = pTrade.TradeTime, TradingDay = pTrade.TradingDay, Volume = pTrade.Volume, SysID = pTrade.OrderSysID, }; Exchange exc; if (Enum.TryParse(pTrade.ExchangeID, out exc)) { f.ExchangeID = exc; } if (DicTradeField.TryAdd(f.TradeID, f)) // string.Format("{0}_{1}", f.TradeID, f.Direction), f)) { f.OrderID = id; //更新成交对应的委托ID of.TradeTime = pTrade.TradeTime; of.AvgPrice = (of.AvgPrice * (of.Volume - of.VolumeLeft) + pTrade.Price * pTrade.Volume) / (of.Volume - of.VolumeLeft + pTrade.Volume); of.TradeVolume = pTrade.Volume; of.VolumeLeft -= of.TradeVolume; if (of.VolumeLeft == 0) { of.Status = OrderStatus.Filled; of.StatusMsg = "全部成交"; } else { of.Status = OrderStatus.Partial; of.StatusMsg = "部分成交"; } if (IsLogin) { #region 更新持仓 PositionField pf; //处理持仓 if (f.Offset == OffsetType.Open) { pf = DicPositionField.GetOrAdd(f.InstrumentID + "_" + f.Direction, new PositionField()); pf.InstrumentID = f.InstrumentID; pf.Direction = f.Direction; pf.Hedge = f.Hedge; pf.Price = (pf.Price * pf.Position + f.Price * f.Volume) / (pf.Position + f.Volume); pf.TdPosition += f.Volume; pf.Position += f.Volume; } else { pf = this.DicPositionField.GetOrAdd(f.InstrumentID + "_" + (f.Direction == DirectionType.Buy ? "Sell" : "Buy"), new PositionField()); if (f.Offset == OffsetType.CloseToday) { pf.TdPosition -= f.Volume; } else { int tdClose = Math.Min(pf.TdPosition, f.Volume); if (pf.TdPosition > 0) { pf.TdPosition -= tdClose; } pf.YdPosition -= Math.Max(0, f.Volume - tdClose); } pf.Position -= f.Volume; } #endregion //委托响应 _OnRtnOrder?.Invoke(this, new OrderArgs { Value = of }); //成交响应 _OnRtnTrade?.Invoke(this, new TradeArgs { Value = f }); } } }
/// <summary> /// 构造函数 /// </summary> public Trade(CThostFtdcTradeField tf) { this._tf = tf; }