private void CTPOnRtnInstrumentStatus(ref CThostFtdcInstrumentStatusField pInstrumentStatus) { ExchangeStatusType status = ExchangeStatusType.BeforeTrading; switch (pInstrumentStatus.InstrumentStatus) { case TThostFtdcInstrumentStatusType.THOST_FTDC_IS_Continous: status = ExchangeStatusType.Trading; break; case TThostFtdcInstrumentStatusType.THOST_FTDC_IS_Closed: status = ExchangeStatusType.Closed; break; case TThostFtdcInstrumentStatusType.THOST_FTDC_IS_NoTrading: status = ExchangeStatusType.NoTrading; break; } DicExcStatus[pInstrumentStatus.InstrumentID] = status; if (IsLogin) { _OnRtnExchangeStatus?.Invoke(this, new StatusEventArgs { Exchange = pInstrumentStatus.InstrumentID, Status = status }); } }
public override ExchangeStatusType GetInstrumentStatus(string pExc) { var instField = DicInstrumentField[pExc]; ExchangeStatusType excStatus = default(ExchangeStatusType); if (DicExcStatus.TryGetValue(instField.ProductID, out excStatus) || DicExcStatus.TryGetValue(instField.ExchangeID.ToString(), out excStatus) || DicExcStatus.TryGetValue(instField.InstrumentID, out excStatus)) { return(excStatus); } return(ExchangeStatusType.Closed); }
void _import_OnRtnExchangeStatus(string pExchange, ExchangeStatusType pStatus) { DicExcStatus.AddOrUpdate(pExchange, pStatus, (k, v) => pStatus); if (_OnRtnExchangeStatus != null) { _OnRtnExchangeStatus(this, new StatusEventArgs { Exchange = pExchange, Status = pStatus, }); } }
public static bool isBeforeTradingTime(ExchangeStatusType type, DateTime dt) { if (dt.Hour == 8 && dt.Minute == 59) { return(true); } if (dt.Hour == 20 && dt.Minute == 59) { return(true); } return(false); }
//收盘 private void _OnRtnExchangeStatus(object sender, StatusEventArgs e) { //收盘后统一视为撤单 ExchangeStatusType status = e.Status; if (status == ExchangeStatusType.Closed) { foreach (SubOrder s in activeOrders) { s.VolumeLeft = 0; s.Status = OrderStatus.Canceled; s.Refresh(); } } }
private void quote_OnRtnTick(object sender, TickEventArgs e) { Product instField; Instrument inst; ExchangeStatusType excStatus = ExchangeStatusType.Trading; if (!_dataProcess.InstrumentInfo.TryGetValue(e.Tick.InstrumentID, out inst) || !_dataProcess.ProductInfo.TryGetValue(inst.ProductID, out instField) || (_t != null && !_t.DicExcStatus.TryGetValue(instField._id, out excStatus))) { return; } Tick tick = new Tick { AskPrice = e.Tick.AskPrice, AveragePrice = e.Tick.AveragePrice, BidPrice = e.Tick.BidPrice, LastPrice = e.Tick.LastPrice, LowerLimitPrice = e.Tick.LowerLimitPrice, OpenInterest = e.Tick.OpenInterest, UpperLimitPrice = e.Tick.UpperLimitPrice, AskVolume = e.Tick.AskVolume, BidVolume = e.Tick.BidVolume, InstrumentID = e.Tick.InstrumentID, TradingDay = int.Parse(_tradingDay), UpdateMillisec = e.Tick.UpdateMillisec, UpdateTime = e.Tick.UpdateTime, Volume = e.Tick.Volume, }; //20170720全处理,避免000的行情错误. //if (_t.DicExcStatus.Count > 1) //非模拟才进行处理 if (!_dataProcess.FixTick(tick, _tradingDay, _dataProcess.InstrumentInfo[tick.InstrumentID].ProductID)) //修正tick时间格式:yyyMMdd HH:mm:ss { return; } foreach (var stra in _dicStrategies.Values) { if (stra.EnableTick) { foreach (var data in stra.Datas) { if (data.Instrument == tick.InstrumentID) { if (sender == null) //tick回测 { data.OnTick(tick); } else { ThreadPool.QueueUserWorkItem((state) => data.OnTick(tick)); } } } } } //处理000数据;20170719增加状态判断,非交易时段会收到脏数据!=>fixtick处理 if (_dicTick000.TryAdd(tick.InstrumentID, tick)) { return; //首个tick只保存不处理 } if (excStatus != ExchangeStatusType.Trading) { return; //只在交易时段处理数据 } //if (_qry.Make000(md, _dicTick, out tick000)) if (_inst888.IndexOf(tick.InstrumentID) >= 0) { if (Make000Double(tick, out Tick tick000)) { Tick TickTmp = (Tick)tick000.Clone(); //传递复制体,保证不会因数据修改造成bug foreach (var stra in _dicStrategies.Values.Where(n => n.EnableTick)) { foreach (var data in stra.Datas) { if (data.Instrument == TickTmp.InstrumentID) { if (sender == null) //tick回测 { data.OnTick(TickTmp); } else { ThreadPool.QueueUserWorkItem((state) => data.OnTick(TickTmp)); } } } } tick000.UpdateTime = tick.UpdateTime; tick000.UpdateMillisec = tick.UpdateMillisec; } } //更新合约数据 _dicTick000[tick.InstrumentID] = tick; //注意f000的先后顺序 }
void _q_OnRtnTick(object sender, TickEventArgs e) { Product instField; Instrument inst; ExchangeStatusType excStatus = ExchangeStatusType.Trading; if (!_dataProcess.InstrumentInfo.TryGetValue(e.Tick.InstrumentID, out inst) || !_dataProcess.ProductInfo.TryGetValue(inst.ProductID, out instField) || (_t != null && !_t.DicExcStatus.TryGetValue(instField._id, out excStatus))) { return; } Tick tick = new Tick { AskPrice = e.Tick.AskPrice, AveragePrice = e.Tick.AveragePrice, BidPrice = e.Tick.BidPrice, LastPrice = e.Tick.LastPrice, LowerLimitPrice = e.Tick.LowerLimitPrice, OpenInterest = e.Tick.OpenInterest, UpperLimitPrice = e.Tick.UpperLimitPrice, AskVolume = e.Tick.AskVolume, BidVolume = e.Tick.BidVolume, InstrumentID = e.Tick.InstrumentID, TradingDay = int.Parse(_tradingDay), UpdateMillisec = e.Tick.UpdateMillisec, UpdateTime = e.Tick.UpdateTime, Volume = e.Tick.Volume, }; //20170720全处理,避免000的行情错误. //if (_t.DicExcStatus.Count > 1) //非模拟才进行处理 if (!_dataProcess.FixTick(tick, _tradingDay, _dataProcess.InstrumentInfo[tick.InstrumentID].ProductID)) //修正tick时间格式:yyyMMdd HH:mm:ss { return; } foreach (var stra in _dicStrategies.Values) { if (stra.EnableTick) { foreach (var data in stra.Datas) { if (data.Instrument == tick.InstrumentID) { if (sender == null) //tick回测 { data.OnTick(tick); } else { ThreadPool.QueueUserWorkItem((state) => data.OnTick(tick)); } } } } } //处理000数据;20170719增加状态判断,非交易时段会收到脏数据!=>fixtick处理 Tick f000; if (_dicTick000.TryGetValue(instField._id + "000", out f000)) //yyyyMMdd HH:mm:ss格式比较 { if (_dicTick000.TryAdd(tick.InstrumentID, tick)) { return; //首个tick只保存不处理 } if (excStatus != ExchangeStatusType.Trading) { return; //只在交易时段处理数据 } if (tick.UpdateTime.CompareTo(f000.UpdateTime) <= 0 || string.IsNullOrEmpty(f000.UpdateTime)) //第2个tick再处理;增加稳定性 { _dicTick000[tick.InstrumentID] = tick; //注意f000的先后顺序 f000.UpdateTime = tick.UpdateTime; return; } f000.UpdateTime = tick.UpdateTime; double priceTick = instField.PriceTick; int sumV = 0; double sumI = 0; List <Tick> ts = new List <Tick>(); foreach (var instInfo in _dataProcess.InstrumentInfo.Values.Where(n => n.ProductID == instField._id)) { if (instInfo._id == f000.InstrumentID) { continue; } Tick md; if (!_dicTick000.TryGetValue(instInfo._id, out md)) { continue; } if (md.OpenInterest <= 0) { continue; } ts.Add(md); } //无有用数据:不处理 if (ts.Count > 0) { foreach (var v in ts) { sumV += v.Volume; sumI += v.OpenInterest; } f000.Volume = sumV; f000.OpenInterest = sumI; f000.UpdateTime = tick.UpdateTime; //数据初始化 f000.LastPrice = 0; f000.BidPrice = 0; f000.BidVolume = 0; f000.AskPrice = 0; f000.AskVolume = 0; f000.AveragePrice = 0; foreach (var v in ts) { double rate = v.OpenInterest / sumI; f000.LastPrice += (v.LastPrice * rate); f000.BidPrice += (v.BidPrice * rate); f000.BidVolume += v.BidVolume; f000.AskPrice += (v.AskPrice * rate); f000.AskVolume += v.AskVolume; f000.AveragePrice += (v.AveragePrice * rate); } //数据修正 f000.LastPrice = Math.Round(f000.LastPrice / priceTick, 0) * priceTick; f000.BidPrice = Math.Round(f000.BidPrice / priceTick, 0) * priceTick; f000.AskPrice = Math.Round(f000.AskPrice / priceTick, 0) * priceTick; f000.AveragePrice = Math.Round(f000.AveragePrice / priceTick, 0) * priceTick; foreach (var stra in _dicStrategies.Values) { if (stra.EnableTick) { foreach (var data in stra.Datas) { if (data.Instrument == f000.InstrumentID) { if (sender == null) //tick回测 { data.OnTick(tick); } else { ThreadPool.QueueUserWorkItem((state) => data.OnTick(f000)); } } } } } } //更新合约数据 _dicTick000[tick.InstrumentID] = tick; //注意f000的先后顺序 } }