//登陆 public void Login(Account account) { if (account == null) { return; } mAccount = account; if (mTrader != null && mTrader.IsLogin) { return; } //初始化 mTrader = new CTPTrade(); //连接 mTrader.OnFrontConnected += (object sender, EventArgs e) => { mTrader.ReqUserLogin(mAccount.Investor, mAccount.Password, mAccount.Broker); LogUtils.EnginLog("ctptd:OnFrontConnected"); }; //登入 mTrader.OnRspUserLogin += (object sender, IntEventArgs e) => { if (e.Value != 0) { Logout(); mTrader = null; } LogUtils.EnginLog("ctptd:OnRspUserLogin:"******"ctptd:OnRspUserLogout"); }; //订单回报 mTrader.OnRtnOrder += _OnRtnOrder; //报单错误回报 mTrader.OnRtnErrOrder += _OnRtnErrOrder; //交易回报 mTrader.OnRtnTrade += _OnRtnTrade; //撤单回报 mTrader.OnRtnCancel += _OnRtnCancel; //撤单错误 mTrader.OnRtnErrCancel += _OnRtnErrCancel; mTrader.OnRtnExchangeStatus += _OnRtnExchangeStatus; //开始连接 mTrader.ReqConnect(mAccount.Server); }
public static bool TryConvert(Trade trade, ref CThostFtdcDepthMarketDataField DepthMarketData) { #if OQ if (tradeField == null) { tradeField = typeof(Trade).GetField("trade", BindingFlags.NonPublic | BindingFlags.Instance); } CTPTrade t = tradeField.GetValue(trade) as CTPTrade; #elif QD CTPTrade t = trade as CTPTrade; #endif if (null != t) { DepthMarketData = t.DepthMarketData; return(true); } return(false); }
private void OnRtnDepthMarketData(IntPtr pApi, ref CThostFtdcDepthMarketDataField pDepthMarketData) { #if CTP string symbol = pDepthMarketData.InstrumentID; #elif CTPZQ string symbol = GetYahooSymbol(pDepthMarketData.InstrumentID, pDepthMarketData.ExchangeID); #endif DataRecord record; if (!_dictAltSymbol2Instrument.TryGetValue(symbol, out record)) { mdlog.Warn("合约{0}不在订阅列表中却收到了数据", symbol); return; } Instrument instrument = record.Instrument; CThostFtdcDepthMarketDataField DepthMarket; _dictDepthMarketData.TryGetValue(symbol, out DepthMarket); //将更新字典的功能提前,因为如果一开始就OnTrade中下单,涨跌停没有更新 _dictDepthMarketData[symbol] = pDepthMarketData; if (TimeMode.LocalTime == _TimeMode) { //为了生成正确的Bar,使用本地时间 _dateTime = Clock.Now; } else { //直接按HH:mm:ss来解析,测试过这种方法目前是效率比较高的方法 try { // 只有使用交易所行情时才需要处理跨天的问题 #if CTP ChangeActionDay(pDepthMarketData.ActionDay); #else ChangeActionDay(pDepthMarketData.TradingDay); #endif int HH = int.Parse(pDepthMarketData.UpdateTime.Substring(0, 2)); int mm = int.Parse(pDepthMarketData.UpdateTime.Substring(3, 2)); int ss = int.Parse(pDepthMarketData.UpdateTime.Substring(6, 2)); _dateTime = new DateTime(_yyyy, _MM, _dd, HH, mm, ss, pDepthMarketData.UpdateMillisec); } catch (Exception) { _dateTime = Clock.Now; } } if (record.TradeRequested) { //通过测试,发现IB的Trade与Quote在行情过来时数量是不同的,在这也做到不同 if (DepthMarket.LastPrice == pDepthMarketData.LastPrice && DepthMarket.Volume == pDepthMarketData.Volume) { } else { //行情过来时是今天累计成交量,得转换成每个tick中成交量之差 int volume = pDepthMarketData.Volume - DepthMarket.Volume; if (0 == DepthMarket.Volume) { //没有接收到最开始的一条,所以这计算每个Bar的数据时肯定超大,强行设置为0 volume = 0; } else if (volume < 0) { //如果隔夜运行,会出现今早成交量0-昨收盘成交量,出现负数,所以当发现为负时要修改 volume = pDepthMarketData.Volume; } // 使用新的类,保存更多信息 CTPTrade trade = new CTPTrade(_dateTime, pDepthMarketData.LastPrice == double.MaxValue ? 0 : pDepthMarketData.LastPrice, volume); // 记录深度数据 trade.DepthMarketData = pDepthMarketData; EmitNewTradeEvent(instrument, trade); } } if (record.QuoteRequested) { //if ( //DepthMarket.BidVolume1 == pDepthMarketData.BidVolume1 //&& DepthMarket.AskVolume1 == pDepthMarketData.AskVolume1 //&& DepthMarket.BidPrice1 == pDepthMarketData.BidPrice1 //&& DepthMarket.AskPrice1 == pDepthMarketData.AskPrice1 //) //{ } //else { CTPQuote quote = new CTPQuote(_dateTime, pDepthMarketData.BidPrice1 == double.MaxValue ? 0 : pDepthMarketData.BidPrice1, pDepthMarketData.BidVolume1, pDepthMarketData.AskPrice1 == double.MaxValue ? 0 : pDepthMarketData.AskPrice1, pDepthMarketData.AskVolume1 ); quote.DepthMarketData = pDepthMarketData; EmitNewQuoteEvent(instrument, quote); } } if (record.MarketDepthRequested) { bool bAsk = true; bool bBid = true; if (bAsk) { bAsk = EmitNewMarketDepth(instrument, _dateTime, 0, MDSide.Ask, pDepthMarketData.AskPrice1, pDepthMarketData.AskVolume1); } if (bBid) { bBid = EmitNewMarketDepth(instrument, _dateTime, 0, MDSide.Bid, pDepthMarketData.BidPrice1, pDepthMarketData.BidVolume1); } #if CTPZQ if (bAsk) { bAsk = EmitNewMarketDepth(instrument, _dateTime, 1, MDSide.Ask, pDepthMarketData.AskPrice2, pDepthMarketData.AskVolume2); } if (bBid) { bBid = EmitNewMarketDepth(instrument, _dateTime, 1, MDSide.Bid, pDepthMarketData.BidPrice2, pDepthMarketData.BidVolume2); } if (bAsk) { bAsk = EmitNewMarketDepth(instrument, _dateTime, 2, MDSide.Ask, pDepthMarketData.AskPrice3, pDepthMarketData.AskVolume3); } if (bBid) { bBid = EmitNewMarketDepth(instrument, _dateTime, 2, MDSide.Bid, pDepthMarketData.BidPrice3, pDepthMarketData.BidVolume3); } if (bAsk) { bAsk = EmitNewMarketDepth(instrument, _dateTime, 3, MDSide.Ask, pDepthMarketData.AskPrice4, pDepthMarketData.AskVolume4); } if (bBid) { bBid = EmitNewMarketDepth(instrument, _dateTime, 3, MDSide.Bid, pDepthMarketData.BidPrice4, pDepthMarketData.BidVolume4); } if (bAsk) { bAsk = EmitNewMarketDepth(instrument, _dateTime, 4, MDSide.Ask, pDepthMarketData.AskPrice5, pDepthMarketData.AskVolume5); } if (bBid) { bBid = EmitNewMarketDepth(instrument, _dateTime, 4, MDSide.Bid, pDepthMarketData.BidPrice5, pDepthMarketData.BidVolume5); } #endif } }
private void OnRtnDepthMarketData(IntPtr pApi, ref CThostFtdcDepthMarketDataField pDepthMarketData) { #if CTP string symbol = pDepthMarketData.InstrumentID; #elif CTPZQ string symbol = GetYahooSymbol(pDepthMarketData.InstrumentID, pDepthMarketData.ExchangeID); #endif DataRecord record; if (!_dictAltSymbol2Instrument.TryGetValue(symbol, out record)) { mdlog.Warn("合约{0}不在订阅列表中却收到了数据", symbol); return; } Instrument instrument = record.Instrument; CThostFtdcDepthMarketDataField DepthMarket; _dictDepthMarketData.TryGetValue(symbol, out DepthMarket); //将更新字典的功能提前,因为如果一开始就OnTrade中下单,涨跌停没有更新 _dictDepthMarketData[symbol] = pDepthMarketData; if (TimeMode.LocalTime == _TimeMode) { //为了生成正确的Bar,使用本地时间 _dateTime = Clock.Now; } else { //直接按HH:mm:ss来解析,测试过这种方法目前是效率比较高的方法 try { // 只有使用交易所行情时才需要处理跨天的问题 #if CTP ChangeActionDay(pDepthMarketData.ActionDay); #else ChangeActionDay(pDepthMarketData.TradingDay); #endif int HH = int.Parse(pDepthMarketData.UpdateTime.Substring(0, 2)); int mm = int.Parse(pDepthMarketData.UpdateTime.Substring(3, 2)); int ss = int.Parse(pDepthMarketData.UpdateTime.Substring(6, 2)); _dateTime = new DateTime(_yyyy, _MM, _dd, HH, mm, ss, pDepthMarketData.UpdateMillisec); } catch (Exception) { _dateTime = Clock.Now; } } if (record.TradeRequested) { //通过测试,发现IB的Trade与Quote在行情过来时数量是不同的,在这也做到不同 if (DepthMarket.LastPrice == pDepthMarketData.LastPrice && DepthMarket.Volume == pDepthMarketData.Volume) { } else { //行情过来时是今天累计成交量,得转换成每个tick中成交量之差 int volume = pDepthMarketData.Volume - DepthMarket.Volume; if (0 == DepthMarket.Volume) { //没有接收到最开始的一条,所以这计算每个Bar的数据时肯定超大,强行设置为0 volume = 0; } else if (volume < 0) { //如果隔夜运行,会出现今早成交量0-昨收盘成交量,出现负数,所以当发现为负时要修改 volume = pDepthMarketData.Volume; } // 使用新的类,保存更多信息 CTPTrade trade = new CTPTrade(_dateTime, pDepthMarketData.LastPrice == double.MaxValue ? 0 : pDepthMarketData.LastPrice, volume); // 记录深度数据 trade.DepthMarketData = pDepthMarketData; EmitNewTradeEvent(instrument, trade); } } if (record.QuoteRequested) { //if ( //DepthMarket.BidVolume1 == pDepthMarketData.BidVolume1 //&& DepthMarket.AskVolume1 == pDepthMarketData.AskVolume1 //&& DepthMarket.BidPrice1 == pDepthMarketData.BidPrice1 //&& DepthMarket.AskPrice1 == pDepthMarketData.AskPrice1 //) //{ } //else { CTPQuote quote = new CTPQuote(_dateTime, pDepthMarketData.BidPrice1 == double.MaxValue ? 0 : pDepthMarketData.BidPrice1, pDepthMarketData.BidVolume1, pDepthMarketData.AskPrice1 == double.MaxValue ? 0 : pDepthMarketData.AskPrice1, pDepthMarketData.AskVolume1 ); quote.DepthMarketData = pDepthMarketData; EmitNewQuoteEvent(instrument, quote); } } if (record.MarketDepthRequested) { bool bAsk = true; bool bBid = true; if (bAsk) bAsk = EmitNewMarketDepth(instrument, _dateTime, 0, MDSide.Ask, pDepthMarketData.AskPrice1, pDepthMarketData.AskVolume1); if (bBid) bBid = EmitNewMarketDepth(instrument, _dateTime, 0, MDSide.Bid, pDepthMarketData.BidPrice1, pDepthMarketData.BidVolume1); #if CTPZQ if(bAsk) bAsk = EmitNewMarketDepth(instrument, _dateTime, 1, MDSide.Ask, pDepthMarketData.AskPrice2, pDepthMarketData.AskVolume2); if(bBid) bBid = EmitNewMarketDepth(instrument, _dateTime, 1, MDSide.Bid, pDepthMarketData.BidPrice2, pDepthMarketData.BidVolume2); if(bAsk) bAsk = EmitNewMarketDepth(instrument, _dateTime, 2, MDSide.Ask, pDepthMarketData.AskPrice3, pDepthMarketData.AskVolume3); if(bBid) bBid = EmitNewMarketDepth(instrument, _dateTime, 2, MDSide.Bid, pDepthMarketData.BidPrice3, pDepthMarketData.BidVolume3); if(bAsk) bAsk = EmitNewMarketDepth(instrument, _dateTime, 3, MDSide.Ask, pDepthMarketData.AskPrice4, pDepthMarketData.AskVolume4); if(bBid) bBid = EmitNewMarketDepth(instrument, _dateTime, 3, MDSide.Bid, pDepthMarketData.BidPrice4, pDepthMarketData.BidVolume4); if(bAsk) bAsk = EmitNewMarketDepth(instrument, _dateTime, 4, MDSide.Ask, pDepthMarketData.AskPrice5, pDepthMarketData.AskVolume5); if(bBid) bBid = EmitNewMarketDepth(instrument, _dateTime, 4, MDSide.Bid, pDepthMarketData.BidPrice5, pDepthMarketData.BidVolume5); #endif } }
static void Main(string[] args) { //var msg = "CTP:登录成功。您的密码为弱密码,密码长度不可少于6位"; //Console.WriteLine(Encoding.Default.BodyName); //var gb = CodePagesEncodingProvider.Instance.GetEncoding("GB2312"); //var bytes = Encoding.Default.GetBytes(msg); //Console.WriteLine(msg.Length); //Console.WriteLine(bytes.Length); //Console.WriteLine(gb.GetBytes(msg).Length); //return; // Encoding.RegisterProvider(CodePagesEncodingProvider.Instance.GetEncoding("GB2312")); //var codePage = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage; //Console.WriteLine(codePage); //// CTP:登录成功。您的密码为弱密码,密码长度不可少于6位 //var codeGB2312 = CodePagesEncodingProvider.Instance.GetEncoding("GB2312"); //Console.WriteLine(codeGB2312.CodePage); //var bodyName = Encoding.Default.BodyName; //Console.WriteLine(bodyName); Logger.Info("start2."); QuoteSave qs = null; var t = new CTPTrade("ctp_trade"); System.AppDomain.CurrentDomain.UnhandledException += (sender, e) => { if (sender != null) { Logger.Error("UnhandledException sender= {0}", sender.ToString()); } if (e.ExceptionObject != null) { var ex = e.ExceptionObject as Exception; if (ex != null) { Logger.Error("UnhandledException ex ", ex.StackTrace); } else { Logger.Error("UnhandledException errorObj {0}", e.ExceptionObject.ToString()); } } Logger.Info("IsTerminating : {0}", e.IsTerminating); }; // 登录交易账号,获得当前所有正在交易的期货代码 t.OnFrontConnected += (sender, e) => { t.ReqUserLogin(investor, pwd, "9999"); t.OnRspUserLogin += (sender2, e2) => { if (e2.Value == 0) { Logger.Info("Login success"); List <string> codes = new List <string>(); foreach (var instrument in t.DicInstrumentField.Values) { codes.Add(instrument.InstrumentID); } Logger.Info("code num: {0}", codes.Count); qs = new QuoteSave(investor, pwd, codes.ToArray()); qs.Run(); } else { Console.WriteLine("登录失败!ret=" + e2.Value); } }; }; t.ReqConnect("tcp://180.168.146.187:10000"); bool isWaitConsole = true; if (args.Length == 1 && args[0] == "linux") { isWaitConsole = false; Logger.Info("not wait console input."); } while (true) { if (isWaitConsole) { var key = Console.ReadKey(); if (key.Key == ConsoleKey.Escape || key.Key == ConsoleKey.Spacebar || key.Key == ConsoleKey.Enter) { break; } } Logger.Info("wait"); Thread.Sleep(500); } qs?.Release(); t?.ReqUserLogout(); }