#include "stdafx.h" #include "QuotesProviderYahoo.h" #include "QuotesProviderVisitor.h" #include "ModuleInfo.h" #include "DBUtils.h" #include "EconomicRateInfo.h" #include "HTTPSession.h" namespace { void remove_quotes(tstring& s) { if (*s.begin() == _T('"')) { s.erase(s.begin()); } if (*s.rbegin() == _T('"')) { tstring::iterator i(s.begin()); std::advance(i,s.size()-1); s.erase(i); } } void remove_end_of_line(tstring& s) { if (*s.rbegin() == _T('\n')) { tstring::iterator i(s.begin()); std::advance(i,s.size()-1); s.erase(i); } if (*s.rbegin() == _T('\r')) { tstring::iterator i(s.begin()); std::advance(i,s.size()-1); s.erase(i); } } bool t2d(const tstring& s,double& d) { tistringstream stream(s); stream >> d; return ((false == stream.fail()) && (false == stream.bad())); // try // { // d = boost::lexical_cast(s); // return true; // } // catch(boost::bad_lexical_cast& e) // { // } // return false; } typedef std::vector TStrings; bool get_double_from_parsed_line(HANDLE hContact,const TStrings& rasParsedLine,size_t nIndex,const char* pszDbName) { if(rasParsedLine.size() > nIndex) { double d = 0.0; if(true == t2d(rasParsedLine[nIndex],d)) { return Quotes_DBWriteDouble(hContact,QUOTES_MODULE_NAME,pszDbName,d); } } DBWriteContactSettingTString(hContact,QUOTES_MODULE_NAME,pszDbName,_T("")); return false; } } void CQuotesProviderYahoo::RefreshQuotes(TContracts& anContacts) { tstring sURL = GetURL(); bool bUseExtendedStatus = CModuleInfo::GetInstance().GetExtendedStatusFlag(); typedef std::map TQuoteID2ContractHandles; TQuoteID2ContractHandles aQuoteID2Handles; tostringstream oURL; oURL << sURL << _T("dioksin.txt?s="); for(TContracts::const_iterator i = anContacts.begin();i != anContacts.end() && IsOnline();++i) { HANDLE hContact = *i; if(bUseExtendedStatus) { SetContactStatus(hContact,ID_STATUS_OCCUPIED); } tstring sQuoteID = Quotes_DBGetStringT(hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_ID); aQuoteID2Handles[sQuoteID] = hContact; if(i != anContacts.begin()) { oURL << _T("+"); } oURL << sQuoteID; } if(true == IsOnline()) { oURL << _T("&f=snl1ohgpc1"); CHTTPSession http; if ((true == http.OpenURL(oURL.str())) && (true == IsOnline())) { tstring sFile; if ((true == http.ReadResponce(sFile)) && (true == IsOnline())) { tistringstream out_str(sFile.c_str()); while(false == out_str.eof()) { tstring sLine; std::getline(out_str,sLine); if(false == sLine.empty()) { remove_end_of_line(sLine); TStrings asStrings; for(tstring::size_type nPos = sLine.find(_T(','));nPos != tstring::npos; nPos = sLine.find(_T(','))) { tstring::iterator i(sLine.begin()); std::advance(i,nPos); tstring s(sLine.begin(),i); remove_quotes(s); asStrings.push_back(s); if(i != sLine.end()) { std::advance(i,1); } sLine.erase(sLine.begin(),i); } if(false == sLine.empty()) { remove_quotes(sLine); if(false == sLine.empty()) asStrings.push_back(sLine); } size_t cItems = asStrings.size(); if(cItems >= 3) { enum { indexSymbol = 0, indexName, indexLastTrade, indexOpen, indexDayHigh, indexDayLow, indexPreviousClose, indexChange }; auto it3 = aQuoteID2Handles.find(asStrings[indexSymbol]); if(it3 != aQuoteID2Handles.end()) { HANDLE hContact = it3->second; double dRate = 0.0; if(true == t2d(asStrings[indexLastTrade],dRate)) { DBWriteContactSettingTString(hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_DESCRIPTION,asStrings[indexName].c_str()); get_double_from_parsed_line(hContact,asStrings,indexOpen,DB_STR_YAHOO_OPEN_VALUE); get_double_from_parsed_line(hContact,asStrings,indexDayHigh,DB_STR_YAHOO_DAY_HIGH); get_double_from_parsed_line(hContact,asStrings,indexDayLow,DB_STR_YAHOO_DAY_LOW); get_double_from_parsed_line(hContact,asStrings,indexPreviousClose,DB_STR_YAHOO_PREVIOUS_CLOSE); get_double_from_parsed_line(hContact,asStrings,indexChange,DB_STR_YAHOO_CHANGE); WriteContactRate(hContact,dRate); aQuoteID2Handles.erase(it3); } } } } } } } if(true == IsOnline()) { std::for_each(aQuoteID2Handles.begin(),aQuoteID2Handles.end(), [](const TQuoteID2ContractHandles::value_type& pair){SetContactStatus(pair.second,ID_STATUS_NA);}); } } } void CQuotesProviderYahoo::Accept(CQuotesProviderVisitor& visitor)const { CQuotesProviderFinance::Accept(visitor); visitor.Visit(*this); }