/// <summary>
        /// Fired each time an event is read from file
        /// </summary>
        /// <param name="eventItem"></param>
        private void EventRecieved(Spark.Event eventItem)
        {
            //Raise event
            if (Spark.TimeToDateTime(eventItem.Time) > _latestMarketTime)
            {
                _latestMarketTime = Spark.TimeToDateTime(eventItem.Time);
            }
            RaiseEvent(new EventFeedArgs(eventItem, _latestMarketTime));

            //Skip over waiting logic if quote event and ignoring quotes
            if ((IgnoreQuoteEvents) && (eventItem.Type == Spark.EVENT_QUOTE))
            {
                return;
            }

            //Wait before playing next event while replay is pause
            while ((IsPaused) && (!_isSteppingForward))
            {
                System.Threading.Thread.Sleep(100);
            }
            if (_isSteppingForward)
            {
                _isSteppingForward = false;
            }
        }
        /// <summary>
        /// Open file for reading and then read one line at a time calling the event processing delegate (function pointer) to
        /// process the event
        /// </summary>
        /// <remarks>
        /// Streaming events sequentially from a file is slightly faster than loading all events into an array before processing.
        /// It also reduces the memory required when processing a large file.
        /// </remarks>
        /// <param name="fileName">Event file name</param>
        /// <param name="eventProcessingFunction">Delegate (function pointer) for the method that will process the events</param>
        internal void StreamFromFile(string fileName, ApiEventFeedReplay.EventReceivedHandler eventProcessingFunction)
        {
            StreamReader file = null;

            try
            {
                file = new StreamReader(fileName);
                string line;
                do
                {
                    line = file.ReadLine();
                    if (line != null)
                    {
                        Spark.Event eventItem = ApiEventReaderWriter.Parse(line);
                        eventProcessingFunction(eventItem);
                    }
                } while (line != null);
            }
            finally
            {
                if (file != null)
                {
                    file.Close();                   //Close file stream even if there is an error
                }
            }
        }
        /// <summary>
        /// Parses Spark event file string into Spark.Event struct
        /// </summary>
        /// <param name="eventItemText">Spark event in tab-delimited text format</param>
        public static Spark.Event Parse(string eventItemText)
        {
            //Parse Row
            string[] entryItems = eventItemText.Split('\t');

            //Create new event
            Spark.Event eventItem = new Spark.Event
            {
                Code           = entryItems[0],
                ConditionCodes = ulong.Parse(entryItems[1]),
                Count          = int.Parse(entryItems[2]),
                Exchange       = entryItems[3],
                Flags          = int.Parse(entryItems[4]),
                Position       = int.Parse(entryItems[5]),
                Price          = int.Parse(entryItems[6]),
                QuoteBases     = ulong.Parse(entryItems[7]),
                Reference      = int.Parse(entryItems[8]),
                State          = int.Parse(entryItems[9]),
                Time           = int.Parse(entryItems[10]),
                TimeNsec       = int.Parse(entryItems[11]),
                Type           = int.Parse(entryItems[12]),
                Volume         = int.Parse(entryItems[13])
            };
            return(eventItem);
        }
