Click to See Complete Forum and Search --> : A stock quote question


zhuang
August 2nd, 1999, 01:55 PM
Hi,

A lot of programs can retrieve stock quote from public web site. Anyone knows the address? Is it possible to keep the retrieved the quote in memmory without saving it as a file? I have tried the following
http://quote.yahoo.com/d/quotes.csv?s=^HSI+^IXIC+^DJI+^IXY2+^BTK&f=sl1d1t1c1ohgv&e=.csv
The problem with this address is that a file/saveas dialog shows up, asking for a filename. My minimum need is to eliminate the dialog with a prespecified filename or show the quotes on the browser directly without asking for filename.

Any hint is thankful.



Best Regards,

Zenger Huang

edmz
August 2nd, 1999, 03:40 PM
I have been wanting do the the same thing. I think what most programs do, is just parse the html source and find certain predetermined patterns.

In perl or php thats easy, but i have never programmed sockets in C so i dont know how to open an http connection.

zhuang
August 2nd, 1999, 04:38 PM
It does not need socket programming, I think. There are lots of sample programming about Http connections in this site or Vc++ samples directory. My problems was the address: what is the correct address I can use to display stock quote directory without saving it as a file. Actually the address I provided does not always fails. Occasionally, I got quote displayed on the screen directly.

thanks for the reply anyway.



Zenger Huang

joacim
August 3rd, 1999, 06:13 AM
Hi!

I am using the following class to download a stock info file from internet. Instead for writing to file you can take it into memory.

Another thing: I'm also developing a stock application but I wonder how to get nice charts. How have you made this. I'm thinking about developing a ActiveX component but it isn't easy.

File "DownloadFile.h"

// DownloadFile.h: interface for the CDownloadFile class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_DOWNLOADFILE_H__8635B0E0_3F77_11D3_841D_0000E85C4B25__INCLUDED_)
#define AFX_DOWNLOADFILE_H__8635B0E0_3F77_11D3_841D_0000E85C4B25__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <afxinet.h>
#include "LogToFile.h"

class CDownloadException : public CException
{
DECLARE_DYNCREATE(CDownloadException)

public:
CDownloadException(int nCode = 0);
~CDownloadException();

int m_nErrorCode;
};

class CDownloadSession : public CInternetSession
{
public:
CDownloadSession(LPCTSTR pszAppName, int nMethod);
virtual void OnStatusCallback(DWORD dwContext, DWORD dwInternetStatus,
LPVOID lpvStatusInfomration, DWORD dwStatusInformationLen);
};


class CDownloadFile
{
public:
BOOL isValidUrl(CString *szURL, DWORD *dwServiceType,
CString *szServerName, CString *szObject,
INTERNET_PORT *nPort);
bool GetFile(CString szFileName, CString szSaveAs,
CString *szStatus);
CDownloadFile(CString &Server, CString &ServerDir, CString &InstallDir);
virtual ~CDownloadFile();

private:
void ProcessMessages();
BOOL m_bErrorHasOccured;
void CloseAndDeallocate();
CString m_szDownloadDirectory;
void SendErrorMsg(DWORD dwRet);
CInternetSession* m_pInetSession;
CHttpConnection* m_pHttpConnection;
CHttpConnection* pHttpConn;
CHttpFile* pFile;
CString m_szServer;
CString m_szDirectory;
CString m_szURL;
CLogToFile m_log;

};

#endif // !defined(AFX_DOWNLOADFILE_H__8635B0E0_3F77_11D3_841D_0000E85C4B25__INCLUDED_)





File "DownloadFile.cpp"

// DownloadFile.cpp: implementation of the CDownloadFile class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DownloadFile.h"
#include <direct.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

/////////////////////////////////////////////////////////////////////////////
// CDownloadException -- used if something goes wrong for us

// Download will throw its own exception type to handle problems it might
// encounter while fulfilling the user's request.
void ThrowDownloadException(int nCode)
{
CDownloadException* pEx = new CDownloadException(nCode);
throw pEx;
}

IMPLEMENT_DYNCREATE(CDownloadException, CException)

CDownloadException::CDownloadException(int nCode)
: m_nErrorCode(nCode)
{
}

CDownloadException::~CDownloadException()
{

}


/////////////////////////////////////////////////////////////////////////////
// CDownloadSession object

// Download wants to use its own derivative of the CInternetSession class
// just so it can implement an OnStatusCallback() override.

CDownloadSession::CDownloadSession(LPCTSTR pszAppName, int nMethod)
: CInternetSession(pszAppName, 1, nMethod)
{
}

