1022 lines
56 KiB
C++
1022 lines
56 KiB
C++
// CPRobotDlg.cpp : 구현 파일
|
||
//
|
||
|
||
#include "stdafx.h"
|
||
#include "CPRobot.h"
|
||
#include "CPRobotDlg.h"
|
||
#include <WinUser.h>
|
||
//#include <cmath>
|
||
|
||
#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"
|
||
|
||
#define _TIMER_CHECK 100
|
||
#define _TIMER_INTERVAL 500
|
||
|
||
#define WM_PROC_PRICE (WM_USER+1)
|
||
#define WM_PROC_CONCLUSION (WM_USER+2)
|
||
|
||
|
||
typedef vector<CP_UNITINFO>::iterator UnitIterator;
|
||
|
||
ICpTdUtilPtr g_pTdUtil = NULL;
|
||
|
||
|
||
|
||
void StringFormat(string &s, const string fmt, ...)
|
||
{
|
||
string ss;
|
||
int n, size=512;
|
||
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_iWindUpDelay(0)
|
||
, m_iWindUpTick(0)
|
||
, m_bPutOption(FALSE)
|
||
, m_bBuyOnBid1(FALSE)
|
||
{
|
||
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_STOCK);
|
||
|
||
m_iBalance = 0;
|
||
m_pOpJpBid = NULL;
|
||
|
||
m_bLookingDeal = FALSE;
|
||
|
||
m_pCpFConclusion = NULL;
|
||
|
||
m_bUsingConclusion = false;
|
||
}
|
||
|
||
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_Text(pDX, IDC_EDIT_WIND_UP_DELAY, m_iWindUpDelay);
|
||
DDX_CBIndex(pDX, IDC_COMBO_WINDUP_TICK, m_iWindUpTick);
|
||
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_START_DEAL, &CCPRobotDlg::OnBnClickedButtonStartDeal)
|
||
ON_BN_CLICKED(IDC_BUTTON_SEARCH, &CCPRobotDlg::OnBnClickedButtonSearch)
|
||
ON_WM_PARENTNOTIFY()
|
||
ON_WM_HOTKEY()
|
||
ON_WM_TIMER()
|
||
ON_MESSAGE(WM_PROC_PRICE, &CCPRobotDlg::OnProcPrice)
|
||
ON_MESSAGE(WM_PROC_CONCLUSION, &CCPRobotDlg::OnProcConclusion)
|
||
END_MESSAGE_MAP()
|
||
|
||
|
||
// CCPRobotDlg 메시지 처리기
|
||
void CCPRobotDlg::CPLog(const string fmt, ...)
|
||
{
|
||
string ss;
|
||
int n, size=1024;
|
||
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)
|
||
{
|
||
((CButton*)GetDlgItem(IDC_RADIO_CALLOP))->SetCheck(1);
|
||
((CButton*)GetDlgItem(IDC_RADIO_PUTOP))->SetCheck(0);
|
||
OnBnClickedButtonStartDeal();
|
||
}
|
||
|
||
if(nHotKeyId == m_IdKeyFxPut)
|
||
{
|
||
((CButton*)GetDlgItem(IDC_RADIO_CALLOP))->SetCheck(0);
|
||
((CButton*)GetDlgItem(IDC_RADIO_PUTOP))->SetCheck(1);
|
||
OnBnClickedButtonStartDeal();
|
||
}
|
||
|
||
if(nHotKeyId == m_IdKeyFxStop)
|
||
{
|
||
m_bLookingDeal = FALSE;
|
||
}
|
||
|
||
__super::OnHotKey(nHotKeyId, nKey1, nKey2);
|
||
}
|
||
|
||
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;
|
||
|
||
const string FirstExerciseMonth = (_bstr_t)pOpCode->GetData(3, 0);
|
||
string ExerciseMonth;
|
||
|
||
CP_PRICEINFO PriceInfo = { 0.0f, };
|
||
|
||
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);
|
||
|
||
m_CurPriceList.insert(map<string, CP_PRICEINFO>::value_type(Code, PriceInfo));
|
||
}
|
||
}
|
||
pOpCode.Release();
|
||
|
||
CPLog("최근 월물 %d개의 코드가 검색되었습니다", m_OpCodeList.size());
|
||
|
||
m_pCpFConclusion.CreateInstance(__uuidof(CpDib::CpFConclusion));
|
||
m_EventHandlerDib.DispEventAdvise(m_pCpFConclusion);
|
||
m_EventHandlerDib.SetIEventHandler(this);
|
||
|
||
m_pCpFConclusion->SubscribeLatest();
|
||
|
||
|
||
|
||
// 핫키 등록
|
||
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();
|
||
LoadFromFile();
|
||
UpdateData(FALSE);
|
||
|
||
SetTimer(_TIMER_CHECK, _TIMER_INTERVAL, NULL);
|
||
|
||
SetForegroundWindow();
|
||
|
||
Subscribe();
|
||
|
||
return TRUE; // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
|
||
}
|
||
|
||
BOOL CCPRobotDlg::DestroyWindow()
|
||
{
|
||
// TODO: Add your specialized code here and/or call the base class
|
||
Unsubscribe();
|
||
|
||
m_EventHandlerSysDib.DispEventUnadvise(m_pOpJpBid);
|
||
m_pOpJpBid.Release();
|
||
|
||
m_EventHandlerDib.DispEventUnadvise(m_pCpFConclusion);
|
||
m_pCpFConclusion.Release();
|
||
|
||
g_pTdUtil.Release();
|
||
|
||
UpdateData();
|
||
SaveToFile();
|
||
|
||
m_LogFile.close();
|
||
|
||
return CDialog::DestroyWindow();
|
||
}
|
||
|
||
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_iCancelDelay);
|
||
|
||
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_iWindUpDelay);
|
||
fprintf_s(fp, "청산 틱 : %d\n", m_iWindUpTick);
|
||
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_iCancelDelay);
|
||
|
||
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_iWindUpDelay);
|
||
fscanf_s(fp, "청산 틱 : %d\n", &m_iWindUpTick);
|
||
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개
|
||
|
||
string Message;
|
||
do
|
||
{
|
||
pTd0721->BlockRequest();
|
||
m_iBalance = pTd0721->GetHeaderValue(9);
|
||
|
||
StringFormat(Message, "원 (잔고 : %d원)", m_iBalance);
|
||
SetDlgItemText(IDC_STATIC_BALANCE, Message.data());
|
||
} while(pTd0721->Continue);
|
||
|
||
pTd0721.Release();
|
||
}
|
||
catch(_com_error e)
|
||
{
|
||
string Message = "[잔고 조회 실패]\n";
|
||
Message += e.ErrorMessage();
|
||
AfxMessageBox(Message.data());
|
||
}
|
||
}
|
||
|
||
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();
|
||
|
||
if(m_pOpJpBid->GetDibStatus() != 0)
|
||
{
|
||
string strErrorMsg;
|
||
strErrorMsg += (LPCTSTR)m_pOpJpBid->GetDibMsg1();
|
||
strErrorMsg += (LPCTSTR)m_pOpJpBid->GetDibMsg2();
|
||
CPLog(strErrorMsg.data());
|
||
}
|
||
}
|
||
}
|
||
catch(_com_error e)
|
||
{
|
||
string Message = "[Subscribe Error]\n";
|
||
Message += e.ErrorMessage();
|
||
CPLog(Message.data());
|
||
}
|
||
}
|
||
|
||
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)
|
||
{
|
||
string Message = "[Unsubscribe Error]\n";
|
||
Message += e.ErrorMessage();
|
||
CPLog(Message.data());
|
||
}
|
||
}
|
||
|
||
void CCPRobotDlg::OnBnClickedButtonSearch()
|
||
{
|
||
// TODO: Add your control notification handler code here
|
||
UpdateData();
|
||
SaveToFile();
|
||
|
||
Unsubscribe();
|
||
Subscribe();
|
||
}
|
||
|
||
|
||
void CCPRobotDlg::OnBnClickedButtonStartDeal()
|
||
{
|
||
// TODO: Add your control notification handler code here
|
||
//Unsubscribe();
|
||
UpdateData();
|
||
|
||
m_bLookingDeal = TRUE;
|
||
CPLog("Start Dealing");
|
||
m_DealStartT = CTime::GetCurrentTime();
|
||
|
||
//Subscribe();
|
||
}
|
||
|
||
void CCPRobotDlg::BuyThis(const string& Code, const float fBid1Price, const int iBid1Cnt, float afAskPrice[5])
|
||
{
|
||
// 수량 계산
|
||
int iBuyCnt = (int)(m_iBalance / (fBid1Price*500000));
|
||
iBuyCnt = min(iBuyCnt, iBid1Cnt);
|
||
|
||
iBuyCnt = 10; // ***
|
||
|
||
// 매수 가격
|
||
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)
|
||
|
||
|
||
CPLog("[매수 요청 중] %s(%d) : %3.2f", Code.data(), iBuyCnt, afAskPrice[0]);
|
||
|
||
pTd6831->BlockRequest();
|
||
if(pTd6831->GetDibStatus() != 0)
|
||
{
|
||
string strErrorMsg;
|
||
strErrorMsg += (LPCTSTR)pTd6831->GetDibMsg1();
|
||
strErrorMsg += (LPCTSTR)pTd6831->GetDibMsg2();
|
||
CPLog(strErrorMsg.data());
|
||
}
|
||
else
|
||
{
|
||
CP_UNITINFO Unit;
|
||
Unit.m_Code = Code;
|
||
Unit.m_fBoughtPrice = fOrderPrice;
|
||
Unit.m_fHighestPrice = fOrderPrice;
|
||
Unit.m_iCnt = iBuyCnt;
|
||
Unit.m_iOrderNum = (int)pTd6831->GetHeaderValue(8); // 8 - (long) 주문번호
|
||
Unit.m_Time = CTime::GetCurrentTime();
|
||
|
||
m_BidOrderList.push_back(Unit);
|
||
}
|
||
|
||
CPLog("[매수 요청 끝] %s(%d) : %3.2f", Code.data(), iBuyCnt, afAskPrice[0]);
|
||
|
||
pTd6831.Release();
|
||
}
|
||
catch(_com_error e)
|
||
{
|
||
string Message = "[매수 요청 에러]\n";
|
||
Message += e.ErrorMessage();
|
||
CPLog(Message.data());
|
||
}
|
||
}
|
||
|
||
void CCPRobotDlg::SellThis(CP_UNITINFO& AskInfo)
|
||
{
|
||
// 매도 요청
|
||
try
|
||
{
|
||
ICpTdDibPtr pTd6831 = NULL;
|
||
pTd6831.CreateInstance(CLSID_CpTd6831);
|
||
pTd6831->SetInputValue(1, m_AccountNum.data()); // 1 - (string) 계좌번호
|
||
pTd6831->SetInputValue(2, AskInfo.m_Code.data()); // 2 - (string) 종목코드
|
||
pTd6831->SetInputValue(3, AskInfo.m_iCnt); // 3 - (long) 주문수량
|
||
const float fAskPrice = AskInfo.m_fBoughtPrice + m_iPlusTick*0.01f;
|
||
pTd6831->SetInputValue(4, fAskPrice); // 4 - (double) 주문가격
|
||
pTd6831->SetInputValue(5, "1"); // 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)
|
||
|
||
CPLog("[매도 요청 중] %s(%d) : %3.2f", AskInfo.m_Code.data(), AskInfo.m_iCnt, fAskPrice);
|
||
|
||
pTd6831->BlockRequest();
|
||
if(pTd6831->GetDibStatus() != 0)
|
||
{
|
||
string strErrorMsg;
|
||
strErrorMsg += (LPCTSTR)pTd6831->GetDibMsg1();
|
||
strErrorMsg += (LPCTSTR)pTd6831->GetDibMsg2();
|
||
CPLog(strErrorMsg.data());
|
||
}
|
||
else
|
||
{
|
||
AskInfo.m_iOrderNum = pTd6831->GetHeaderValue(8); // 8 - (long) 주문번호
|
||
|
||
m_AskOrderList.push_back(AskInfo);
|
||
}
|
||
|
||
CPLog("[매도 요청 끝] %s(%d) : %3.2f", AskInfo.m_Code.data(), AskInfo.m_iCnt, fAskPrice);
|
||
|
||
pTd6831.Release();
|
||
}
|
||
catch(_com_error e)
|
||
{
|
||
string Message = "[매도 요청 에러]\n";
|
||
Message += e.ErrorMessage();
|
||
CPLog(Message.data());
|
||
}
|
||
}
|
||
|
||
void CCPRobotDlg::WindUp(const CP_UNITINFO& Unit)
|
||
{
|
||
// 정정 주문
|
||
for(UnitIterator iter = m_AskOrderList.begin(); iter != m_AskOrderList.end(); iter++)
|
||
{
|
||
if(iter->m_Code == Unit.m_Code && iter->m_iOrderNum == Unit.m_iOrderNum)
|
||
{
|
||
try
|
||
{
|
||
ICpTdDibPtr pTd6832 = NULL;
|
||
pTd6832.CreateInstance(CLSID_CpTd6832);
|
||
pTd6832->SetInputValue(2, iter->m_iOrderNum); // 2 - (long) 원주문번호
|
||
pTd6832->SetInputValue(3, m_AccountNum.data()); // 3 - (string) 계좌번호
|
||
pTd6832->SetInputValue(4, Unit.m_Code.data()); // 4 - (string) 종목코드
|
||
pTd6832->SetInputValue(5, iter->m_iCnt); // 5 - (long) 주문수량
|
||
//const double dPrice = (double)m_CurPriceList[Code].m_afBidPrice[m_iWindUpTick];
|
||
const double dPrice = 0.01; // ***
|
||
pTd6832->SetInputValue(6, dPrice); // 6 - (double)주문가격
|
||
pTd6832->SetInputValue(8, " "); // 8 - (string) 정정 후 주문 유형 (" ":변경 안함, "1":지정가IOC, "2":시장가, "3":조건부, "4":최유리)
|
||
pTd6832->SetInputValue(9, " "); // 9 - (string) 주문조건구분코드 (" ":변경 안함, "0":없음, "1":IOC, "2":FOK)
|
||
pTd6832->SetInputValue(10, "50"); // 10- 상품관리구분코드[Default::50]
|
||
|
||
CPLog("[정정 요청 중] %s(%d) : %3.2f 주문번호 : %d 원주문번호 : %d",
|
||
Unit.m_Code.data(), Unit.m_iCnt, dPrice,
|
||
(int)iter->m_iOrderNum, (int)iter->m_iOrderNum);
|
||
|
||
pTd6832->BlockRequest();
|
||
if(pTd6832->GetDibStatus() != 0)
|
||
{
|
||
string strErrorMsg;
|
||
strErrorMsg += (LPCTSTR)pTd6832->GetDibMsg1();
|
||
strErrorMsg += (LPCTSTR)pTd6832->GetDibMsg2();
|
||
CPLog(strErrorMsg.data());
|
||
}
|
||
else
|
||
{
|
||
m_AskOrderList.erase(iter);
|
||
}
|
||
|
||
CPLog("[정정 요청 끝] %s(%d) : %3.2f 주문번호 : %d 원주문번호 : %d",
|
||
Unit.m_Code.data(), Unit.m_iCnt, dPrice,
|
||
(int)pTd6832->GetHeaderValue(6), (int)pTd6832->GetHeaderValue(1));
|
||
|
||
pTd6832.Release();
|
||
}
|
||
catch(_com_error e)
|
||
{
|
||
string Message = "[정정 주문 에러]\n";
|
||
Message += e.ErrorMessage();
|
||
CPLog(Message.data());
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void CCPRobotDlg::CancelOrder(const CP_UNITINFO& Unit)
|
||
{
|
||
const int iCnt = m_BidOrderList.size();
|
||
|
||
vector<CP_UNITINFO>::iterator iter = m_BidOrderList.begin();
|
||
while(iter != m_BidOrderList.end())
|
||
{
|
||
if(iter->m_Code == Unit.m_Code && iter->m_iOrderNum == Unit.m_iOrderNum)
|
||
{
|
||
try
|
||
{
|
||
ICpTdDibPtr pTd6833 = NULL;
|
||
pTd6833.CreateInstance(CLSID_CpTd6833);
|
||
pTd6833->SetInputValue(2, iter->m_iOrderNum); // 2 - (long) 원주문번호
|
||
pTd6833->SetInputValue(3, m_AccountNum.data()); // 3 - (string) 계좌번호
|
||
pTd6833->SetInputValue(4, iter->m_Code.data()); // 4 - (string) 종목코드
|
||
pTd6833->SetInputValue(5, iter->m_iCnt); // 5 - (long) 취소 수량 (주) 정확한 취소수량을 입력해야함
|
||
pTd6833->SetInputValue(6, 50); // 6 - 상품관리구분코드[Default::50] 계좌구분
|
||
|
||
CPLog("[취소 요청 중] %s(%d) : 시장가 ", Unit.m_Code.data(), Unit.m_iCnt);
|
||
|
||
pTd6833->BlockRequest();
|
||
if(pTd6833->GetDibStatus() != 0)
|
||
{
|
||
string strErrorMsg;
|
||
strErrorMsg += (LPCTSTR)pTd6833->GetDibMsg1();
|
||
strErrorMsg += (LPCTSTR)pTd6833->GetDibMsg2();
|
||
CPLog(strErrorMsg.data());
|
||
}
|
||
|
||
// 취소 요청 중에 체결될 수 있기 때문에 리스트에서 그냥 삭제
|
||
m_BidOrderList.erase(iter);
|
||
|
||
CPLog("[취소 요청 끝] %s(%d) : 시장가 ", Unit.m_Code.data(), Unit.m_iCnt);
|
||
|
||
pTd6833.Release();
|
||
}
|
||
catch(_com_error e)
|
||
{
|
||
string Message = "[취소 주문 에러]\n";
|
||
Message += e.ErrorMessage();
|
||
CPLog(Message.data());
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
iter++;
|
||
}
|
||
}
|
||
|
||
void CCPRobotDlg::OnTimer(UINT_PTR nIDEvent)
|
||
{
|
||
// TODO: Add your message handler code here and/or call default
|
||
CTime CurTime = CTime::GetCurrentTime();
|
||
CTimeSpan ElapseTime;
|
||
|
||
// 주문 취소
|
||
for(UnitIterator UnitIter=m_BidOrderList.begin(); UnitIter != m_BidOrderList.end(); UnitIter++)
|
||
{
|
||
ElapseTime = CurTime-UnitIter->m_Time;
|
||
if(ElapseTime.GetSeconds()*1000 >= m_iCancelDelay)
|
||
{
|
||
CancelOrder(*UnitIter);
|
||
UnitIter = m_BidOrderList.begin();
|
||
}
|
||
|
||
if(m_BidOrderList.empty() == true)
|
||
break;
|
||
}
|
||
|
||
// 청산
|
||
for(UnitIterator UnitIter=m_AskOrderList.begin(); UnitIter != m_AskOrderList.end(); UnitIter++)
|
||
{
|
||
ElapseTime = CurTime-UnitIter->m_Time;
|
||
if(ElapseTime.GetSeconds()*1000 >= m_iWindUpDelay)
|
||
{
|
||
CPLog("[청산 요청] %s(%d)", UnitIter->m_Code.data(), UnitIter->m_iCnt);
|
||
WindUp(*UnitIter);
|
||
UnitIter = m_AskOrderList.begin();
|
||
}
|
||
|
||
if(m_AskOrderList.empty() == true)
|
||
break;
|
||
}
|
||
|
||
// 물량 찾기 취소
|
||
if(m_bLookingDeal == TRUE)
|
||
{
|
||
ElapseTime = CurTime - m_DealStartT;
|
||
if(ElapseTime.GetSeconds()*1000 >= m_iCancelDelay)
|
||
{
|
||
CPLog("Cancel Dealing");
|
||
m_bLookingDeal = FALSE;
|
||
}
|
||
}
|
||
|
||
__super::OnTimer(nIDEvent);
|
||
}
|
||
|
||
void CCPRobotDlg::CheckPrice(const string Code)
|
||
{
|
||
const float fBid1Price = m_CurPriceList[Code].m_afBidPrice[0];
|
||
const int iBid1Cnt = m_CurPriceList[Code].m_aiBidCnt[0];
|
||
|
||
for(UnitIterator iter = m_BidOrderList.begin(); iter != m_BidOrderList.end(); iter++)
|
||
{
|
||
if(iter->m_Code == Code)
|
||
{
|
||
// 최고가 갱신
|
||
if(iter->m_fHighestPrice < fBid1Price)
|
||
iter->m_fHighestPrice = fBid1Price;
|
||
}
|
||
}
|
||
|
||
int iAskSize = m_AskOrderList.size();
|
||
for(UnitIterator iter = m_AskOrderList.begin(); iter != m_AskOrderList.end(); iter++)
|
||
{
|
||
if(iter->m_Code == Code)
|
||
{
|
||
// 최고가 갱신
|
||
if(fBid1Price > iter->m_fHighestPrice)
|
||
iter->m_fHighestPrice = fBid1Price;
|
||
|
||
// 트레일링 or 손절
|
||
if(fBid1Price <= iter->m_fHighestPrice-m_fTrailingTick)
|
||
{
|
||
CPLog("[트레일링 매도 요청] %s(%d) : 고점(%3.2f) 현재가(%3.2f)", iter->m_Code.data(), iter->m_iCnt, iter->m_fHighestPrice, fBid1Price);
|
||
WindUp(*iter);
|
||
iter = m_AskOrderList.begin();
|
||
}
|
||
else if(fBid1Price <= iter->m_fBoughtPrice-m_fLossCutTick)
|
||
{
|
||
CPLog("[손절 매도 요청] %s(%d) 구매가(%3.2f) 현재가(%3.2f)", iter->m_Code.data(), iter->m_iCnt, iter->m_fBoughtPrice, fBid1Price);
|
||
WindUp(*iter);
|
||
iter = m_AskOrderList.begin();
|
||
}
|
||
}
|
||
|
||
if(m_AskOrderList.empty() == true)
|
||
break;
|
||
}
|
||
|
||
|
||
if(m_bPutOption == FALSE && Code[0] == '2' || m_bPutOption == TRUE && Code[0] == '3')
|
||
{
|
||
if(fBid1Price >= m_fMinPriceSet && fBid1Price <= m_fMaxPriceSet)
|
||
{
|
||
if(m_bLookingDeal == TRUE)
|
||
{
|
||
CPLog("Matched [%s] %3.2f", Code.data(), fBid1Price);
|
||
|
||
m_bLookingDeal = FALSE;
|
||
BuyThis(Code, fBid1Price, iBid1Cnt, m_CurPriceList[Code].m_afAskPrice);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
LRESULT CCPRobotDlg::OnProcPrice(WPARAM wParam, LPARAM lParam)
|
||
{
|
||
for(map<string, CP_PRICEINFO>::iterator iter = m_CurPriceList.begin(); iter != m_CurPriceList.end(); iter++)
|
||
{
|
||
if(iter->second.m_bUpdated == true)
|
||
{
|
||
CheckPrice(iter->first);
|
||
iter->second.m_bUpdated = false;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
void CCPRobotDlg::ReceivedSysDib()
|
||
{
|
||
const string Code = (_bstr_t)m_pOpJpBid->GetHeaderValue(0);
|
||
|
||
CP_PRICEINFO PriceInfo;
|
||
PriceInfo.m_afAskPrice[0] = m_pOpJpBid->GetHeaderValue(2); // 2 - (float) 매도 1 우선호가
|
||
PriceInfo.m_afAskPrice[1] = m_pOpJpBid->GetHeaderValue(3); // 3 - (float) 매도 2 우선호가
|
||
PriceInfo.m_afAskPrice[2] = m_pOpJpBid->GetHeaderValue(4); // 4 - (float) 매도 3 우선호가
|
||
PriceInfo.m_afAskPrice[3] = m_pOpJpBid->GetHeaderValue(5); // 5 - (float) 매도 4 우선호가
|
||
PriceInfo.m_afAskPrice[4] = m_pOpJpBid->GetHeaderValue(6); // 6 - (float) 매도 5 우선호가
|
||
PriceInfo.m_aiAskCnt[0] = m_pOpJpBid->GetHeaderValue(7); // 7 - (long) 매도 1 우선호가잔량
|
||
PriceInfo.m_aiAskCnt[1] = m_pOpJpBid->GetHeaderValue(8); // 8 - (long) 매도 2 우선호가잔량
|
||
PriceInfo.m_aiAskCnt[2] = m_pOpJpBid->GetHeaderValue(9); // 9 - (long) 매도 3 우선호가잔량
|
||
PriceInfo.m_aiAskCnt[3] = m_pOpJpBid->GetHeaderValue(10); // 10 - (long) 매도 4 우선호가잔량
|
||
PriceInfo.m_aiAskCnt[4] = m_pOpJpBid->GetHeaderValue(11); // 11 - (long) 매도 5 우선호가잔량
|
||
PriceInfo.m_afBidPrice[0] = m_pOpJpBid->GetHeaderValue(19); // 19 - (float) 매수 1 우선호가
|
||
PriceInfo.m_afBidPrice[1] = m_pOpJpBid->GetHeaderValue(20); // 20 - (float) 매수 2 우선호가
|
||
PriceInfo.m_afBidPrice[2] = m_pOpJpBid->GetHeaderValue(21); // 21 - (float) 매수 3 우선호가
|
||
PriceInfo.m_afBidPrice[3] = m_pOpJpBid->GetHeaderValue(22); // 22 - (float) 매수 4 우선호가
|
||
PriceInfo.m_afBidPrice[4] = m_pOpJpBid->GetHeaderValue(23); // 23 - (float) 매수 5 우선호가
|
||
PriceInfo.m_aiBidCnt[0] = m_pOpJpBid->GetHeaderValue(24); // 24 - (long) 매수 1 우선호가잔량
|
||
PriceInfo.m_aiBidCnt[1] = m_pOpJpBid->GetHeaderValue(25); // 25 - (long) 매수 2 우선호가잔량
|
||
PriceInfo.m_aiBidCnt[2] = m_pOpJpBid->GetHeaderValue(26); // 26 - (long) 매수 3 우선호가잔량
|
||
PriceInfo.m_aiBidCnt[3] = m_pOpJpBid->GetHeaderValue(27); // 27 - (long) 매수 4 우선호가잔량
|
||
PriceInfo.m_aiBidCnt[4] = m_pOpJpBid->GetHeaderValue(28); // 28 - (long) 매수 5 우선호가잔량
|
||
PriceInfo.m_bUpdated = true;
|
||
m_CurPriceList[Code] = PriceInfo;
|
||
|
||
PostMessage(WM_PROC_PRICE, (WPARAM)&Code, 0);
|
||
}
|
||
|
||
void CCPRobotDlg::CheckConclusion(const CP_CONCLUSIONINFO& ConclusionInfo)
|
||
{
|
||
const string Code = ConclusionInfo.m_Code;
|
||
const int iConclusionCnt = ConclusionInfo.m_iCnt;
|
||
const double ConclusionPrice = ConclusionInfo.m_dPrice;
|
||
const int iOrderNum = ConclusionInfo.m_iOrderNum;
|
||
const int iOrgOrderNum = ConclusionInfo.m_iOrgOrderNum;
|
||
|
||
const string astrType[] = { "", "매도", "매수" };
|
||
const int iOrderType = ConclusionInfo.m_enOrderType;
|
||
|
||
const string astrResult[] = { "", "접수", "정정확인", "취소확인", "체결", "거부" };
|
||
const int iOrderState = ConclusionInfo.m_enState;
|
||
|
||
CPLog("[%s 결과][%s] %s(%d) : %3.2f 주문번호:%d 원주문번호:%d",
|
||
astrType[iOrderType].data(), astrResult[iOrderState].data(), Code.data(), iConclusionCnt, ConclusionPrice,
|
||
iOrderNum, iOrgOrderNum);
|
||
|
||
CP_UNITINFO AskData;
|
||
|
||
if(ConclusionInfo.m_enState == CPOS_CONCLUTION)
|
||
{
|
||
if(ConclusionInfo.m_enOrderType == CPOT_BID)
|
||
{
|
||
BOOL bCheck = FALSE;
|
||
for(UnitIterator UnitIter = m_BidOrderList.begin(); UnitIter != m_BidOrderList.end(); UnitIter++)
|
||
{
|
||
if(UnitIter->m_Code == Code && UnitIter->m_iOrderNum == iOrderNum)
|
||
{
|
||
if(iConclusionCnt == UnitIter->m_iCnt)
|
||
{
|
||
AskData = *UnitIter;
|
||
AskData.m_iOrderNum = iOrderNum;
|
||
AskData.m_fBoughtPrice = (float)ConclusionPrice;
|
||
AskData.m_fHighestPrice = (float)ConclusionPrice;
|
||
|
||
m_BidOrderList.erase(UnitIter);
|
||
|
||
bCheck = TRUE;
|
||
}
|
||
else if(iConclusionCnt < UnitIter->m_iCnt)
|
||
{
|
||
AskData = *UnitIter;
|
||
AskData.m_iOrderNum = iOrderNum;
|
||
AskData.m_iCnt = iConclusionCnt;
|
||
AskData.m_fBoughtPrice = (float)ConclusionPrice;
|
||
AskData.m_fHighestPrice = (float)ConclusionPrice;
|
||
|
||
UnitIter->m_iCnt = UnitIter->m_iCnt-iConclusionCnt;
|
||
|
||
bCheck = TRUE;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 매수 취소를 했지만 매수 체결이 먼저 된 경우임
|
||
// 청산 타이밍이 늦어진다는 문제가 있을 수 있음.
|
||
if(bCheck == FALSE)
|
||
{
|
||
AskData.m_Code = ConclusionInfo.m_Code;
|
||
AskData.m_iCnt = ConclusionInfo.m_iCnt;
|
||
AskData.m_fBoughtPrice = (float)ConclusionPrice;
|
||
AskData.m_fHighestPrice = (float)ConclusionPrice;
|
||
AskData.m_Time = CTime::GetCurrentTime();
|
||
AskData.m_iOrderNum = ConclusionInfo.m_iOrderNum;
|
||
}
|
||
|
||
SellThis(AskData);
|
||
}
|
||
else if(ConclusionInfo.m_enOrderType == CPOT_ASK)
|
||
{
|
||
for(UnitIterator UnitIter = m_AskOrderList.begin(); UnitIter != m_AskOrderList.end(); UnitIter++)
|
||
{
|
||
if(UnitIter->m_Code == Code && UnitIter->m_iOrderNum == iOrderNum)
|
||
{
|
||
if(iConclusionCnt == UnitIter->m_iCnt)
|
||
m_AskOrderList.erase(UnitIter);
|
||
else if(iConclusionCnt < UnitIter->m_iCnt)
|
||
UnitIter->m_iCnt = UnitIter->m_iCnt-iConclusionCnt;
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
if(m_AskOrderList.empty() == true)
|
||
{
|
||
OnBnClickedButtonRefreshBalance();
|
||
SaveToFile();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
LRESULT CCPRobotDlg::OnProcConclusion(WPARAM wParam, LPARAM lParam)
|
||
{
|
||
m_bUsingConclusion = true;
|
||
vector<CP_CONCLUSIONINFO> CopyList = m_ConclusionList;
|
||
m_bUsingConclusion = false;
|
||
|
||
for(vector<CP_CONCLUSIONINFO>::iterator iter=CopyList.begin(); iter != CopyList.end(); iter++)
|
||
{
|
||
CheckConclusion(*iter);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
void CCPRobotDlg::ReceivedDib()
|
||
{
|
||
if(m_bUsingConclusion == false)
|
||
m_ConclusionList.clear();
|
||
|
||
CP_CONCLUSIONINFO Conclusion;
|
||
|
||
Conclusion.m_Code = (LPCSTR)(_bstr_t)m_pCpFConclusion->GetHeaderValue(9); // 9 - (string) 종목코드
|
||
Conclusion.m_iOrderNum = m_pCpFConclusion->GetHeaderValue(5); // 5 - (long) 주문번호
|
||
Conclusion.m_iOrgOrderNum = m_pCpFConclusion->GetHeaderValue(6); // 6 - (long) 원주문번호
|
||
Conclusion.m_dPrice = m_pCpFConclusion->GetHeaderValue(4); // 4 - (double) 체결가격
|
||
Conclusion.m_iCnt = m_pCpFConclusion->GetHeaderValue(3); // 3 - (long) 체결수량
|
||
|
||
const string OrderType = (LPCSTR)(_bstr_t)m_pCpFConclusion->GetHeaderValue(12); // 12 - (string) 매매구분 코드(1:매도, 2:매수)
|
||
const string OrderState = (LPCSTR)(_bstr_t)m_pCpFConclusion->GetHeaderValue(44); // 44 - (string) 주문상태구분코드 (1:접수 2:정정확인 3:취소확인 4:체결 5:거부)
|
||
|
||
Conclusion.m_enState = (CP_ORDER_STATE)atoi(OrderState.data());
|
||
Conclusion.m_enOrderType = (CP_ORDER_TYPE)atoi(OrderType.data());
|
||
|
||
m_ConclusionList.push_back(Conclusion);
|
||
|
||
PostMessage(WM_PROC_CONCLUSION, 0, 0);
|
||
}
|