1009 lines
25 KiB
C++
1009 lines
25 KiB
C++
// StockData.cpp: implementation of the CStockData class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "hookmsg.h"
|
|
#include "StockData.h"
|
|
#include "HookMsgDlg.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
using std::fstream;
|
|
using std::ios;
|
|
using std::ofstream;
|
|
using std::endl;
|
|
|
|
UINT StockDataThread( LPVOID arg );
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
CStockData::CStockData(CHookMsgDlg * pParent)
|
|
{
|
|
m_pParent = pParent;
|
|
m_pDataPos = NULL;
|
|
m_pData = NULL;
|
|
m_pAddRepetitionCode = NULL;
|
|
m_nMaxData = 0;
|
|
|
|
m_hWaitEventStockData = ::CreateEvent( NULL, FALSE, FALSE, NULL );
|
|
m_hCloseEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL );
|
|
m_objStockMstm = NULL;
|
|
|
|
m_bRunning = FALSE;
|
|
m_bThreadRun = FALSE;
|
|
m_bRunningSkip = FALSE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
CStockData::~CStockData()
|
|
{
|
|
::CloseHandle( m_hWaitEventStockData );
|
|
::CloseHandle( m_hCloseEvent );
|
|
|
|
SAFE_DELETE( m_pDataPos );
|
|
SAFE_DELETE( m_pData );
|
|
SAFE_DELETE( m_pAddRepetitionCode );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Thread
|
|
BOOL CStockData::Open()
|
|
{
|
|
m_bThreadRun = TRUE;
|
|
|
|
CWinThread* pThread = AfxBeginThread(StockDataThread, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
|
|
//AssignThreadToCPU(pThread, CPU_0);
|
|
pThread->ResumeThread();
|
|
pThread->m_bAutoDelete = TRUE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Thread 시작
|
|
BOOL CStockData::Start()
|
|
{
|
|
m_bRunning = TRUE;
|
|
::SetEvent( m_hWaitEventStockData );
|
|
return TRUE;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Thread 종료
|
|
BOOL CStockData::Stop(bool bForce)
|
|
{
|
|
m_bRunning = FALSE;
|
|
::SetEvent( m_hWaitEventStockData );
|
|
return TRUE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Thread
|
|
HANDLE CStockData::Close(bool bWait)
|
|
{
|
|
m_bThreadRun = FALSE;
|
|
|
|
TRACE0("*** StockDataThread Thread Close step 0.\n");
|
|
::SetEvent( m_hWaitEventStockData );
|
|
|
|
// the thread is still running.
|
|
if( bWait )
|
|
{
|
|
if(::WaitForSingleObject(m_hCloseEvent,INFINITE) == WAIT_OBJECT_0) // 쓰레드 종료를 확인.
|
|
TRACE0("*** Close waitting success.\n");
|
|
else
|
|
TRACE0("*** Close waitting failed.\n");
|
|
}
|
|
|
|
return m_hCloseEvent;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
UINT StockDataThread( LPVOID arg )
|
|
{
|
|
CoInitialize(NULL);
|
|
|
|
CStockData *pStockData = (CStockData*)arg;
|
|
|
|
try
|
|
{
|
|
// CWnd pCPValue;
|
|
// pCPValue.Attach( (HWND)(pStockData->m_pParent->m_hCPValue.m_hWnd) );
|
|
|
|
DWORD dwRet;
|
|
DWORD dwMilliseconds;
|
|
while( pStockData->m_bThreadRun )
|
|
{
|
|
if( pStockData->m_bRunning ) {
|
|
dwMilliseconds = g_AppEnv.StockCheckInterval;
|
|
if( dwMilliseconds < 4000 ) {
|
|
dwMilliseconds = g_AppEnv.StockCheckInterval = 4000;
|
|
AfxMessageBox("[환경설정] -> [현재가 쓰레드 체크주기]는 4000ms 이상입니다.\n체크주기를 4000ms로 자동변경합니다.");
|
|
}
|
|
|
|
pStockData->m_pParent->m_hCPValue.SetWindowText("대기중...");
|
|
}
|
|
else {
|
|
pStockData->m_pParent->m_hCPValue.SetWindowText("멈춤");
|
|
dwMilliseconds = INFINITE;
|
|
|
|
// 현재가 기능을 끄면 모든종목의 현재가기록을 지움.
|
|
for( int i=0; i<pStockData->m_nMaxData; i++ )
|
|
pStockData->m_pData[ i ].lStockPrice = 0;
|
|
}
|
|
|
|
TRACE1("Wait...(dwMilliseconds: 0x%X)\n", dwMilliseconds);
|
|
dwRet = ::WaitForSingleObject( pStockData->m_hWaitEventStockData, dwMilliseconds );
|
|
if( dwRet == WAIT_OBJECT_0 &&
|
|
pStockData->m_bThreadRun == FALSE )
|
|
break;
|
|
|
|
if( pStockData->m_bRunning )
|
|
{
|
|
if( pStockData->m_objStockMstm == NULL ) {
|
|
TRACE("CLSID_StockMstm 객체생성...\n");
|
|
HRESULT hr = pStockData->m_objStockMstm.CreateInstance( CLSID_StockMstm );
|
|
if (FAILED(hr)) {
|
|
AfxMessageBox("현재가 StockMstm생성 실패했습니다.");
|
|
_com_issue_error( hr );
|
|
}
|
|
}
|
|
|
|
pStockData->m_pParent->m_hCPValue.SetWindowText("갱신중입니다.");
|
|
|
|
TRACE("검사시작.\n");
|
|
pStockData->Running();
|
|
TRACE("검사완료.\n");
|
|
|
|
#ifdef _DEBUG
|
|
long lCode = 4790;
|
|
STOCKDATA * pData = pStockData->GetStockData( lCode );
|
|
if( pData )
|
|
TRACE2("현재가 : 코드(A%06d), 현재가(%d) \n", lCode, pData->lStockPrice);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// pCPValue.Detach();
|
|
}
|
|
catch( _com_error e )
|
|
{
|
|
TRACE("CStockData::Run -> catch(_com_error)\n");
|
|
}
|
|
catch(...)
|
|
{
|
|
TRACE("CStockData::Run -> catch(...)\n");
|
|
}
|
|
|
|
if( pStockData->m_objStockMstm != NULL ) {
|
|
pStockData->m_objStockMstm.Release();
|
|
pStockData->m_objStockMstm = NULL;
|
|
}
|
|
|
|
TRACE0("*** StockDataThread Thread Close step 1.\n");
|
|
::SetEvent( pStockData->m_hCloseEvent ); // 쓰레드 종료를 확인.
|
|
|
|
CoUninitialize();
|
|
TRACE0("*** StockDataThread Thread Ended\n");
|
|
return 0;
|
|
}
|
|
|
|
void CStockData::Running()
|
|
{
|
|
try
|
|
{
|
|
CString strJCode;
|
|
long i, nJCode, nLow, nHeigh;
|
|
short sCompare;
|
|
long nMergeCount;
|
|
char szMergeCode[1024]={0,};
|
|
|
|
STOCKDATA * pData = NULL;
|
|
long nIndex=0;
|
|
|
|
while( nIndex<m_nMaxData )
|
|
{
|
|
if( m_bRunningSkip || !m_bRunning || !m_bThreadRun ) // 작업진행중 작업중지(매매중 부하를 줄여주기위함)
|
|
break;
|
|
|
|
memset( &szMergeCode, NULL, 1024 );
|
|
nMergeCount=0;
|
|
|
|
for(; nMergeCount<110; nIndex++ )
|
|
{
|
|
if(nIndex>=m_nMaxData)
|
|
break;
|
|
|
|
if( m_pData[ nIndex ].cbStockType == 5 ) // 1-장내, 5-코스닥, 6-제3시장
|
|
{
|
|
strcat( szMergeCode, m_pData[ nIndex ].szCode );
|
|
nMergeCount++;
|
|
}
|
|
}
|
|
|
|
if( strlen( szMergeCode ) == 0 ) continue;
|
|
|
|
m_objStockMstm->SetInputValue( 0, szMergeCode );
|
|
m_objStockMstm->BlockRequest();
|
|
|
|
short nGetCount = m_objStockMstm->GetHeaderValue( 0 ); // 0. (short) count
|
|
for( i=0; i<nGetCount; i++ )
|
|
{
|
|
strJCode = (LPSTR)(_bstr_t)m_objStockMstm->GetDataValue(0, i); // 0 : (string) 종목 코드
|
|
|
|
nJCode = atol( (LPSTR)(LPCTSTR)strJCode.Right(6) );
|
|
pData = GetStockData( nJCode );
|
|
if( pData != NULL )
|
|
{
|
|
pData->lStockPrice = (long)m_objStockMstm->GetDataValue(4, i); // 4. (long) 현재가.
|
|
|
|
sCompare = (short)m_objStockMstm->GetDataValue(3, i); // 3. (short) 대비 구분 *1:"상한",2:"상승",3:"보합",4:"하한",5:"하락",6:"기세상한",7:"기세상승",8:"기세하한",9:"기세하락".
|
|
nLow = (long)m_objStockMstm->GetDataValue(6, i); // 6. (long) 매수호가.
|
|
nHeigh = (long)m_objStockMstm->GetDataValue(5, i); // 5. (long) 매도호가
|
|
|
|
if( nLow == 0 || sCompare == 4 ) // 매수호가가 0 이면 하한종목으로 판단.
|
|
pData->bLowest = true;
|
|
else
|
|
pData->bLowest = false;
|
|
|
|
if( nHeigh == 0 || sCompare == 1 ) // 매도호가가 0 이면 상한종목으로 판단.
|
|
pData->bHeigest = true;
|
|
else
|
|
pData->bHeigest = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
::MessageBox( NULL, "현재가검사기능을 멀티쓰레드에서 재시작하지 못했습니다.\n"
|
|
"이 문제는 CybosPlus의 자체문제입니다.\n\n"
|
|
"현재가 기능을 다시 사용하시려면 프로그램을 재실행하십시오.", "현재가 검사", MB_TOPMOST );
|
|
}
|
|
}
|
|
/******************************************************************************/
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void CStockData::Initialize()
|
|
{
|
|
try
|
|
{
|
|
HRESULT hr;
|
|
ICpStockCodePtr _objStockCode;
|
|
|
|
hr = _objStockCode.CreateInstance( CLSID_CpStockCode ); // 종목코드변환.
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
m_nMaxData = (long)_objStockCode->GetCount();
|
|
|
|
// 전종목 데이터 생성 및 초기화.
|
|
m_pDataPos = new long[ MAX_DATA ];
|
|
memset( m_pDataPos, NULL, sizeof(long)*MAX_DATA );
|
|
m_pData = new STOCKDATA[ m_nMaxData ];
|
|
memset( m_pData, NULL, sizeof(STOCKDATA)*m_nMaxData );
|
|
|
|
long nCode;
|
|
CString _strJCode, _strJName;
|
|
for(int i=0; i<m_nMaxData; i++)
|
|
{
|
|
_strJCode = (LPCSTR)(_bstr_t)_objStockCode->GetData(0, i);
|
|
_strJName = (LPCSTR)(_bstr_t)_objStockCode->GetData(1, i);
|
|
|
|
nCode = atol( (LPSTR)(LPCTSTR)_strJCode.Right(6) );
|
|
m_pDataPos[nCode] = (long)i;
|
|
|
|
m_pData[ i ].lCode = nCode;
|
|
strcpy( m_pData[ i ].szCode, (LPSTR)(LPCTSTR)_strJCode );
|
|
strcpy( m_pData[ i ].szName, (LPSTR)(LPCTSTR)_strJName );
|
|
m_pData[ i ].cbStockType = (BYTE)_objStockCode->GetData( 4, i ); // 1-장내, 5-코스닥, 6-제3시장
|
|
}
|
|
|
|
_objStockCode.Release();
|
|
|
|
InitExclusionCodeFromRegistery(); // 거부 : 레지스트리에서 거부종목을 읽어옴.
|
|
ReadFileExclusionCodeFromFile(); // 거부 : 파일에서 거부종목 읽어옴.
|
|
|
|
ReadFileSpecialCodeByPublish(); // 공시 특별종목 설정파일 읽어옴.
|
|
|
|
ReadFileManualInputCodeFromFile();// 수동종목코드.
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
TCHAR szFilePath[_MAX_PATH]={0,};
|
|
::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
|
|
*(strrchr( szFilePath, '\\' ) + 1) = 0;
|
|
strcat( szFilePath, "Temp_RepetitionCode.tmp" );
|
|
Initialize_RepetitionCode( szFilePath );
|
|
}
|
|
else
|
|
{
|
|
AfxMessageBox( "CStockData::Initialize() 객체 생성실패!" );
|
|
}
|
|
}
|
|
catch( _com_error e )
|
|
{
|
|
AfxMessageBox( "CStockData::Initialize() Catch Error!" );
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
BOOL CStockData::StockVerify( CString &strCode, long & _Price, BYTE & _Type )
|
|
{
|
|
long nIndex = atol( (LPSTR)(LPCTSTR)strCode );
|
|
STOCKDATA * pData = GetStockData( nIndex );
|
|
if( pData != NULL )
|
|
{
|
|
_Price = pData->lStockPrice;
|
|
_Type = pData->cbStockType;
|
|
|
|
if( pData->lStockPrice )
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
BOOL CStockData::StockVerify( long nCode, long & _Price, BYTE & _Type )
|
|
{
|
|
STOCKDATA * pData = GetStockData( nCode );
|
|
if( pData != NULL )
|
|
{
|
|
_Price = pData->lStockPrice;
|
|
_Type = pData->cbStockType;
|
|
|
|
if( pData->lStockPrice )
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
long CStockData::ReCalcPrice( long _Price, long nLevel )
|
|
{
|
|
// 호가 재계산.
|
|
// ----------------------
|
|
// 5000 미만 : 5원.
|
|
// 5000 ~ 10000 : 10원.
|
|
// 10000 ~ 50000 : 50원.
|
|
// 50000 이상 : 100원.
|
|
// ----------------------
|
|
long lRetPrice = _Price;
|
|
|
|
if( _Price < 5000 )
|
|
{
|
|
lRetPrice += (5*nLevel);
|
|
}
|
|
else if( _Price >= 5000 && _Price < 10000 )
|
|
{
|
|
lRetPrice += (10*nLevel);
|
|
}
|
|
else if( _Price >= 10000 && _Price < 50000 )
|
|
{
|
|
lRetPrice += (50*nLevel);
|
|
}
|
|
else if( _Price >= 50000 )
|
|
{
|
|
lRetPrice += (100*nLevel);
|
|
}
|
|
|
|
return lRetPrice;
|
|
}
|
|
|
|
|
|
void CStockData::InitExclusionCodeFromRegistery()
|
|
{
|
|
int i;
|
|
for( i=0; i<m_nMaxData; i++ )
|
|
m_pData[ i ].bRejectedFromRegistery = false;
|
|
|
|
CHookMsgApp* pApp = (CHookMsgApp*)AfxGetApp();
|
|
|
|
CString strCodes;
|
|
strCodes = pApp->RegReadString(HKEY_CURRENT_USER,
|
|
"SOFTWARE\\LimmSoft\\TKRRDR\\RejectList\\",
|
|
"Codes");
|
|
|
|
CString strTemp = ""; long strTempCount = 0;
|
|
STOCKDATA * pData = NULL;
|
|
long nIndex;
|
|
while(i + 5 < strCodes.GetLength())
|
|
{
|
|
nIndex = atol( (LPSTR)(LPCTSTR)strCodes.Mid(i, 6) );
|
|
pData = GetStockData( nIndex );
|
|
if( pData != NULL )
|
|
{
|
|
pData->bRejectedFromRegistery = true;
|
|
}
|
|
else
|
|
{
|
|
strTemp += strCodes.Mid(i, 6) + " ";
|
|
if( (++strTempCount % 4) == 0 ) strTemp += "\r\n";
|
|
}
|
|
|
|
i += 6;
|
|
}
|
|
|
|
if( strTempCount )
|
|
{
|
|
CString str;
|
|
str.Format("<거부리스트1> Registery \r\n\r\n%s\r\n전체 %d개 처리불가.", strTemp, strTempCount);
|
|
::MessageBox(NULL, str, "종목코드 예외처리", MB_OK|MB_ICONSTOP|MB_TOPMOST);
|
|
}
|
|
}
|
|
|
|
void CStockData::ListBoxLoad_RepeatedCode( CListBox *pListBox )
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
CString strAdd;
|
|
for( int i=0; i<m_nMaxData; i++ )
|
|
{
|
|
if(m_pData[i].bRepeated == true )
|
|
{
|
|
strAdd.Format( "%s: %s (%d)", m_pData[i].szCode+1, m_pData[i].szName, m_pData[i].lStockPrice );
|
|
pListBox->AddString(strAdd);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStockData::ListBoxSave_RepeatedCode( CListBox *pListBox )
|
|
{
|
|
//////////////////////////////////////////////////////////////////
|
|
int i;
|
|
for( i=0; i<m_nMaxData; i++ )
|
|
m_pData[ i ].bRepeated = false;
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
m_pAddRepetitionCode->close();
|
|
SAFE_DELETE( m_pAddRepetitionCode );
|
|
|
|
TCHAR szFilePath[_MAX_PATH]={0,};
|
|
::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
|
|
*(strrchr( szFilePath, '\\' ) + 1) = 0;
|
|
strcat( szFilePath, "Temp_RepetitionCode.tmp" );
|
|
_unlink( szFilePath );
|
|
|
|
CString _strDate;
|
|
char szTmp[100];
|
|
_strdate( szTmp );
|
|
_strDate = szTmp;
|
|
|
|
m_pAddRepetitionCode = new ofstream;
|
|
m_pAddRepetitionCode->open( szFilePath, ios::app );
|
|
*m_pAddRepetitionCode << _strDate << endl;
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
long nIndex;
|
|
STOCKDATA * pData = NULL;
|
|
CString strCode;
|
|
for(i = 0; i < pListBox->GetCount(); i++)
|
|
{
|
|
pListBox->GetText(i, strCode);
|
|
|
|
nIndex = atol( (LPSTR)(LPCTSTR)strCode.Left(6) );
|
|
pData = GetStockData( nIndex );
|
|
if( pData != NULL )
|
|
{
|
|
pData->bRepeated = true;
|
|
*m_pAddRepetitionCode << strCode.Left(6) << endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CStockData::Initialize_RepetitionCode( CString strFile )
|
|
{
|
|
if( m_pAddRepetitionCode != NULL )
|
|
{
|
|
AfxMessageBox("중복파일 초기화를할 수 없습니다.");
|
|
return FALSE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
int i;
|
|
for( i=0; i<m_nMaxData; i++ )
|
|
m_pData[ i ].bRepeated = false;
|
|
|
|
CString _strDate;
|
|
char szTmp[100];
|
|
_strdate( szTmp );
|
|
_strDate = szTmp;
|
|
|
|
CStdioFile file;
|
|
BOOL bReturn = FALSE;
|
|
|
|
if( !file.Open(strFile, CFile::modeRead | CFile::typeText) )
|
|
{
|
|
m_pAddRepetitionCode = new ::ofstream;
|
|
m_pAddRepetitionCode->open( (LPSTR)(LPCSTR)strFile, ios::app );
|
|
*m_pAddRepetitionCode << _strDate << endl;
|
|
return FALSE;
|
|
}
|
|
|
|
long nCount=0;
|
|
|
|
TRY
|
|
{
|
|
CString strTemp = ""; long strTempCount = 0;
|
|
long nIndex=0;
|
|
STOCKDATA * pData = NULL;
|
|
|
|
CString _strFileDate;
|
|
if( file.ReadString(_strFileDate) )
|
|
{
|
|
CString strSourceData;
|
|
while( file.ReadString(strSourceData) )
|
|
{
|
|
if( "'" == strSourceData.Left(1) || strSourceData.GetLength() == 0 )
|
|
continue;
|
|
|
|
strSourceData.TrimLeft( " " );
|
|
strSourceData.TrimRight( " " );
|
|
|
|
if( strSourceData.GetLength() >= 6 )
|
|
{
|
|
nIndex = atol( (LPSTR)(LPCTSTR)strSourceData.Left(6) );
|
|
pData = GetStockData( nIndex );
|
|
if( pData != NULL )
|
|
{
|
|
pData->bRepeated = true;
|
|
}
|
|
else
|
|
{
|
|
strTemp += strSourceData.Left(6) + " ";
|
|
if( (++strTempCount % 4) == 0 ) strTemp += "\r\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
if( strTempCount )
|
|
{
|
|
CString str;
|
|
str.Format("<중복종목(임시저장)> \r\n\r\n%s\r\n전체 %d개 처리불가.", strTemp, strTempCount);
|
|
::MessageBox(NULL, str, "종목코드 예외처리", MB_OK|MB_ICONSTOP|MB_TOPMOST);
|
|
}
|
|
|
|
if( _strDate == _strFileDate && nIndex != 0 )
|
|
{
|
|
bReturn = TRUE;
|
|
}
|
|
}
|
|
}
|
|
CATCH(CFileException, e)
|
|
{
|
|
#ifdef _DEBUG
|
|
afxDump << "Error during reading. " << e->m_cause << "\n";
|
|
#endif
|
|
AfxMessageBox("Error during reading file.");
|
|
file.Close();
|
|
return FALSE;
|
|
}
|
|
END_CATCH
|
|
|
|
file.Close();
|
|
|
|
if( bReturn == FALSE )
|
|
_unlink( strFile );
|
|
|
|
m_pAddRepetitionCode = new ::ofstream;
|
|
m_pAddRepetitionCode->open( (LPSTR)(LPCSTR)strFile, ios::app );
|
|
|
|
if( bReturn == FALSE )
|
|
*m_pAddRepetitionCode << _strDate << endl;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CStockData::ListBoxLoad_ExclusionCode( CListBox *pListBox )
|
|
{
|
|
CString strAdd;
|
|
for( int i=0; i<m_nMaxData; i++ )
|
|
{
|
|
if(m_pData[i].bRejectedFromFile == true )
|
|
{
|
|
if( strlen(m_pData[i].szCode) == 0 )
|
|
{
|
|
TRACE("Error : 종목명변환안됨");
|
|
strAdd.Format( "%06d: ---------- 종목명변환안됨.", i );
|
|
}
|
|
else
|
|
{
|
|
strAdd.Format( "%s: %s (%d)", m_pData[i].szCode+1, m_pData[i].szName, m_pData[i].lStockPrice );
|
|
}
|
|
|
|
pListBox->AddString(strAdd);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStockData::ListBoxSave_ExclusionCode( CListBox *pListBox )
|
|
{
|
|
int i;
|
|
for( i=0; i<m_nMaxData; i++ )
|
|
m_pData[ i ].bRejectedFromFile = false;
|
|
|
|
long nIndex;
|
|
STOCKDATA * pData = NULL;
|
|
CString strCode;
|
|
for(i = 0; i < pListBox->GetCount(); i++)
|
|
{
|
|
pListBox->GetText(i, strCode);
|
|
|
|
nIndex = atol( (LPSTR)(LPCTSTR)strCode.Left(6) );
|
|
pData = GetStockData( nIndex );
|
|
if( pData != NULL )
|
|
{
|
|
pData->bRejectedFromFile = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStockData::ListBoxLoad_SpecialCode( CListBox *pListBox )
|
|
{
|
|
CString strAdd;
|
|
for( int i=0; i<m_nMaxData; i++ )
|
|
{
|
|
if(m_pData[i].bSpecialCodeByPublish == true )
|
|
{
|
|
if( strlen(m_pData[i].szCode) == 0 )
|
|
{
|
|
TRACE("Error : 종목명변환안됨");
|
|
strAdd.Format( "%06d: ---------- 종목명변환안됨.", i );
|
|
}
|
|
else
|
|
{
|
|
strAdd.Format( "%s: %s (%d)", m_pData[i].szCode+1, m_pData[i].szName, m_pData[i].lStockPrice );
|
|
}
|
|
|
|
pListBox->AddString(strAdd);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStockData::ListBoxSave_SpecialCode( CListBox *pListBox )
|
|
{
|
|
int i;
|
|
for( i=0; i<m_nMaxData; i++ )
|
|
m_pData[ i ].bSpecialCodeByPublish = false;
|
|
|
|
long nIndex;
|
|
STOCKDATA * pData = NULL;
|
|
CString strCode;
|
|
for(i = 0; i < pListBox->GetCount(); i++)
|
|
{
|
|
pListBox->GetText(i, strCode);
|
|
|
|
nIndex = atol( (LPSTR)(LPCTSTR)strCode.Left(6) );
|
|
pData = GetStockData( nIndex );
|
|
if( pData != NULL )
|
|
{
|
|
pData->bSpecialCodeByPublish = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStockData::ListBoxLoad_ManualInputCode( CListBox *pListBox )
|
|
{
|
|
CString strAdd;
|
|
for( int i=0; i<m_nMaxData; i++ )
|
|
{
|
|
if(m_pData[i].bManualInputCode == true )
|
|
{
|
|
if( strlen(m_pData[i].szCode) == 0 )
|
|
{
|
|
TRACE("Error : 종목명변환안됨");
|
|
strAdd.Format( "%06d: ---------- 종목명변환안됨.", i );
|
|
}
|
|
else
|
|
{
|
|
strAdd.Format( "%s: %s (%d)", m_pData[i].szCode+1, m_pData[i].szName, m_pData[i].lStockPrice );
|
|
}
|
|
|
|
pListBox->AddString(strAdd);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStockData::ListBoxSave_ManualInputCode( CListBox *pListBox )
|
|
{
|
|
int i;
|
|
for( i=0; i<m_nMaxData; i++ )
|
|
m_pData[ i ].bManualInputCode = false;
|
|
|
|
long nIndex;
|
|
STOCKDATA * pData = NULL;
|
|
CString strCode;
|
|
for(i = 0; i < pListBox->GetCount(); i++)
|
|
{
|
|
pListBox->GetText(i, strCode);
|
|
|
|
nIndex = atol( (LPSTR)(LPCTSTR)strCode.Left(6) );
|
|
pData = GetStockData( nIndex );
|
|
if( pData != NULL )
|
|
{
|
|
pData->bManualInputCode = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStockData::AddRepeatedCode( CString strCode )
|
|
{
|
|
long nIndex = atol( (LPSTR)(LPCTSTR)strCode.Right(6) );
|
|
STOCKDATA * pData = GetStockData( nIndex );
|
|
if( pData != NULL )
|
|
{
|
|
pData->bRepeated = true;
|
|
|
|
if( m_pAddRepetitionCode != NULL )
|
|
*m_pAddRepetitionCode << strCode.Right(6) << endl;
|
|
}
|
|
}
|
|
|
|
BOOL CStockData::ReadFileSpecialCodeByPublish()
|
|
{
|
|
int i;
|
|
for( i=0; i<m_nMaxData; i++ )
|
|
m_pData[ i ].bSpecialCodeByPublish = false;
|
|
|
|
CString strFile = "공시_특별종목코드.txt";
|
|
|
|
TCHAR szFilePath[_MAX_PATH]={0,};
|
|
::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
|
|
*(strrchr( szFilePath, '\\' ) + 1) = 0;
|
|
strcat( szFilePath, (LPSTR)(LPCTSTR)strFile );
|
|
|
|
CStdioFile file;
|
|
|
|
if( !file.Open(szFilePath, CFile::modeRead | CFile::typeText) )
|
|
{
|
|
CString str;
|
|
str.Format(TEXT("File Open Error : %d\n%s"), GetLastError(), szFilePath);
|
|
AfxMessageBox(str);
|
|
return FALSE;
|
|
}
|
|
|
|
TRY
|
|
{
|
|
CString strTemp = ""; long strTempCount = 0;
|
|
long nIndex;
|
|
STOCKDATA * pData = NULL;
|
|
|
|
CString strSourceData;
|
|
|
|
while( file.ReadString(strSourceData) )
|
|
{
|
|
if( "'" == strSourceData.Left(1) || strSourceData.GetLength() == 0 )
|
|
continue;
|
|
|
|
strSourceData.TrimLeft( " " );
|
|
strSourceData.TrimRight( " " );
|
|
int nLength = strSourceData.GetLength();
|
|
if (6 <= nLength)
|
|
{
|
|
nLength = 6;
|
|
}
|
|
else
|
|
{
|
|
if( nLength == 0 ) continue;
|
|
AfxMessageBox( strSourceData + " : 종목코드 길이가 다릅니다." );
|
|
return FALSE;
|
|
}
|
|
|
|
for (int i = 0; i < nLength; i++)
|
|
{
|
|
if (strSourceData[i] < '0' || strSourceData[i] > '9')
|
|
{
|
|
AfxMessageBox( "종목코드는 숫자만 가능합니다. (숫자 6자리)" );
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
nIndex = atol( (LPSTR)(LPCTSTR)strSourceData.Left(6) );
|
|
pData = GetStockData( nIndex );
|
|
if( pData != NULL )
|
|
{
|
|
pData->bSpecialCodeByPublish = true;
|
|
}
|
|
else
|
|
{
|
|
strTemp += strSourceData.Left(6) + " ";
|
|
if( (++strTempCount % 4) == 0 ) strTemp += "\r\n";
|
|
}
|
|
}
|
|
|
|
if( strTempCount )
|
|
{
|
|
CString str;
|
|
str.Format("<공시_특별종목코드.txt> \r\n\r\n%s\r\n전체 %d개 처리불가.", strTemp, strTempCount);
|
|
::MessageBox(NULL, str, "종목코드 예외처리", MB_OK|MB_ICONSTOP|MB_TOPMOST);
|
|
}
|
|
}
|
|
CATCH(CFileException, e)
|
|
{
|
|
#ifdef _DEBUG
|
|
afxDump << "Error during reading. " << e->m_cause << "\n";
|
|
#endif
|
|
AfxMessageBox("Error during reading file.");
|
|
file.Close();
|
|
return FALSE;
|
|
}
|
|
END_CATCH
|
|
|
|
file.Close();
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CStockData::ReadFileExclusionCodeFromFile()
|
|
{
|
|
int i;
|
|
for( i=0; i<m_nMaxData; i++ )
|
|
m_pData[ i ].bRejectedFromFile = false;
|
|
|
|
CString strFile = "거부_전장거래부진종목코드.txt";
|
|
|
|
TCHAR szFilePath[_MAX_PATH]={0,};
|
|
::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
|
|
*(strrchr( szFilePath, '\\' ) + 1) = 0;
|
|
strcat( szFilePath, (LPSTR)(LPCTSTR)strFile );
|
|
|
|
CStdioFile file;
|
|
|
|
if( !file.Open(szFilePath, CFile::modeRead | CFile::typeText) )
|
|
{
|
|
CString str;
|
|
str.Format(TEXT("File Open Error : %d\n%s"), GetLastError(), szFilePath);
|
|
AfxMessageBox(str);
|
|
return FALSE;
|
|
}
|
|
|
|
TRY
|
|
{
|
|
CString strTemp = ""; long strTempCount = 0;
|
|
STOCKDATA * pData = NULL;
|
|
|
|
CString strSourceData;
|
|
while( file.ReadString(strSourceData) )
|
|
{
|
|
if( "'" == strSourceData.Left(1) || strSourceData.GetLength() == 0 )
|
|
continue;
|
|
|
|
// 종목코드, 종목명, 구분, 거래량, 거래금액(천원)
|
|
// 000020, 동화약품, [1], 2120, 14110
|
|
char seps[] = ",";
|
|
char *token;
|
|
|
|
int i=0;
|
|
token = strtok( (LPSTR)(LPCTSTR)strSourceData, seps );
|
|
while( token != NULL )
|
|
{
|
|
i++;
|
|
if( i==1 ) {
|
|
long nIndex = atol( token );
|
|
pData = GetStockData( nIndex ); // 종목코드 데이터.
|
|
if( pData != NULL )
|
|
{
|
|
pData->bRejectedFromFile = true; // 거부종목 등록.
|
|
}
|
|
else
|
|
{
|
|
strTemp += token; strTemp += " ";
|
|
if( (++strTempCount % 4) == 0 ) strTemp += "\r\n";
|
|
|
|
break;
|
|
}
|
|
} else if( i==4 ) {
|
|
pData->lTradeCount = atol( token ); // 거래량.
|
|
*seps = 0x0D; // next read cr/lf.
|
|
} else if( i==5 ) {
|
|
pData->lTradeMoney = atol( token ); // 거래금액.
|
|
break;
|
|
}
|
|
|
|
token = strtok( NULL, seps );
|
|
}
|
|
}
|
|
|
|
if( strTempCount )
|
|
{
|
|
CString str;
|
|
str.Format("<거부_전장거래부진종목코드.txt> \r\n\r\n%s\r\n전체 %d개 처리불가.", strTemp, strTempCount);
|
|
::MessageBox(NULL, str, "종목코드 예외처리", MB_OK|MB_ICONSTOP|MB_TOPMOST);
|
|
}
|
|
}
|
|
CATCH(CFileException, e)
|
|
{
|
|
#ifdef _DEBUG
|
|
afxDump << "Error during reading. " << e->m_cause << "\n";
|
|
#endif
|
|
AfxMessageBox("Error during reading file.");
|
|
file.Close();
|
|
return FALSE;
|
|
}
|
|
END_CATCH
|
|
|
|
file.Close();
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CStockData::ReadFileManualInputCodeFromFile()
|
|
{
|
|
int i;
|
|
for( i=0; i<m_nMaxData; i++ )
|
|
m_pData[ i ].bManualInputCode = false;
|
|
|
|
CString strFile = "수동_종목코드.txt";
|
|
|
|
TCHAR szFilePath[_MAX_PATH]={0,};
|
|
::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
|
|
*(strrchr( szFilePath, '\\' ) + 1) = 0;
|
|
strcat( szFilePath, (LPSTR)(LPCTSTR)strFile );
|
|
|
|
CStdioFile file;
|
|
|
|
if( !file.Open(szFilePath, CFile::modeRead | CFile::typeText) )
|
|
{
|
|
CString str;
|
|
str.Format(TEXT("File Open Error : %d\n%s"), GetLastError(), szFilePath);
|
|
AfxMessageBox(str);
|
|
return FALSE;
|
|
}
|
|
|
|
TRY
|
|
{
|
|
CString strTemp = ""; long strTempCount = 0;
|
|
STOCKDATA * pData = NULL;
|
|
|
|
CString strSourceData;
|
|
while( file.ReadString(strSourceData) )
|
|
{
|
|
if( "'" == strSourceData.Left(1) || strSourceData.GetLength() == 0 )
|
|
continue;
|
|
|
|
strSourceData.TrimLeft( " " );
|
|
strSourceData.TrimRight( " " );
|
|
|
|
if( strSourceData.GetLength() >= 6 )
|
|
{
|
|
long nIndex = atol( (LPSTR)(LPCTSTR)strSourceData.Left(6) );
|
|
pData = GetStockData( nIndex );
|
|
if( pData != NULL )
|
|
{
|
|
pData->bManualInputCode = true;
|
|
}
|
|
else
|
|
{
|
|
strTemp += strSourceData.Left(6) + " ";
|
|
if( (++strTempCount % 4) == 0 ) strTemp += "\r\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
if( strTempCount )
|
|
{
|
|
CString str;
|
|
str.Format("<수동_종목코드.txt> \r\n\r\n%s\r\n전체 %d개 처리불가.", strTemp, strTempCount);
|
|
::MessageBox(NULL, str, "종목코드 예외처리", MB_OK|MB_ICONSTOP|MB_TOPMOST);
|
|
}
|
|
}
|
|
CATCH(CFileException, e)
|
|
{
|
|
#ifdef _DEBUG
|
|
afxDump << "Error during reading. " << e->m_cause << "\n";
|
|
#endif
|
|
AfxMessageBox("Error during reading file.");
|
|
file.Close();
|
|
return FALSE;
|
|
}
|
|
END_CATCH
|
|
|
|
file.Close();
|
|
return TRUE;
|
|
}
|