void CDownloadSession::OnStatusCallback(DWORD /* dwContext */, DWORD dwInternetStatus,
LPVOID /* lpvStatusInfomration */, DWORD /* dwStatusInformationLen */)
{
if (dwInternetStatus == INTERNET_STATUS_CONNECTED_TO_SERVER)
// AfxMessageBox("Connection made!");
if (dwInternetStatus == INTERNET_STATUS_REQUEST_SENT)
// AfxMessageBox("Successfully sent the information request to the server!");
if (dwInternetStatus == INTERNET_STATUS_CLOSING_CONNECTION)
AfxMessageBox("Closing the connection to the server");
}


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDownloadFile::CDownloadFile(CString &Server, CString &ServerDir, CString &InstallDir)
: m_log(InstallDir + (CString)"\\log\\", (CString)"download.log")
{
m_log.PrintCurTime();

// Will be installation directory
m_szDownloadDirectory = InstallDir + "\\data\\";
// Looks if it exist and create it if nessary
if ( _chdir(m_szDownloadDirectory) == -1)
{
if( _mkdir(m_szDownloadDirectory) == -1)
{
AfxMessageBox("Couldn't create dir::\n" + m_szDownloadDirectory);
}
}

m_szServer = Server;
m_szDirectory = ServerDir;
m_pHttpConnection = NULL;
m_bErrorHasOccured = false;

// the CInternetSession will not be closed or deleted
// until the dialog is closed
CString str;
if (!str.LoadString(IDS_APPNAME))
{
str = _T("Application Unknown");
}

m_pInetSession = new CInternetSession(str, 1, PRE_CONFIG_INTERNET_ACCESS);

// Alert the user if the internet session could
// not be started and close app
if (!m_pInetSession)
{
AfxMessageBox(IDS_BAD_SESSION, MB_OK);
}
}

CDownloadFile::~CDownloadFile()
{
// clean up any objets that are still lying around
if (m_pHttpConnection != NULL)
{
m_pHttpConnection->Close();
delete m_pHttpConnection;
}

if (m_pInetSession != NULL)
{
m_pInetSession->Close();
delete m_pInetSession;
}
// delete m_log;
}

// ***************************************************************************
// Get requested file
// ***************************************************************************
bool CDownloadFile::GetFile(CString szFileName, CString szSaveAs,
CString *szStatus)
{
if (m_bErrorHasOccured)
{
m_log << "Error\n";
}
m_szURL = m_szServer + m_szDirectory + szFileName;

int nRetCode = 0;
DWORD dwAccessType = PRE_CONFIG_INTERNET_ACCESS;
DWORD dwHttpRequestFlags = INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_NO_AUTO_REDIRECT;
//const TCHAR szHeaders[] = _T("Accept: text/*\r\nUser-Agent: MFC_Tear_Sample\r\n");

CDownloadSession session(_T("Download Stock Information"), dwAccessType);
pHttpConn = NULL;
pFile = NULL;

try
{
CString strServerName;
CString strObject;
INTERNET_PORT nPort = 0;
DWORD dwServiceType = 0;

isValidUrl(&m_szURL, &dwServiceType, &strServerName, &strObject, &nPort);

VERIFY(session.EnableStatusCallback(TRUE));
pHttpConn = session.GetHttpConnection(strServerName, nPort);
pFile = pHttpConn->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject, NULL,
1, NULL, NULL, dwHttpRequestFlags);
// pFile->AddRequestHeaders(szHeaders);
pFile->SendRequest();

DWORD dwRet;
pFile->QueryInfoStatusCode(dwRet);

if (dwRet == 200)
{
TRY
{
//CFile file(szSaveAs, CFile::modeCreate | CFile::modeWrite );
CFile file(m_szDownloadDirectory + szSaveAs,
CFile::modeCreate | CFile::modeWrite );

BYTE sz[1024];
long nRead = 0;
nRead = pFile->Read(sz, 1024);
while ( nRead > 0 )
{
file.Write(sz,nRead);
nRead = pFile->Read(sz, 1024);
ProcessMessages();
}
m_log << szFileName + " downloaded\n";
*szStatus = szFileName + " saved";

}
CATCH( CFileException, e )
{
#ifdef _DEBUG
afxDump << "File could not be opened " << e->m_cause << "\n";
#endif
}
END_CATCH
}
else
{
SendErrorMsg(dwRet);
CloseAndDeallocate();
session.Close();
return false;
}
}
catch (CInternetException* pEx)
{
// catch errors from WinINet
TCHAR szErr[1024];
pEx->GetErrorMessage(szErr, 1024);
CString str;
str.Format("Error: '%d'\r\n", pEx->m_dwError);
m_log << str;

nRetCode = 2;
pEx->Delete();
CloseAndDeallocate();
session.Close();
m_bErrorHasOccured = true;
return false;
}
catch (CDownloadException* pEx)
{
// catch things wrong with parameters, etc
nRetCode = pEx->m_nErrorCode;
CString str;
str.Format("Error: Exiting with CDownloadException: %d\r\n", nRetCode);
m_log << str;
pEx->Delete();
CloseAndDeallocate();
session.Close();
m_bErrorHasOccured = true;
return false;
}

