// constructor used on very first event to initialize market state (market summary event) public MarketState(Security security, TickData bid, TickData ask, TickData trade) { if (security == null) throw new ArgumentException("security object must not be null", "security"); if (bid == null) throw new ArgumentException("TickData object for bid object must not be null", "bid"); if (ask == null) throw new ArgumentException("TickData object for ask object must not be null", "ask"); if (trade == null) throw new ArgumentException("TickData object for trade object must not be null", "bid"); VolumeTdy = 0; OrderFlowTdy = 0; VolAtBidTdy = 0; VolAtAskTdy = 0; _securityObj = security; StateType = MktStateType.Summary; TimeStamp = bid.TimeStamp; FirstOfInterval = true; OnBidQuote(bid); SetBidOpen(bid); OnAskQuote(ask); SetAskOpen(ask); OnTrade(trade); SetTradeOpn(trade); SetMid(); SetMidOpen(); }
private bool DuplicateOfPrevDataPoint(TickData newData, MarketState current) { double currPrice = 0; bool hasSizeData = false; switch (newData.Type) { case Type.Ask: currPrice = current.Ask; hasSizeData = ((_securityObj.HasQuoteSize) && (newData.Size != current.AskVol)); break; case Type.Bid: currPrice = current.Bid; hasSizeData = ((_securityObj.HasQuoteSize) && (newData.Size != current.BidVol)); break; case Type.Trade: currPrice = current.LastTrdPrice; hasSizeData = (_securityObj.HasTradeSize); break; } // if it doesn't have size data and the price hasn't changed flag it as as duplicate return((!hasSizeData) && (Math.Abs(newData.Price - currPrice) < Double.Epsilon)); }
private void ParseDataTable(DataFactory factory, DataTable dt) { Console.WriteLine("Parsing {0} DataTable({1} rows)", factory.SecurityName, dt.Rows.Count.ToString()); if (!_mktSummaryEvents.ContainsKey(factory)) { _mktSummaryEvents.Add(factory, new MktSummaryEvent { Complete = false }); } MktSummaryEvent mktSummary = _mktSummaryEvents[factory]; foreach (DataRow row in dt.Rows) { TickData tick = DataRowToTickData(factory, row); if (tick != null) { if (!mktSummary.Complete) { mktSummary = PrepareMktSummaryEvent(factory, mktSummary, tick); _mktSummaryEvents[factory] = mktSummary; } else { AddHistDataToCache(factory, tick); } } } }
private void OnBidQuote(TickData bidEvent) { PrevBid = Bid; Bid = bidEvent.Price; PrevBidVol = BidVol; BidVol = _securityObj.HasQuoteSize ? bidEvent.Size : 0; }
private void OnAskQuote(TickData askEvent) { PrevAsk = Ask; Ask = askEvent.Price; PrevAskVol = AskVol; AskVol = _securityObj.HasQuoteSize? askEvent.Size : 0; }
public void NewTick(TickData newData) { DateTime currTimeBinTimeStamp = getCurrentInterval(newData.TimeStamp); if (currTimeBinTimeStamp > DateTime.MinValue) // check to make sure the initialzation has happend { // get the current market state SortedDictionary <uint, MarketState> currTimeBin = _marketData[currTimeBinTimeStamp]; MarketState currentState = currTimeBin.ElementAt(currTimeBin.Count - 1).Value; // last data point in time bin // disregard duplicates if (!DuplicateOfPrevDataPoint(newData, currentState)) { bool addedNewTimeStamp = false; if (!_marketData.ContainsKey(newData.TimeStamp)) { _marketData.Add(newData.TimeStamp, new SortedDictionary <uint, MarketState>()); _latestTimeBin = newData.TimeStamp > _latestTimeBin ? newData.TimeStamp : _latestTimeBin; addedNewTimeStamp = true; } var marketDataForTimeStamp = _marketData[newData.TimeStamp]; lock (marketDataForTimeStamp) { // create a new updated market state var newState = new MarketState(_securityObj, currentState, newData); newState.BinCnt = (uint)marketDataForTimeStamp.Count; marketDataForTimeStamp.Add(newState.BinCnt, newState); if (LogEachTick) { string output = newState.ToStringAllData(); if (newState.StateType == MktStateType.Trade) { output += " " + newState.ToStringAllTradesNoIndentity(); } Console.WriteLine(output); } } // let the market aggregator know there is a new timestamp to aggregate if (addedNewTimeStamp) { _markets.AddTickData(this, _marketData[newData.TimeStamp], newData.TimeStamp); } } } }
private static TickData DataRowToTickData(DataFactory factory, DataRow row) { Type type; DateTime timeStamp; Double price; uint size; Dictionary <string, string> codes = null; TickData tick = null; // try parse dataRow for tick data values if (Enum.TryParse(row[0].ToString(), out type)) { if (DateTime.TryParse(row[1].ToString(), out timeStamp)) { if (Double.TryParse(row[2].ToString(), out price)) { if (uint.TryParse(row[3].ToString(), out size)) { if ((price > 0) || (price < 0)) { // if there are any codes, add to the tickData event if ((row[4].ToString() != String.Empty) || (row[5].ToString() != String.Empty)) { codes = GetCodes(row[4].ToString(), row[5].ToString(), type); } // create a new tick data event tick = new TickData { Type = type, TimeStamp = timeStamp, Price = price, Size = size, Codes = codes, Security = factory.SecurityObj.Name, SecurityObj = factory.SecurityObj, SecurityID = factory.SecurityObj.Id }; //Console.WriteLine(tick.ToString()); } } } } } return(tick); }
private void OnTrade(TickData trade) { LastTrdPrice = trade.Price; if (LastTrdPrice == Bid) { TrdCntBid++; } if (LastTrdPrice == Ask) { TrdCntAsk++; } if ((_securityObj.HasTradeSize) && (trade.Size > 0)) { LastTrdSize = trade.Size; if (LastTrdPrice == Bid) { VolAtBid += LastTrdSize; } if (LastTrdPrice == Ask) { VolAtAsk += LastTrdSize; } } else { LastTrdSize = 0; VolAtBid = 0; VolAtAsk = 0; } if (TrdsAtPrice.ContainsKey(trade.Price)) { TrdsAtPrice[trade.Price].NewTradeAtPrice(LastTrdSize, this); } else { if ((_securityObj.HasTradeSize) && (trade.Size > 0)) { TrdsAtPrice.Add(LastTrdPrice, new TradesAtPrice(LastTrdPrice, LastTrdSize, this)); } else { TrdsAtPrice.Add(LastTrdPrice, new TradesAtPrice(LastTrdPrice, this)); } } }
private void AddHistDataToCache(DataFactory factory, TickData tick) { if (!CachedTickData.ContainsKey(tick.TimeStamp)) { CachedTickData.Add(tick.TimeStamp, new Dictionary <DataFactory, List <TickData> >()); } Dictionary <DataFactory, List <TickData> > timeInterval = CachedTickData[tick.TimeStamp]; if (!timeInterval.ContainsKey(factory)) { timeInterval.Add(factory, new List <TickData>()); } List <TickData> tickData = timeInterval[factory]; tickData.Add(tick); }
// constructor used on very first event to initialize market state (market summary event) public MarketState(Security security, TickData bid, TickData ask, TickData trade) { if (security == null) { throw new ArgumentException("security object must not be null", "security"); } if (bid == null) { throw new ArgumentException("TickData object for bid object must not be null", "bid"); } if (ask == null) { throw new ArgumentException("TickData object for ask object must not be null", "ask"); } if (trade == null) { throw new ArgumentException("TickData object for trade object must not be null", "bid"); } VolumeTdy = 0; OrderFlowTdy = 0; VolAtBidTdy = 0; VolAtAskTdy = 0; _securityObj = security; StateType = MktStateType.Summary; TimeStamp = bid.TimeStamp; FirstOfInterval = true; OnBidQuote(bid); SetBidOpen(bid); OnAskQuote(ask); SetAskOpen(ask); OnTrade(trade); SetTradeOpn(trade); SetMid(); SetMidOpen(); }
public void FirstTick(TickData bid, TickData ask, TickData trade) { Console.WriteLine("Summary for " + _securityObj.Name); DateTime timeBin = bid.TimeStamp; // no timestamp if (!_mktInitialized) { _mktInitialized = true; _marketData.Add(timeBin, new SortedDictionary <uint, MarketState>()); lock (_marketData[timeBin]) { // initialize the market var newState = new MarketState(_securityObj, bid, ask, trade); // Add the new state to its time bin _marketData[newState.TimeStamp].Add(newState.BinCnt, newState); _markets.AddTickData(this, _marketData[newState.TimeStamp], newState.TimeStamp); } } }
private void AddHistDataToCache(DataFactory factory, TickData tick) { if (!CachedTickData.ContainsKey(tick.TimeStamp)) CachedTickData.Add(tick.TimeStamp, new Dictionary<DataFactory, List<TickData>>()); Dictionary<DataFactory, List<TickData>> timeInterval = CachedTickData[tick.TimeStamp]; if (!timeInterval.ContainsKey(factory)) timeInterval.Add(factory, new List<TickData>()); List<TickData> tickData = timeInterval[factory]; tickData.Add(tick); }
private void SetBidOpen(TickData bidEvent) { BidOpen = bidEvent.Price; BidVolOpen = _securityObj.HasQuoteSize ? bidEvent.Size : 0; }
private void SetTradeOpn(TickData trade) { LastPriceOpn = trade.Price; }
private void SetAskOpen(TickData askEvent) { AskOpen = askEvent.Price; AskVolOpen = _securityObj.HasQuoteSize ? askEvent.Size : 0; }
// constructor used for each successive data event after the initial market summary event public MarketState(Security security, MarketState previousMktState, TickData tickData) { VolumeTdy = 0; OrderFlowTdy = 0; VolAtBidTdy = 0; VolAtAskTdy = 0; _securityObj = security; if (previousMktState == null) throw new ArgumentException("Previous MarketState object must not be null", "previousMktState"); if (tickData.TimeStamp == null) throw new ArgumentException("tickData.TimeStamp must not be null", "tickData.TimeStamp"); TimeStamp = tickData.TimeStamp; FirstOfInterval = (tickData.TimeStamp.Subtract(previousMktState.TimeStamp).TotalSeconds > 0); CopyPrevState(previousMktState, FirstOfInterval); switch (tickData.Type) { case Type.Ask: StateType = MktStateType.Ask; OnAskQuote(tickData); SetAskVolChg(previousMktState); SetMid(); if (FirstOfInterval) { SetAskOpen(tickData); SetMidOpen(); } break; case Type.Bid: StateType = MktStateType.Bid; OnBidQuote(tickData); SetBidVolChg(previousMktState); SetMid(); if (FirstOfInterval) { SetBidOpen(tickData); SetMidOpen(); } break; case Type.Trade: StateType = MktStateType.Trade; OnTrade(tickData); if (FirstOfInterval) { SetTradeOpn(tickData); } break; default: throw new ArgumentException("TickData's 'Type' parameter must be of enum of type TickData.Type", "tickData"); } if ((FirstOfInterval) || (Codes == null)) { Codes = tickData.Codes; } else { if (tickData.Codes != null) { if (tickData.Codes.Count > 0) { foreach (var code in tickData.Codes) { if (!Codes.ContainsKey(code.Key)) Codes.Add(code.Key, code.Value); } } } } }
// constructor used for each successive data event after the initial market summary event public MarketState(Security security, MarketState previousMktState, TickData tickData) { VolumeTdy = 0; OrderFlowTdy = 0; VolAtBidTdy = 0; VolAtAskTdy = 0; _securityObj = security; if (previousMktState == null) { throw new ArgumentException("Previous MarketState object must not be null", "previousMktState"); } if (tickData.TimeStamp == null) { throw new ArgumentException("tickData.TimeStamp must not be null", "tickData.TimeStamp"); } TimeStamp = tickData.TimeStamp; FirstOfInterval = (tickData.TimeStamp.Subtract(previousMktState.TimeStamp).TotalSeconds > 0); CopyPrevState(previousMktState, FirstOfInterval); switch (tickData.Type) { case Type.Ask: StateType = MktStateType.Ask; OnAskQuote(tickData); SetAskVolChg(previousMktState); SetMid(); if (FirstOfInterval) { SetAskOpen(tickData); SetMidOpen(); } break; case Type.Bid: StateType = MktStateType.Bid; OnBidQuote(tickData); SetBidVolChg(previousMktState); SetMid(); if (FirstOfInterval) { SetBidOpen(tickData); SetMidOpen(); } break; case Type.Trade: StateType = MktStateType.Trade; OnTrade(tickData); if (FirstOfInterval) { SetTradeOpn(tickData); } break; default: throw new ArgumentException("TickData's 'Type' parameter must be of enum of type TickData.Type", "tickData"); } if ((FirstOfInterval) || (Codes == null)) { Codes = tickData.Codes; } else { if (tickData.Codes != null) { if (tickData.Codes.Count > 0) { foreach (var code in tickData.Codes) { if (!Codes.ContainsKey(code.Key)) { Codes.Add(code.Key, code.Value); } } } } } }
private void OnTrade(TickData trade) { LastTrdPrice = trade.Price; if (LastTrdPrice == Bid) TrdCntBid++; if (LastTrdPrice == Ask) TrdCntAsk++; if ((_securityObj.HasTradeSize) && (trade.Size > 0)) { LastTrdSize = trade.Size; if (LastTrdPrice == Bid) VolAtBid += LastTrdSize; if (LastTrdPrice == Ask) VolAtAsk += LastTrdSize; } else { LastTrdSize = 0; VolAtBid = 0; VolAtAsk = 0; } if (TrdsAtPrice.ContainsKey(trade.Price)) { TrdsAtPrice[trade.Price].NewTradeAtPrice(LastTrdSize, this); } else { if ((_securityObj.HasTradeSize) && (trade.Size > 0)) TrdsAtPrice.Add(LastTrdPrice, new TradesAtPrice(LastTrdPrice, LastTrdSize, this)); else TrdsAtPrice.Add(LastTrdPrice, new TradesAtPrice(LastTrdPrice, this)); } }
private static MktSummaryEvent PrepareMktSummaryEvent(DataFactory factory, MktSummaryEvent mktSummary, TickData tick) { switch (tick.Type) { case Type.Ask: if (mktSummary.Ask == null) { mktSummary.Ask = tick; if (tick.TimeStamp > mktSummary.EventTime) mktSummary.EventTime = tick.TimeStamp; mktSummary = CheckForSyntheticTradeCondition(factory, mktSummary); } break; case Type.Bid: if (mktSummary.Bid == null) { mktSummary.Bid = tick; if (tick.TimeStamp > mktSummary.EventTime) mktSummary.EventTime = tick.TimeStamp; mktSummary = CheckForSyntheticTradeCondition(factory, mktSummary); } break; case Type.Trade: if (mktSummary.Trade == null) { mktSummary.Trade = tick; if (tick.TimeStamp > mktSummary.EventTime) mktSummary.EventTime = tick.TimeStamp; mktSummary = CheckForSyntheticTradeCondition(factory, mktSummary); } break; } if ((mktSummary.Ask != null) && (mktSummary.Bid != null) && mktSummary.Trade != null) { mktSummary.Complete = true; Console.WriteLine("Mkt summary {0} {1} ask {2} bid {3} trade {4}", tick.Security, mktSummary.EventTime.ToLongTimeString(), mktSummary.Ask.Price, mktSummary.Bid.Price, mktSummary.Trade.Price); } return mktSummary; }
public void NewTick(TickData newData) { DateTime currTimeBinTimeStamp = getCurrentInterval(newData.TimeStamp); if (currTimeBinTimeStamp > DateTime.MinValue) // check to make sure the initialzation has happend { // get the current market state SortedDictionary<uint, MarketState> currTimeBin = _marketData[currTimeBinTimeStamp]; MarketState currentState = currTimeBin.ElementAt(currTimeBin.Count - 1).Value; // last data point in time bin // disregard duplicates if (!DuplicateOfPrevDataPoint(newData, currentState)) { bool addedNewTimeStamp = false; if (!_marketData.ContainsKey(newData.TimeStamp)) { _marketData.Add(newData.TimeStamp, new SortedDictionary<uint, MarketState>()); addedNewTimeStamp = true; } var marketDataForTimeStamp = _marketData[newData.TimeStamp]; lock (marketDataForTimeStamp) { // create a new updated market state var newState = new MarketState(_securityObj, currentState, newData); newState.BinCnt = (uint) marketDataForTimeStamp.Count; marketDataForTimeStamp.Add(newState.BinCnt, newState); if (LogEachTick) { string output = newState.ToStringAllData(); if (newState.StateType == MktStateType.Trade) output += " " + newState.ToStringAllTradesNoIndentity(); Console.WriteLine(output); } } // let the market aggregator know there is a new timestamp to aggregate if (addedNewTimeStamp) _markets.AddTickData(this, _marketData[newData.TimeStamp], newData.TimeStamp); } } }
private static TickData DataRowToTickData(DataFactory factory, DataRow row) { Type type; DateTime timeStamp; Double price; uint size; Dictionary<string, string> codes = null; TickData tick = null; // try parse dataRow for tick data values if (Enum.TryParse(row[0].ToString(), out type)) if (DateTime.TryParse(row[1].ToString(), out timeStamp)) if (Double.TryParse(row[2].ToString(), out price)) if (uint.TryParse(row[3].ToString(), out size)) { if ((price > 0) || (price < 0)) { // if there are any codes, add to the tickData event if ((row[4].ToString() != String.Empty) || (row[5].ToString() != String.Empty)) { codes = GetCodes(row[4].ToString(), row[5].ToString(), type); } // create a new tick data event tick = new TickData { Type = type, TimeStamp = timeStamp, Price = price, Size = size, Codes = codes, Security = factory.SecurityObj.Name, SecurityObj = factory.SecurityObj, SecurityID = factory.SecurityObj.Id }; //Console.WriteLine(tick.ToString()); } } return tick; }
private static MktSummaryEvent PrepareMktSummaryEvent(DataFactory factory, MktSummaryEvent mktSummary, TickData tick) { switch (tick.Type) { case Type.Ask: if (mktSummary.Ask == null) { mktSummary.Ask = tick; if (tick.TimeStamp > mktSummary.EventTime) { mktSummary.EventTime = tick.TimeStamp; } mktSummary = CheckForSyntheticTradeCondition(factory, mktSummary); } break; case Type.Bid: if (mktSummary.Bid == null) { mktSummary.Bid = tick; if (tick.TimeStamp > mktSummary.EventTime) { mktSummary.EventTime = tick.TimeStamp; } mktSummary = CheckForSyntheticTradeCondition(factory, mktSummary); } break; case Type.Trade: if (mktSummary.Trade == null) { mktSummary.Trade = tick; if (tick.TimeStamp > mktSummary.EventTime) { mktSummary.EventTime = tick.TimeStamp; } mktSummary = CheckForSyntheticTradeCondition(factory, mktSummary); } break; } if ((mktSummary.Ask != null) && (mktSummary.Bid != null) && mktSummary.Trade != null) { mktSummary.Complete = true; Console.WriteLine("Mkt summary {0} {1} ask {2} bid {3} trade {4}", tick.Security, mktSummary.EventTime.ToLongTimeString(), mktSummary.Ask.Price, mktSummary.Bid.Price, mktSummary.Trade.Price); } return(mktSummary); }
public void FirstTick(TickData bid, TickData ask, TickData trade) { Console.WriteLine("Summary for " + _securityObj.Name); DateTime timeBin = bid.TimeStamp; // no timestamp if (!_mktInitialized) { _mktInitialized = true; _marketData.Add(timeBin, new SortedDictionary<uint, MarketState>()); lock (_marketData[timeBin]) { // initialize the market var newState = new MarketState(_securityObj, bid, ask, trade); // Add the new state to its time bin _marketData[newState.TimeStamp].Add(newState.BinCnt, newState); _markets.AddTickData(this, _marketData[newState.TimeStamp], newState.TimeStamp); } } }
private void OnAskQuote(TickData askEvent) { PrevAsk = Ask; Ask = askEvent.Price; PrevAskVol = AskVol; AskVol = _securityObj.HasQuoteSize ? askEvent.Size : 0; }
private bool DuplicateOfPrevDataPoint(TickData newData, MarketState current) { double currPrice = 0; bool hasSizeData = false; switch (newData.Type) { case Type.Ask: currPrice = current.Ask; hasSizeData = ((_securityObj.HasQuoteSize) && (newData.Size != current.AskVol)); break; case Type.Bid: currPrice = current.Bid; hasSizeData = ((_securityObj.HasQuoteSize) && (newData.Size != current.BidVol)); break; case Type.Trade: currPrice = current.LastTrdPrice; hasSizeData = (_securityObj.HasTradeSize); break; } // if it doesn't have size data and the price hasn't changed flag it as as duplicate return ((!hasSizeData) && (Math.Abs(newData.Price - currPrice) < Double.Epsilon)); }