#include "MainFrame.h"
|
|
#include <wx/frame.h>
|
#include <wx/panel.h>
|
#include <wx/sizer.h>
|
#include <string.h>
|
#include "MyNetworkApi.h"
|
#include <thread>
|
#include "DataParseUtil.h"
|
#include "../common_nopch/StringUtil.h"
|
#include "../common_nopch/TimeUtil.h"
|
#include "MyConfigUtil.h"
|
#include "TickFrame.h"
|
#include <wx/app.h>
|
#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<wxTextCtrl*>(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<wxButton*>::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<PositionInfo>::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<PositionInfo> 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<PositionInfo>::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<PositionInfo>::iterator e = positionList.begin(); e != positionList.end(); ++e) {
|
PositionInfo p = *e;
|
//{ "Ãû³Æ", "ÕÇ·ù", "ÏÖ¼Û", "L1ÏÖÊÖ", "Ê£Óà³Ö²Ö", "³Ö²Ö½ð¶î", "Ó¯¿÷", "Ó¯¿÷±È", "Õý¹ÉÃû³Æ", "¸ü¶à" };
|
wxVector<wxVariant> data;
|
bool hasPosition = p.currentPosition > 0;
|
wxColor color = !hasPosition ? COLOR_INVALID : COLOR_VALID;
|
map<int, wxVariant> 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<DealInfo>::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<DealInfo>::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<TickTradeData> tradePoints;
|
for (std::list<DealInfo>::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<DealInfo>::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<TickTradeData> buyPoints, std::list<TickTradeData> 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<const char*>(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<int> 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<PositionInfo>::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<PositionInfo>::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<Quote> 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<PositionInfo>::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<PositionInfo>::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<DealInfo>::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<DealInfo>::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<CodeBlockInfo>::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<wxString>::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<CodeBlockInfo>::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"ÍøÂçÇëÇó³ö´í");
|
}
|
|
|
|
}
|