Files
CPRobot/CPRobotDlg.cpp
2013-09-02 21:12:33 +00:00

722 lines
36 KiB
C++
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// CPRobotDlg.cpp : 구현 파일
//
#include "stdafx.h"
#include "CPRobot.h"
#include "CPRobotDlg.h"
#include <WinUser.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define IDS_HOTKEY_FX_CALL "CallOpCheck"
#define IDS_HOTKEY_FX_PUT "PutOpCheck"
#define IDS_HOTKEY_FX_STOP "StopDealing"
ICpTdUtilPtr g_pTdUtil = NULL;
void StringFormat(std::string &s, const std::string fmt, ...)
{
std::string ss;
int n, size=100;
bool b=false;
va_list marker;
while (!b)
{
ss.resize(size);
va_start(marker, fmt);
n = vsnprintf_s((char*)ss.c_str(), size, size, fmt.c_str(), marker);
va_end(marker);
if ((n>0) && ((b=(n<size))==true))
ss.resize(n);
else
size *= 2;
}
s += ss;
}
CCPRobotDlg::CCPRobotDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCPRobotDlg::IDD, pParent)
, m_iAmountSet(0)
, m_fMinPriceSet(0.0f)
, m_fMaxPriceSet(0.0f)
, m_iPlusTick(0)
, m_fLossCutTick(0.0f)
, m_fTrailingTick(0.0f)
, m_iCancelDelay(0)
, m_bPutOption(FALSE)
, m_bBuyOnBid1(FALSE)
{
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON2);
m_iBalance = 0;
m_pOpJpBid = NULL;
m_CurCode = "";
m_fBoughtPrice = 0.0f;
m_fHighestBid1 = 0.0f;
m_fCurBid1 = 0.0f;
m_iBoughtCnt = 0;
m_iOrderNum = 0;
m_pCpFConclusion = NULL;
m_enPrevState = CPS_WAIT;
m_enState = CPS_WAIT;
}
void CCPRobotDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_ITEMS, m_ResultList);
DDX_Text(pDX, IDC_EDIT_ORDERINGPRICE, m_iAmountSet);
DDX_Text(pDX, IDC_EDIT_ORDERING_TICK_MIN, m_fMinPriceSet);
DDX_Text(pDX, IDC_EDIT_ORDERING_TICK_MAX, m_fMaxPriceSet);
DDX_Text(pDX, IDC_EDIT_SELL_TICK, m_iPlusTick);
DDX_Text(pDX, IDC_EDIT_LOSS_CUT_TICK, m_fLossCutTick);
DDX_Text(pDX, IDC_EDIT_TRAING_TICK, m_fTrailingTick);
DDX_Text(pDX, IDC_EDIT_CANCEL_DELAY, m_iCancelDelay);
DDX_Radio(pDX, IDC_RADIO_CALLOP, m_bPutOption);
DDX_Radio(pDX, IDC_RADIO_BID, m_bBuyOnBid1);
}
BEGIN_MESSAGE_MAP(CCPRobotDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON_REFRESH_BALANCE, &CCPRobotDlg::OnBnClickedButtonRefreshBalance)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_BUTTON_START_DEAL, &CCPRobotDlg::OnBnClickedButtonStartDeal)
ON_BN_CLICKED(IDC_BUTTON_SEARCH, &CCPRobotDlg::OnBnClickedButtonSearch)
ON_WM_PARENTNOTIFY()
ON_WM_HOTKEY()
END_MESSAGE_MAP()
// CCPRobotDlg 메시지 처리기
BOOL CCPRobotDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는
// 프레임워크가 이 작업을 자동으로 수행합니다.
SetIcon(m_hIcon, TRUE); // 큰 아이콘을 설정합니다.
SetIcon(m_hIcon, FALSE); // 작은 아이콘을 설정합니다.
// TODO: 여기에 추가 초기화 작업을 추가합니다.
// 로그 폴더
CFileFind FileFinder;
BOOL bHasFolder = FileFinder.FindFile(".\\Log\\*.*");
if(bHasFolder == FALSE)
CreateDirectory(".\\Log\\", NULL);
CTime time = CTime::GetCurrentTime();
string LogFileName;
StringFormat(LogFileName, ".\\Log\\Log_%04d-%02d-%02d.txt",
time.GetYear(), time.GetMonth(), time.GetDay());
m_LogFile.open(LogFileName.data(), std::ios_base::app | std::ios_base::out);
// Trade utli 초기화
g_pTdUtil.CreateInstance(CLSID_CpTdUtil);
const short iInitResult = g_pTdUtil->TradeInit(0);
switch(iInitResult)
{
case -1:
AfxMessageBox("TradeInit 오류");
return -2;
break;
case 1:
AfxMessageBox("업무 키 잘못 입력됨");
return -2;
break;
case 2:
AfxMessageBox("계좌 비밀번호 잘못 입력됨");
return -2;
break;
case 3:
AfxMessageBox("취소됨");
return -2;
break;
}
// Get Account Number
_variant_t sa = g_pTdUtil->GetAccountNumber();
SAFEARRAY* pSafeArray = sa.parray;
LONG iLBound;
LONG iUBound;
SafeArrayGetLBound(pSafeArray, 1, &iLBound);
SafeArrayGetUBound(pSafeArray, 1, &iUBound);
BSTR AccNum;
for(LONG i=iLBound; i<=iUBound; i++)
{
SafeArrayGetElement(pSafeArray, &i, &AccNum);
m_AccountNum = (LPCSTR)(_bstr_t)AccNum;
break;
}
m_pOpJpBid.CreateInstance(CpSysDib::CLSID_OptionJpBid);
m_EventHandlerSysDib.DispEventAdvise(m_pOpJpBid);
m_EventHandlerSysDib.SetIEventHandler(this);
ICpOptionCodePtr pOpCode;
pOpCode.CreateInstance(CLSID_CpOptionCode);
short iCodeCnt = pOpCode->GetCount();
string Code;
string FirstExerciseMonth = (_bstr_t)pOpCode->GetData(3, 0);
string ExerciseMonth;
for(int i=0; i<iCodeCnt; i++)
{
ExerciseMonth = (_bstr_t)pOpCode->GetData(3, i);
if(ExerciseMonth == FirstExerciseMonth)
{
Code = (_bstr_t)pOpCode->GetData(0, i);
m_OpCodeList.push_back(Code);
}
}
pOpCode.Release();
CPLog("최근 월물 %d개의 코드가 검색되었습니다", m_OpCodeList.size());
m_pCpFConclusion.CreateInstance(__uuidof(CpDib::CpFConclusion));
m_EventHandlerDib.DispEventAdvise(m_pCpFConclusion);
m_EventHandlerDib.SetIEventHandler(this);
m_pCpFConclusion->Subscribe();
// 핫키 등록
m_IdKeyFxCall = GlobalAddAtom(IDS_HOTKEY_FX_CALL);
RegisterHotKey(GetSafeHwnd(), m_IdKeyFxCall, MOD_CONTROL | MOD_SHIFT, 0x41+'c'-'a');
m_IdKeyFxPut = GlobalAddAtom(IDS_HOTKEY_FX_PUT);
RegisterHotKey(GetSafeHwnd(), m_IdKeyFxPut, MOD_CONTROL | MOD_SHIFT, 0x41+'p'-'a');
m_IdKeyFxStop = GlobalAddAtom(IDS_HOTKEY_FX_STOP);
RegisterHotKey(GetSafeHwnd(), m_IdKeyFxStop, MOD_CONTROL | MOD_SHIFT, 0x41+'x'-'a');
OnBnClickedButtonRefreshBalance();
SetForegroundWindow();
return TRUE; // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
}
int CCPRobotDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
return 0;
}
void CCPRobotDlg::OnDestroy()
{
CDialog::OnDestroy();
// TODO: Add your message handler code here
m_pOpJpBid.Release();
m_EventHandlerSysDib.DispEventUnadvise(m_pOpJpBid);
m_EventHandlerDib.DispEventUnadvise(m_pCpFConclusion);
UpdateData();
SaveToFile();
m_LogFile.close();
}
BOOL CCPRobotDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
g_pTdUtil.Release();
return CDialog::DestroyWindow();
}
void CCPRobotDlg::SwitchState(const CP_STATE enState)
{
m_enPrevState = m_enState;
m_enState = enState;
}
void CCPRobotDlg::SaveToFile(void)
{
FILE* fp = NULL;
const int iError = fopen_s(&fp, "setting.ini", "wt");
if(iError != 0)
{
AfxMessageBox("저장 실패");
return;
}
fprintf_s(fp, "거래 금액 : %d\n", m_iAmountSet);
fprintf_s(fp, "매수 조건 최소 : %f\n", m_fMinPriceSet);
fprintf_s(fp, "매수 조건 최대 : %f\n", m_fMaxPriceSet);
fprintf_s(fp, "매도 요청 : %d\n", m_iPlusTick);
fprintf_s(fp, "손절 범위 : %f\n", m_fLossCutTick);
fprintf_s(fp, "트레일링 범위 : %f\n", m_fTrailingTick);
fprintf_s(fp, "취소 시간 : %d\n", m_iCancelDelay);
fprintf_s(fp, "1차 매수호가로 구매 : %d\n", m_bBuyOnBid1);
fprintf_s(fp, "풋옵션 : %d\n", m_bPutOption);
fclose(fp);
fp = NULL;
}
void CCPRobotDlg::LoadFromFile(void)
{
FILE* fp = NULL;
const int iError = fopen_s(&fp, "setting.ini", "rt");
if(iError != 0)
return;
fscanf_s(fp, "거래 금액 : %d\n", &m_iAmountSet);
fscanf_s(fp, "매수 조건 최소 : %f\n", &m_fMinPriceSet);
fscanf_s(fp, "매수 조건 최대 : %f\n", &m_fMaxPriceSet);
fscanf_s(fp, "매도 요청 : %d\n", &m_iPlusTick);
fscanf_s(fp, "손절 범위 : %f\n", &m_fLossCutTick);
fscanf_s(fp, "트레일링 범위 : %f\n", &m_fTrailingTick);
fscanf_s(fp, "취소 시간 : %d\n", &m_iCancelDelay);
fscanf_s(fp, "1차 매수호가로 구매 : %d\n", &m_bBuyOnBid1);
fscanf_s(fp, "풋옵션 : %d\n", &m_bPutOption);
fclose(fp);
fp = NULL;
}
// 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면
// 아래 코드가 필요합니다. 문서/뷰 모델을 사용하는 MFC 응용 프로그램의 경우에는
// 프레임워크에서 이 작업을 자동으로 수행합니다.
void CCPRobotDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 클라이언트 사각형에서 아이콘을 가운데에 맞춥니다.
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 아이콘을 그립니다.
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// 사용자가 최소화된 창을 끄는 동안에 커서가 표시되도록 시스템에서 이 함수를 호출합니다.
HCURSOR CCPRobotDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CCPRobotDlg::OnBnClickedButtonRefreshBalance()
{
// TODO: Add your control notification handler code here
try
{
ICpTdDibPtr pTd0721 = NULL;
pTd0721.CreateInstance(CLSID_CpTd0721F);
pTd0721->SetInputValue(0, m_AccountNum.data()); // 0 - (string) 계좌번호
pTd0721->SetInputValue(1, "50"); // 1 - (string) 상품관리 구분[defaut:50]
pTd0721->SetInputValue(2, ""); // 2 (string) 종목코드[default:""]
pTd0721->SetInputValue(3, "10"); // 3 (long) 요청건수[default:10] - 최대 20개
CString Message;
do
{
pTd0721->BlockRequest();
m_iBalance = pTd0721->GetHeaderValue(9);
Message.Format("원 (잔고 : %d원)", m_iBalance);
SetDlgItemText(IDC_STATIC_BALANCE, Message.GetString());
} while(pTd0721->Continue);
pTd0721.Release();
}
catch(_com_error e)
{
AfxMessageBox(e.ErrorMessage());
}
LoadFromFile();
UpdateData(FALSE);
}
void CCPRobotDlg::Subscribe(void)
{
const int iCodeCnt = m_OpCodeList.size();
try
{
CPLog("Subscribe");
for(int i=0; i<iCodeCnt; i++)
{
m_pOpJpBid->SetInputValue(0, m_OpCodeList[i].data());
m_pOpJpBid->SubscribeLatest();
//CPLog("Subscribe[%s]", m_OpCodeList[i].data());
if(m_pOpJpBid->GetDibStatus() != 0)
{
CString strErrorMsg;
strErrorMsg += (LPCTSTR)m_pOpJpBid->GetDibMsg1();
strErrorMsg += (LPCTSTR)m_pOpJpBid->GetDibMsg2();
strErrorMsg.TrimRight();
AfxMessageBox(strErrorMsg);
}
}
}
catch(_com_error e)
{
AfxMessageBox("Subscribe Error");
}
}
void CCPRobotDlg::Unsubscribe(void)
{
const int iCodeCnt = m_OpCodeList.size();
try
{
CPLog("Unsubscribe");
for(int i=0; i<iCodeCnt; i++)
{
m_pOpJpBid->SetInputValue(0, m_OpCodeList[i].data());
m_pOpJpBid->Unsubscribe();
}
}
catch(_com_error e)
{
AfxMessageBox("Unsubscribe Error");
}
}
void CCPRobotDlg::OnBnClickedButtonSearch()
{
// TODO: Add your control notification handler code here
UpdateData();
m_CurCode = "";
m_fBoughtPrice = 0.0f;
m_fHighestBid1 = 0.0f;
m_fCurBid1 = 0.0f;
m_iBoughtCnt = 0;
m_iOrderNum = 0;
Unsubscribe();
Subscribe();
SwitchState(CPS_LOOKING);
}
void CCPRobotDlg::OnBnClickedButtonStartDeal()
{
// TODO: Add your control notification handler code here
Unsubscribe();
if(m_enState == CPS_WAIT || m_enState == CPS_LOOKING)
{
SwitchState(CPS_LOOKING_DEAL);
((CButton*)(GetDlgItem(IDC_BUTTON_START_DEAL)))->SetCheck(TRUE);
CPLog("Start Dealing");
Subscribe();
}
else
{
SwitchState(CPS_WAIT);
((CButton*)(GetDlgItem(IDC_BUTTON_START_DEAL)))->SetCheck(FALSE);
CPLog("Stop Dealing");
}
}
void CCPRobotDlg::BuyThis(const string& Code, const float fBid1Price, const int iBid1Cnt, float afAskPrice[5])
{
SwitchState(CPS_BUYING);
// 수량 계산
int iBuyCnt = (int)(m_iBalance / (fBid1Price*500000));
iBuyCnt = min(iBuyCnt, iBid1Cnt);
// 매수 가격
const float fOrderPrice = ((m_bBuyOnBid1 == TRUE) ? fBid1Price : afAskPrice[0]);
// 매수 주문
try
{
ICpTdDibPtr pTd6831 = NULL;
pTd6831.CreateInstance(CLSID_CpTd6831);
pTd6831->SetInputValue(1, m_AccountNum.data()); // 1 - (string) 계좌번호
pTd6831->SetInputValue(2, Code.data()); // 2 - (string) 종목코드
pTd6831->SetInputValue(3, iBuyCnt); // 3 - (long) 주문수량
pTd6831->SetInputValue(4, fOrderPrice); // 4 - (double) 주문가격
pTd6831->SetInputValue(5, "2"); // 5 - (string) 매매구분코드 (1:매도, 2:매수)
pTd6831->SetInputValue(6, "1"); // 6 - (string) 주문유형코드 (1:지정가[default] 2:시장가 3:조건부지정가 4:최유리지정가)
pTd6831->SetInputValue(7, "0"); // 7- (string) 주문조건구분코드(0:없음, 1:IOC, 2:FOK)
pTd6831->BlockRequest();
if(pTd6831->GetDibStatus() != 0)
{
CString strErrorMsg;
strErrorMsg += (LPCTSTR)pTd6831->GetDibMsg1();
strErrorMsg += (LPCTSTR)pTd6831->GetDibMsg2();
strErrorMsg.TrimRight();
CPLog(strErrorMsg.GetString());
}
else
{
CPLog("매수 요청 [%s] %f(%d)", Code.data(), afAskPrice[0], iBuyCnt);
}
//m_CurCode = Code;
//m_fBoughtPrice = fOrderPrice;
//m_fHighestBid1 = fOrderPrice;
//m_fCurBid1 = fOrderPrice;
//m_iBoughtCnt = iBuyCnt; // *** 체결 수량 체크해야 함
//m_iOrderNum = (int)pTd6831->GetHeaderValue(8); // 8 - (long) 주문번호
//m_BoughtT = CTime::GetCurrentTime();
//// 매도 요청
//SwitchState(CPS_SELLING);
//int iSellAskIdx = ((m_bBuyOnBid1 == TRUE) ? (m_iPlusTick-1) : (m_iPlusTick));
//iSellAskIdx = min(iSellAskIdx, 4);
//pTd6831->SetInputValue(4, afAskPrice[iSellAskIdx]); // 4 - (double) 주문가격
//pTd6831->SetInputValue(5, "1"); // 5 - (string) 매매구분코드 (1:매도, 2:매수)
//pTd6831->SetInputValue(7, "0"); // 7- (string) 주문조건구분코드(0:없음, 1:IOC, 2:FOK)
//pTd6831->BlockRequest();
//if(pTd6831->GetDibStatus() != 0)
//{
// CString strErrorMsg;
// strErrorMsg += (LPCTSTR)pTd6831->GetDibMsg1();
// strErrorMsg += (LPCTSTR)pTd6831->GetDibMsg2();
// strErrorMsg.TrimRight();
// CPLog(strErrorMsg.GetString());
//}
//else
//{
// CPLog("매도 요청 [%s] %f(%d)", Code.data(), afAskPrice[iSellAskIdx], iBuyCnt);
//}
//pTd6831.Release();
//Subscribe();
//SwitchState(CPS_WAITING_SELL);
}
catch(_com_error e)
{
AfxMessageBox(e.ErrorMessage());
}
}
void CCPRobotDlg::CorrectToCurrent(const string& Code)
{
SwitchState(CPS_SELLING);
// 정정 주문
ICpTdDibPtr pTd6832 = NULL;
pTd6832.CreateInstance(CLSID_CpTd6831);
pTd6832->SetInputValue(2, m_iOrderNum); // 2 - (long) 원주문번호
pTd6832->SetInputValue(3, m_AccountNum.data()); // 3 - (string) 계좌번호
pTd6832->SetInputValue(4, Code.data()); // 4 - (string) 종목코드
pTd6832->SetInputValue(5, m_iBoughtCnt); // 5 - (long) 주문수량
//pTd6832->SetInputValue(6, m_fCurBid1); // 6 - (double)주문가격
pTd6832->SetInputValue(6, 0);
pTd6832->SetInputValue(8, "2"); // 8 - (string) 정정 후 주문 유형 (" ":변경 안함, "1":지정가IOC, "2":시장가, "3":조건부, "4":최유리)
pTd6832->SetInputValue(9, "0"); // 9 - (string) 주문조건구분코드 ("0":변경 안함, "0":없음, "1":IOC, "2":FOK)
pTd6832.Release();
SwitchState(CPS_WAIT);
CPLog("정정주문 [%s] %f(%d)", Code.data(), m_fCurBid1, m_iBoughtCnt);
}
void CCPRobotDlg::ReceivedSysDib()
{
if(m_pOpJpBid->GetDibStatus() != 0)
{
CString strErrorMsg;
strErrorMsg += (LPCTSTR)m_pOpJpBid->GetDibMsg1();
strErrorMsg += (LPCTSTR)m_pOpJpBid->GetDibMsg2();
strErrorMsg.TrimRight();
AfxMessageBox(strErrorMsg);
return;
}
string Code = (_bstr_t)m_pOpJpBid->GetHeaderValue(0);
const float fBid1Price = m_pOpJpBid->GetHeaderValue(19); // 매수 1 우선호가
const int iBid1Cnt = m_pOpJpBid->GetHeaderValue(24); //매수 1 우선호가잔량
float afAskPrice[5];
afAskPrice[0] = m_pOpJpBid->GetHeaderValue(2); // 2 - (float) 매도 1 우선호가
afAskPrice[1] = m_pOpJpBid->GetHeaderValue(3); // 3 - (float) 매도 2 우선호가
afAskPrice[2] = m_pOpJpBid->GetHeaderValue(4); // 4 - (float) 매도 3 우선호가
afAskPrice[3] = m_pOpJpBid->GetHeaderValue(5); // 5 - (float) 매도 4 우선호가
afAskPrice[4] = m_pOpJpBid->GetHeaderValue(6); // 6 - (float) 매도 5 우선호가
if(m_enState == CPS_WAITING_SELL)
{
if(Code == m_CurCode)
{
m_fCurBid1 = fBid1Price;
if(fBid1Price > m_fHighestBid1)
m_fHighestBid1 = fBid1Price;
// check for trailing bid or loss cut
if(m_fCurBid1 < m_fHighestBid1-m_fTrailingTick || m_fCurBid1 < m_fBoughtPrice-m_fLossCutTick)
CorrectToCurrent(m_CurCode);
}
}
const CTimeSpan ElapseT = CTime::GetCurrentTime()-m_BoughtT;
if(ElapseT.GetSeconds() >= m_iCancelDelay)
CorrectToCurrent(m_CurCode);
try
{
if(m_bPutOption == FALSE && Code[0] == '2' || m_bPutOption == TRUE && Code[0] == '3')
{
if(fBid1Price >= m_fMinPriceSet && fBid1Price <= m_fMaxPriceSet)
{
CPLog("Matched [%s] %f", Code.data(), fBid1Price);
if(m_enState == CPS_LOOKING_DEAL)
{
SwitchState(CPS_BUYING);
Unsubscribe();
BuyThis(Code, fBid1Price, iBid1Cnt, afAskPrice);
}
}
}
}
catch(_com_error e)
{
AfxMessageBox(e.ErrorMessage());
}
}
void CCPRobotDlg::ReceivedDib()
{
string AccountName = (LPCSTR)(_bstr_t)m_pCpFConclusion->GetHeaderValue(1);
string CodeName = (LPCSTR)(_bstr_t)m_pCpFConclusion->GetHeaderValue(2);
CPLog("체결 결과 %s %s", AccountName.data(), CodeName.data());
}
void CCPRobotDlg::CPLog(const std::string fmt, ...)
{
std::string ss;
int n, size=100;
bool b=false;
va_list marker;
while (!b)
{
ss.resize(size);
va_start(marker, fmt);
n = vsnprintf_s((char*)ss.c_str(), size, size, fmt.c_str(), marker);
va_end(marker);
if ((n>0) && ((b=(n<size))==true))
ss.resize(n);
else
size *= 2;
}
CTime time = CTime::GetCurrentTime();
string Message;
StringFormat(Message, "[%04d-%02d-%02d %02d:%02d:%02d] %s\n",
time.GetYear(),
time.GetMonth(),
time.GetDay(),
time.GetHour(),
time.GetMinute(),
time.GetSecond(),
ss.data());
TRACE(Message.data());
m_ResultList.AddString(Message.data());
if(m_ResultList.GetCurSel() == m_ResultList.GetCount()-2)
m_ResultList.SetCurSel(m_ResultList.GetCount()-1);
if(m_LogFile.is_open() == true)
{
m_LogFile << Message.data();
m_LogFile.flush();
}
}
void CCPRobotDlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
// TODO: Add your message handler code here and/or call default
if(nHotKeyId == m_IdKeyFxCall)
{
SwitchState(CPS_WAIT);
((CButton*)GetDlgItem(IDC_RADIO_CALLOP))->SetCheck(1);
((CButton*)GetDlgItem(IDC_RADIO_PUTOP))->SetCheck(0);
OnBnClickedButtonStartDeal();
}
if(nHotKeyId == m_IdKeyFxPut)
{
SwitchState(CPS_WAIT);
((CButton*)GetDlgItem(IDC_RADIO_CALLOP))->SetCheck(0);
((CButton*)GetDlgItem(IDC_RADIO_PUTOP))->SetCheck(1);
OnBnClickedButtonStartDeal();
}
if(nHotKeyId == m_IdKeyFxStop)
{
if(m_enState == CPS_WAIT || m_enState == CPS_LOOKING)
SwitchState(CPS_SELLING);
OnBnClickedButtonStartDeal();
}
__super::OnHotKey(nHotKeyId, nKey1, nKey2);
}