public bool Equals(RealTimeStreamInfo compare) { bool equal = compare.RequestID == RequestID && compare.Datasource == Datasource && compare.Instrument.ID == Instrument.ID && compare.Frequency == Frequency && compare.RTHOnly == RTHOnly; return equal; }
public bool Equals(RealTimeStreamInfo compare) { bool equal = compare.RequestID == RequestID && compare.Datasource == Datasource && compare.Instrument.ID == Instrument.ID && compare.Frequency == Frequency && compare.RTHOnly == RTHOnly; return(equal); }
/// <summary> /// Sends a real time data request to the correct data source, logs it, and updates subscriber counts /// </summary> /// <param name="request"></param> private void ForwardRTDRequest(RealTimeDataRequest request) { //send the request to the correct data source int reqID; try { reqID = DataSources[request.Instrument.Datasource.Name].RequestRealTimeData(request); } catch (Exception ex) { Log(LogLevel.Error, "Error requesting real time data: " + ex.Message); return; } //log the request Log(LogLevel.Info, string.Format("RTD Request: {0} from {1} @ {2} ID:{3}", request.Instrument.Symbol, request.Instrument.Datasource.Name, Enum.GetName(typeof(BarSize), request.Frequency), reqID)); //add the request to the active streams, though it's not necessarily active yet var streamInfo = new RealTimeStreamInfo( request.Instrument, reqID, request.Instrument.Datasource.Name, request.Frequency, request.RTHOnly); lock (_activeStreamsLock) { ActiveStreams.TryAdd(streamInfo); } lock (_subscriberCountLock) { StreamSubscribersCount.Add(streamInfo, 1); } }
// Accept a real time data request private void HandleRTDataRequest(TimeSpan timeout, MemoryStream ms) { int receivedBytes; byte[] buffer = _reqSocket.Receive(null, timeout, out receivedBytes); if (receivedBytes <= 0) return; ms.Write(buffer, 0, receivedBytes); ms.Position = 0; var request = Serializer.Deserialize<RealTimeDataRequest>(ms); //with the current approach we can't handle multiple real time data streams from //the same symbol and data source, but at different frequencies //if there is already an active stream of this instrument if (ActiveStreams.Collection.Any(x => x.Instrument.ID == request.Instrument.ID)) { //Find the KeyValuePair<string, int> from the dictionary that corresponds to this instrument //The KVP consists of key: request ID, value: data source name var streamInfo = ActiveStreams.Collection.First(x => x.Instrument.ID == request.Instrument.ID); //increment the subsriber count lock (_subscriberCountLock) { _streamSubscribersCount[streamInfo]++; } //log the request Application.Current.Dispatcher.InvokeAsync(() => Log(LogLevel.Info, string.Format("RTD Request for existing stream: {0} from {1} @ {2} ID:{3}", request.Instrument.Symbol, request.Instrument.Datasource.Name, Enum.GetName(typeof(BarSize), request.Frequency), streamInfo.RequestID))); //and report success back to the requesting client _reqSocket.SendMore("SUCCESS", Encoding.UTF8); //along with the symbol of the instrument _reqSocket.Send(request.Instrument.Symbol, Encoding.UTF8); } else if (DataSources.ContainsKey(request.Instrument.Datasource.Name) && //make sure the datasource is present & connected DataSources[request.Instrument.Datasource.Name].Connected) { //send the request to the correct data source int reqID = DataSources[request.Instrument.Datasource.Name].RequestRealTimeData(request); //log the request Application.Current.Dispatcher.InvokeAsync(() => Log(LogLevel.Info, string.Format("RTD Request: {0} from {1} @ {2} ID:{3}", request.Instrument.Symbol, request.Instrument.Datasource.Name, Enum.GetName(typeof(BarSize), request.Frequency), reqID))); //add the request to the active streams, though it's not necessarily active yet var streamInfo = new RealTimeStreamInfo( request.Instrument, reqID, request.Instrument.Datasource.Name, request.Frequency, request.RTHOnly); ActiveStreams.TryAdd(streamInfo); lock (_subscriberCountLock) { _streamSubscribersCount.Add(streamInfo, 1); } //and report success back to the requesting client _reqSocket.SendMore("SUCCESS", Encoding.UTF8); //along with the symbol of the instrument _reqSocket.Send(request.Instrument.Symbol, Encoding.UTF8); } else //no new request was made, send the client the reason why { _reqSocket.SendMore("ERROR", Encoding.UTF8); if (!DataSources.ContainsKey(request.Instrument.Datasource.Name)) { _reqSocket.Send("No such data source", Encoding.UTF8); } else if (!DataSources[request.Instrument.Datasource.Name].Connected) { _reqSocket.Send("Data source not connected", Encoding.UTF8); } } }
/// <summary> /// This method is called when the continuous futures broker returns the results of a request for the "front" /// contract of a continuous futures instrument. /// </summary> private void _cfBroker_FoundFrontContract(object sender, FoundFrontContractEventArgs e) { RealTimeDataRequest request; if (!e.Instrument.ID.HasValue) { Log(LogLevel.Error, "CF Broker returned front contract with no ID"); return; } Log(LogLevel.Info, string.Format("Front contract received on request ID {0}, is: {1}", e.ID, e.Instrument.Symbol)); //grab the original request lock (_cfRequestLock) { request = _pendingCFRealTimeRequests[e.ID]; _pendingCFRealTimeRequests.Remove(e.ID); } //add the contract to the ID map if (request.Instrument.ID.HasValue && !_continuousFuturesIDMap.ContainsKey(request.Instrument.ID.Value)) { _continuousFuturesIDMap.Add(request.Instrument.ID.Value, e.Instrument.ID.Value); } //add the alias lock (_aliasLock) { int contractID = e.Instrument.ID.Value; if (!_aliases.ContainsKey(contractID)) { _aliases.Add(contractID, new List <int>()); } if (request.Instrument.ID.HasValue) { _aliases[contractID].Add(request.Instrument.ID.Value); } } //need to check if there's already a stream of the contract.... bool streamExists; lock (_activeStreamsLock) { streamExists = ActiveStreams.Collection.Any(x => x.Instrument.ID == e.Instrument.ID); } if (streamExists) { //all we need to do in this case is increment the number of subscribers to this stream IncrementSubscriberCount(e.Instrument); //log it Log(LogLevel.Info, string.Format("RTD Request for CF {0} @ {1} {2}, filled by existing stream of symbol {3}.", request.Instrument.Symbol, request.Instrument.Datasource.Name, Enum.GetName(typeof(BarSize), request.Frequency), e.Instrument.Symbol)); } else //no current stream of this contract, add it { //make the request var contractRequest = (RealTimeDataRequest)request.Clone(); contractRequest.Instrument = e.Instrument; //we take the original request, and substitute the CF for the front contract ForwardRTDRequest(contractRequest); //add the request to the active streams, though it's not necessarily active yet var streamInfo = new RealTimeStreamInfo( request.Instrument, -1, request.Instrument.Datasource.Name, request.Frequency, request.RTHOnly); lock (_activeStreamsLock) { ActiveStreams.TryAdd(streamInfo); } lock (_subscriberCountLock) { StreamSubscribersCount.Add(streamInfo, 1); } //log it Log(LogLevel.Info, string.Format("RTD Request for CF: {0} from {1} @ {2}, filled by contract: {3}", request.Instrument.Symbol, request.Instrument.Datasource.Name, Enum.GetName(typeof(BarSize), request.Frequency), e.Instrument.Symbol)); } }