//重载OnRecvDataMsg方法,接收行情数据 // 请注意: // 1. 不要在这个函数里做耗时操作 // 2. 只在这个函数里做数据获取工作 -- 将数据复制到其它数据缓存区,由其它线程做业务逻辑处理 public override void OnRecvDataMsg(TDFMSG msg) { if (msg.MsgID == TDFMSGID.MSG_DATA_MARKET) { //行情消息 TDFMarketData[] marketDataArr = msg.Data as TDFMarketData[]; MarketDataCache.Enqueue(marketDataArr); } else if (msg.MsgID == TDFMSGID.MSG_DATA_TRANSACTION) { //逐笔成交 TDFTransaction[] transactionDataArr = msg.Data as TDFTransaction[]; TransactionCache.Enqueue(transactionDataArr); } else if (msg.MsgID == TDFMSGID.MSG_DATA_ORDER) { //逐笔委托 TDFOrder[] orderDataArr = msg.Data as TDFOrder[]; OrderCache.Enqueue(orderDataArr); } else if (msg.MsgID == TDFMSGID.MSG_DATA_ORDERQUEUE) { //委托队列 TDFOrderQueue[] orderQueueDataArr = msg.Data as TDFOrderQueue[]; OrderQueueCache.Enqueue(orderQueueDataArr); } }
/// <summary> /// 系统消息回调 /// MSG_SYS_DISCONNECT_NETWORK: 网络断开事件 /// MSG_SYS_CONNECT_RESULT: 主动发起连接的结果 /// MSG_SYS_LOGIN_RESULT: 登陆应答 /// MSG_SYS_CODETABLE_RESULT: 获取代码表结果 /// MSG_SYS_QUOTATIONDATE_CHANGE: 行情日期变更通知 /// MSG_SYS_MARKET_CLOSE: 闭市 /// MSG_SYS_HEART_BEAT: 服务器心跳消息 /// </summary> /// <param name="msg"></param> public override void OnRecvSysMsg(TDFMSG msg) { SysMsgDeal(msg); }
/// <summary> /// 行情数据回调 /// MSG_DATA_MARKET: 行情快照数据 /// MSG_DATA_INDEX: 指数行情快照数据 /// MSG_DATA_FUTURE: 期货和期权行情快照数据 /// MSG_DATA_TRANSACTION: 逐笔成交 /// MSG_DATA_ORDERQUEUE: 委托队列 /// MSG_DATA_ORDER: 逐笔委托 /// </summary> /// <param name="msg"></param> public override void OnRecvDataMsg(TDFMSG msg) { DataMsgDeal(msg); }
//重载 OnRecvSysMsg 方法,接收系统消息通知 // 请注意: // 1. 不要在这个函数里做耗时操作 // 2. 只在这个函数里做数据获取工作 -- 将数据复制到其它数据缓存区,由其它线程做业务逻辑处理 public override void OnRecvSysMsg(TDFMSG msg) { //throw new NotImplementedException(); if (msg.MsgID == TDFMSGID.MSG_SYS_CONNECT_RESULT) { //连接结果 TDFConnectResult connectResult = msg.Data as TDFConnectResult; string strPrefix = connectResult.ConnResult ? "连接成功" : "连接失败"; logA.LogEvent("系统服务器连接情况 :" + strPrefix); } else if (msg.MsgID == TDFMSGID.MSG_SYS_LOGIN_RESULT) { //登陆结果 TDFLoginResult loginResult = msg.Data as TDFLoginResult; if (loginResult.LoginResult) { logA.LogEvent("系统服务器登陆成功"); for (int i = 0; i < loginResult.Markets.Length; i++) { logA.LogEvent(String.Format("market:{0},dyn-date:{1}", loginResult.Markets[i], loginResult.DynDate[i])); } } else { logA.LogEvent(String.Format("登陆失败! info:{0}", loginResult.Info)); } } else if (msg.MsgID == TDFMSGID.MSG_SYS_CODETABLE_RESULT) { //接收代码表结果 TDFCodeResult codeResult = msg.Data as TDFCodeResult; logA.LogEvent(String.Format("获取到代码表, info:{0},市场个数:{1}", codeResult.Info, codeResult.Markets.Length)); //代码表是什么鸟玩意?? TDFCode[] codeArrSZ; GetCodeTable("SZ", out codeArrSZ); TDFCode[] codeArrSH; GetCodeTable("SH", out codeArrSH); //for (int i = 0; i < 100 && i < codeArr.Length; i++) //{ // if (codeArr[i].Type >= 0x90 && codeArr[i].Type <= 0x95) // { // // 期权数据 // TDFOptionCode code = new TDFOptionCode(); // var ret = GetOptionCodeInfo(codeArr[i].WindCode, ref code); // PrintHelper.PrintObject(code); // } // else // { // PrintHelper.PrintObject(codeArr[i]); // } //} } else if (msg.MsgID == TDFMSGID.MSG_SYS_QUOTATIONDATE_CHANGE) { //行情日期变更。 TDFQuotationDateChange quotationChange = msg.Data as TDFQuotationDateChange; logA.LogEvent(String.Format("接收到行情日期变更通知消息,market:{0}, old date:{1}, new date:{2}", quotationChange.Market, quotationChange.OldDate, quotationChange.NewDate)); } else if (msg.MsgID == TDFMSGID.MSG_SYS_MARKET_CLOSE) { //闭市消息 TDFMarketClose marketClose = msg.Data as TDFMarketClose; logA.LogEvent(String.Format("接收到闭市消息, 交易所:{0}, 时间:{1}, 信息:{2}", marketClose.Market, marketClose.Time, marketClose.Info)); } else if (msg.MsgID == TDFMSGID.MSG_SYS_HEART_BEAT) { //心跳消息 } }
//重载OnRecvDataMsg方法,接收行情数据 // 请注意: // 1. 不要在这个函数里做耗时操作 // 2. 只在这个函数里做数据获取工作 -- 将数据复制到其它数据缓存区,由其它线程做业务逻辑处理 public override void OnRecvDataMsg(TDFMSG msg) { if (msg.MsgID == TDFMSGID.MSG_DATA_MARKET) { //行情消息 TDFMarketData[] marketDataArr = msg.Data as TDFMarketData[]; foreach (TDFMarketData data in marketDataArr) { EnQueueType obj = new EnQueueType() { Type = "S", value = (object)data }; if (Queue_Data.Suspend == false) { Queue_Data.GetQueue().Enqueue((object)obj); if (data.Status == 68) { stop_plate_stocks.GetInstance().updateStopList(data); } } } } else if (msg.MsgID == TDFMSGID.MSG_DATA_FUTURE) { //期货行情数据 TDFFutureData[] futureDataArr = msg.Data as TDFFutureData[]; foreach (TDFFutureData data in futureDataArr) { EnQueueType obj = new EnQueueType() { Type = "F", value = (object)data }; if (Queue_Data.Suspend == false) { Queue_Data.GetQueue().Enqueue((object)obj); } } } else if (msg.MsgID == TDFMSGID.MSG_DATA_INDEX) { //指数消息 TDFIndexData[] indexDataArr = msg.Data as TDFIndexData[]; foreach (TDFIndexData data in indexDataArr) { EnQueueType obj = new EnQueueType() { Type = "I", value = (object)data }; if (Queue_Data.Suspend == false) { Queue_Data.GetQueue().Enqueue((object)obj); } } } }
//重载 OnRecvSysMsg 方法,接收系统消息通知 // 请注意: // 1. 不要在这个函数里做耗时操作 // 2. 只在这个函数里做数据获取工作 -- 将数据复制到其它数据缓存区,由其它线程做业务逻辑处理 public override void OnRecvSysMsg(TDFMSG msg) { try { if (msg.MsgID == TDFMSGID.MSG_SYS_CONNECT_RESULT) { //连接结果 TDFConnectResult connectResult = msg.Data as TDFConnectResult; string strPrefix = connectResult.ConnResult ? "连接成功" : "连接失败"; PrintHelper.PrintText(String.Format("{0}!server:{1}:{2},{3},{4}, connect id:{5}", strPrefix, connectResult.Ip, connectResult.Port, connectResult.Username, connectResult.Password, connectResult.ConnectID)); } else if (msg.MsgID == TDFMSGID.MSG_SYS_LOGIN_RESULT) { TDFLoginResult loginResult = msg.Data as TDFLoginResult; if (loginResult.LoginResult) { //登陆结果 PrintHelper.PrintText(String.Format("登陆成功,市场个数:{0}:", loginResult.Markets.Length)); for (int i = 0; i < loginResult.Markets.Length; i++) { PrintHelper.PrintText(String.Format("market:{0}, dyn-date:{1}", loginResult.Markets[i], loginResult.DynDate[i])); } } else { PrintHelper.PrintText(String.Format("登陆失败!info:{0}", loginResult.Info)); } } else if (msg.MsgID == TDFMSGID.MSG_SYS_CODETABLE_RESULT) { //接收代码表结果 TDFCodeResult codeResult = msg.Data as TDFCodeResult; PrintHelper.PrintText(String.Format("获取到代码表, info:{0},市场个数:{1}", codeResult.Info, codeResult.Markets.Length)); for (int i = 0; i < codeResult.Markets.Length; i++) { PrintHelper.PrintText(String.Format("market:{0}, date:{1}, code count:{2}", codeResult.Markets[i], codeResult.CodeDate[i], codeResult.CodeCount[i])); } //客户端请自行保存代码表,本处演示怎么获取代码表内容 TDFCode[] codeArr; GetCodeTable("", out codeArr); //Console.WriteLine("接收到{0}项代码!, 输出前100项", codeArr.Length); ChinaMarketValue.dicTDFCode.Clear(); for (int i = 0; i < codeArr.Length; i++) { ChinaMarketValue.dicTDFCode.TryAdd(codeArr[i].WindCode, codeArr[i]); } } else if (msg.MsgID == TDFMSGID.MSG_SYS_QUOTATIONDATE_CHANGE) { //行情日期变更。 TDFQuotationDateChange quotationChange = msg.Data as TDFQuotationDateChange; PrintHelper.PrintText(String.Format("接收到行情日期变更通知消息,market:{0}, old date:{1}, new date:{2}", quotationChange.Market, quotationChange.OldDate, quotationChange.NewDate)); } else if (msg.MsgID == TDFMSGID.MSG_SYS_MARKET_CLOSE) { //闭市消息 TDFMarketClose marketClose = msg.Data as TDFMarketClose; PrintHelper.PrintText(String.Format("接收到闭市消息, 交易所:{0}, 时间:{1}, 信息:{2}", marketClose.Market, marketClose.Time, marketClose.Info)); } else if (msg.MsgID == TDFMSGID.MSG_SYS_HEART_BEAT) { //心跳消息 //Console.WriteLine("接收到心跳消息!"); } } catch (Exception ex) { ChinaMarketValue.exceptionLog.log(ChinaMarketValue.logLevel, ex.ToString()); } }
//重载 OnRecvSysMsg 方法,接收系统消息通知 // 请注意: // 1. 不要在这个函数里做耗时操作 // 2. 只在这个函数里做数据获取工作 -- 将数据复制到其它数据缓存区,由其它线程做业务逻辑处理 public override void OnRecvSysMsg(TDFMSG msg) { if (msg.MsgID == TDFMSGID.MSG_SYS_CONNECT_RESULT) { //连接结果 TDFConnectResult connectResult = msg.Data as TDFConnectResult; ConnectResult = connectResult; IsOnline = connectResult.ConnResult; if (NewSysEvent != null) { NewSysEvent("连接状态 " + (IsOnline ? "已连接" : "未连接")); } App.Logger.Info("TDF:连接状态 " + (IsOnline ? "已连接" : "未连接")); } else if (msg.MsgID == TDFMSGID.MSG_SYS_LOGIN_RESULT) { TDFLoginResult loginResult = msg.Data as TDFLoginResult; LoginResult = loginResult; IsLogin = loginResult.LoginResult; if (NewSysEvent != null) { NewSysEvent("登陆状态 " + (IsLogin ? "已登陆" : "未登陆")); } App.Logger.Info("TDF:登陆状态 " + (IsLogin ? "已登陆" : "未登陆")); } else if (msg.MsgID == TDFMSGID.MSG_SYS_CODETABLE_RESULT) { //接收代码表结果 TDFCodeResult codeResult = msg.Data as TDFCodeResult; //客户端请自行保存代码表,本处演示怎么获取代码表内容 if (codeResult != null) { TDFCode[] sh_codes; TDFCode[] sz_codes; GetCodeTable("SH", out sh_codes); GetCodeTable("SZ", out sz_codes); _codes = new TDFCode[sh_codes.Length + sz_codes.Length]; sh_codes.CopyTo(_codes, 0); sz_codes.CopyTo(_codes, sh_codes.Length); if (NewSysEvent != null) { NewSysEvent("已获取代码列表," + _codes.Length); } } else { if (NewSysEvent != null) { NewSysEvent("获取代码列表失败"); } } App.Logger.Info("TDF:获取代码列表消息"); } else if (msg.MsgID == TDFMSGID.MSG_SYS_QUOTATIONDATE_CHANGE) { //行情日期变更。 TDFQuotationDateChange quotationChange = msg.Data as TDFQuotationDateChange; if (NewSysEvent != null) { NewSysEvent("行情日期变更"); } App.Logger.Info("TDF:行情日期变更"); } else if (msg.MsgID == TDFMSGID.MSG_SYS_MARKET_CLOSE) { //闭市消息 TDFMarketClose marketClose = msg.Data as TDFMarketClose; IsClose = true; if (NewSysEvent != null) { NewSysEvent("闭市状态 " + (IsClose ? "闭市" : "未闭市")); } App.Logger.Info("TDF:闭市状态 " + (IsClose ? "闭市" : "未闭市")); } else if (msg.MsgID == TDFMSGID.MSG_SYS_HEART_BEAT) { //心跳消息 AliveTime = DateTime.Now; } }
//重载OnRecvDataMsg方法,接收行情数据 // 请注意: // 1. 不要在这个函数里做耗时操作 // 2. 只在这个函数里做数据获取工作 -- 将数据复制到其它数据缓存区,由其它线程做业务逻辑处理 public override void OnRecvDataMsg(TDFMSG msg) { try { if (msg.MsgID == TDFMSGID.MSG_DATA_MARKET) { //行情消息 TDFMarketData[] marketDataArr = msg.Data as TDFMarketData[]; foreach (TDFMarketData data in marketDataArr) { //if (data.Code.Contains("10000015")) // continue; lock (this.dataDict) { if (dataDict.Keys.Contains(data.Code)) { SingleStockData sd = dataDict[data.Code]; //数据获取部分 if (data.Match != 0) { sd.LastPrice = (double)data.Match / 10000; //最新成交价 } sd.PrevClose = (double)data.PreClose / 10000; sd.AskPrices[0] = (double)data.AskPrice[0] / 10000; sd.BidPrices[0] = (double)data.BidPrice[0] / 10000; for (int i = 0; i < 10; i++) { sd.BidPrices[i] = (double)data.BidPrice[i] / 10000; sd.AskPrices[i] = (double)data.AskPrice[i] / 10000; sd.BidVol[i] = data.BidVol[i]; sd.AskVol[i] = data.AskVol[i]; } if ((sd.ShortPriceListed != sd.AskPrices[0]) && (sd.StatusTrending == StrategyStatus.ShortListedOnly)) //最新卖一已变动,需改价重挂 { sd.bAskPriceChanged = true; //测试,按卖五挂单 } # region Fishing Strategies //业务逻辑部分,只有对FishingStrategy这样时效要求极高的放在此处,其余均放入EngineClass if (sd.StatusCBFishing != StrategyStatus.None) //此ticker需要跑CBFishing Strategy { if (sd.StatusCBFishing == StrategyStatus.New) //首次挂买单,或上一轮结束后重新挂单 { //sd.LongPriceListed = sd.BidPrices[0] - sd.CBBuyPriceOffset; //挂在卖五,后续可以参数化 sd.LongPriceListed = sd.BidPrices[4]; //挂在卖五,后续可以参数化 sd.StatusCBFishing = StrategyStatus.LongListedOnly; //下一步考虑在EngineClass或TradeClass中生成Order,只需有strategy和ticker,即可在dataDict中取到生成order所需数据 FIXApi.OrderBookEntry entry = new OrderBookEntry(); entry.strategies = TradingStrategies.CBFishing; entry.action = OrderAction.Buy; entry.type = FIXApi.OrderType.CreditBuy; entry.ticker = data.Code; entry.quantityListed = sd.Quantity; entry.priceListed = sd.LongPriceListed; sd.StatusCBFishing = StrategyStatus.Pending; //获得成交回报后再改变状态,避免重复执行 Thread orderThread = new Thread(new ParameterizedThreadStart(tc.OrderSender_CBFishing)); orderThread.IsBackground = true; orderThread.Start(entry); } else if (sd.StatusCBFishing == StrategyStatus.LongListedOnly) //买单已挂,根据最新价格检查是否需要撤单重挂 { if ((sd.LongPriceListed >= sd.BidPrices[3]) || (sd.LongPriceListed <= sd.BidPrices[5])) //大于卖三或小于卖七时重挂 { sd.LongPriceListed = sd.BidPrices[0] - sd.CBBuyPriceOffset; FIXApi.OrderBookEntry entry = new OrderBookEntry(); entry.strategies = TradingStrategies.CBFishing; entry.action = OrderAction.CancelAndBuy; entry.type = FIXApi.OrderType.CreditBuy; entry.ticker = data.Code; entry.quantityListed = sd.Quantity; entry.priceListed = sd.LongPriceListed; sd.StatusCBFishing = StrategyStatus.Pending; //获得成交回报后再改变状态,避免重复执行 Thread orderThread = new Thread(new ParameterizedThreadStart(tc.OrderSender_CBFishing)); orderThread.IsBackground = true; orderThread.Start(entry); } //if ((sd.ShortPriceListed<data.AskPrice[4]) || (sd.ShortPriceListed>data.AskPrice[6]) ) //低于卖五或者高于卖七时撤单重挂,避免撤单过于频繁 // sd.ShortPriceListed = sd.AskPrices[4]; ////cancel and resend } else if (sd.StatusCBFishing == StrategyStatus.ShortListedOnly) //卖单已挂,根据最新价格检查是否需要撤单重挂 { if (sd.ShortPriceListed > sd.AskPrices[0]) { sd.ShortPriceListed = sd.AskPrices[0] - sd.CBSellPriceOffset; //一直挂在比卖一低0.01的位置 FIXApi.OrderBookEntry entry = new OrderBookEntry(); entry.strategies = TradingStrategies.CBFishing; entry.action = OrderAction.CancelAndSell_CF; entry.type = FIXApi.OrderType.CreditSell; entry.ticker = data.Code; entry.quantityListed = sd.Quantity; entry.priceListed = sd.ShortPriceListed; entry.strategies = TradingStrategies.CBFishing; sd.StatusCBFishing = StrategyStatus.Pending; //获得成交回报后再改变状态,避免重复执行 Thread orderThread = new Thread(new ParameterizedThreadStart(tc.OrderSender_CBFishing)); orderThread.IsBackground = true; orderThread.Start(entry); } //if ((sd.ShortPriceListed<data.AskPrice[4]) || (sd.ShortPriceListed>data.AskPrice[6]) ) //低于卖五或者高于卖七时撤单重挂,避免撤单过于频繁 // sd.ShortPriceListed = sd.AskPrices[4]; ////cancel and resend } else if (sd.StatusStockFishing != StrategyStatus.None) //此ticker需要跑StockFishing Strategy { } } # endregion } } } //极其耗时,轻易不要打开 //RecvDataReport(this, null); } else if (msg.MsgID == TDFMSGID.MSG_DATA_FUTURE) { //期货行情消息 TDFFutureData[] futureDataArr = msg.Data as TDFFutureData[]; foreach (TDFFutureData data in futureDataArr) { ; } return; } else if (msg.MsgID == TDFMSGID.MSG_DATA_INDEX) { //指数消息 TDFIndexData[] indexDataArr = msg.Data as TDFIndexData[]; foreach (TDFIndexData data in indexDataArr) { return; } } else if (msg.MsgID == TDFMSGID.MSG_DATA_TRANSACTION) { //逐笔成交 TDFTransaction[] transactionDataArr = msg.Data as TDFTransaction[]; foreach (TDFTransaction data in transactionDataArr) { //每一data变量包含最底层的一笔逐笔成交数据 lock (this.dataDict) { if (dataDict.Keys.Contains(data.Code)) { //数据获取部分 int timeStamp = Convert.ToInt32((double)data.Time / 1000 - 0.5); //去掉毫秒部分; if (timeStamp == 93524) { timeStamp = 93524; } int direction = 0; if (data.BSFlag == 66) { direction = 1; } else if (data.BSFlag == 83) { direction = -1; } int volume = data.Volume; double price = (double)data.Price / 10000; if (dataDict[data.Code].zbDataList.Count == 0) //第一次添加 { ZBTickData zbdata = new ZBTickData(); zbdata.timeStamp = timeStamp; if (direction == 1) { zbdata.volumeB = volume; zbdata.priceTotalB = price; zbdata.countB = 1; zbdata.priceB = zbdata.priceTotalB / (double)zbdata.countB;//计算该秒、买方向的平均价格 } else if (direction == -1) { zbdata.volumeS = volume; zbdata.priceTotalS = price; zbdata.countS = 1; zbdata.priceS = zbdata.priceTotalS / (double)zbdata.countS;//计算该秒、买方向的平均价格 } if ((zbdata.priceB > 0) && (zbdata.priceS > 0)) { zbdata.price = (zbdata.priceB + zbdata.priceS) / 2; } else { zbdata.price = (zbdata.priceB + zbdata.priceS); } zbdata.volume = zbdata.volumeB + zbdata.volumeS; if ((zbdata.volume == 0) || (zbdata.price == 0)) { continue; //空记录 } dataDict[data.Code].zbDataList.Add(zbdata); dataDict[data.Code].ZBFirstIndex = 0; dataDict[data.Code].ZBLastIndex = 0; } else { int currLastIndex = dataDict[data.Code].ZBLastIndex; if (dataDict[data.Code].zbDataList[currLastIndex].timeStamp == timeStamp) //同一时间戳存在,只需更新价格与成交量,不需插入新纪录 { ZBTickData zbdata = dataDict[data.Code].zbDataList[currLastIndex]; //取出字典中的元素并进行修改,由于是引用,对zbdata的修改会自动在字典中更新 if (direction == 1) { zbdata.priceTotalB = zbdata.priceTotalB + price; zbdata.countB = zbdata.countB + 1; zbdata.priceB = zbdata.priceTotalB / (double)zbdata.countB;//计算该秒、该方向的平均价格 zbdata.volumeB = zbdata.volumeB + volume; } else if (direction == -1) { zbdata.priceTotalS = zbdata.priceTotalS + price; zbdata.countS = zbdata.countS + 1; zbdata.priceS = zbdata.priceTotalS / (double)zbdata.countS;//计算该秒、该方向的平均价格 zbdata.volumeS = zbdata.volumeS + volume; } if ((zbdata.priceB > 0) && (zbdata.priceS > 0)) { zbdata.price = (zbdata.priceB + zbdata.priceS) / 2; } else { zbdata.price = (zbdata.priceB + zbdata.priceS); } zbdata.volume = zbdata.volumeB + zbdata.volumeS; dataDict[data.Code].zbDataList.RemoveAt(currLastIndex); dataDict[data.Code].zbDataList.Add(zbdata); } else //不存在此时间戳,需添加新纪录 { ZBTickData zbdata = new ZBTickData(); zbdata.timeStamp = timeStamp; if (direction == 1) { zbdata.volumeB = volume; zbdata.priceTotalB = price; zbdata.countB = 1; zbdata.priceB = zbdata.priceTotalB / (double)zbdata.countB;//计算该秒、买方向的平均价格 } else if (direction == -1) { zbdata.volumeS = volume; zbdata.priceTotalS = price; zbdata.countS = 1; zbdata.priceS = zbdata.priceTotalS / (double)zbdata.countS;//计算该秒、买方向的平均价格 } if ((zbdata.priceB > 0) && (zbdata.priceS > 0)) { zbdata.price = (zbdata.priceB + zbdata.priceS) / 2; } else { zbdata.price = (zbdata.priceB + zbdata.priceS); } zbdata.volume = zbdata.volumeB + zbdata.volumeS; //dataDict[data.Code].totalVolTillNow += zbdata.volume; if ((zbdata.volume == 0) || (zbdata.price == 0)) { continue; //空记录 } dataDict[data.Code].zbDataList.Add(zbdata); dataDict[data.Code].ZBLastIndex = dataDict[data.Code].ZBLastIndex + 1; } } /* * //数据获取部分 * ZBTickData zbdata = new ZBTickData(); * zbdata.timeStamp = Convert.ToInt32((double)data.Time / 1000); //去掉毫秒部分 * * //if (zbdata.timeStamp > 93850) { int i = 0; i++; } * * zbdata.price = (double)data.Price / 10000; * if (data.BSFlag == 66) * zbdata.direction = 1; * else if (data.BSFlag == 83) * zbdata.direction = -1; * else * zbdata.direction = 0; * zbdata.volume = data.Volume; * dataDict[data.Code].totalVolTillNow += zbdata.volume; * * dataDict[data.Code].zbDataList.Add(zbdata); * * if (dataDict[data.Code].zbDataList.Count == 1) //第一次添加 * { * dataDict[data.Code].ZBFirstIndex = 0; * dataDict[data.Code].ZBLastIndex = 0; * } * else * { * dataDict[data.Code].ZBLastIndex = dataDict[data.Code].ZBLastIndex + 1; * } */ } } //极其耗时,轻易不要打开 //RecvDataReport(this, null); } } else if (msg.MsgID == TDFMSGID.MSG_DATA_ORDER) { //逐笔委托 TDFOrder[] orderDataArr = msg.Data as TDFOrder[]; foreach (TDFOrder data in orderDataArr) { return; } } else if (msg.MsgID == TDFMSGID.MSG_DATA_ORDERQUEUE) { //委托队列 TDFOrderQueue[] orderQueueArr = msg.Data as TDFOrderQueue[]; foreach (TDFOrderQueue data in orderQueueArr) { return; } } }
//重载OnRecvDataMsg方法,接收行情数据 // 请注意: // 1. 不要在这个函数里做耗时操作 // 2. 只在这个函数里做数据获取工作 -- 将数据复制到其它数据缓存区,由其它线程做业务逻辑处理 public override void OnRecvDataMsg(TDFMSG msg) { try { if (msg.MsgID == TDFMSGID.MSG_DATA_MARKET) { //行情消息 TDFMarketData[] marketDataArr = msg.Data as TDFMarketData[]; foreach (TDFMarketData data in marketDataArr) { // if (!ShowAllData) // Console.WriteLine(data.WindCode); // else // PrintHelper.PrintObject(data); // return; //Let's only show the first element. ChinaMarketValue.blkMarketInfo.TryAdd(data); } } else if (msg.MsgID == TDFMSGID.MSG_DATA_FUTURE) { //期货行情消息 //TDFFutureData[] futureDataArr = msg.Data as TDFFutureData[]; //foreach (TDFFutureData data in futureDataArr) //{ // if (!ShowAllData) // Console.WriteLine(data.WindCode); // else // PrintHelper.PrintObject(data); // return; //Let's only show the first element. //} } else if (msg.MsgID == TDFMSGID.MSG_DATA_INDEX) { //指数消息 //TDFIndexData[] indexDataArr = msg.Data as TDFIndexData[]; //foreach (TDFIndexData data in indexDataArr) //{ // if (!ShowAllData) // Console.WriteLine(data.WindCode); // else // PrintHelper.PrintObject(data); // return; //Let's only show the first element. //} } else if (msg.MsgID == TDFMSGID.MSG_DATA_TRANSACTION) { //逐笔成交 //TDFTransaction[] transactionDataArr = msg.Data as TDFTransaction[]; //foreach (TDFTransaction data in transactionDataArr) //{ // if (!ShowAllData) // Console.WriteLine(data.WindCode); // else // PrintHelper.PrintObject(data); // return; //Let's only show the first element. //} } else if (msg.MsgID == TDFMSGID.MSG_DATA_ORDER) { //逐笔委托 //TDFOrder[] orderDataArr = msg.Data as TDFOrder[]; //foreach (TDFOrder data in orderDataArr) //{ // if (!ShowAllData) // Console.WriteLine(data.WindCode); // else // PrintHelper.PrintObject(data); // return; //Let's only show the first element. //} } else if (msg.MsgID == TDFMSGID.MSG_DATA_ORDERQUEUE) { //委托队列 //TDFOrderQueue[] orderQueueArr = msg.Data as TDFOrderQueue[]; //foreach (TDFOrderQueue data in orderQueueArr) //{ // if (!ShowAllData) // Console.WriteLine(data.WindCode); // else // PrintHelper.PrintObject(data); // return; //Let's only show the first element. //} } } catch (Exception ex) { ChinaMarketValue.exceptionLog.log(ChinaMarketValue.logLevel, ex.ToString()); } }
/// <summary> /// TDFConnectResult /// public int ConnectID; //连接ID /// public bool ConnResult; //为0则表示连接失败,非0则表示连接成功 /// public string Ip; //连接TDFServer主机IP /// public string Password; //登录密码 /// public string Port; //连接TDFServer主机的端口 /// public string Username; //登录用户名 /// TDFLoginResult /// public int[] DynDate; //动态数据日期 /// public string Info; //登录结果文本 /// public bool LoginResult; //true表示登录验证成功,false表示登录验证失败 /// public string[] Markets; //市场代码 SZ, SH, CF, SHF, CZC, DCE /// /// TDFCodeResult /// public int[] CodeCount; //代码表项数 /// public int[] CodeDate; //代码表日期 /// public string Info; //代码表文本结果 /// public string[] Markets;//市场代码 SZ, SH, CF, SHF, CZC, DCE /// --调用GetCodeTable只能获得调用该函数为止的最新代码表,在运行程序中,当在回调函数中接收到新代码时,客户端可以再次调用GetCodeTable获得该新代码信息 /// /// TDFQuotationDateChange /// public string Market; //市场代码 /// public int NewDate; //新行情日期 /// public int OldDate; //原行情日期 /// /// TDFMarketClose /// public string Info; //闭市信息 /// public string Market; //交易所名称 /// public int Time; //时间(HHMMSSmmm) /// /// TDFCode /// public string CNName; //代码中文名称,如:沪银1302 /// public string Code; //原始代码,如:AG1302 /// public string ENName; //代码英文名称 /// public string Market; //交易所名称 /// public string WindCode; //万得代码,如:AG1302.SHF /// public int Type; //证券类型,详细类型 Type位与 0xFF /// //0x00 指数 /// //0x10 股票 (0x10 A股, 0x11中小板股,0x12创业板股) /// //0x20 基金 /// //0x30 债券&可转债 /// //0x40 回购 /// //0x60 权证 /// //0x70 期货(0x70指数期货,0x71商品期货,0x72股票期货) /// //0x80 外汇 /// //0xd0 银行利率 /// //0xe0 贵金属 /// //0xf0 其他 /// </summary> /// <param name="msg"></param> private void OnRecvSysMsg(TDFMSG msg) { switch (msg.MsgID) { case TDFMSGID.MSG_SYS_CONNECT_RESULT: { //连接结果 TDFConnectResult connectResult = msg.Data as TDFConnectResult; if (!connectResult.ConnResult) { string strMsg = string.Format("宏汇行情连接服务器失败: IP:{0} Port:{1} User:{2} Password:{3}", connectResult.Ip, connectResult.Port, connectResult.Username, connectResult.Password); logger.Error(strMsg); //TODO: notify the user to handle the connect failure Stop(); } else { string strMsg = "宏汇行情连接服务器成功!"; logger.Info(strMsg); } } break; case TDFMSGID.MSG_SYS_LOGIN_RESULT: { //登陆结果 TDFLoginResult loginResult = msg.Data as TDFLoginResult; if (!loginResult.LoginResult) { string strMsg = string.Format("宏汇行情登录失败: {0}", loginResult.Info); logger.Error(strMsg); //TODO: notify the user to handle the login failure Stop(); } else { string strMsg = "宏汇行情登录成功"; logger.Info(strMsg); } } break; case TDFMSGID.MSG_SYS_CODETABLE_RESULT: { //接收代码表结果 TDFCodeResult codeResult = msg.Data as TDFCodeResult; string strMsg = string.Format("获取到代码表, info:{0}, 市场个数:{1}", codeResult.Info, codeResult.Markets.Length); logger.Info(strMsg); //获取代码表内容,多个市场使用分号分割:SH;SZ;CF TDFCode[] codeArr; this._dataSource.GetCodeTable("", out codeArr); AddSecurity(codeArr); //if (codeArr[i].Type >= 0x90 && codeArr[i].Type <= 0x95) //{ // // 期权数据 // TDFOptionCode code = new TDFOptionCode(); // var ret = this._tdfImp.GetOptionCodeInfo(codeArr[i].WindCode, ref code); //} } break; case TDFMSGID.MSG_SYS_QUOTATIONDATE_CHANGE: { //行情日期变更。 TDFQuotationDateChange quotationChange = msg.Data as TDFQuotationDateChange; string strMsg = string.Format("接收到行情日期变更通知消息,market:{0}, old date:{1}, new date:{2}", quotationChange.Market, quotationChange.OldDate, quotationChange.NewDate); logger.Info(strMsg); } break; case TDFMSGID.MSG_SYS_MARKET_CLOSE: { //闭市消息 TDFMarketClose marketClose = msg.Data as TDFMarketClose; string strMsg = string.Format("接收到闭市消息, 交易所:{0}, 时间:{1}, 信息:{2}", marketClose.Market, marketClose.Time, marketClose.Info); logger.Info(strMsg); } break; case TDFMSGID.MSG_SYS_HEART_BEAT: { //心跳消息 logger.Info("接收到心跳消息!"); } break; default: break; } }
//重载 OnRecvSysMsg 方法,接收系统消息通知 // 请注意: // 1. 不要在这个函数里做耗时操作 // 2. 只在这个函数里做数据获取工作 -- 将数据复制到其它数据缓存区,由其它线程做业务逻辑处理 public override void OnRecvSysMsg(TDFMSG msg) { if (msg.MsgID == TDFMSGID.MSG_SYS_CONNECT_RESULT) { //连接结果 TDFConnectResult connectResult = msg.Data as TDFConnectResult; string strPrefix = connectResult.ConnResult ? "连接成功" : "连接失败"; ;//Console.WriteLine("{0}!server:{1}:{2},{3},{4}, connect id:{5}", strPrefix, connectResult.Ip, connectResult.Port, connectResult.Username, connectResult.Password, connectResult.ConnectID); } else if (msg.MsgID == TDFMSGID.MSG_SYS_LOGIN_RESULT) { TDFLoginResult loginResult = msg.Data as TDFLoginResult; if (loginResult.LoginResult) { //登陆结果 ;//Console.WriteLine("登陆成功,市场个数:{0}:", loginResult.Markets.Length); for (int i = 0; i < loginResult.Markets.Length; i++) { ;//Console.WriteLine("market:{0}, dyn-date:{1}", loginResult.Markets[i], loginResult.DynDate[i]); } } else { ;//Console.WriteLine("登陆失败!info:{0}", loginResult.Info); } } else if (msg.MsgID == TDFMSGID.MSG_SYS_CODETABLE_RESULT) { //接收代码表结果 TDFCodeResult codeResult = msg.Data as TDFCodeResult; ;//Console.WriteLine("获取到代码表, info:{0},市场个数:{1}", codeResult.Info, codeResult.Markets.Length); for (int i = 0; i < codeResult.Markets.Length; i++) { ;//Console.WriteLine("market:{0}, date:{1}, code count:{2}", codeResult.Markets[i], codeResult.CodeDate[i], codeResult.CodeCount[i]); } //客户端请自行保存代码表,本处演示怎么获取代码表内容 TDFCode[] codeArr; GetCodeTable("", out codeArr); ;//Console.WriteLine("接收到{0}项代码!, 输出前100项", codeArr.Length); for (int i = 0; i < 100 && i < codeArr.Length; i++) { if (codeArr[i].Type >= 0x90 && codeArr[i].Type <= 0x95) { // 期权数据 TDFOptionCode code = new TDFOptionCode(); var ret = GetOptionCodeInfo(codeArr[i].WindCode, ref code); ;//PrintHelper.PrintObject(code); } else { ;//PrintHelper.PrintObject(codeArr[i]); } } } else if (msg.MsgID == TDFMSGID.MSG_SYS_QUOTATIONDATE_CHANGE) { //行情日期变更。 TDFQuotationDateChange quotationChange = msg.Data as TDFQuotationDateChange; ;//Console.WriteLine("接收到行情日期变更通知消息,market:{0}, old date:{1}, new date:{2}", quotationChange.Market, quotationChange.OldDate, quotationChange.NewDate); } else if (msg.MsgID == TDFMSGID.MSG_SYS_MARKET_CLOSE) { //闭市消息 TDFMarketClose marketClose = msg.Data as TDFMarketClose; ;//Console.WriteLine("接收到闭市消息, 交易所:{0}, 时间:{1}, 信息:{2}", marketClose.Market, marketClose.Time, marketClose.Info); if (!(marketClose.Market == "CF")) { EvMarketClose(this, null); } } else if (msg.MsgID == TDFMSGID.MSG_SYS_HEART_BEAT) { //心跳消息 ;//Console.WriteLine("接收到心跳消息!"); } }
/// <summary> /// TDFMarketData /// public int ActionDay; //业务发生日(自然日) YYMMDD /// public uint[] AskPrice; //申卖价 /// public uint[] AskVol; //申卖量 /// public uint[] BidPrice; //申买价 /// public uint[] BidVol; //申买量 /// public string Code; //原始代码 /// public uint High; //最高价 /// public uint HighLimited; //涨停价 /// public int IOPV; //IOPV净值估值 /// public uint Low; //最低价 /// public uint LowLimited; //跌停价 /// public uint Match; //最新价 /// public uint NumTrades; //成交笔数 /// public uint Open; //开盘价 /// public uint PreClose; //前收盘价 /// public byte[] Prefix; //证券信息前缀 /// public int SD2; //升跌2(对比上一笔) /// public int Status; //状态 /// public int Syl1; //市盈率1 /// public int Syl2; //市盈率2 /// public int Time; //时间(HHMMSSmmm) /// public long TotalAskVol; //委托卖出总量 /// public long TotalBidVol; //委托买入总量 /// public int TradingDay; // /// public long Turnover; //成交总金额 /// public long Volume; //成交总量 /// public uint WeightedAvgAskPrice; //加权平均委卖价格 /// public uint WeightedAvgBidPrice; //加权平均委买价格 /// public string WindCode; //万得代码,如:600001.SH /// public int YieldToMaturity; //到期收益率 /// /// Status状态 /// //0 首日上市 /// //1 增发新股 /// //2 上网定价发行 /// //3 上网竞价发行 /// //A 交易节休市 /// //B 整体停牌 /// //C 全天收市 /// //D 暂停交易 /// //E Start - 启动交易盘 /// //F PRETR - 盘前处理 /// //H Holiday - 放假 /// //I OCALL - 开市集合竞价 /// //J ICALL - 盘中集合竞价 /// //K OPOBB - 开市订单簿平衡前期 /// //L IPOBB - 盘中订单簿平衡前期 /// //M OOBB - 开市订单簿平衡 /// //N IOBB - 盘中订单簿平衡 /// //O TRADE - 连续撮合 /// //P BREAK - 休市 /// //Q VOLA - 波动性中断 /// //R BETW - 交易间 /// //S NOTRD - 非交易服务支持 /// //T FCALL - 固定价格集合竞价 /// //U POSTR - 盘后处理 /// //V ENDTR - 结束交易 /// //W HALT - 暂停 /// //X SUSP - 停牌 /// //Y ADD - 新增产品 /// //Z DEL - 可删除的产品 /// //d 集合竞价阶段结束到连续竞价阶段开始之前的时段(如有) /// //G DEL - 不可恢复交易的熔断阶段(上交所的N) /// //Q VOLA - 波动性中断 /// //q 可恢复交易的熔断时段(上交所的M) /// /// TDFIndexData /// public int ActionDay; //业务发生日(自然日)(YYMMDD) /// public string Code; //原始代码 /// public int HighIndex; //最高指数 /// public int LastIndex; //最新指数 /// public int LowIndex; //最低指数 /// public int OpenIndex; //今开盘指数 /// public int PreCloseIndex;//前盘指数 /// public int Time; //时间(HHMMSSmmm) /// public long TotalVolume;//参与计算相应指数的交易数量 /// public int TradingDay; // /// public long Turnover; //参与计算相应指数的成交金额 /// public string WindCode; //万得代码 /// /// /// TDFFutureData /// public int ActionDay; //业务发生日(自然日)(YYMMDD) /// public uint[] AskPrice; //申卖价 /// public uint[] AskVol; //申卖量 /// public uint[] BidPrice; //申买价 /// public uint[] BidVol; //申买量 /// public uint Close; //今收盘 /// public string Code; //原始代码 /// public int CurrDelta; //今虚实度 /// public uint High; //最高价 /// public uint HighLimited; //涨停价 /// public uint Low; //最低价 /// public uint LowLimited; //跌停价 /// public uint Match; //最新价 /// public uint Open; //开盘价 /// public long OpenInterest; //持仓总量 /// public uint PreClose; //昨收盘价 /// public int PreDelta; //昨虚实度 /// public long PreOpenInterest;//昨持仓 /// public uint PreSettlePrice; //昨结算 /// public uint SettlePrice; //今结算 /// public int Status; //状态 /// public int Time; //时间(HHMMSSmmm) /// public int TradingDay; //交易日 /// public long Turnover; //成交总金额 /// public long Volume; //成交总量 /// public string WindCode; //万得代码 /// /// /// /// TDFOrderQueue /// public int ABItems; //明细个数 /// public int[] ABVolume; //订单明细 /// public int ActionDay; //自然日(YYMMDD) /// public string Code; //原始代码 /// public int Orders; //订单数量 /// public int Price; //委托价格 /// public int Side; //买卖方向('B': Bid, 'A': Ask) /// public int Time; //时间(HHMMSSmmm) /// public string WindCode; //万得代码 /// /// /// TDFTransaction /// public int ActionDay; //成交日期(YYMMDD) /// public int AskOrder; //叫卖方委托序号 /// public int BidOrder; //叫买方委托序号 /// public int BSFlag; //买卖方向(买:'B', 卖:'A',不明:' ') /// public string Code; //原始代码 /// public byte FunctionCode;//成交代码 /// public int Index; //成交编号 /// public byte OrderKind; //成交类别 /// public int Price; //成交价格 /// public int Time; //成交时间(HHMMSS) /// public int Turnover; //成交金额 /// public int Volume; //成交数量 /// public string WindCode; //万得代码 /// /// TDFOrder /// public int ActionDay; //委托日期(YYMMDD) /// public string Code; //原始代码 /// public byte FunctionCode; //委托代码 /// public int Order; //委托号 /// public byte OrderKind; //委托类别 /// public int Price; //委托价格 /// public int Time; //委托时间(HHMMSSmmm) /// public int Volume; //委托数量 /// public string WindCode; //万得代码 /// </summary> /// <param name="msg"></param> private void OnRecvDataMsg(TDFMSG msg) { switch (msg.MsgID) { case TDFMSGID.MSG_DATA_MARKET: { //行情消息 TDFMarketData[] marketOldDataArr = msg.Data as TDFMarketData[]; for (int i = 0, length = marketOldDataArr.Length; i < length; i++) { TDFMarketData data = marketOldDataArr[i]; string code = data.Code; string windCode = data.WindCode; MarketData marketData = new MarketData { InstrumentID = windCode, LimitUpDownFlag = LimitUpDownFlag.Normal, }; char status = (char)data.Status; switch (status) { case 'B': { marketData.TradingStatus = TradingStatus.Suspend; marketData.SuspendFlag = SuspendFlag.Suspend1Day; } break; case 'C': { marketData.TradingStatus = TradingStatus.Close; marketData.SuspendFlag = SuspendFlag.NoSuspension; } break; case 'D': { marketData.TradingStatus = TradingStatus.Suspend; marketData.SuspendFlag = SuspendFlag.SuspendTemp; } break; case 'W': { marketData.TradingStatus = TradingStatus.Suspend; marketData.SuspendFlag = SuspendFlag.SuspendTemp; } break; case 'X': { marketData.TradingStatus = TradingStatus.Suspend; marketData.SuspendFlag = SuspendFlag.Suspend1Day; } break; default: { //正常交易 marketData.TradingStatus = TradingStatus.Normal; marketData.SuspendFlag = SuspendFlag.NoSuspension; } break; } if (data.Match == 0) { //TODO: fix the close period marketData.TradingStatus = TradingStatus.Suspend; marketData.SuspendFlag = SuspendFlag.Suspend1Day; } else if (data.Match >= data.HighLimited) { marketData.TradingStatus = TradingStatus.Normal; marketData.SuspendFlag = SuspendFlag.NoSuspension; marketData.LimitUpDownFlag = LimitUpDownFlag.LimitUp; } else if (data.Match <= data.LowLimited) { marketData.TradingStatus = TradingStatus.Normal; marketData.SuspendFlag = SuspendFlag.NoSuspension; marketData.LimitUpDownFlag = LimitUpDownFlag.LimitDown; } marketData.CurrentPrice = (double)data.Match / 10000; marketData.PreClose = data.PreClose / 10000; if (data.AskPrice != null && data.AskPrice.Length >= 5) { marketData.SellPrice1 = (double)data.AskPrice[0] / 10000; marketData.SellPrice2 = (double)data.AskPrice[1] / 10000; marketData.SellPrice3 = (double)data.AskPrice[2] / 10000; marketData.SellPrice4 = (double)data.AskPrice[3] / 10000; marketData.SellPrice5 = (double)data.AskPrice[4] / 10000; } if (data.BidPrice != null && data.BidPrice.Length >= 5) { marketData.BuyPrice1 = (double)data.BidPrice[0] / 10000; marketData.BuyPrice2 = (double)data.BidPrice[1] / 10000; marketData.BuyPrice3 = (double)data.BidPrice[2] / 10000; marketData.BuyPrice4 = (double)data.BidPrice[3] / 10000; marketData.BuyPrice5 = (double)data.BidPrice[4] / 10000; } marketData.HighLimitPrice = (double)data.HighLimited / 10000; marketData.LowLimitPrice = (double)data.LowLimited / 10000; marketData.BuyAmount = data.TotalBidVol; marketData.SellAmount = data.TotalAskVol; _quote.Add(windCode, marketData); } } break; case TDFMSGID.MSG_DATA_FUTURE: { //期货行情消息 TDFFutureData[] futureDataArr = msg.Data as TDFFutureData[]; foreach (TDFFutureData data in futureDataArr) { string windCode = data.WindCode; if (!windCode.EndsWith(".CF")) { continue; } MarketData marketData = new MarketData { InstrumentID = windCode }; char status = (char)data.Status; switch (status) { case 'B': { marketData.TradingStatus = TradingStatus.Suspend; marketData.SuspendFlag = SuspendFlag.Suspend1Day; } break; case 'C': { marketData.TradingStatus = TradingStatus.Close; marketData.SuspendFlag = SuspendFlag.NoSuspension; } break; case 'D': { marketData.TradingStatus = TradingStatus.Suspend; marketData.SuspendFlag = SuspendFlag.SuspendTemp; } break; case 'W': { marketData.TradingStatus = TradingStatus.Suspend; marketData.SuspendFlag = SuspendFlag.SuspendTemp; } break; case 'X': { marketData.TradingStatus = TradingStatus.Suspend; marketData.SuspendFlag = SuspendFlag.Suspend1Day; } break; default: { //正常交易 marketData.TradingStatus = TradingStatus.Normal; marketData.SuspendFlag = SuspendFlag.NoSuspension; } break; } if (data.Match == 0) { //TODO: fix the close period marketData.TradingStatus = TradingStatus.Suspend; marketData.SuspendFlag = SuspendFlag.Suspend1Day; } else if (data.Match >= data.HighLimited) { marketData.TradingStatus = TradingStatus.Normal; marketData.SuspendFlag = SuspendFlag.Suspend1Day; marketData.LimitUpDownFlag = LimitUpDownFlag.LimitUp; } else if (data.Match <= data.LowLimited) { marketData.TradingStatus = TradingStatus.Normal; marketData.SuspendFlag = SuspendFlag.Suspend1Day; marketData.LimitUpDownFlag = LimitUpDownFlag.LimitDown; } marketData.CurrentPrice = (double)data.Match / 10000; marketData.PreClose = (double)data.PreClose / 10000; if (data.AskPrice != null && data.AskPrice.Length >= 5) { marketData.SellPrice1 = (double)data.AskPrice[0] / 10000; marketData.SellPrice2 = (double)data.AskPrice[1] / 10000; marketData.SellPrice3 = (double)data.AskPrice[2] / 10000; marketData.SellPrice4 = (double)data.AskPrice[3] / 10000; marketData.SellPrice5 = (double)data.AskPrice[4] / 10000; } if (data.BidPrice != null && data.BidPrice.Length >= 5) { marketData.BuyPrice1 = (double)data.BidPrice[0] / 10000; marketData.BuyPrice2 = (double)data.BidPrice[1] / 10000; marketData.BuyPrice3 = (double)data.BidPrice[2] / 10000; marketData.BuyPrice4 = (double)data.BidPrice[3] / 10000; marketData.BuyPrice5 = (double)data.BidPrice[4] / 10000; } marketData.HighLimitPrice = (double)data.HighLimited / 10000; marketData.LowLimitPrice = (double)data.LowLimited / 10000; //BuyAmount, SellAmount _quote.Add(windCode, marketData); } } break; case TDFMSGID.MSG_DATA_INDEX: { //指数消息 TDFIndexData[] indexDataArr = msg.Data as TDFIndexData[]; foreach (TDFIndexData data in indexDataArr) { string windCode = data.WindCode; MarketData marketData = new MarketData { InstrumentID = windCode }; marketData.CurrentPrice = (double)data.LastIndex / 10000; marketData.PreClose = (double)data.PreCloseIndex / 10000; _quote.Add(windCode, marketData); } } break; //case TDFMSGID.MSG_DATA_TRANSACTION: // { // TDFTransaction[] tranDataArr = msg.Data as TDFTransaction[]; // } // break; //case TDFMSGID.MSG_DATA_ORDER: // { // TDFOrder[] orderDataArr = msg.Data as TDFOrder[]; // } // break; //case TDFMSGID.MSG_DATA_ORDERQUEUE: // { // TDFOrderQueue[] orderQueueDataArr = msg.Data as TDFOrderQueue[]; // } // break; default: break; } }
//重载 OnRecvSysMsg 方法,接收系统消息通知 // 请注意: // 1. 不要在这个函数里做耗时操作 // 2. 只在这个函数里做数据获取工作 -- 将数据复制到其它数据缓存区,由其它线程做业务逻辑处理 public override void OnRecvSysMsg(TDFMSG msg) { if (msg.MsgID == TDFMSGID.MSG_SYS_CONNECT_RESULT) { //连接结果 TDFConnectResult connectResult = msg.Data as TDFConnectResult; string strPrefix = connectResult.ConnResult ? "连接成功" : "连接失败"; Console.WriteLine("{0}!server:{1}:{2},{3},{4}, connect id:{5}", strPrefix, connectResult.Ip, connectResult.Port, connectResult.Username, connectResult.Password, connectResult.ConnectID); } else if (msg.MsgID == TDFMSGID.MSG_SYS_LOGIN_RESULT) { TDFLoginResult loginResult = msg.Data as TDFLoginResult; if (loginResult.LoginResult) { //登陆结果 Console.WriteLine("登陆成功,市场个数:{0}:", loginResult.Markets.Length); for (int i = 0; i < loginResult.Markets.Length; i++) { Console.WriteLine("market:{0}, dyn-date:{1}", loginResult.Markets[i], loginResult.DynDate[i]); } } else { Console.WriteLine("登陆失败!info:{0}", loginResult.Info); } } else if (msg.MsgID == TDFMSGID.MSG_SYS_CODETABLE_RESULT) { //接收代码表结果 TDFCodeResult codeResult = msg.Data as TDFCodeResult; Console.WriteLine("获取到代码表, info:{0},市场个数:{1}", codeResult.Info, codeResult.Markets.Length); for (int i = 0; i < codeResult.Markets.Length; i++) { Console.WriteLine("market:{0}, date:{1}, code count:{2}", codeResult.Markets[i], codeResult.CodeDate[i], codeResult.CodeCount[i]); } //FileStream fsFile = new FileStream(@"d:\log.txt", FileMode.OpenOrCreate); //StreamWriter swWriter = new StreamWriter(fsFile); ////寫入數據 ////swWriter.WriteLine("Hello Wrold."); ////swWriter.WriteLine("It is now {0}", DateTime.Now.ToLongDateString()); ////客户端请自行保存代码表,本处演示怎么获取代码表内容 //TDFCode[] codeArr; //GetCodeTable("", out codeArr); ////Console.WriteLine("接收到{0}项代码!, 输出前100项", codeArr.Length); ////for (int i = 0; i < 100 && i < codeArr.Length; i++) //for (int i = 0; i < codeArr.Length; i++) //{ // if (codeArr[i].Type >= 0x90 && codeArr[i].Type <= 0x95) // { // // 期权数据 // TDFOptionCode code = new TDFOptionCode(); // var ret = GetOptionCodeInfo(codeArr[i].WindCode, ref code); // PrintHelper.PrintObject(code); // swWriter.WriteLine(codeArr[i].WindCode + "\t" + codeArr[i].Code + "\t" + codeArr[i].CNName + "\t" + codeArr[i].Type); // } // else // { // //PrintHelper.PrintObject(codeArr[i]); // swWriter.WriteLine(codeArr[i].WindCode + "\t" + codeArr[i].Code + "\t" + codeArr[i].CNName + "\t" + codeArr[i].Type); // } //} //swWriter.Close(); } else if (msg.MsgID == TDFMSGID.MSG_SYS_QUOTATIONDATE_CHANGE) { //行情日期变更。 TDFQuotationDateChange quotationChange = msg.Data as TDFQuotationDateChange; Console.WriteLine("接收到行情日期变更通知消息,market:{0}, old date:{1}, new date:{2}", quotationChange.Market, quotationChange.OldDate, quotationChange.NewDate); } else if (msg.MsgID == TDFMSGID.MSG_SYS_MARKET_CLOSE) { //闭市消息 TDFMarketClose marketClose = msg.Data as TDFMarketClose; Console.WriteLine("接收到闭市消息, 交易所:{0}, 时间:{1}, 信息:{2}", marketClose.Market, marketClose.Time, marketClose.Info); } else if (msg.MsgID == TDFMSGID.MSG_SYS_HEART_BEAT) { //心跳消息 Console.WriteLine("接收到心跳消息!"); } }
//重载OnRecvDataMsg方法,接收行情数据 // 请注意: // 1. 不要在这个函数里做耗时操作 // 2. 只在这个函数里做数据获取工作 -- 将数据复制到其它数据缓存区,由其它线程做业务逻辑处理 public override void OnRecvDataMsg(TDFMSG msg) { if (msg.MsgID == TDFMSGID.MSG_DATA_MARKET) { //行情消息 TDFMarketData[] marketDataArr = msg.Data as TDFMarketData[]; foreach (TDFMarketData data in marketDataArr) { if (!ShowAllData) { //Console.WriteLine("行情消息 - 代码:{0}, 时间:{1}, 价格:{2}, 交易量:{3} ", data.WindCode, data.Time, data.Match, data.Volume); Console.WriteLine("行情消息 - 代码:{0}, 时间:{1}, 价格:{2}, 交易量:{3} ", DateTime.Now.Second.ToString(), data.Time, data.Match, data.Volume); } else { PrintHelper.PrintObject(data); } return; //Let's only show the first element. } } else if (msg.MsgID == TDFMSGID.MSG_DATA_FUTURE) { //期货行情消息 TDFFutureData[] futureDataArr = msg.Data as TDFFutureData[]; foreach (TDFFutureData data in futureDataArr) { if (!ShowAllData) { Console.WriteLine(data.WindCode); } else { PrintHelper.PrintObject(data); } return; //Let's only show the first element. } } else if (msg.MsgID == TDFMSGID.MSG_DATA_INDEX) { //指数消息 TDFIndexData[] indexDataArr = msg.Data as TDFIndexData[]; foreach (TDFIndexData data in indexDataArr) { if (!ShowAllData) { Console.WriteLine("指数行情 - 代码:{0}, 时间:{1}, 价格:{2}, 交易量:{3} ", DateTime.Now.Second.ToString(), data.Time, data.LastIndex, data.TotalVolume); } else { PrintHelper.PrintObject(data); } return; //Let's only show the first element. } } else if (msg.MsgID == TDFMSGID.MSG_DATA_TRANSACTION) { //逐笔成交 TDFTransaction[] transactionDataArr = msg.Data as TDFTransaction[]; foreach (TDFTransaction data in transactionDataArr) { if (!ShowAllData) { Console.WriteLine("逐笔成交 - 代码:{0}, 时间:{1}, 价格:{2}, 交易量:{3} ", DateTime.Now.Second.ToString(), data.Time, data.Price, data.Volume); } else { PrintHelper.PrintObject(data); } return; //Let's only show the first element. } } else if (msg.MsgID == TDFMSGID.MSG_DATA_ORDER) { //逐笔委托 TDFOrder[] orderDataArr = msg.Data as TDFOrder[]; foreach (TDFOrder data in orderDataArr) { if (!ShowAllData) { Console.WriteLine("逐笔委托 - 代码:{0}, 时间:{1}, 价格:{2}, 交易量:{3} ", DateTime.Now.Second.ToString(), data.Time, data.Price, data.Volume); } else { PrintHelper.PrintObject(data); } return; //Let's only show the first element. } } else if (msg.MsgID == TDFMSGID.MSG_DATA_ORDERQUEUE) { //委托队列 TDFOrderQueue[] orderQueueArr = msg.Data as TDFOrderQueue[]; foreach (TDFOrderQueue data in orderQueueArr) { if (!ShowAllData) { Console.WriteLine("委托队列 - 代码:{0}, 时间:{1}, 价格:{2}, 第一单:{3} ", DateTime.Now.Second.ToString(), data.Time, data.Price, data.ABVolume[0]); } else { PrintHelper.PrintObject(data); } return; //Let's only show the first element. } } }
//重载OnRecvDataMsg方法,接收行情数据 // 请注意: // 1. 不要在这个函数里做耗时操作 // 2. 只在这个函数里做数据获取工作 -- 将数据复制到其它数据缓存区,由其它线程做业务逻辑处理 public override void OnRecvDataMsg(TDFMSG msg) { if (Queue_Data.GetQueueNumber() > 2000) { Queue_Data.GetQueue().Clear(); GlobalMarketLog.LogInstance.LogEvent("Queue_Data超量自动删除,时间:" + DateTime.Now.ToString()); } if (MarketInfoQueue.GetQueueLength() > 2000) { MarketInfoQueue.ClearQueue(); GlobalMarketLog.LogInstance.LogEvent("MarketInfoQueue超量自动删除,时间:" + DateTime.Now.ToString()); } if (msg.MsgID == TDFMSGID.MSG_DATA_MARKET) { //行情消息 TDFMarketData[] marketDataArr = msg.Data as TDFMarketData[]; foreach (TDFMarketData data in marketDataArr) { EnQueueType obj = new EnQueueType() { Type = "S", value = (object)data }; if (Queue_Data.Suspend == false) { if (!simulate_trade.MarketRecorder) { Queue_Data.GetQueue().Enqueue((object)obj); } if (data.Status == 68) { stop_plate_stocks.GetInstance().updateStopList(data); } if (simulate_trade.MarketRecorder) { MarketInfoQueue.EnQueueNew(data); } } } } else if (msg.MsgID == TDFMSGID.MSG_DATA_FUTURE) { //期货行情数据 TDFFutureData[] futureDataArr = msg.Data as TDFFutureData[]; foreach (TDFFutureData data in futureDataArr) { EnQueueType obj = new EnQueueType() { Type = "F", value = (object)data }; if (Queue_Data.Suspend == false) { Queue_Data.GetQueue().Enqueue((object)obj); } } } else if (msg.MsgID == TDFMSGID.MSG_DATA_INDEX) { //指数消息 TDFIndexData[] indexDataArr = msg.Data as TDFIndexData[]; foreach (TDFIndexData data in indexDataArr) { EnQueueType obj = new EnQueueType() { Type = "I", value = (object)data }; if (Queue_Data.Suspend == false) { Queue_Data.GetQueue().Enqueue((object)obj); } } } }