public DepthTick GetLevelObject(PbTick tick, int level) { if (level <= 0) { throw new InvalidOperationException("the level must be gt zero"); } DepthTick from_last = null; DepthTick from_next = null; from_last = null; from_next = tick.Depth1_3; while (level > 0) { if (from_next == null) { return(null); } from_last = from_next; from_next = from_next.Next; level -= 3; } return(from_last); }
public void SetUpperLimitPrice(PbTick tick, double price) { if (tick.Static == null) { tick.Static = new StaticInfo(); } SetUpperLimitPrice(tick.Static, price); }
public void SetSettlementPrice(PbTick tick, double price) { if (tick.Static == null) { tick.Static = new StaticInfo(); } SetSettlementPrice(tick.Static, price); }
public void SetBarSize(PbTick tick, int barSize) { if (tick.Bar == null) { tick.Bar = new BarInfo(); } SetBarSize(tick.Bar, barSize); }
public void SetClose(PbTick tick, double price) { if (tick.Bar == null) { tick.Bar = new BarInfo(); } SetClose(tick.Bar, price); }
public string GetExchange(PbTick tick) { if (tick.Static == null) { return(null); } return(tick.Static.Exchange); }
public string GetSymbol(PbTick tick) { if (tick.Static == null) { return(null); } return(tick.Static.Symbol); }
/// <summary> /// 可以同时得到原始的raw和解码后的数据 /// </summary> /// <param name="source"></param> /// <param name="raw"></param> /// <returns></returns> public PbTick Read(Stream source, out PbTick raw) { raw = ProtoBuf.Serializer.DeserializeWithLengthPrefix <PbTick>(source, PrefixStyle.Base128); if (raw == null) { return(null); } _lastRead = Codec.Restore(_lastRead, raw); return(_lastRead); }
/// <summary> /// 支持同时写向多个Stream /// 这样,只要有Tick来了,可以将转码后的小数据同时放在FileStream和MemoryStream. /// MemoryStream可以用来网络传输 /// </summary> /// <param name="data"></param> /// <param name="dest"></param> public PbTick Write(PbTick data, params Stream[] dest) { PbTick diff = Codec.Diff(_lastWrite, data); _lastWrite = data; foreach (var d in dest) { ProtoBuf.Serializer.SerializeWithLengthPrefix <PbTick>(d, diff, PrefixStyle.Base128); } return(diff); }
public void SetExchange(PbTick tick, string val) { if (string.IsNullOrWhiteSpace(val)) { return; } if (tick.Static == null) { tick.Static = new StaticInfo(); } tick.Static.Exchange = val; }
public List <PbTick> Restore(IEnumerable <PbTick> list) { if (list == null) { return(null); } List <PbTick> _list = new List <PbTick>(); PbTick last = null; foreach (var item in list) { last = Restore(last, item); _list.Add(last); } return(_list); }
public void SetAskPrice(PbTick tick, int level, double price) { var next = CreateLevelObject(tick, level); switch (level % 3) { case 1: next.AskPrice1 = PriceToTick(price); break; case 2: next.AskPrice2 = PriceToTick(price); break; case 0: next.AskPrice3 = PriceToTick(price); break; } }
public List <PbTick> Diff(IEnumerable <PbTick> list) { if (list == null) { return(null); } List <PbTick> _list = new List <PbTick>(); PbTick last = null; foreach (var item in list) { PbTick diff = Diff(last, item); last = item; _list.Add(diff); } return(_list); }
public void SetAskCount(PbTick tick, int level, int count) { var next = CreateLevelObject(tick, level); switch (level % 3) { case 1: next.AskCount1 = count; break; case 2: next.AskCount2 = count; break; case 0: next.AskCount3 = count; break; } }
public void SetAskSize(PbTick tick, int level, int size) { var next = CreateLevelObject(tick, level); switch (level % 3) { case 1: next.AskSize1 = size; break; case 2: next.AskSize2 = size; break; case 0: next.AskSize3 = size; break; } }
public static List <PbTick> Read(Stream stream) { PbTick diff = null; List <PbTick> _list = new List <PbTick>(); while (true) { diff = PbTickSerializer.ReadOne(stream); if (diff == null) { break; } _list.Add(diff); } stream.Close(); return(_list); }
public PbTick Double2Int(PbTickView tick) { if (tick == null) { return(null); } PbTick field = new PbTick(); // 利用此机会设置TickSize if (Codec == null) { Codec = new PbTickCodec(); } field.Config = Double2Int(tick.Config); Codec.Config = field.Config; Codec.UseFlat(flat); Codec.SetTurnover(field, tick.Turnover); Codec.SetAveragePrice(field, tick.AveragePrice); field.LastPrice = Codec.PriceToTick(tick.LastPrice); field.Depth1_3 = Double2Int(tick.Depth1_3); field.Volume = tick.Volume; field.OpenInterest = tick.OpenInterest; field.TradingDay = tick.TradingDay; field.ActionDay = tick.ActionDay; field.Time_HHmm = tick.Time_HHmm; field.Time_____ssf__ = tick.Time_____ssf__; field.Time________ff = tick.Time________ff; field.Bar = Double2Int(tick.Bar); field.Static = Double2Int(tick.Static); field.Split = Double2Int(tick.Split); return(field); }
public PbTickView Int2Double(PbTick tick) { if (tick == null) { return(null); } PbTickView field = new PbTickView(); // 利用此机会设置TickSize if (Codec == null) { Codec = new PbTickCodec(); } field.Config = Int2Double(tick.Config); Codec.Config = tick.Config; Codec.UseFlat(flat); field.Turnover = Codec.GetTurnover(tick); field.AveragePrice = Codec.GetAveragePrice(tick); field.LastPrice = Codec.TickToPrice(tick.LastPrice); field.Depth1_3 = Int2Double(tick.Depth1_3); field.Volume = tick.Volume; field.OpenInterest = tick.OpenInterest; field.TradingDay = tick.TradingDay; field.ActionDay = tick.ActionDay; field.Time_HHmm = tick.Time_HHmm; field.Time_____ssf__ = tick.Time_____ssf__; field.Time________ff = tick.Time________ff; field.Bar = Int2Double(tick.Bar); field.Static = Int2Double(tick.Static); field.Split = Int2Double(tick.Split); return(field); }
public double GetAskPrice(PbTick tick, int level) { var next = GetLevelObject(tick, level); if (next == null) { return(0); } switch (level % 3) { case 1: return(TickToPrice(next.AskPrice1)); case 2: return(TickToPrice(next.AskPrice2)); case 0: return(TickToPrice(next.AskPrice3)); } return(0); }
public int GetBidSize(PbTick tick, int level) { var next = GetLevelObject(tick, level); if (next == null) { return(0); } switch (level % 3) { case 1: return(next.BidSize1); case 2: return(next.BidSize2); case 0: return(next.BidSize3); } return(0); }
public int GetAskCount(PbTick tick, int level) { var next = GetLevelObject(tick, level); if (next == null) { return(0); } switch (level % 3) { case 1: return(next.AskCount1); case 2: return(next.AskCount2); case 0: return(next.AskCount3); } return(0); }
public TimeSpan GetUpdateTime(PbTick tick) { return(GetUpdateTime(tick.Time_HHmm, tick.Time_____ssf__, tick.Time________ff)); }
public static void WriteOne(PbTick tick, Stream stream) { ProtoBuf.Serializer.SerializeWithLengthPrefix <PbTick>(stream, tick, PrefixStyle.Base128); }
public double GetTurnover(PbTick tick) { return(tick.Turnover * _config.TurnoverMultiplier); }
public void SetLastPrice(PbTick tick, double price) { tick.LastPrice = PriceToTick(price); }
public double GetLastPrice(PbTick tick) { return(TickToPrice(tick.LastPrice)); }
/// <summary> /// 传入两个tick得到tick的差分 /// </summary> /// <param name="prev"></param> /// <param name="current"></param> /// <returns></returns> public PbTick Diff(PbTick prev, PbTick current) { if (prev == null) { if (current.Config == null) { throw new Exception("快照的配置不能为空"); } // 是快照,直接返回 return(current); } PbTick tick = new PbTick(); #region 配置数据 // 当前数据为空或前后相同,表示 if (current.Config == null || prev.Config.IsSame(current.Config)) { tick.Config = null; // 可以继续下去 } else { // 是新数据,返回快照 _config = current.Config; TickSize = _config.GetTickSize(); return(current); } #endregion // 先取最关键的数据,因为前一条的config总会补成有效 _config = prev.Config; TickSize = _config.GetTickSize(); tick.LastPrice = current.LastPrice - prev.LastPrice; DepthTick from_last = null; DepthTick from_next = null; DepthTick to_last = null; DepthTick to_next = null; DepthTick last_last = null; DepthTick last_next = null; #region 买1到买N from_last = null; from_next = current.Depth1_3; to_last = null; to_next = tick.Depth1_3; last_last = null; last_next = prev.Depth1_3; while (true) { // 如果下一步没有数据,直接跳过 if (from_next == null) { break; } // 每节的循环 if (from_next.BidSize1 == 0) { break; } // 如果没有上一笔,这个地方就比较特殊 if (from_last == null) { // 需要考察目标是否有数据 if (to_next == null) { to_next = new DepthTick(); tick.Depth1_3 = to_next; } to_next.BidPrice1 = current.LastPrice - from_next.BidPrice1; } else { // 需要考察目标是否有数据 if (to_next == null) { to_next = new DepthTick(); to_last.Next = to_next; } to_next.BidPrice1 = from_last.BidPrice3 - from_next.BidPrice1 - 1; } if (last_next == null) { to_next.BidSize1 = from_next.BidSize1; to_next.BidCount1 = from_next.BidCount1; } else { to_next.BidSize1 = from_next.BidSize1 - last_next.BidSize1; to_next.BidCount1 = from_next.BidCount1 - last_next.BidCount1; } if (from_next.BidSize2 == 0) { break; } to_next.BidPrice2 = from_next.BidPrice1 - from_next.BidPrice2 - 1; if (last_next == null) { to_next.BidSize2 = from_next.BidSize2; to_next.BidCount2 = from_next.BidCount2; } else { to_next.BidSize2 = from_next.BidSize2 - last_next.BidSize2; to_next.BidCount2 = from_next.BidCount2 - last_next.BidCount2; } if (from_next.BidSize3 == 0) { break; } to_next.BidPrice3 = from_next.BidPrice2 - from_next.BidPrice3 - 1; if (last_next == null) { to_next.BidSize3 = from_next.BidSize3; to_next.BidCount3 = from_next.BidCount3; } else { to_next.BidSize3 = from_next.BidSize3 - last_next.BidSize3; to_next.BidCount3 = from_next.BidCount3 - last_next.BidCount3; } // 移动到下一个数据块 from_last = from_next; from_next = from_next.Next; to_last = to_next; to_next = to_next.Next; last_last = last_next; if (last_next != null) { last_next = last_next.Next; } } #endregion #region 卖1到卖N from_last = null; from_next = current.Depth1_3; to_last = null; to_next = tick.Depth1_3; last_last = null; last_next = prev.Depth1_3; while (true) { // 如果下一步没有数据,直接跳过 if (from_next == null) { break; } // 每节的循环 if (from_next.AskSize1 == 0) { break; } // 如果没有上一笔,这个地方就比较特殊 if (from_last == null) { // 需要考察目标是否有数据 if (to_next == null) { to_next = new DepthTick(); tick.Depth1_3 = to_next; } to_next.AskPrice1 = from_next.AskPrice1 - current.LastPrice; } else { // 需要考察目标是否有数据 if (to_next == null) { to_next = new DepthTick(); to_last.Next = to_next; } to_next.AskPrice1 = from_next.AskPrice1 - from_last.AskPrice3 - 1; } if (last_next == null) { to_next.AskSize1 = from_next.AskSize1; to_next.AskCount1 = from_next.AskCount1; } else { to_next.AskSize1 = from_next.AskSize1 - last_next.AskSize1; to_next.AskCount1 = from_next.AskCount1 - last_next.AskCount1; } if (from_next.AskSize2 == 0) { break; } to_next.AskPrice2 = from_next.AskPrice2 - from_next.AskPrice1 - 1; if (last_next == null) { to_next.AskSize2 = from_next.AskSize2; to_next.AskCount2 = from_next.AskCount2; } else { to_next.AskSize2 = from_next.AskSize2 - last_next.AskSize2; to_next.AskCount2 = from_next.AskCount2 - last_next.AskCount2; } if (from_next.AskSize3 == 0) { break; } to_next.AskPrice3 = from_next.AskPrice3 - from_next.AskPrice2 - 1; if (last_next == null) { to_next.AskSize3 = from_next.AskSize3; to_next.AskCount3 = from_next.AskCount3; } else { to_next.AskSize3 = from_next.AskSize3 - last_next.AskSize3; to_next.AskCount3 = from_next.AskCount3 - last_next.AskCount3; } // 移动到下一个数据块 from_last = from_next; from_next = from_next.Next; to_last = to_next; to_next = to_next.Next; last_last = last_next; if (last_next != null) { last_next = last_next.Next; } } #endregion #region 常用行情信息 tick.Volume = current.Volume - prev.Volume; tick.OpenInterest = current.OpenInterest - prev.OpenInterest; tick.Turnover = current.Turnover - prev.Turnover; tick.AveragePrice = current.AveragePrice - prev.AveragePrice; tick.TradingDay = current.TradingDay - prev.TradingDay; tick.ActionDay = current.ActionDay - prev.ActionDay; tick.Time_HHmm = current.Time_HHmm - prev.Time_HHmm; tick.Time________ff = current.Time________ff - prev.Time________ff; // 这个地方有区别要减去一个差,将时间再缩小 tick.Time_____ssf__ = current.Time_____ssf__ - prev.Time_____ssf__ - _config.Time_ssf_Diff; #endregion #region Bar数据 // Bar数据要进行差分计算 if (current.Bar != null || prev.Bar != null) { tick.Bar = new BarInfo(); if (current.Bar == null) { current.Bar = new BarInfo(); } if (prev.Bar == null) { prev.Bar = new BarInfo(); } tick.Bar.Open = current.Bar.Open - prev.Bar.Open; tick.Bar.High = current.Bar.High - prev.Bar.High; tick.Bar.Low = current.Bar.Low - prev.Bar.Low; tick.Bar.Close = current.Bar.Close - prev.Bar.Close; tick.Bar.BarSize = current.Bar.BarSize - prev.Bar.BarSize; if (tick.Bar.IsZero) { tick.Bar = null; } } #endregion #region 静态数据 if (current.Static != null || prev.Static != null) { tick.Static = new StaticInfo(); if (current.Static == null) { current.Static = new StaticInfo(); } if (prev.Static == null) { prev.Static = new StaticInfo(); } tick.Static.LowerLimitPrice = current.Static.LowerLimitPrice - prev.Static.LowerLimitPrice; tick.Static.UpperLimitPrice = current.Static.UpperLimitPrice - prev.Static.UpperLimitPrice; tick.Static.SettlementPrice = current.Static.SettlementPrice - prev.Static.SettlementPrice; if (!string.Equals(current.Static.Exchange, prev.Static.Exchange)) { tick.Static.Exchange = current.Static.Exchange; } if (!string.Equals(current.Static.Symbol, prev.Static.Symbol)) { tick.Static.Symbol = current.Static.Symbol; } if (tick.Static.IsZero) { tick.Static = null; } } #endregion #region 除权除息数据 // 除权除息数据本来就是稀疏矩阵,不需要做差分 if (current.Split != null) { tick.Split = current.Split; if (tick.Split.IsZero) { tick.Split = null; } } #endregion return(tick); }
public void SetVolume(PbTick tick, long val) { tick.Volume = val; }
public long GetOpenInterest(PbTick tick) { return(tick.OpenInterest); }
public void SetOpenInterest(PbTick tick, long val) { tick.OpenInterest = val; }