static void OnRtnDepthMarketData(object sender, ref DepthMarketDataNClass marketData) { Debugger.Log(0, null, "CTP:C#"); Console.WriteLine(marketData.InstrumentID); Console.WriteLine(marketData.Exchange); Console.WriteLine(marketData.LastPrice); }
public static DepthMarketDataNClass GetDepthMarketDataNClass(IntPtr ptr) { DepthMarketDataNField obj = (DepthMarketDataNField)Marshal.PtrToStructure(ptr, typeof(DepthMarketDataNField)); DepthMarketDataNClass cls = new DepthMarketDataNClass(); //obj.Size; cls.TradingDay = obj.TradingDay; cls.ActionDay = obj.ActionDay; cls.UpdateTime = obj.UpdateTime; cls.UpdateMillisec = obj.UpdateMillisec; cls.Exchange = obj.Exchange; cls.Symbol = obj.Symbol; cls.InstrumentID = obj.InstrumentID; cls.LastPrice = obj.LastPrice; cls.Volume = obj.Volume; cls.Turnover = obj.Turnover; cls.OpenInterest = obj.OpenInterest; cls.AveragePrice = obj.AveragePrice; cls.OpenPrice = obj.OpenPrice; cls.HighestPrice = obj.HighestPrice; cls.LowestPrice = obj.LowestPrice; cls.ClosePrice = obj.ClosePrice; cls.SettlementPrice = obj.SettlementPrice; cls.UpperLimitPrice = obj.UpperLimitPrice; cls.LowerLimitPrice = obj.LowerLimitPrice; cls.PreClosePrice = obj.PreClosePrice; cls.PreSettlementPrice = obj.PreSettlementPrice; cls.PreOpenInterest = obj.PreOpenInterest; cls.TradingPhase = obj.TradingPhase; //obj.BidCount; int size = Marshal.SizeOf(typeof(DepthField)); IntPtr pBid = new IntPtr(ptr.ToInt64() + Marshal.SizeOf(typeof(DepthMarketDataNField))); int AskCount = (obj.Size - Marshal.SizeOf(typeof(DepthMarketDataNField))) / size - obj.BidCount; IntPtr pAsk = new IntPtr(ptr.ToInt64() + Marshal.SizeOf(typeof(DepthMarketDataNField)) + obj.BidCount * size); cls.Bids = new DepthField[obj.BidCount]; cls.Asks = new DepthField[AskCount]; for (int i = 0; i < obj.BidCount; ++i) { cls.Bids[i] = (DepthField)Marshal.PtrToStructure(new IntPtr(pBid.ToInt64() + i * size), typeof(DepthField)); } for (int i = 0; i < AskCount; ++i) { cls.Asks[i] = (DepthField)Marshal.PtrToStructure(new IntPtr(pAsk.ToInt64() + i * size), typeof(DepthField)); } return(cls); }
public static DateTime ExchangeDateTime([In] this DepthMarketDataNClass field) { int HH = field.UpdateTime / 10000; int mm = field.UpdateTime % 10000 / 100; int ss = field.UpdateTime % 100; int yyyy = field.ActionDay / 10000; int MM = field.ActionDay % 10000 / 100; int dd = field.ActionDay % 100; return(new DateTime(yyyy, MM, dd, HH, mm, ss, field.UpdateMillisec)); }
static void OnRtnDepthMarketData(object sender, ref DepthMarketDataNClass marketData) { Debugger.Log(0, null, "CTP:C#"); Console.WriteLine(marketData.InstrumentID); //Console.WriteLine(marketData.Exchange); Console.WriteLine(marketData.LastPrice); //Console.WriteLine(marketData.OpenInterest); if (marketData.Bids.Count() > 0) { Console.WriteLine(marketData.Bids[0].Price); } if (marketData.Asks.Count() > 0) { Console.WriteLine(marketData.Asks[0].Price); } }
public static DateTime ExchangeDateTime_([In] this DepthMarketDataNClass field) { // 表示传回来的时间可能有问题,要检查一下 if (field.UpdateTime == 0) { DateTime now = DateTime.Now; int HH = now.Hour; int mm = now.Minute; int ss = now.Second; int datetime = HH * 10000 + mm * 100 + ss; if (datetime > 1500 && datetime < 234500) { return(now); } } { int HH = field.UpdateTime / 10000; int mm = field.UpdateTime % 10000 / 100; int ss = field.UpdateTime % 100; DateTime now = DateTime.Now; if (HH >= 23) { if (now.Hour < 1) { // 表示行情时间慢了,系统日期减一天即可 now = now.AddDays(-1); } } else if (HH < 1) { if (now.Hour >= 23) { // 表示本地时间慢了,本地时间加一天即可 now = now.AddDays(1); } } return(now.Date.AddSeconds(HH * 3600 + mm * 60 + ss).AddMilliseconds(field.UpdateMillisec)); } }
//public ActionBlock<DepthMarketDataField> Input; //public void OnInputMarketData(DepthMarketDataField pDepthMarketData) //{ // if (!_tickWriter.Write(ref pDepthMarketData)) // { // Instrument i = framework.InstrumentManager.Get(pDepthMarketData.Symbol); // if (i != null) // { // _tickWriter.AddInstrument(i); // _tickWriter.Write(ref pDepthMarketData); // } // } //} private void OnRtnDepthMarketData_callback(object sender, ref DepthMarketDataNClass pDepthMarketData) { //if (_SaveToPd0) //{ // Input.Post(pDepthMarketData); //} if (!_enableEmitData) return; try { // 传过来的Symbol,有可能是不带点,有可能是带点的 // 要同时存成完整版,因为下单时 MarketDataRecord record; if (!marketDataRecords.TryGetValue(pDepthMarketData.Symbol, out record)) { //if (!marketDataRecords.TryGetValue(pDepthMarketData.InstrumentID, out record)) //{ // //(sender as XApi).Log.Warn("合约 {0} {1} 不在订阅列表中却收到了数据", pDepthMarketData.Symbol, pDepthMarketData.InstrumentID); // return; //} return; } // 取出上次的行情记录 DepthMarketDataNClass depthMarket = record.DepthMarket; //将更新字典的功能提前,因为如果一开始就OnTrade中下单,涨跌停没有更新 record.DepthMarket = pDepthMarketData; _dateTime = DateTime.Now; try { _exchangeDateTime = pDepthMarketData.ExchangeDateTime(); } catch { _exchangeDateTime = _dateTime; (sender as XApi).Log.Error("{0} ExchangeDateTime有误,现使用LocalDateTime代替,请找API开发人员处理API中的时间兼容问题。", pDepthMarketData.ToFormattedStringExchangeDateTime()); } if (_emitBidAskFirst) { if (_emitBidAsk) { FireBid(record.Instrument.Id, _dateTime, _exchangeDateTime, pDepthMarketData, depthMarket); FireAsk(record.Instrument.Id, _dateTime, _exchangeDateTime, pDepthMarketData, depthMarket); } FireTrade(record.Instrument.Id, _dateTime, _exchangeDateTime, pDepthMarketData, depthMarket); } else { FireTrade(record.Instrument.Id, _dateTime, _exchangeDateTime, pDepthMarketData, depthMarket); if (_emitBidAsk) { FireBid(record.Instrument.Id, _dateTime, _exchangeDateTime, pDepthMarketData, depthMarket); FireAsk(record.Instrument.Id, _dateTime, _exchangeDateTime, pDepthMarketData, depthMarket); } } } catch (Exception ex) { (sender as XApi).Log.Error(ex); } }
private void FireAsk(int InstrumentId, DateTime _dateTime, DateTime _exchangeDateTime, DepthMarketDataNClass pDepthMarketData, DepthMarketDataNClass DepthMarket) { do { if (pDepthMarketData.Asks == null || pDepthMarketData.Asks.Length == 0) break; if (DepthMarket.Asks != null && DepthMarket.Asks.Length > 0) { if (DepthMarket.Asks[0].Size == pDepthMarketData.Asks[0].Size && DepthMarket.Asks[0].Price == pDepthMarketData.Asks[0].Price) { // 由于与上次一样,不能动 break; } } Ask ask = new Ask( _dateTime, _exchangeDateTime, this.id, InstrumentId, pDepthMarketData.Asks[0].Price, pDepthMarketData.Asks[0].Size); EmitData(ask); } while (false); }
private void FireBid(int InstrumentId, DateTime _dateTime, DateTime _exchangeDateTime, DepthMarketDataNClass pDepthMarketData, DepthMarketDataNClass DepthMarket) { do { if (pDepthMarketData.Bids == null || pDepthMarketData.Bids.Length == 0) break; if (DepthMarket.Bids != null && DepthMarket.Bids.Length > 0) { if (DepthMarket.Bids[0].Size == pDepthMarketData.Bids[0].Size && DepthMarket.Bids[0].Price == pDepthMarketData.Bids[0].Price) { // 由于与上次一样,不能动 break; } } Bid bid = new Bid( _dateTime, _exchangeDateTime, this.id, InstrumentId, pDepthMarketData.Bids[0].Price, pDepthMarketData.Bids[0].Size); EmitData(bid); } while (false); }
private void FireTrade(int InstrumentId,DateTime _dateTime, DateTime _exchangeDateTime, DepthMarketDataNClass pDepthMarketData,DepthMarketDataNClass DepthMarket) { //行情过来时是今天累计成交量,得转换成每个tick中成交量之差 double volume = pDepthMarketData.Volume - DepthMarket.Volume; // 以前第一条会导致集合竞价后的第一条没有成交量,这种方法就明确了上一笔是空数据 if (0 == DepthMarket.TradingDay && 0 == DepthMarket.ActionDay) { //没有接收到最开始的一条,所以这计算每个Bar的数据时肯定超大,强行设置为0 volume = 0; } else if (volume < 0) { //如果隔夜运行,会出现今早成交量0-昨收盘成交量,出现负数,所以当发现为负时要修改 volume = pDepthMarketData.Volume; } // 使用新的类,保存更多信息 var trade = new TradeEx( _dateTime, _exchangeDateTime, this.id, InstrumentId, pDepthMarketData.LastPrice, (int) volume) {DepthMarketData = pDepthMarketData}; // 启用底层数据上传 EmitData(trade); }
public bool Write(ref DepthMarketDataNClass pDepthMarketData) { QuantBox.Data.Serializer.V2.TickWriter.WriterDataItem item; if (Items.TryGetValue(pDepthMarketData.Symbol, out item)) { item.Tick = CreateTick(ref pDepthMarketData, item.Serializer.Codec); base.Write(item, item.Tick); return true; } return false; }
// 目前先不处理港股的tickSize变化的那种行情 PbTick CreateTick(ref DepthMarketDataNClass pDepthMarketData, PbTickCodec codec) { var tick = new PbTick(); tick.DepthList = new List<DepthItem>(); tick.Config = codec.Config; tick.TradingDay = pDepthMarketData.TradingDay; tick.ActionDay = pDepthMarketData.ActionDay; tick.Time_HHmm = pDepthMarketData.UpdateTime / 100; tick.Time_____ssf__ = pDepthMarketData.UpdateTime % 100 * 10 + pDepthMarketData.UpdateMillisec / 100; tick.Time________ff = pDepthMarketData.UpdateMillisec % 100; // 数据接收器时计算本地与交易所的行情时间差 // 1.这个地方是否保存? // 2.到底是XAPI中提供还是由接收器提供? //tick.LocalTime_Msec = (int)(DateTime.Now - codec.GetActionDayDateTime(tick)).TotalMilliseconds; codec.SetSymbol(tick, pDepthMarketData.Symbol); if (pDepthMarketData.Exchange != ExchangeType.Undefined) codec.SetExchange(tick, Enum<ExchangeType>.ToString(pDepthMarketData.Exchange)); codec.SetLowerLimitPrice(tick, pDepthMarketData.LowerLimitPrice); codec.SetUpperLimitPrice(tick, pDepthMarketData.UpperLimitPrice); codec.SetOpen(tick, pDepthMarketData.OpenPrice); codec.SetHigh(tick, pDepthMarketData.HighestPrice); codec.SetLow(tick, pDepthMarketData.LowestPrice); codec.SetClose(tick, pDepthMarketData.ClosePrice); codec.SetVolume(tick, (long)pDepthMarketData.Volume); codec.SetOpenInterest(tick, (long)pDepthMarketData.OpenInterest); codec.SetTurnover(tick, pDepthMarketData.Turnover);//一定要设置合约乘数才能最优保存 codec.SetAveragePrice(tick, pDepthMarketData.AveragePrice); codec.SetLastPrice(tick, pDepthMarketData.LastPrice); codec.SetSettlementPrice(tick, pDepthMarketData.SettlementPrice); codec.SetPreClosePrice(tick, pDepthMarketData.PreClosePrice); codec.SetPreSettlementPrice(tick, pDepthMarketData.PreSettlementPrice); codec.SetPreOpenInterest(tick, (long)pDepthMarketData.PreOpenInterest); for(int i = pDepthMarketData.Bids.Length - 1;i>=0;--i) { var bid = pDepthMarketData.Bids[i]; if (bid.Size == 0) break; // 记录卖一价 if (i == 0) { codec.SetAskPrice1(tick, bid.Price); tick.AskPrice1 += 1; } tick.DepthList.Add(new DepthItem(codec.PriceToTick(bid.Price), bid.Size, bid.Count)); } for (int i = 0; i < pDepthMarketData.Asks.Length; ++i) { var ask = pDepthMarketData.Asks[i]; if (ask.Size == 0) break; // 记录卖一价 if (i == 0) { codec.SetAskPrice1(tick, ask.Price); } tick.DepthList.Add(new DepthItem(codec.PriceToTick(ask.Price), ask.Size, ask.Count)); } return tick; }
public static string ToFormattedStringExchangeDateTime([In] this DepthMarketDataNClass field) { return(string.Format("[TradingDay={0};ActionDay={1};UpdateTime={2},UpdateMillisec={3}]", field.TradingDay, field.ActionDay, field.UpdateTime, field.UpdateMillisec)); }
public MarketDataRecord(Instrument instrument) { this.Instrument = instrument; this.DepthMarket = new DepthMarketDataNClass(); }
public void OnInputMarketData(DepthMarketDataNClass pDepthMarketData) { TickWriter.Write(ref pDepthMarketData); }
private void OnRtnDepthMarketData(object sender, ref DepthMarketDataNClass marketData) { Input.Post(marketData); }