// method is called when there are new data to update public Array RefreshData(ref int topicCount) { object[,] data = null; try { TwsRtdServerConnection connection = null; TwsRtdServerMktDataRequest mktDataRequest = null; TwsRtdServerTopic topic = null; // in loop - update all topics from updatedTopicIds array int[] updatedTopicIds; lock (m_updatedTopicIds) { updatedTopicIds = m_updatedTopicIds.ToArray(); m_updatedTopicIds.Clear(); } topicCount = updatedTopicIds.Length; data = new object[2, topicCount]; int n = 0; foreach(var topicId in updatedTopicIds) { TwsRtdServerTopicIdMap twsRtdServerTopicIdMap = null; if (m_topicIdMap.TryGetValue(topicId, out twsRtdServerTopicIdMap)) { // get appropriate connection if (m_connections.TryGetValue(twsRtdServerTopicIdMap.ConnectionStr(), out connection)) { // get appropriate mktDataRequest mktDataRequest = connection.GetMktDataRequest(twsRtdServerTopicIdMap.TwsReqId()); if (mktDataRequest != null) { // get appropriate topic topic = mktDataRequest.GetTopic(twsRtdServerTopicIdMap.TopicStr()); } if (topic != null) { // update data array with topic.Id and topic.Value data[0, n] = topic.TopicId(); data[1, n] = topic.TopicValue(); n++; } } } } } catch //(COMException comException) { // comException.Message = "The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))" // Console.WriteLine(comException.Message); } return data; }
void GetTopicAndAddUpdate(string topicStr, TwsRtdServerMktDataRequest mktDataRequest, object value) { TwsRtdServerTopic topic = mktDataRequest.GetTopic(topicStr); if (topic != null) { // set topic's new value topic.TopicValue(value); m_server.AddUpdatedTopicId(topic.TopicId()); // add topic to updatedTopicIds array } // save latest value mktDataRequest.SetMktDataTickValue(topicStr, value); }
// this method is called when topic is removed public void DisconnectData(int topicId) { try { // find appropriate connection, mktDataRequest and topic TwsRtdServerTopicIdMap twsRtdServerTopicIdMap = null; if (!m_topicIdMap.TryGetValue(topicId, out twsRtdServerTopicIdMap)) { return; } // get appropriate connection TwsRtdServerConnection connection = null; if (!m_connections.TryGetValue(twsRtdServerTopicIdMap.ConnectionStr(), out connection)) { return; } // get appropriate mktDataRequest TwsRtdServerMktDataRequest mktDataRequest = connection.GetMktDataRequest(twsRtdServerTopicIdMap.TwsReqId()); if (mktDataRequest != null) { // get appropriate topic TwsRtdServerTopic topic = mktDataRequest.GetTopic(twsRtdServerTopicIdMap.TopicStr()); if (topic != null) { // remove topic mktDataRequest.RemoveTopic(twsRtdServerTopicIdMap.TopicStr()); } m_topicIdMap.Remove(topicId); // remove topicId from updatedTopicIds lock (m_updatedTopicIds) { m_updatedTopicIds.Remove(topicId); } // try to remove mktDataRequest connection.RemoveMktDataRequest(twsRtdServerTopicIdMap.TwsReqId()); } } catch { // error disconnecting data } }
public TwsRtdServerTopic GetOrAddTopic(string topicStr, int topicId) { // find topic (to reuse existing topic and not create new one) TwsRtdServerTopic topic = null; if (topicStr != null && !m_topics.TryGetValue(topicStr, out topic)) { // if topic was not found, then create new one topic = new TwsRtdServerTopic(topicStr, topicId); // add [topicStr=>topic] mapping to collection of topics m_topics.Add(topicStr, topic); // set initial value of topic (in case of non-streaming market data) topic.TopicValue(m_mktDataTicks.GetValue(topicStr)); } return(topic); }
// this method is called when new topic is requested public object ConnectData(int topicId, ref Array strings, ref bool newValues) { string connectionStr, mktDataRequestStr, topicStr; newValues = true; try { // parse input strings (connection, marketDataRequest and topic) connectionStr = TwsRtdServerConnection.ParseConnectionStrings(strings); mktDataRequestStr = TwsRtdServerMktDataRequest.ParseMktDataRequestStrings(strings); topicStr = TwsRtdServerTopic.ParseTopicStrings(strings); // check that connectioStr, mktDataRequestStr and topicStr is not null if (connectionStr == null) { return("TwsRtdServer: Cannot parse connection strings"); } if (mktDataRequestStr == null) { return("TwsRtdServer: Cannot parse mktDataRequest strings"); } if (topicStr == null) { return("TwsRtdServer: Cannot parse topic strings"); } TwsRtdServerConnection connection = null; // find connection from RTD server to TWS (to reuse existing connection and not to create new one) if (!m_connections.TryGetValue(connectionStr, out connection)) { // if connection is not found, then create new one and add it to collection connection = new TwsRtdServerConnection(this, connectionStr); // save connection m_connections.Add(connectionStr, connection); } if (connection != null && connection.GetErrorCode() != -1) { // error connecting to TWS return("TwsRtdServer error: " + connection.GetErrorText()); } TwsRtdServerMktDataRequest mktDataRequest = connection.GetOrAddMktDataRequest(mktDataRequestStr); string errorStr = null; if (mktDataRequest != null) { // save topicId -> connection/mktDataRequest/topicStr map m_topicIdMap.Add(topicId, new TwsRtdServerTopicIdMap(connectionStr, mktDataRequest.TwsReqId(), topicStr)); if (mktDataRequest.GetErrorCode() != -1 && mktDataRequest.GetErrorCode() != TwsRtdServerErrors.REQUESTED_MARKET_DATA_NOT_SUBSCRIBED) { // error creating market data request return(errorStr = "TwsRtdServer error: " + mktDataRequest.GetErrorText()); } } else { // error creating market data request return(errorStr = "TwsRtdServer error: market data request creation error"); } TwsRtdServerTopic topic = mktDataRequest.GetOrAddTopic(topicStr, topicId); if (topic == null) { // error creating topic return(errorStr = "TwsRtdServer error: topic creation error"); } // check if topic is delayed type if (topic != null && Array.IndexOf(TwsRtdServerData.DelayedTopics(), topic.TopicStr()) < 0 && mktDataRequest.GetErrorCode() == TwsRtdServerErrors.REQUESTED_MARKET_DATA_NOT_SUBSCRIBED) { errorStr = "TwsRtdServer error: " + mktDataRequest.GetErrorText(); } return((topic != null && errorStr == null) ? topic.TopicValue() : errorStr); } catch { return("RTDServer: Error connecting data"); } }