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 DepthTickView Int2Double(DepthTick depthTick) { if (depthTick == null) { return(null); } DepthTickView field = new DepthTickView(); field.BidPrice1 = Codec.TickToPrice(depthTick.BidPrice1); field.BidSize1 = depthTick.BidSize1; field.AskPrice1 = Codec.TickToPrice(depthTick.AskPrice1); field.AskSize1 = depthTick.AskSize1; field.BidPrice2 = Codec.TickToPrice(depthTick.BidPrice2); field.BidSize2 = depthTick.BidSize2; field.AskPrice2 = Codec.TickToPrice(depthTick.AskPrice2); field.AskSize2 = depthTick.AskSize2; field.BidPrice3 = Codec.TickToPrice(depthTick.BidPrice3); field.BidSize3 = depthTick.BidSize3; field.AskPrice3 = Codec.TickToPrice(depthTick.AskPrice3); field.AskSize3 = depthTick.AskSize3; if (depthTick.Next != null) { field.Next = Int2Double(depthTick.Next); } field.BidCount1 = depthTick.BidCount1; field.AskCount1 = depthTick.AskCount1; field.BidCount2 = depthTick.BidCount2; field.AskCount2 = depthTick.AskCount2; field.BidCount3 = depthTick.BidCount3; field.AskCount3 = depthTick.AskCount3; return(field); }
public DepthTick Double2Int(DepthTickView depthTick) { if (depthTick == null) { return(null); } DepthTick field = new DepthTick(); field.BidPrice1 = Codec.PriceToTick(depthTick.BidPrice1); field.BidSize1 = depthTick.BidSize1; field.AskPrice1 = Codec.PriceToTick(depthTick.AskPrice1); field.AskSize1 = depthTick.AskSize1; field.BidPrice2 = Codec.PriceToTick(depthTick.BidPrice2); field.BidSize2 = depthTick.BidSize2; field.AskPrice2 = Codec.PriceToTick(depthTick.AskPrice2); field.AskSize2 = depthTick.AskSize2; field.BidPrice3 = Codec.PriceToTick(depthTick.BidPrice3); field.BidSize3 = depthTick.BidSize3; field.AskPrice3 = Codec.PriceToTick(depthTick.AskPrice3); field.AskSize3 = depthTick.AskSize3; if (depthTick.Next != null) { field.Next = Double2Int(depthTick.Next); } field.BidCount1 = depthTick.BidCount1; field.AskCount1 = depthTick.AskCount1; field.BidCount2 = depthTick.BidCount2; field.AskCount2 = depthTick.AskCount2; field.BidCount3 = depthTick.BidCount3; field.AskCount3 = depthTick.AskCount3; return(field); }
/// <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 PbTick Restore(PbTick prev, PbTick diff) { if (prev == null) { if (diff.Config == null) { throw new Exception("快照的配置不能为空"); } // 记下配置,要用到 _config = diff.Config; TickSize = _config.GetTickSize(); // 是快照,直接返回 return(diff); } var tick = new PbTick(); #region 配置数据 if (diff.Config == null) { // 使用上条的配置 tick.Config = prev.Config; } else { // 新配置 _config = diff.Config; TickSize = _config.GetTickSize(); // 是快照,直接返回 return(diff); } #endregion _config = tick.Config; TickSize = _config.GetTickSize(); tick.LastPrice = prev.LastPrice + diff.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 = diff.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_last == null) { // 需要考察目标是否有数据 if (to_next == null) { to_next = new DepthTick(); tick.Depth1_3 = to_next; } to_next.BidPrice1 = tick.LastPrice - from_next.BidPrice1; } else { // 需要考察目标是否有数据 if (to_next == null) { to_next = new DepthTick(); to_last.Next = to_next; } to_next.BidPrice1 = to_last.BidPrice3 - from_next.BidPrice1 - 1; } to_next.BidPrice2 = to_next.BidPrice1 - from_next.BidPrice2 - 1; to_next.BidPrice3 = to_next.BidPrice2 - from_next.BidPrice3 - 1; if (last_next == null) { to_next.BidSize1 = from_next.BidSize1; to_next.BidSize2 = from_next.BidSize2; to_next.BidSize3 = from_next.BidSize3; to_next.BidCount1 = from_next.BidCount1; to_next.BidCount2 = from_next.BidCount2; to_next.BidCount3 = from_next.BidCount3; } else { to_next.BidSize1 = from_next.BidSize1 + last_next.BidSize1; to_next.BidSize2 = from_next.BidSize2 + last_next.BidSize2; to_next.BidSize3 = from_next.BidSize3 + last_next.BidSize3; to_next.BidCount1 = from_next.BidCount1 + last_next.BidCount1; to_next.BidCount2 = from_next.BidCount2 + last_next.BidCount2; to_next.BidCount3 = from_next.BidCount3 + last_next.BidCount3; } // 太复杂了,简化为发现Size=0就设Price等为0 if (to_next.BidSize3 == 0) { to_next.BidCount3 = 0; to_next.BidPrice3 = 0; } if (to_next.BidSize2 == 0) { to_next.BidCount2 = 0; to_next.BidPrice2 = 0; } if (to_next.BidSize1 == 0) { to_next.BidCount1 = 0; to_next.BidPrice1 = 0; } // 移动到下一个数据块 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 = diff.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_last == null) { // 需要考察目标是否有数据 if (to_next == null) { to_next = new DepthTick(); tick.Depth1_3 = to_next; } to_next.AskPrice1 = tick.LastPrice + from_next.AskPrice1; } else { // 需要考察目标是否有数据 if (to_next == null) { to_next = new DepthTick(); to_last.Next = to_next; } to_next.AskPrice1 = to_last.AskPrice3 + from_next.AskPrice1 + 1; } to_next.AskPrice2 = to_next.AskPrice1 + from_next.AskPrice2 + 1; to_next.AskPrice3 = to_next.AskPrice2 + from_next.AskPrice3 + 1; if (last_next == null) { to_next.AskSize1 = from_next.AskSize1; to_next.AskSize2 = from_next.AskSize2; to_next.AskSize3 = from_next.AskSize3; to_next.AskCount1 = from_next.AskCount1; to_next.AskCount2 = from_next.AskCount2; to_next.AskCount3 = from_next.AskCount3; } else { to_next.AskSize1 = from_next.AskSize1 + last_next.AskSize1; to_next.AskSize2 = from_next.AskSize2 + last_next.AskSize2; to_next.AskSize3 = from_next.AskSize3 + last_next.AskSize3; to_next.AskCount1 = from_next.AskCount1 + last_next.AskCount1; to_next.AskCount2 = from_next.AskCount2 + last_next.AskCount2; to_next.AskCount3 = from_next.AskCount3 + last_next.AskCount3; } // 太复杂了,简化为发现Size=0就设Price等为0 if (to_next.AskSize3 == 0) { to_next.AskCount3 = 0; to_next.AskPrice3 = 0; } if (to_next.AskSize2 == 0) { to_next.AskCount2 = 0; to_next.AskPrice2 = 0; } if (to_next.AskSize1 == 0) { to_next.AskCount1 = 0; to_next.AskPrice1 = 0; } // 移动到下一个数据块 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 = prev.Volume + diff.Volume; tick.OpenInterest = prev.OpenInterest + diff.OpenInterest; tick.Turnover = prev.Turnover + diff.Turnover; tick.AveragePrice = prev.AveragePrice + diff.AveragePrice; tick.TradingDay = prev.TradingDay + diff.TradingDay; tick.ActionDay = prev.ActionDay + diff.ActionDay; tick.Time_HHmm = prev.Time_HHmm + diff.Time_HHmm; tick.Time________ff = prev.Time________ff + diff.Time________ff; // 还原时间 tick.Time_____ssf__ = prev.Time_____ssf__ + diff.Time_____ssf__ + _config.Time_ssf_Diff; #endregion #region Bar数据 if (prev.Bar != null || diff.Bar != null) { tick.Bar = new BarInfo(); if (prev.Bar == null) { prev.Bar = new BarInfo(); } if (diff.Bar == null) { diff.Bar = new BarInfo(); } tick.Bar.Open = prev.Bar.Open + diff.Bar.Open; tick.Bar.High = prev.Bar.High + diff.Bar.High; tick.Bar.Low = prev.Bar.Low + diff.Bar.Low; tick.Bar.Close = prev.Bar.Close + diff.Bar.Close; tick.Bar.BarSize = prev.Bar.BarSize + diff.Bar.BarSize; } #endregion #region 静态数据 if (prev.Static != null || diff.Static != null) { tick.Static = new StaticInfo(); if (prev.Static == null) { prev.Static = new StaticInfo(); } if (diff.Static == null) { diff.Static = new StaticInfo(); } tick.Static.LowerLimitPrice = prev.Static.LowerLimitPrice + diff.Static.LowerLimitPrice; tick.Static.UpperLimitPrice = prev.Static.UpperLimitPrice + diff.Static.UpperLimitPrice; tick.Static.SettlementPrice = prev.Static.SettlementPrice + diff.Static.SettlementPrice; tick.Static.Symbol = string.IsNullOrWhiteSpace(diff.Static.Symbol) ? prev.Static.Symbol : diff.Static.Symbol; tick.Static.Exchange = string.IsNullOrWhiteSpace(diff.Static.Exchange) ? prev.Static.Exchange : diff.Static.Exchange; } #endregion #region 除权除息数据 // 没有做过差分,所以直接返回 if (diff.Split != null) { tick.Split = diff.Split; } #endregion return(tick); }