CloseAndDeallocate();
session.Close();
return true;
}

// ***************************************************************************
// Send error message
// ***************************************************************************
void CDownloadFile::SendErrorMsg(DWORD dwRet)
{
if (dwRet == 200)
m_log << "URL located, transmission follows\n";
else if (dwRet == 400)
m_log << "Unintelligble request\n";
else if (dwRet == 404)
m_log << "Requested URL not found\n";
else if (dwRet == 405)
m_log << "Server does not support requested method\n";
else if (dwRet == 500)
m_log << "Unknown server error\n";
else if (dwRet == 503)
m_log << "Server capacity reached\n";
}

// ***************************************************************************
// Check the URL and try to fix it if missing "http://"
// ***************************************************************************
BOOL CDownloadFile::isValidUrl(CString *szURL, DWORD *dwServiceType,
CString *szServerName, CString *szObject,
INTERNET_PORT *nPort)
{
// check if it's a valid URL
if ( ! AfxParseURL(*szURL, *dwServiceType, *szServerName, *szObject, *nPort) ||
*dwServiceType != INTERNET_SERVICE_HTTP)
{
// add "http://" and check again
CString szHttpURL = _T("http://");
szHttpURL += *szURL;
if (!AfxParseURL(szHttpURL, *dwServiceType, *szServerName, *szObject, *nPort) ||
*dwServiceType != INTERNET_SERVICE_HTTP)
{
ThrowDownloadException(1);
return false;
}
else
{
// Add "http://" to the original URL
*szURL = szHttpURL;
return true;
}
}
return true;
}

// ***************************************************************************
// Close/delete file and connection
// ***************************************************************************
void CDownloadFile::CloseAndDeallocate()
{
if (pFile != NULL)
{
pFile->Close();
delete pFile;
}
if (pHttpConn != NULL)
{
pHttpConn->Close();
delete pHttpConn;
}
}

// ***************************************************************************
// This gives control (temporarily) back to Windows so it can forward you any
// pending messages, such as the user pressing Cancel.
// After that you need to determine if the user has pressed Cancel
// (through a member variable, etc.) so you can break out of the loop.
// Processes any messages waiting in the current thread's queue.
// ***************************************************************************
void CDownloadFile::ProcessMessages()
{
for (MSG msg; ::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); )
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}





Regards
Joacim

zhuang
August 3rd, 1999, 08:31 AM
Thank you for your response. Can you provide a simple example to use your class. I am in desperate
need of the quote address where I can get the quote data without saving it as a file. I am wondering how the Server, ServerDir and InstallDir are determined in the constructor.

Try to search for "stock chart" in this site, you can find a partial answer to your question. I will have to
deal with the same problem as soon as I am able to get the stock data.



Regards,
Zenger

joacim
August 3rd, 1999, 09:55 AM
Hello again!

I have made a little test application for CDownloadFile and some small modifications (clean up a little).
You can download it from: http://www.algonet.se/~joacim_j/temp/DownloadFileDemo.zip

I am using a quote address in Sweden with swedish stocks so I don't think you want it.

Regards
Joacim

zhuang
August 3rd, 1999, 11:29 AM
There is a compile error "'afxdtctl.h': No such file or directory Error" in my vc5.0. Is there anything wrong?

joacim
August 3rd, 1999, 03:38 PM
I use VC 6.0
Have you tried to comment it away?
I don't remember why it is there but I think it for some date.....

Regards
Joacim

Ron Daemen
August 6th, 1999, 01:13 AM
Hi

If you are trying to open the location using your browser this behaviour is normal. Because a file is return by the yahoo webserver. Thsi webserver sends a http header of type application/exe. Your browser asks to open it directly or save it. Use telnet to check if this correct. Connect to the URL on port 80
-> telnet url 80
type -> GET [URL] HTTP/1.0
Now can see the raw data returned from the server.
A sollution would be connecting on socket level and striping the information !

-- Ron

-- Ron