Beispiel #4
0
        /// <summary>
        /// Update order list according to details in specified order change event
        /// </summary>
        /// <param name="eventItem">Spark event</param>
        public void SubmitEvent(Spark.Event eventItem)
        {
            switch (eventItem.Type)
            {
            case Spark.EVENT_NEW_DEPTH:

                //ENTER
                LimitOrder order = eventItem.ToLimitOrder();
                if (Count == 0)
                {
                    Add(order);
                }
                else
                {
                    Insert(eventItem.Position - 1, order);
                }
                break;

            case Spark.EVENT_AMEND_DEPTH:

                //AMEND
                this[eventItem.Position - 1].Volume = (int)eventItem.Volume;
                break;

            case Spark.EVENT_DELETE_DEPTH:

                //DELETE
                RemoveAt(eventItem.Position - 1);
                break;

            default:
                break;
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="eventItem"></param>
        private void ProcessEvent(Spark.Event eventItem)
        {
            //Skip over waiting logic if quote event and ignoring quotes
            if ((IgnoreQuoteEvents) && (eventItem.Type == Spark.EVENT_QUOTE))
            {
                return;
            }

            //Raise event
            DateTime sparkEventTime = ApiFunctions.DateTimeFromUnixTimestampSeconds(eventItem.Time);

            if (sparkEventTime > _latestMarketTime)
            {
                _latestMarketTime = sparkEventTime;
            }
            RaiseEvent(new EventFeedArgs(eventItem, _latestMarketTime));

            //Wait before playing next event while replay is pause
            while ((IsPaused) && (!_isSteppingForward))
            {
                System.Threading.Thread.Sleep(100);
            }
            if (_isSteppingForward)
            {
                _isSteppingForward = false;
            }
        }
Beispiel #6
0
        /// <summary>
        /// Execute query
        /// </summary>
        /// <param name="exchange">Security exchange</param>
        public static List <Spark.Event> Execute(string exchange)
        {
            //Connect to Spark API if required
            ApiControl.Instance.Connect();

            //Get exchange reference
            Spark.Exchange     exchangeRef;
            List <Spark.Event> result = null;

            if (ApiFunctions.GetSparkExchange(exchange, out exchangeRef))
            {
                //Wait to allow Spark API to prepare for large download (it will only return a small number of events without this)
                System.Threading.Thread.Sleep(1000);

                //Request stock events
                result = new List <Spark.Event>();
                Spark.Event sparkEvent = new Spark.Event();

                //Execute query using current day request method
                if (Spark.GetAllExchangeEvents(ref exchangeRef, ref sparkEvent))
                {
                    while (Spark.GetNextExchangeEvent(ref exchangeRef, ref sparkEvent, 1000))
                    {
                        result.Add(sparkEvent);
                    }
                }
                Spark.ReleaseCurrentEvents();
            }
            return(result);
        }
Beispiel #7
0
        /// <summary>
        /// Extension method for the Spark.Event struct that generates new trade from order event if there is an
        /// event type match, otherwise returns NULL.
        /// </summary>
        internal static Trade ToTrade(this Spark.Event eventItem, string symbol, string exchange, DateTime observationTime)
        {
            int      price          = eventItem.Price;
            int      volume         = (int)eventItem.Volume;
            DateTime timeStamp      = DateTimeFromUnixTimestampSeconds(eventItem.Time);
            string   conditionCodes = Spark.ConditionCodesToStr(eventItem.ConditionCodes, eventItem.Exchange);

            return(new Trade(timeStamp, symbol, exchange, price, volume, conditionCodes, observationTime));
        }
Beispiel #8
0
        /// <summary>
        /// Extension method for the Spark.Event struct that converts a Spark event into LimitOrder that can be submitted
        /// into the LimitOrderBook
        /// </summary>
        /// <param name="eventItem">Spark event</param>
        internal static LimitOrder ToLimitOrder(this Spark.Event eventItem)
        {
            MarketSide side      = ApiFunctions.GetMarketSide(eventItem.Flags);
            int        price     = eventItem.Price;
            int        volume    = (int)eventItem.Volume;
            DateTime   timeStamp = DateTimeFromUnixTimestampSeconds(eventItem.Time);

            return(new LimitOrder(side, price, volume, timeStamp));
        }
Beispiel #9
0
        /// <summary>
        /// EventFeedArgs constructor
        /// </summary>
        /// <param name="eventItem">Spark event</param>
        /// <param name="timestamp">Observation timestamp</param>
        internal EventFeedArgs(Spark.Event eventItem, DateTime timestamp)
        {
            Event     = eventItem;
            TimeStamp = timestamp;
            var adjustedValues = ApiFunctions.GetSymbolExchange(eventItem.Code, eventItem.Exchange);

            Symbol   = adjustedValues.Item1;
            Exchange = adjustedValues.Item2;
        }
Beispiel #10
0
        /// <summary>
        /// Submit Spark.Event depth update event (thread-safe)
        /// </summary>
        /// <param name="eventItem">Spark event</param>
        public void SubmitEvent(Spark.Event eventItem)
        {
            LimitOrderList list = (ApiFunctions.GetMarketSide(eventItem.Flags) == MarketSide.Bid) ? Bid : Ask;

            lock (_lock)
            {
                list.SubmitEvent(eventItem);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="symbol">Security symbol</param>
        /// <param name="exchange">Security exchange</param>
        /// <param name="date">Request date</param>
        public static List <Spark.Event> Execute(string symbol, string exchange, DateTime date)
        {
            //Connect to Spark API if required
            ApiControl.Instance.Connect();

            //Determine what Spark considers to be the current date
            DateTime sparkDate = ApiFunctions.GetCurrentSparkDate();

            Debug.WriteLine("\tCurrent Spark Date: " + date.ToShortDateString());

            //Get instance to stock
            Spark.Stock        stock;
            List <Spark.Event> result = null;

            if (ApiFunctions.GetSparkStock(symbol, exchange, out stock))
            {
                //Request stock events
                Spark.Event sparkEvent = new Spark.Event();
                result = new List <Spark.Event>();
                if (date == sparkDate)
                {
                    //Wait to allow Spark API to prepare for download (it may only return a small number of events without this)
                    System.Threading.Thread.Sleep(1000);
                    //NOTE: This is only returning 1 event when requested over a mobile wireless connection. It may require more delay or some other sort of test.

                    //Execute query using current day request method
                    Debug.WriteLine("\tSpark.GetAllStockEvents(" + symbol + ")");
                    if (Spark.GetAllStockEvents(ref stock, ref sparkEvent))
                    {
                        while (Spark.GetNextStockEvent(ref stock, ref sparkEvent, 1000))  //Specifying 0 timeout will return events until there are no more in the queue
                        {
                            result.Add(sparkEvent);
                        }
                    }
                    Spark.ReleaseStockEvents(ref stock);
                }
                else
                {
                    //Execute query using historical request method
                    Debug.WriteLine("\tSpark.GetPastStockEvents(" + symbol + ", " + date.ToShortDateString() + ")");
                    if (Spark.GetPastStockEvents(ref stock, ref sparkEvent, date))
                    {
                        while (Spark.GetNextPastStockEvent(ref stock, ref sparkEvent))
                        {
                            result.Add(sparkEvent);
                        }
                    }
                    Spark.ReleasePastStockEvents(ref stock, (DateTime)date);
                }
            }
            return(result);
        }
Beispiel #12
0
 /// <summary>
 /// Convert Spark.Event struct into tab-separted human readable string
 /// </summary>
 /// <param name="eventItem">Spark event item</param>
 internal static string ToOutputString(this Spark.Event eventItem)
 {
     System.Text.StringBuilder result = new StringBuilder();
     result.Append(DateTimeFromUnixTimestampSeconds(eventItem.Time).ToMarketDateTime() + "\t");
     result.Append(Spark.EventTypeToStr(eventItem.Type) + "\t");
     result.Append(eventItem.Code + "\t");
     result.Append(eventItem.Exchange + "\t");
     result.Append(ApiFunctions.GetMarketSide(eventItem.Flags).ToString() + "\t");
     result.Append(eventItem.Price.ToPriceString() + "\t");
     result.Append(eventItem.Volume + "\t");
     result.Append(Spark.ConditionCodesToStr(eventItem.ConditionCodes, eventItem.Exchange) + "\t");
     result.Append(eventItem.Flags + "\t");
     result.Append(Spark.StateToStr(eventItem.State) + "\t");
     result.Append(eventItem.Position + "\t");
     result.Append(Spark.QuoteBasesToStr(eventItem.QuoteBases, eventItem.Exchange) + "\t");
     result.Append(eventItem.Reference + "\t");
     result.Append(eventItem.Count + "\t");
     return(result.ToString());
 }
        /// <summary>
        /// Convert Spark.Event struct into tab-separted string for file storage
        /// </summary>
        /// <param name="eventItem">Spark event item</param>
        public static string ToFileString(Spark.Event eventItem)
        {
            StringBuilder result = new StringBuilder();

            result.Append(eventItem.Code + "\t");
            result.Append(eventItem.ConditionCodes + "\t");
            result.Append(eventItem.Count + "\t");
            result.Append(eventItem.Exchange + "\t");
            result.Append(eventItem.Flags + "\t");
            result.Append(eventItem.Position + "\t");
            result.Append(eventItem.Price + "\t");
            result.Append(eventItem.QuoteBases + "\t");
            result.Append(eventItem.Reference + "\t");
            result.Append(eventItem.State + "\t");
            result.Append(eventItem.Time + "\t");
            result.Append(eventItem.TimeNsec + "\t");
            result.Append(eventItem.Type + "\t");
            result.Append(eventItem.Volume);
            return(result.ToString());
        }
Beispiel #14
0
        /// <summary>
        /// Initiate data feed
        /// </summary>
        public override void Execute()
        {
            //Connect to Spark API if required
            ApiControl.Instance.Connect();

            //Get instance to stock
            Spark.Stock stock;
            if (ApiFunctions.GetSparkStock(Symbol, Exchange, out stock))
            {
                //Request all events for current day
                Spark.Event sparkEvent = new Spark.Event();
                if (Spark.GetAllStockEvents(ref stock, ref sparkEvent))
                {
                    while (Spark.GetNextStockEvent(ref stock, ref sparkEvent, -1))  //Specifying -1 timeout will keep it waiting until end of day
                    {
                        RaiseEvent(new EventFeedArgs(sparkEvent, Spark.TimeToDateTime(sparkEvent.Time)));
                    }
                }

                //Release memory at end of day
                Spark.ReleaseStockEvents(ref stock);
            }
        }
        /// <summary>
        /// Initiate data feed
        /// </summary>
        public override void Execute()
        {
            //Connect to Spark API if required
            ApiControl.Instance.Connect();

            //Get instance to exchange
            Spark.Exchange exchangeRef;
            if (ApiFunctions.GetSparkExchange(Exchange, out exchangeRef))
            {
                //Request all events for current day
                Spark.Event sparkEvent = new Spark.Event();
                if (Spark.GetAllExchangeEvents(ref exchangeRef, ref sparkEvent))
                {
                    while (Spark.GetNextExchangeEvent(ref exchangeRef, ref sparkEvent, -1))     //Specifying -1 timeout will keep it waiting until end of day
                    {
                        RaiseEvent(new EventFeedArgs(sparkEvent, Spark.TimeToDateTime(sparkEvent.Time)));
                    }
                }

                //Release memory at end of day
                Spark.ReleaseCurrentEvents();
            }
        }
Beispiel #16
0
        /// <summary>
        /// Processes the Spark update event provided in the EventFeedArgs and updates security properties based on the event type
        /// </summary>
        /// <param name="sender">Event sender</param>
        /// <param name="eventFeedArgs">Event feed args</param>
        internal void EventReceived(object sender, EventFeedArgs eventFeedArgs)
        {
            //Process event
            Spark.Event eventItem = eventFeedArgs.Event;
            switch (eventItem.Type)
            {
            //Depth update
            case Spark.EVENT_NEW_DEPTH:
            case Spark.EVENT_AMEND_DEPTH:
            case Spark.EVENT_DELETE_DEPTH:

                //Check if exchange order book exists and create if it doesn't
                LimitOrderBook orderBook;
                if (!OrderBooks.TryGetValue(eventFeedArgs.Exchange, out orderBook))
                {
                    orderBook = new LimitOrderBook(eventFeedArgs.Symbol, eventFeedArgs.Exchange);
                    OrderBooks.Add(eventFeedArgs.Exchange, orderBook);
                }

                //Submit update to appropriate exchange order book
                orderBook.SubmitEvent(eventItem);
                if (OnDepthUpdate != null)
                {
                    OnDepthUpdate(this, new GenericEventArgs <LimitOrderBook>(eventFeedArgs.TimeStamp, orderBook));
                }
                break;

            //Trade update
            case Spark.EVENT_TRADE:

                //Create and store trade record
                Trade trade = eventItem.ToTrade(eventFeedArgs.Symbol, eventFeedArgs.Exchange, eventFeedArgs.TimeStamp);
                Trades.Add(trade);
                if (OnTradeUpdate != null)
                {
                    OnTradeUpdate(this, new GenericEventArgs <Trade>(eventFeedArgs.TimeStamp, trade));
                }
                break;

            //Trade cancel
            case Spark.EVENT_CANCEL_TRADE:

                //Find original trade in trade record and delete
                Trade cancelledTrade = eventItem.ToTrade(eventFeedArgs.TimeStamp);
                Trade originalTrade  = Trades.Find(x => (x.TimeStamp == cancelledTrade.TimeStamp && x.Price == cancelledTrade.Price && x.Volume == cancelledTrade.Volume));
                if (originalTrade != null)
                {
                    Trades.Remove(originalTrade);
                }
                break;

            //Market state update
            case Spark.EVENT_STATE_CHANGE:
                State = ApiFunctions.ConvertToMarketState(eventItem.State);
                if (OnMarketStateUpdate != null)
                {
                    OnMarketStateUpdate(this, new GenericEventArgs <MarketState>(eventFeedArgs.TimeStamp, State));
                }
                break;

            //Market quote update (change to best market bid-ask prices)
            case Spark.EVENT_QUOTE:
                if (OnQuoteUpdate != null)
                {
                    LimitOrderBook depth = OrderBooks[eventFeedArgs.Exchange];
                    MarketQuote    quote = new MarketQuote(eventFeedArgs.Symbol, eventFeedArgs.Exchange, depth.BidPrice, depth.AskPrice, eventFeedArgs.TimeStamp);
                    OnQuoteUpdate(this, new GenericEventArgs <MarketQuote>(eventFeedArgs.TimeStamp, quote));
                }
                break;

            //IAP (Indicative Auction Price) Update
            case Spark.EVENT_AUCTION_PRICE:
                break;

            default:
                //Console.WriteLine(eventItem.ToOutputString());
                break;
            }
        }
Beispiel #17
0
        /// <summary>
        /// Extension method for the Spark.Event struct that generates new trade from order event if there is an
        /// event type match, otherwise returns NULL.
        /// </summary>
        internal static Trade ToTrade(this Spark.Event eventItem, DateTime observationTime)
        {
            var values = GetSymbolExchange(eventItem.Code, eventItem.Exchange);

            return(eventItem.ToTrade(values.Item1, values.Item2, observationTime));
        }
 /// <summary>
 /// Fired each time an event is read from file
 /// </summary>
 /// <param name="eventItem"></param>
 private void EventRecieved(Spark.Event eventItem)
 {
     _eventQueue.Add(eventItem);
 }