#include "MainFrame.h" #include #include #include #include #include "MyNetworkApi.h" #include #include "DataParseUtil.h" #include "../common_nopch/StringUtil.h" #include "../common_nopch/TimeUtil.h" #include "MyConfigUtil.h" #include "TickFrame.h" #include #include "../common_nopch/Win32Util.h" #define MSG_SHOW_TIME 5 * 1000 #define COLOR_VALID wxColor(0,0,0) #define COLOR_INVALID wxColor(164,164,164) BEGIN_EVENT_TABLE(MainFrame, wxFrame) EVT_MENU(wxID_ABOUT, MainFrame::OnAbout) EVT_MENU(wxID_EXIT, MainFrame::OnQuit) EVT_TEXT_ENTER(wxID_ANY, MainFrame::OnTextEnter) END_EVENT_TABLE() MainFrame::MainFrame(const wxString& title, wxPoint position, wxSize size) :wxFrame(NULL, wxID_ANY, title, position, size) { wxIcon icon; icon.LoadFile("logo.ico", wxBITMAP_TYPE_ICO); // Ìæ»» "app_icon.ico" ΪÄãµÄÓ¦ÓóÌÐòͼ±êÎļþ·¾¶ SetIcon(icon); //SetTransparent(225); viewManager = new ViewManager(); viewManager->initView(this); initData(); bindEvent(); initTask(); Bind(wxEVT_SHOW, [this](wxShowEvent& event) { this->SetWindowStyleFlag(GetWindowStyleFlag() | wxSTAY_ON_TOP); }); this->SetWindowStyleFlag(GetWindowStyleFlag() | wxSTAY_ON_TOP); } void MainFrame::OnQuit(wxCommandEvent& event) { } void MainFrame::OnAbout(wxCommandEvent& event) { } void MainFrame::OnTextEnter(wxCommandEvent& event) { wxTextCtrl* textCtrl = dynamic_cast(event.GetEventObject()); string value = textCtrl->GetValue().ToStdString(); if (textCtrl == viewManager->sellWidgets->buyMoney) { if (!viewManager->sellWidgets->buyLock->GetValue()) { return; } if (!StringUtil::isNumber(value)) { wxMessageBox("ÊäÈë¸ñʽ´íÎó"); return; } MyConfigUtil::setBuyMoney(stoi(value.c_str())); wxMessageBox("Ëø¶¨ÂòÈë½ð¶î³É¹¦"); } else if (textCtrl == viewManager->sellWidgets->sellMoney) { if (!viewManager->sellWidgets->sellLock->GetValue()) { return; } if (!StringUtil::isNumber(value)) { wxMessageBox("ÊäÈë¸ñʽ´íÎó"); return; } lockSellVolume(); } } void MainFrame::bindEvent() { Bind(wxEVT_CLOSE_WINDOW, &MainFrame::OnClose, this); viewManager->topWidgets->refreshBtn->Bind(wxEVT_BUTTON, &MainFrame::OnBtnRefreshClick, this); viewManager->sellWidgets->buyBtn->Bind(wxEVT_BUTTON, &MainFrame::OnBtnBuyClick, this); viewManager->sellWidgets->sellBtn->Bind(wxEVT_BUTTON, &MainFrame::OnBtnSellClick, this); viewManager->positionWidgets->listCtrlReport->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &MainFrame::OnPositionSelectionChanged, this); viewManager->topWidgets->btnBackTest->Bind(wxEVT_BUTTON, &MainFrame::OnBtnBackTest, this); for (std::list::iterator e = viewManager->sellWidgets->sellNums.begin(); e != viewManager->sellWidgets->sellNums.end(); ++e) { wxButton* sellBtn = *e; //sellBtn->Bind(wxEVT_BUTTON, &MainFrame::OnBtnSellNum, this); sellBtn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { wxButton* btn = (wxButton*)event.GetEventObject(); this->viewManager->sellWidgets->sellMoney->SetLabelText(btn->GetLabelText()); // Ëø¶¨Á¿ if (this->viewManager->sellWidgets->sellLock->IsChecked()) { lockSellVolume(); } }); } viewManager->sellWidgets->openTrade->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { try { string result = MyNetworkApi::set_trade_state(1); auto doc = JsonUtil::parseUTF16(result); if (doc.IsObject()) { if (doc[L"code"] == 0) { this->setTradeStateView(1); } else { throw wstring(doc[L"msg"].GetString()); } } else { throw wstring(L"ÍøÂçÇëÇóʧ°Ü"); } } catch (wstring st) { wxMessageBox(st); } }); viewManager->sellWidgets->closeTrade->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { try { string result = MyNetworkApi::set_trade_state(0); auto doc = JsonUtil::parseUTF16(result); if (doc.IsObject()) { if (doc[L"code"] == 0) { this->setTradeStateView(0); } else { throw wstring(doc[L"msg"].GetString()); } } else { throw wstring(L"ÍøÂçÇëÇóʧ°Ü"); } } catch (wstring st) { wxMessageBox(st); } }); viewManager->sellWidgets->addWantBuy->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { try { wxString code = this->viewManager->topWidgets->codeEdit->GetValue(); if (code.Length() != 6) { throw wstring(L"´úÂë¸ñʽ´íÎó"); } string result = MyNetworkApi::add_want_buy_code(code.ToStdString()); auto doc = JsonUtil::parseUTF16(result); if (doc.IsObject()) { if (doc[L"code"] == 0) { wxMessageBox("Ìí¼Ó³É¹¦"); } else { throw wstring(doc[L"msg"].GetString()); } } else { throw wstring(L"ÍøÂçÇëÇóʧ°Ü"); } } catch (wstring st) { wxMessageBox(st); } }); viewManager->sellWidgets->removeWantBuy->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { try { wxString code = this->viewManager->topWidgets->codeEdit->GetValue(); if (code.Length() != 6) { throw wstring(L"´úÂë¸ñʽ´íÎó"); } string result = MyNetworkApi::remove_want_buy_code(code.ToStdString()); auto doc = JsonUtil::parseUTF16(result); if (doc.IsObject()) { if (doc[L"code"] == 0) { wxMessageBox("ÒÆ³ý³É¹¦"); } else { throw wstring(doc[L"msg"].GetString()); } } else { throw wstring(L"ÍøÂçÇëÇóʧ°Ü"); } } catch (wstring st) { wxMessageBox(st); } }); viewManager->sellWidgets->wantBuyList->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { try { string result = MyNetworkApi::list_want_buy_codes(); auto doc = JsonUtil::parseUTF16(result); if (doc.IsObject()) { if (doc[L"code"] == 0) { wxString st = ""; auto array = doc[L"data"].GetArray(); for (int i = 0; i < array.Size(); i++) { st.Append(array[i].GetArray()[0].GetString()); st.Append("£¨"); st.Append(array[i].GetArray()[1].GetString()); st.Append("£©"); if (i % 2 == 1) { st.Append("\n"); } } wxMessageBox(st, "ÏëÂòµ¥"); } else { throw wstring(doc[L"msg"].GetString()); } } else { throw wstring(L"ÍøÂçÇëÇóʧ°Ü"); } } catch (wstring st) { wxMessageBox(st); } }); } void MainFrame::initData() { // -----------------------³õʼ»¯¾ò½ð²ÎÊý-------------------------- JueJinParams jueJinParams = MyConfigUtil::getJueJinParams(); tickDataRequestStrategy = new TickDataRequestStrategy(jueJinParams.token, jueJinParams.strategy_id, MODE_LIVE, this, &MainFrame::tickDataCallback); // ÉèÖûزâ²ÎÊý tickDataRequestStrategy->set_token(jueJinParams.token.c_str()); tickDataRequestStrategy->set_strategy_id(jueJinParams.strategy_id.c_str()); tickDataRequestStrategy->set_mode(MODE_LIVE); JueJinDataUtil::init(jueJinParams.token); MyNetworkApi::set_server_info("43.138.167.68", 13008, "43.138.167.68", 13008); // -----------------------³õʼ»¯¿ì½Ý¼ü-------------------------- wxAcceleratorEntry entries[2] = { wxAcceleratorEntry(wxACCEL_SHIFT, WXK_F10, 901), wxAcceleratorEntry(wxACCEL_CTRL, 'H', 902) }; auto acceleratorTable = wxAcceleratorTable(2, entries); this->SetAcceleratorTable(acceleratorTable); this->Bind(wxEVT_MENU, [this](wxCommandEvent& event) { this->OnBtnSellClick(event); }, 901); this->Bind(wxEVT_MENU, [this](wxCommandEvent& event) { for (std::list::iterator e = this->positionList.begin(); e != this->positionList.end(); e++) { PositionInfo info = *e; if (this->selectPositionId == info.id) { try { Sleep(200); CallAfter([info]() { thread t(Win32Util::addToTHS, info.underlyingMarketInfo.code.ToStdString()); t.detach(); }); } catch (...) { } break; } } }, 902); //-----------------------»ñÈ¡µ±Ç°½»Ò×״̬-------------------------- try { string result = MyNetworkApi::get_trade_state(); auto doc = JsonUtil::parseUTF8(result); if (doc.IsObject() && doc["code"].GetInt() == 0) { tradeState = doc["data"]["state"].GetInt(); setTradeStateView(tradeState); } } catch (...) { } // -----------------------Âô³ö²ÎÊý³õʼ»¯-------------------------- int buyMoney = MyConfigUtil::getBuyMoney(); int sellMoney = MyConfigUtil::getSellMoney(); viewManager->sellWidgets->buyMoney->SetValue(to_string(buyMoney)); viewManager->sellWidgets->sellMoney->SetValue(to_string(sellMoney)); viewManager->sellWidgets->buyLock->SetValue(TRUE); viewManager->sellWidgets->sellLock->SetValue(TRUE); killed = FALSE; blinkingMessageDialog = nullptr; } void MainFrame::initTask() { thread t(MainFrame::startRequestPositionsTask, this); t.detach(); thread t2(MainFrame::startRequestMoneyTask, this); t2.detach(); thread t1(MainFrame::runJueJinStrategy, this); t1.detach(); } void MainFrame::requestPositions() { cout << "###########ÇëÇó³Ö²Ö##########" << endl; string result = MyNetworkApi::get_all_positions(); if (this == nullptr) { return; } requestCount += 1; std::list plist = DataParseUtil::parsePositionList(result); if (plist.size() == 0) { string nowTime = TimeUtil::format(TimeUtil::getNowTimeStamp(), "%H%M%S"); if (stoi(nowTime) < stoi("093000")) { MyConfigUtil::clearCodesSellMoney(); } } //¸ù¾Ý³Ö²ÖÅÅÐò, plist.sort([](PositionInfo p1, PositionInfo p2) { int p1Int = p1.currentPosition > 0 ? 1 : 0; int p2Int = p2.currentPosition > 0 ? 1 : 0; return p1Int == p2Int ? p1.createTime > p2.createTime: p1Int > p2Int; }); if (requestCount > 1 && this->orginPositionList.size() != plist.size()) { CallAfter([this]() { this->blinkingMessageDialog = new BlinkingMessageDialog(this, "¿ÉתծÓÐÐÂϵ¥"); this->blinkingMessageDialog->show(); }); } this->orginPositionList = plist; viewManager->positionWidgets->listCtrlReport->DeleteAllItems(); // °´Ìõ¼þ¹ýÂË std::list < PositionInfo> temList; for (std::list::iterator e = plist.begin(); e != plist.end(); ++e) { PositionInfo p = *e; if (!viewManager->sellWidgets->showAllPosition->GetValue()) { if (p.availablePosition > 0) { temList.push_back(*e); } } else { temList.push_back(*e); } } this->positionList = temList; int index = 0; for (std::list::iterator e = positionList.begin(); e != positionList.end(); ++e) { PositionInfo p = *e; //{ "Ãû³Æ", "ÕÇ·ù", "ÏÖ¼Û", "L1ÏÖÊÖ", "Ê£Óà³Ö²Ö", "³Ö²Ö½ð¶î", "Ó¯¿÷", "Ó¯¿÷±È", "Õý¹ÉÃû³Æ", "¸ü¶à" }; wxVector data; bool hasPosition = p.currentPosition > 0; wxColor color = !hasPosition ? COLOR_INVALID : COLOR_VALID; map dataMap; dataMap[0] = wxVariant(MyColorText(p.securityName, color)); if (!hasPosition) { dataMap[1] = wxVariant(wxVariant(MyColorText(p.marketInfo.rate, color))); } else { wxString rateText = p.marketInfo.rate; rateText.Replace("%", ""); double rate; rateText.ToCDouble(&rate); wxColor tempColor; if (rate > 0.0001) { tempColor = wxColor(255, 42, 7); if (rate > 8.9) { tempColor = wxColor(243, 143, 250); } } else if (rate < 0.0001) { tempColor = wxColor(0, 230, 0); } else { tempColor = wxColor(64, 64, 64); } dataMap[1] = (wxVariant(MyColorText(p.marketInfo.rate, tempColor))); } dataMap[7] = (wxVariant(MyColorText(wxString(p.marketInfo.price), color))); // »ñÈ¡Âô¶î int sellMoney = MyConfigUtil::getSellMoney(p.securityID.ToStdString()); dataMap[6] = (wxVariant(MyColorText(to_string(sellMoney), color))); dataMap[2] = wxVariant(MyColorText(p.underlyingMarketInfo.rate, color)); if (!hasPosition) { dataMap[3]=wxVariant(MyColorText(p.underlyingMarketInfo.buy1Money, color)); } else { dataMap[3] = wxVariant(MyColorText(p.underlyingMarketInfo.buy1Money, wxColor(204, 78, 232))); } // ¼ÆËã³Ö²Ö½ð¶î double positionMoney = 0.00; if (p.marketInfo.price.Length() > 0) { double price; p.marketInfo.price.ToCDouble(&price); positionMoney = price * p.currentPosition; } if (!hasPosition) { dataMap[4]=wxVariant(MyColorText(StringUtil::to_string(positionMoney, 2), color)); } else { dataMap[4]=wxVariant(MyColorText(StringUtil::to_string(positionMoney, 2), *wxRED)); } // ³É±¾¼Û¼ÆËã: ×ÜÂòÈë½ð¶î + ÊÖÐø·Ñ double totalPosCost = 0; int totalVolume = 0; for (std::list::iterator e = p.buyList.begin(); e != p.buyList.end(); e++) { DealInfo info = *e; string price = info.price.ToStdString(); totalPosCost += stod(price.c_str()) * info.volume; totalVolume += info.volume; } double todayCommission; p.todayCommission.ToDouble(&todayCommission); totalPosCost += todayCommission; wxString cost_price = StringUtil::to_string(totalPosCost / totalVolume, 3); dataMap[8] = (wxVariant(MyColorText(cost_price, color))); // ½ñÈÕÓ¯¿÷¼ÆË㣺 ×ÜÂô³ö½ð¶î + ³Ö²Ö*ÏÖ¼Û - ÂòÈë½ð¶î - ÊÖÐø·Ñ double totalSellMoney = 0; for (std::list::iterator e = p.sellList.begin(); e != p.sellList.end(); e++) { double price; (*e).price.ToDouble(&price); totalSellMoney += price * (*e).volume; } double profit_money = totalSellMoney + positionMoney - totalPosCost; // ¼ÆËã½ñÈÕÓ¯¿÷±È double profit_rate = profit_money / totalPosCost; wxString profit_rate_str = ""; profit_rate_str.Append(StringUtil::to_string(profit_rate * 100)).Append("%"); dataMap[5] = (wxVariant(MyColorText(profit_rate_str, color))); // Õý¹ÉÊý¾ÝÉèÖà if (hasPosition) { dataMap[9] = (wxVariant(MyButton(p.underlyingMarketInfo.code, "²é¿´", wxColor(64, 64, 64), wxColor(225, 225, 225)))); } else { dataMap[9] = (wxVariant(MyButton(p.underlyingMarketInfo.code, "²é¿´", color, wxColor(255, 255, 255)))); } dataMap[10] = (wxVariant(MyColorText(wxString(to_string(p.currentPosition).c_str()), color))); dataMap[11] = (wxVariant(MyColorText(StringUtil::to_string(profit_money, 2), color))); dataMap[12] = (wxVariant(MyColorText(p.underlyingMarketInfo.name, color))); for (const auto& pair : dataMap) { data.push_back(pair.second); } viewManager->positionWidgets->listCtrlReport->AppendItem(data); if (selectPositionId == p.id) { viewManager->positionWidgets->listCtrlReport->Select(viewManager->positionWidgets->listCtrlReport->RowToItem(index)); // ÉèÖÃtickµÄÂòµãÓëÂôµã std::list tradePoints; for (std::list::iterator e = p.buyList.begin(); e != p.buyList.end(); ++e) { DealInfo info = *e; double price = stod(info.price.ToStdString().c_str()); double rate = (price - p.marketInfo.preClosePrice) * 100 / p.marketInfo.preClosePrice; tradePoints.push_back(TickTradeData({ info.tradeTime, (float)rate, info.price.ToStdString(), info.volume, StringUtil::to_string(info.volume * stod(info.price.ToStdString().c_str())), info.type })); } viewManager->tickWidgets->tickChart->SetBuyPoint(tradePoints); tradePoints.clear(); for (std::list::iterator e = p.sellList.begin(); e != p.sellList.end(); ++e) { DealInfo info = *e; double price = stod(info.price.ToStdString().c_str()); double rate = (price - p.marketInfo.preClosePrice) * 100 / p.marketInfo.preClosePrice; tradePoints.push_back(TickTradeData({ info.tradeTime, (float)rate, info.price.ToStdString(), info.volume, StringUtil::to_string(info.volume * stod(info.price.ToStdString().c_str())) })); } viewManager->tickWidgets->tickChart->SetSellPoint(tradePoints); } index += 1; } viewManager->positionWidgets->listCtrlReport->HandleDataUpdate(); } void MainFrame::requestMoney() { cout << "###########ÇëÇóÕË»§×ʽð##########" << endl; string result = MyNetworkApi::get_money(); if (this == nullptr) { return; } auto doc = JsonUtil::parseUTF16(result); try { if (doc.IsObject() && doc[L"code"].GetInt() == 0) { auto array = doc[L"data"].GetArray(); if (array.Size() > 0) { auto data = array[0].GetObject(); viewManager->moneyWidgets->availableLabel->SetLabelText(StringUtil::to_string(data[L"usefulMoney"].GetDouble(), 2)); viewManager->moneyWidgets->frozenLabel->SetLabelText(StringUtil::to_string(data[L"frozenCash"].GetDouble(), 2)); } } } catch (...) { } } void MainFrame::startRequestPositionsTask(MainFrame* context) { while (TRUE) { try { context->requestPositions(); } catch (...) { } Sleep(2000); } } void MainFrame::startRequestMoneyTask(MainFrame* context) { while (TRUE) { try { context->requestMoney(); } catch (...) { } Sleep(2000); } } void MainFrame::OnTickCallBack(CodeBasicInfo info, wxString xStartTime, wxString xEndTime, std::list buyPoints, std::list sellPoints, float costRate, void* context) { MainFrame* mainFrame = (MainFrame*)context; wxSize size = mainFrame->GetSize(); int width = size.GetWidth(); width = width * 3 / 4; int height = width * 2 / 3; TickFrame* tickFrame = new TickFrame(mainFrame, info.codeName, info.code, info.codeName, info.preClosePrice, xStartTime, xEndTime, buyPoints, sellPoints, costRate, wxDefaultPosition, wxSize(width, height)); tickFrame->Show(); } LRESULT MainFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { cout << "MSWWindowProc:" << nMsg << endl; if (nMsg == WM_COPYDATA) { COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam; if (pcds != NULL) { int action_code = pcds->dwData; if (action_code == 100) { // Âô BYTE* pBuf = (BYTE*)(pcds->lpData); DWORD dwSize = (DWORD)(pcds->cbData); std::string str(reinterpret_cast(pBuf), dwSize); // ÔÚÕâÀï´¦Àí½ÓÊÕµ½µÄ×Ö·û´®Êý¾Ý receivedData cout << "ÄÚÈÝ:" << str << endl; wxCommandEvent event; this->OnBtnSellClick(event); } } } return wxFrame::MSWWindowProc(nMsg, wParam, lParam); } void MainFrame::OnClose(wxCloseEvent& event) { killed = true; MyConfigUtil::setMainWindowPos(GetPosition(), GetSize()); // ±£´æ³Ö²Ö¹ÉÁпí int columnCount = viewManager->positionWidgets->listCtrlReport->GetColumnCount(); std::list positionWidthList; for (int i = 0; i < columnCount; i++) { wxDataViewColumn* column = viewManager->positionWidgets->listCtrlReport->GetColumn(i); int columnWidth = column->GetWidth(); positionWidthList.push_back(columnWidth); } MyConfigUtil::setPositionColumnWidth(positionWidthList); event.Skip(); exit(0); } void MainFrame::lockSellVolume() { string value = viewManager->sellWidgets->sellMoney->GetValue().ToStdString(); if (selectPositionId.IsEmpty()) { MyConfigUtil::setSellMoney(stoi(value.c_str())); //wxMessageBox("Ëø¶¨Âô³ö½ð¶î³É¹¦"); } else { for (std::list::iterator e = orginPositionList.begin(); e != orginPositionList.end(); ++e) { if ((*e).id == selectPositionId) { MyConfigUtil::setSellMoney((*e).securityID.ToStdString(), stoi(value.c_str())); //wxMessageBox("Ëø¶¨Âô³ö½ð¶î³É¹¦"); break; } } } } void MainFrame::OnBtnRefreshClick(wxCommandEvent& event) { string result = MyNetworkApi::refresh_position(); cout << "ˢгֲֽá¹û£º" << result.c_str() << endl; result = MyNetworkApi::refresh_deal(); cout << "ˢгɽ»½á¹û£º" << result.c_str() << endl; } void MainFrame::OnBtnBuyClick(wxCommandEvent& event) { if (!selectPositionId || selectPositionId.length() == 0) { showMsg("ÉÐδѡÖгֲÖ", MSG_TYPE_WARNING); return; } PositionInfo pos = getSeclectedPosition(); wxString code = viewManager->topWidgets->codeEdit->GetValue(); wxString buyMoney = viewManager->sellWidgets->buyMoney->GetValue(); if (buyMoney.length() <= 0) { showMsg("ÇëÊäÈëÂòÈë½ð¶î", MSG_TYPE_WARNING); return; } int priceType = viewManager->sellWidgets->buyPrice->GetSelection(); // ͨ¹ý½ð¶î¼ÆËãÂôµÄÁ¿ double volume = stoi(buyMoney.ToStdString().c_str()) / stod(pos.marketInfo.price.ToStdString().c_str()); int volume_int = (int)volume; volume_int = volume_int / 10 * 10; if (volume_int <= 0) { showMsg("ÂòÈëСÓÚ10¹É", MSG_TYPE_WARNING); return; } string result = MyNetworkApi::buy(code.ToStdString(), priceType, volume_int); auto doc = JsonUtil::parseUTF16(result); if (doc.IsObject()) { if (doc[L"code"].GetInt() == 0) { auto data = doc[L"data"].GetObject(); if (data.HasMember(L"orderStatus") && data[L"orderStatus"].GetInt() == -1) { showMsg(data[L"orderStatusMsg"].GetString(), MSG_TYPE_ERROR); } else { showMsg("ÂòÈë³É¹¦", MSG_TYPE_INFO); requestPositions(); } } else { showMsg(doc[L"msg"].GetString(), MSG_TYPE_ERROR); } } else { showMsg("ÍøÂçÇëÇó³ö´í", MSG_TYPE_ERROR); } } void MainFrame::showMsg(wxString msg, MsgTypeEnum type) { // ÏÔʾ15s msgExpireTime = TimeUtil::getNowTimeStamp() + MSG_SHOW_TIME; switch (type) { case MSG_TYPE_ERROR: viewManager->topWidgets->msgLabel->SetForegroundColour(*wxGREEN); break; case MSG_TYPE_WARNING: viewManager->topWidgets->msgLabel->SetForegroundColour(*wxGREEN); break; case MSG_TYPE_INFO: viewManager->topWidgets->msgLabel->SetForegroundColour(*wxBLACK); break; default: break; } viewManager->topWidgets->msgLabel->SetLabelText(msg); // Æô¶¯Ï߳̽áÊøÏÔʾ thread t(clearMsg, this); t.detach(); } void MainFrame::clearMsg(MainFrame* context) { Sleep(MSG_SHOW_TIME); if (TimeUtil::getNowTimeStamp() > context->msgExpireTime) { context->viewManager->topWidgets->msgLabel->SetLabelText(""); } } void MainFrame::runJueJinStrategy(MainFrame* context) { context->tickDataRequestStrategy->run(); while (TRUE) { Sleep(3000); } } void MainFrame::tickDataCallback(Tick* tick, void* context) { string symbol = tick->symbol; symbol = symbol.substr(symbol.find(".") + 1, 6); cout << "»Øµ÷£º" << symbol << endl; MainFrame* that = (MainFrame*)context; for (std::list::iterator e = that->positionList.begin(); e != that->positionList.end(); e++) { PositionInfo info = *e; if (that->selectPositionId == info.id) { if (info.securityID == symbol) { that->viewManager->tickWidgets->tickChart->AddTickData(TimeUtil::format((long)tick->created_at, "%H:%M:%S"), 100 * (tick->price - info.marketInfo.preClosePrice) / info.marketInfo.preClosePrice, to_string(tick->price)); } else if (info.underlyingMarketInfo.code == symbol) { list quotes; for (int i = 0; i < 5; i++) { quotes.push_back(tick->quotes[i]); } that->viewManager->tickWidgets->tickChart->AddUnderlyingTickData(TimeUtil::format((long)tick->created_at, "%H:%M:%S"), 100 * (tick->price - info.underlyingMarketInfo.preClosePrice) / info.underlyingMarketInfo.preClosePrice, quotes); } break; } } } PositionInfo MainFrame::getSeclectedPosition() { for (list::iterator e = positionList.begin(); e != positionList.end(); ++e) { PositionInfo info = *e; if (info.id == selectPositionId) { return info; } } } void MainFrame::setTradeStateView(int state) { if (state > 0) { viewManager->sellWidgets->openTrade->SetForegroundColour(*wxRED); viewManager->sellWidgets->closeTrade->SetForegroundColour(*wxBLACK); } else { viewManager->sellWidgets->openTrade->SetForegroundColour(*wxBLACK); viewManager->sellWidgets->closeTrade->SetForegroundColour(*wxRED); } } void MainFrame::OnBtnSellClick(wxCommandEvent& event) { if (!selectPositionId || selectPositionId.length() == 0) { showMsg("ÉÐδѡÖгֲÖ", MSG_TYPE_WARNING); return; } PositionInfo pos = getSeclectedPosition(); wxString code = viewManager->topWidgets->codeEdit->GetValue(); wxString sellMoney = viewManager->sellWidgets->sellMoney->GetValue(); if (sellMoney.length() <= 0) { showMsg("ÇëÊäÈëÂô½ð¶î", MSG_TYPE_WARNING); return; } int priceType = viewManager->sellWidgets->sellPrice->GetSelection(); // ͨ¹ý½ð¶î¼ÆËãÂôµÄÁ¿ double volume = stoi(sellMoney.ToStdString().c_str()) / stod(pos.marketInfo.price.ToStdString().c_str()); int volume_int = (int)volume; volume_int = volume_int / 10 * 10; cout << "Âô³öµÄÁ¿£º" << volume_int << endl; if (volume_int > pos.availablePosition) { volume_int = pos.availablePosition; } string result = MyNetworkApi::sell(code.ToStdString(), priceType, volume_int); auto doc = JsonUtil::parseUTF16(result); if (doc.IsObject()) { if (doc[L"code"].GetInt() == 0) { auto data = doc[L"data"].GetObject(); if (data.HasMember(L"orderStatus") && data[L"orderStatus"].GetInt() == -1) { showMsg(data[L"orderStatusMsg"].GetString(), MSG_TYPE_ERROR); } else { showMsg("Âô³ö³É¹¦", MSG_TYPE_INFO); requestPositions(); } } else { showMsg(doc[L"msg"].GetString(), MSG_TYPE_ERROR); } } else { showMsg("ÍøÂçÇëÇó³ö´í", MSG_TYPE_ERROR); } } void MainFrame::OnPositionSelectionChanged(wxDataViewEvent& event) { auto item = viewManager->positionWidgets->listCtrlReport->GetSelection(); int rowIndex = viewManager->positionWidgets->listCtrlReport->ItemToRow(item); std::list::iterator e = positionList.begin(); if (rowIndex > 0) { std::advance(e, rowIndex); } if (rowIndex >= 0) { PositionInfo p = *e; selectPositionId = p.id; // ÉèÖÃÄÚÈÝ this->viewManager->topWidgets->codeEdit->SetValue(p.securityID); this->viewManager->tickWidgets->tickChart->Init(CodeBasicInfo({ p.securityID ,p.marketInfo.name,p.marketInfo.preClosePrice }), CodeBasicInfo({ p.underlyingMarketInfo.code ,p.underlyingMarketInfo.name,p.underlyingMarketInfo.preClosePrice }), this, MainFrame::OnTickCallBack); float costRate = DataParseUtil::computeCostRate(p); this->viewManager->tickWidgets->tickChart->SetCostRate(p.securityID, costRate, ""); for (std::list::iterator e = p.buyList.begin(); e != p.buyList.end(); ++e) { DealInfo info = *e; double price = stod(info.price.ToStdString().c_str()); double rate = (price - p.marketInfo.preClosePrice) * 100 / p.marketInfo.preClosePrice; this->viewManager->tickWidgets->tickChart->AddBuyPoint(info.tradeTime, rate, info.price.ToStdString(), info.volume, StringUtil::to_string(info.volume * stod(info.price.ToStdString().c_str())), info.type); } for (std::list::iterator e = p.sellList.begin(); e != p.sellList.end(); ++e) { DealInfo info = *e; double price = stod(info.price.ToStdString().c_str()); double rate = (price - p.marketInfo.preClosePrice) * 100 / p.marketInfo.preClosePrice; this->viewManager->tickWidgets->tickChart->AddSellPoint(info.tradeTime, rate, info.price.ToStdString(), info.volume, StringUtil::to_string(info.volume * stod(info.price.ToStdString().c_str()))); } wxRichTextAttr style; wxRichTextCtrl* richText = this->viewManager->topWidgets->codeInfoLabel; richText->GetBuffer().Clear(); richText->Clear(); //ÉèÖÃÖµ wxString codeInfoStr = ""; codeInfoStr.Append(p.underlyingMarketInfo.code).Append("(").Append(p.underlyingMarketInfo.name).Append(")£¬"); richText->WriteText(codeInfoStr); codeInfoStr = ""; style.SetTextColour(*wxRED); richText->BeginStyle(style); richText->WriteText("¡¾ÕÇÍ£Ô­Òò£º"); richText->WriteText(p.underlyingDetailInfo.limitUpReason); codeInfoStr.Append("&°å¿éÉíλ£º"); int i = 0; for (std::list::iterator e = p.underlyingDetailInfo.blockInfos.begin(); e != p.underlyingDetailInfo.blockInfos.end(); ++e) { CodeBlockInfo info = *e; codeInfoStr.Append(info.name).Append("-").Append(to_string(info.rank)); i++; if (i != p.underlyingDetailInfo.blockInfos.size()) { codeInfoStr.Append("¡¢"); } } codeInfoStr.Append("¡¿"); richText->WriteText(codeInfoStr); richText->EndStyle(); style.SetTextColour(*wxBLACK); codeInfoStr = ""; codeInfoStr.Append("£¬°å¿é£º"); auto blocks = p.underlyingDetailInfo.blocks; i = 0; for (std::list::iterator e = blocks.begin(); e != blocks.end(); ++e) { codeInfoStr.Append(*e); i++; if (i != blocks.size()) { codeInfoStr.Append("/"); } } codeInfoStr.Append("£¬"); codeInfoStr.Append("ʱ¼ä£º").Append(p.underlyingDetailInfo.limit_up_time).Append("£¬"); codeInfoStr.Append("Êг¡Éíλ£º").Append(p.underlyingDetailInfo.highDesc).Append("£¬"); codeInfoStr.Append("°å¿éÊýÁ¿£º"); i = 0; for (std::list::iterator e = p.underlyingDetailInfo.blockInfos.begin(); e != p.underlyingDetailInfo.blockInfos.end(); ++e) { CodeBlockInfo info = *e; wxString s = "&"; codeInfoStr.Append(info.name).Append(s).Append(to_string(info.totalLimitUpCount)).Append(s).Append(to_string(info.openLimitUpCount)); i++; if (i != p.underlyingDetailInfo.blockInfos.size()) { codeInfoStr.Append("¡¢"); } } codeInfoStr.Append("£¬"); codeInfoStr.Append("ÊÐÖµ£º").Append(p.underlyingDetailInfo.zyltgb).Append("£¬"); codeInfoStr.Append("¹É¼Û£º").Append(p.underlyingDetailInfo.price).Append("£¬"); codeInfoStr.Append("´óµ¥³É½»£º").Append(p.underlyingDetailInfo.bigOrderDealMoney).Append("-").Append(to_string(p.underlyingDetailInfo.bigOrderDealCount)).Append("±Ê"); richText->WriteText(codeInfoStr); tickDataRequestStrategy->subscribeSymbol(JueJinDataUtil::getSymbol(p.securityID.ToStdString()), JueJinDataUtil::getSymbol(p.underlyingMarketInfo.code.ToStdString())); // »ñÈ¡ÉèÖõÄÂô³ö½ð¶î int sellMoney = MyConfigUtil::getSellMoney(p.securityID.ToStdString()); viewManager->sellWidgets->sellMoney->SetLabelText(to_wstring(sellMoney)); } else { selectPositionId = ""; } cout << "Ñ¡ÖеÄÐУº" << rowIndex << endl; event.Skip(); //event.Veto(); } void MainFrame::OnBtnBackTest(wxCommandEvent& event) { wxString date = viewManager->topWidgets->backTestDate->GetValue(); wxString btnValue = viewManager->topWidgets->btnBackTest->GetLabelText(); try { if (btnValue.StartsWith("¿ªÊ¼")) { string result = MyNetworkApi::set_backtest_mode(date.ToStdString(), true); auto doc = JsonUtil::parseUTF16(result); if (!doc.IsObject()) { throw wxString("ÍøÂçÇëÇó³ö´í"); } if (doc[L"code"].GetInt() != 0) { throw wxString(doc[L"msg"].GetString()); } viewManager->topWidgets->btnBackTest->SetLabelText("½áÊø»Ø²â"); } else { string result = MyNetworkApi::set_backtest_mode(date.ToStdString(), false); auto doc = JsonUtil::parseUTF16(result); if (!doc.IsObject()) { throw wxString("ÍøÂçÇëÇó³ö´í"); } if (doc[L"code"].GetInt() != 0) { throw wxString(doc[L"msg"].GetString()); } viewManager->topWidgets->btnBackTest->SetLabelText("¿ªÊ¼»Ø²â"); } } catch (wxString st) { wxMessageBox(st); } catch (...) { wxMessageBox(L"ÍøÂçÇëÇó³ö´í"); } }