// CPRobotDlg.cpp : 구현 파일 // #include "stdafx.h" #include "CPRobot.h" #include "CPRobotDlg.h" #include #ifdef _DEBUG #define new DEBUG_NEW #endif ICpTdUtilPtr g_pTdUtil = NULL; CCPRobotDlg::CCPRobotDlg(CWnd* pParent /*=NULL*/) : CDialog(CCPRobotDlg::IDD, pParent) , m_iAmountSet(0) , m_fMinPriceSet(0.0f) , m_fMaxPriceSet(0.0f) , m_iSellTick(0) , m_iLossCutTick(0) , m_iTrailingTick(0) , m_iCancelDelay(0) , m_bPutOption(FALSE) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_iBalance = 0; m_pOpJpBid = NULL; } 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_iSellTick); DDX_Text(pDX, IDC_EDIT_LOSS_CUT_TICK, m_iLossCutTick); DDX_Text(pDX, IDC_EDIT_TRAING_TICK, m_iTrailingTick); DDX_Text(pDX, IDC_EDIT_CANCEL_DELAY, m_iCancelDelay); DDX_Radio(pDX, IDC_RADIO_CALLOP, m_bPutOption); } 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_BN_CLICKED(IDC_RADIO_BID, &CCPRobotDlg::OnBnClickedRadioBid) ON_BN_CLICKED(IDC_RADIO_ASK, &CCPRobotDlg::OnBnClickedRadioAsk) ON_WM_PARENTNOTIFY() END_MESSAGE_MAP() // CCPRobotDlg 메시지 처리기 BOOL CCPRobotDlg::OnInitDialog() { CDialog::OnInitDialog(); // 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는 // 프레임워크가 이 작업을 자동으로 수행합니다. SetIcon(m_hIcon, TRUE); // 큰 아이콘을 설정합니다. SetIcon(m_hIcon, FALSE); // 작은 아이콘을 설정합니다. // TODO: 여기에 추가 초기화 작업을 추가합니다. return TRUE; // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다. } int CCPRobotDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here CoInitializeEx(NULL, COINIT_MULTITHREADED); // 모의투자 mjjo53 // 계좌번호 335190813 g_pTdUtil.CreateInstance(CLSID_CpTdUtil); const short iInitResult = g_pTdUtil->TradeInit(0); switch(iInitResult) { case -1: MessageBox("TradeInit 오류"); return -2; break; case 1: MessageBox("업무 키 잘못 입력됨"); return -2; break; case 2: MessageBox("계좌 비밀번호 잘못 입력됨"); return -2; break; case 3: MessageBox("취소됨"); return -2; break; } m_AccountNum = "117126165"; // m_AccountNum = "412120700"; // m_AccountNum = "335190813"; // mjjo53 모의투자 계좌 m_pOpJpBid.CreateInstance(CLSID_OptionJpBid); m_EventHandler.DispEventAdvise(m_pOpJpBid); m_EventHandler.SetIEventHandler(this); ICpOptionCodePtr pOpCode; pOpCode.CreateInstance(CLSID_CpOptionCode); short iCodeCnt = pOpCode->GetCount(); string Code; for(int i=0; iGetData(0, i); m_OpCodeList.push_back(Code); } pOpCode.Release(); return 0; } void CCPRobotDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: Add your message handler code here m_pOpJpBid.Release(); m_EventHandler.DispEventUnadvise(m_pOpJpBid); UpdateData(); SaveToFile(); } BOOL CCPRobotDlg::DestroyWindow() { // TODO: Add your specialized code here and/or call the base class g_pTdUtil.Release(); 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", m_iAmountSet); fprintf_s(fp, "매수 조건 최소 : %f", m_fMinPriceSet); fprintf_s(fp, "매수 조건 최대 : %f", m_fMaxPriceSet); fprintf_s(fp, "매도 요청 : %d", m_iSellTick); fprintf_s(fp, "손절 범위 : %d", m_iLossCutTick); fprintf_s(fp, "트레일링 범위 : %d", m_iTrailingTick); fprintf_s(fp, "취소 시간 : %d", m_iCancelDelay); fprintf_s(fp, "풋옵션 : %d", 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", &m_iAmountSet); fscanf_s(fp, "매수 조건 최소 : %f", &m_fMinPriceSet); fscanf_s(fp, "매수 조건 최대 : %f", &m_fMaxPriceSet); fscanf_s(fp, "매도 요청 : %d", &m_iSellTick); fscanf_s(fp, "손절 범위 : %d", &m_iLossCutTick); fscanf_s(fp, "트레일링 범위 : %d", &m_iTrailingTick); fscanf_s(fp, "취소 시간 : %d", &m_iCancelDelay); fscanf_s(fp, "풋옵션 : %d", &m_bPutOption); fclose(fp); fp = NULL; } // 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면 // 아래 코드가 필요합니다. 문서/뷰 모델을 사용하는 MFC 응용 프로그램의 경우에는 // 프레임워크에서 이 작업을 자동으로 수행합니다. void CCPRobotDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트 SendMessage(WM_ICONERASEBKGND, reinterpret_cast(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(m_hIcon); } void CCPRobotDlg::OnBnClickedButtonRefreshBalance() { // TODO: Add your control notification handler code here ICpTdDibPtr pTd0721 = NULL; pTd0721.CreateInstance(CLSID_CpTd0721F); pTd0721->SetInputValue(0, m_AccountNum.data()); pTd0721->SetInputValue(1, "50"); pTd0721->SetInputValue(2, "50"); pTd0721->SetInputValue(3, "10"); 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(); LoadFromFile(); UpdateData(FALSE); } void CCPRobotDlg::Subscribe(void) { const int iCodeCnt = m_OpCodeList.size(); try { for(int i=0; iSetInputValue(0, m_OpCodeList[i].data()); m_pOpJpBid->SubscribeLatest(); TRACE1("Subscribe[%s]\n", 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 { for(int i=0; iSetInputValue(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(); Unsubscribe(); Subscribe(); } void CCPRobotDlg::OnBnClickedButtonStartDeal() { // TODO: Add your control notification handler code here } void CCPRobotDlg::OnBnClickedRadioBid() { // TODO: Add your control notification handler code here m_bSell = (((CButton*)GetDlgItem(IDC_RADIO_BID))->GetCheck() == 1); } void CCPRobotDlg::OnBnClickedRadioAsk() { // TODO: Add your control notification handler code here m_bSell = (((CButton*)GetDlgItem(IDC_RADIO_BID))->GetCheck() == 1); } void CCPRobotDlg::Received() { 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); float fBid1Price = m_pOpJpBid->GetHeaderValue(19); // 매수 1 우선호가 int iBid1Cnt = m_pOpJpBid->GetHeaderValue(24); //매수 1 우선호가잔량 float afOfferPrice[5]; afOfferPrice[0] = m_pOpJpBid->GetHeaderValue(2); // 2 - (float) 매도 1 우선호가 afOfferPrice[1] = m_pOpJpBid->GetHeaderValue(3); // 3 - (float) 매도 2 우선호가 afOfferPrice[2] = m_pOpJpBid->GetHeaderValue(4); // 4 - (float) 매도 3 우선호가 afOfferPrice[3] = m_pOpJpBid->GetHeaderValue(5); // 5 - (float) 매도 4 우선호가 afOfferPrice[4] = m_pOpJpBid->GetHeaderValue(6); // 6 - (float) 매도 5 우선호가 if(m_bPutOption == FALSE && Code[0] == '2') { if(fBid1Price >= m_fMinPriceSet && fBid1Price <= m_fMaxPriceSet) { TRACE2("received [%s] %f\n", Code.data(), fBid1Price); Unsubscribe(); // 수량 계산 int iBuyCnt = 1; // 매수 주문 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, afOfferPrice[0]); // 4 - (double) 주문가격 pTd6831->SetInputValue(5, "2"); // 5 - (string) 매매구분코드 (1:매도, 2:매수) pTd6831->SetInputValue(7, "1"); // 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(); TRACE(strErrorMsg); } // 매도 요청 const int iSellAsk = min(m_iSellTick, 4); pTd6831->SetInputValue(4, iSellAsk); // 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(); TRACE(strErrorMsg); } } } else if(m_bPutOption == TRUE && Code[0] == '3') { if(fBid1Price >= m_fMinPriceSet && fBid1Price <= m_fMaxPriceSet) { TRACE2("received [%s] %f\n", Code.data(), fBid1Price); } } }