| | |
| | | </Link> |
| | | </ItemDefinitionGroup> |
| | | <ItemGroup> |
| | | <ClCompile Include="CurrentPriceCapture.cpp" /> |
| | | <ClCompile Include="TaskChecker.cpp" /> |
| | | <ClCompile Include="THSGPDataCapture.cpp" /> |
| | | <ClCompile Include="THSL2RepairTool.cpp" /> |
| | | <ClCompile Include="TradeQueueCapture.cpp" /> |
| | | <ClCompile Include="TradeListCapture.cpp" /> |
| | | <ClCompile Include="CaptureUtil.cpp" /> |
| | |
| | | <ClCompile Include="win32_screen_shots.cpp" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClInclude Include="CurrentPriceCapture.h" /> |
| | | <ClInclude Include="TaskChecker.h" /> |
| | | <ClInclude Include="THSGPDataCapture.h" /> |
| | | <ClInclude Include="THSL2RepairTool.h" /> |
| | | <ClInclude Include="TradeQueueCapture.h" /> |
| | | <ClInclude Include="TradeListCapture.h" /> |
| | | <ClInclude Include="CaptureUtil.h" /> |
| | |
| | | <ClCompile Include="THSGPDataCapture.cpp"> |
| | | <Filter>源文件</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="TaskChecker.cpp"> |
| | | <Filter>源文件</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="CurrentPriceCapture.cpp"> |
| | | <Filter>源文件</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="THSL2RepairTool.cpp"> |
| | | <Filter>源文件</Filter> |
| | | </ClCompile> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClInclude Include="resource.h"> |
| | |
| | | <ClInclude Include="THSGPDataCapture.h"> |
| | | <Filter>头文件</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="TaskChecker.h"> |
| | | <Filter>头文件</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="CurrentPriceCapture.h"> |
| | | <Filter>头文件</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="THSL2RepairTool.h"> |
| | | <Filter>头文件</Filter> |
| | | </ClInclude> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="ConsoleApplication.rc"> |
New file |
| | |
| | | #include "CurrentPriceCapture.h" |
| | | #include "THSActionUtil.h" |
| | | #include <set> |
| | | #include "Win32Util.h" |
| | | #include "TaskChecker.h" |
| | | OpenCLExcuter* CurrentPriceCapture::openCLExcuter; |
| | | bool CurrentPriceCapture::inited; |
| | | //是否正在执行 |
| | | bool CurrentPriceCapture::running; |
| | | |
| | | bool CurrentPriceCapture::kill; |
| | | |
| | | CallbackFun_Current_Price CurrentPriceCapture::data_callback; |
| | | |
| | | std::list<cv::Point> CurrentPriceCapture::pointList; |
| | | |
| | | void* CurrentPriceCapture::context; |
| | | |
| | | HWND CurrentPriceCapture::win; |
| | | |
| | | |
| | | |
| | | |
| | | RecognitionManager* CurrentPriceCapture::recognitionManager; |
| | | |
| | | |
| | | void CurrentPriceCapture::_run() { |
| | | while (true) { |
| | | if (kill) |
| | | break; |
| | | TaskChecker::clientLiveTime.limitUp = clock(); |
| | | if (running && inited) { |
| | | clock_t start = clock(); |
| | | try { |
| | | cout << "现价识别" << endl; |
| | | list<CurrentPriceData> codes = capture(); |
| | | cout << "现价识别耗时:" << clock() - start << " 数量:" << codes.size() << endl; |
| | | data_callback(codes, context); |
| | | codes.clear(); |
| | | } |
| | | catch (...) { |
| | | cout<<"现价识别error"<<endl; |
| | | } |
| | | Sleep(10); |
| | | } |
| | | else { |
| | | Sleep(1000); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | void CurrentPriceCapture::init(CallbackFun_Current_Price callback, void* contex) { |
| | | data_callback = callback; |
| | | context = contex; |
| | | running = false; |
| | | kill = false; |
| | | recognitionManager = new RecognitionManager(); |
| | | openCLExcuter = new OpenCLExcuter(); |
| | | openCLExcuter->init(); |
| | | thread rt(&(CurrentPriceCapture::_run)); |
| | | rt.detach(); |
| | | inited = true; |
| | | refreshHWND(); |
| | | } |
| | | void CurrentPriceCapture::reCreateRunning() |
| | | { |
| | | kill = TRUE; |
| | | Sleep(4000); |
| | | kill = FALSE; |
| | | thread rt(&(CurrentPriceCapture::_run)); |
| | | rt.detach(); |
| | | } |
| | | void CurrentPriceCapture::refreshHWND() { |
| | | HWND hwnd = THSActionUtil::getMainWin(); |
| | | if (hwnd <= 0) |
| | | throw string("同花顺主屏未打开"); |
| | | |
| | | //采用快捷键打开 |
| | | Win32Util::focus(hwnd); |
| | | //Win32Util::keyboardNum("51", 200); |
| | | //Win32Util::keyboard(VK_RETURN, 10); |
| | | Sleep(1000); |
| | | |
| | | |
| | | HWND content = FindWindowExA(hwnd, NULL, "AfxFrameOrView100s", NULL); |
| | | |
| | | if (content <= 0) |
| | | throw string("未获取到内容窗口句柄"); |
| | | |
| | | win = content; |
| | | } |
| | | |
| | | bool CurrentPriceCapture::isRunning() { |
| | | return running; |
| | | } |
| | | |
| | | list<CurrentPriceData> CurrentPriceCapture::capture(cv::Mat oimg) { |
| | | cv::Mat grayImg = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);//ImgUtil::grayImage(oimg); |
| | | |
| | | uchar* imgData = (uchar*)malloc(sizeof(uchar) * oimg.rows * oimg.cols); |
| | | if (oimg.channels() == 3) |
| | | { |
| | | openCLExcuter->rgb2Gray(oimg.data, oimg.cols, oimg.rows, imgData); |
| | | } |
| | | else { |
| | | openCLExcuter->rgba2Gray(oimg.data, oimg.cols, oimg.rows, imgData); |
| | | } |
| | | grayImg.data = imgData; |
| | | |
| | | |
| | | |
| | | list<int*> rowData = THSActionUtil::splitPlateRowArea(grayImg); |
| | | |
| | | //每行的元素个数 |
| | | int ele_count_per_line = 2; |
| | | int* splitResult = (int*)malloc(sizeof(int) * 4 * 4 * rowData.size()); |
| | | int* rowIndex = (int*)malloc(sizeof(int) * 4 * rowData.size()); |
| | | int count = 0; |
| | | for (std::list<int*>::iterator ele = rowData.begin();ele != rowData.end();ele++) { |
| | | string path = "C:\\Users\\Administrator\\Desktop\\ocr\\limit_up\\"; |
| | | path.append(to_string(count)).append(".jpg"); |
| | | //cv::imwrite(path, cv::Mat(grayImg, cv::Rect((*ele)[0], (*ele)[1], (*ele)[2] - (*ele)[0] + 1, (*ele)[3] - (*ele)[1] + 1))); |
| | | |
| | | rowIndex[4 * count + 0] = (*ele)[0]; |
| | | rowIndex[4 * count + 1] = (*ele)[1]; |
| | | rowIndex[4 * count + 2] = (*ele)[2]; |
| | | rowIndex[4 * count + 3] = (*ele)[3]; |
| | | free(*ele); |
| | | count++; |
| | | } |
| | | |
| | | int line_number_count = ele_count_per_line * 6; |
| | | |
| | | openCLExcuter->splitPlateContentRowData(grayImg.data, grayImg.cols, grayImg.rows, rowIndex, rowData.size(), ele_count_per_line,1,2,splitResult); |
| | | |
| | | /* |
| | | *测试 |
| | | for (int i = 0;i < rowData.size();i++) { |
| | | for (int j = 0;j < line_number_count;j++) { |
| | | int sx = splitResult[(line_number_count * i + j) * 4 + 0]; |
| | | int sy = splitResult[(line_number_count * i + j) * 4 + 1]; |
| | | int ex = splitResult[(line_number_count * i + j) * 4 + 2]; |
| | | int ey = splitResult[(line_number_count * i + j) * 4 + 3]; |
| | | string path = "C:\\Users\\Administrator\\Desktop\\ocr\\limit_up\\"; |
| | | path.append(to_string(i)).append("_").append(to_string(j)).append(".jpg"); |
| | | //cv::imwrite(path, cv::Mat(grayImg, cv::Rect(sx, sy, ex - sx + 1, ey - sy + 1))); |
| | | } |
| | | } |
| | | */ |
| | | |
| | | |
| | | |
| | | int start = 4 * 4 * 1 + 4 * 1; |
| | | |
| | | string path = "C:\\Users\\Administrator\\Desktop\\ocr\\limit_up\\"; |
| | | path.append(to_string(start)).append(".jpg"); |
| | | |
| | | //cv::imwrite(path, cv::Mat(grayImg,cv::Rect(splitResult[start], splitResult[start+1], splitResult[start+2]- splitResult[start]+1, splitResult[start+3]- splitResult[start+1]+1))); |
| | | |
| | | //cv::imwrite(path, cv::Mat(grayImg, cv::Rect(447, 102, 454-447+1,111-102+1 ))); |
| | | |
| | | //分割数字 |
| | | unsigned char* zeroData = (unsigned char*)malloc(sizeof(unsigned char) * _NUMBER_GP_CODE_WIDTH * _NUMBER_GP_CODE_HEIGHT); |
| | | for (int r = 0;r < _NUMBER_GP_CODE_HEIGHT;r++) { |
| | | for (int c = 0;c < _NUMBER_GP_CODE_WIDTH;c++) |
| | | { |
| | | zeroData[r * _NUMBER_GP_CODE_WIDTH + c] = ImgUtil::NUMS_GP_CODE[0].data.ptr<uchar>(r)[c]; |
| | | } |
| | | } |
| | | unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * rowData.size()) * _NUMBER_GP_CODE_WIDTH * 10 * line_number_count); |
| | | |
| | | |
| | | UcharDataInfo typesData = UcharDataInfo(); |
| | | unsigned char types[] = { NUM_TYPE_CODE, NUM_TYPE_PRICE }; |
| | | typesData.length = 2; |
| | | typesData.data = types; |
| | | int length_per_num = 6; |
| | | openCLExcuter->splitPlateNum(grayImg, IntDataInfo({ splitResult,(int)(ele_count_per_line * rowData.size()) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, ele_count_per_line, length_per_num); |
| | | |
| | | |
| | | |
| | | |
| | | //识别数字 |
| | | uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * rowData.size()) * _NUMBER_GP_CODE_WIDTH * 10 * line_number_count); |
| | | openCLExcuter->createNumberTemplates(rowData.size(), _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, line_number_count, ImgUtil::numsOneLevel_gpcode, templateNums); |
| | | uchar** numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, rowData.size() * _NUMBER_GP_CODE_HEIGHT, _NUMBER_GP_CODE_WIDTH * 10 * line_number_count, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, line_number_count); |
| | | |
| | | list<CurrentPriceData> dataList; |
| | | for (int i = 0;i < rowData.size();i++) { |
| | | CurrentPriceData currentData = CurrentPriceData(); |
| | | string code = ""; |
| | | for (int j = 0;j < 6;j++) |
| | | { |
| | | code.append(to_string(numberResult[i][j])); |
| | | } |
| | | |
| | | string price = ""; |
| | | for (int j = 0;j < 6;j++) |
| | | { |
| | | if (j == 4) { |
| | | price.append("."); |
| | | } |
| | | price.append(to_string(numberResult[i][6 * 1 + j])); |
| | | } |
| | | |
| | | currentData.index = i; |
| | | currentData.code = code; |
| | | |
| | | currentData.price = price; |
| | | if ( currentData.price != "0000.00") { |
| | | dataList.push_back(currentData); |
| | | } |
| | | free(numberResult[i]); |
| | | } |
| | | free(numberResult); |
| | | int* unitData = (int*)malloc(sizeof(int) * 4 * dataList.size()); |
| | | |
| | | free(rowIndex); |
| | | free(splitResult); |
| | | free(zeroData); |
| | | free(templateNums); |
| | | free(unitData); |
| | | free(imgData); |
| | | |
| | | grayImg.release(); |
| | | return dataList; |
| | | } |
| | | |
| | | list<CurrentPriceData> CurrentPriceCapture::capture() { |
| | | |
| | | if (win <= 0) { |
| | | throw string("未找到目标标的窗口"); |
| | | } |
| | | |
| | | cout << "开始运行" << endl; |
| | | RECT wrect; |
| | | GetWindowRect(win,&wrect); |
| | | list<CurrentPriceData> flist; |
| | | set<string> codesSet; |
| | | for (int i = 0;i < 3;i++) |
| | | { |
| | | if (kill) { |
| | | break; |
| | | } |
| | | int x = wrect.right - 50; |
| | | int y = wrect.top + 50; |
| | | SendMessage(win, WM_MOUSEWHEEL, 0, MAKEWORD(x, y)); |
| | | Sleep(100); |
| | | cv::Mat oimg = CaptureUtil::capture(win); |
| | | list<CurrentPriceData> codes = capture(oimg); |
| | | for (list<CurrentPriceData>::iterator ele = codes.begin();ele != codes.end();ele++) { |
| | | string code = (*ele).code; |
| | | if (codesSet.count(code) == 0&&stof((*ele).price)>0) { |
| | | codesSet.insert(code); |
| | | flist.push_back(*ele); |
| | | } |
| | | } |
| | | codes.clear(); |
| | | Sleep(50); |
| | | } |
| | | |
| | | |
| | | |
| | | return flist; |
| | | |
| | | } |
| | | |
| | | //全部开始 |
| | | void CurrentPriceCapture::start() { |
| | | running = true; |
| | | } |
| | | //全部结束 |
| | | void CurrentPriceCapture::stop() { |
| | | running = false; |
| | | } |
| | | bool CurrentPriceCapture::isInited() { |
| | | return inited; |
| | | } |
New file |
| | |
| | | #pragma once |
| | | #include <string> |
| | | #include <iostream> |
| | | #include <list> |
| | | #include "ImgUtil.h" |
| | | #include "RecognitionManager.h" |
| | | #include "THSActionUtil.h" |
| | | //现价 |
| | | struct CurrentPriceData |
| | | { |
| | | string code; |
| | | string price; |
| | | //辅助功能 |
| | | int index; |
| | | }; |
| | | |
| | | //涨停获取 |
| | | typedef void (*CallbackFun_Current_Price)(list<CurrentPriceData> codeList, void* contex); |
| | | |
| | | |
| | | class CurrentPriceCapture |
| | | { |
| | | private: |
| | | static OpenCLExcuter* openCLExcuter; |
| | | static RecognitionManager* recognitionManager; |
| | | static bool inited; |
| | | //是否正在执行 |
| | | static bool running; |
| | | |
| | | static bool kill; |
| | | |
| | | static CallbackFun_Current_Price data_callback; |
| | | |
| | | static void* context; |
| | | |
| | | static void _run(); |
| | | |
| | | static HWND win; |
| | | |
| | | static HWND menuWin; |
| | | |
| | | static std::list<cv::Point> pointList; |
| | | |
| | | |
| | | public: |
| | | void init(CallbackFun_Current_Price callback, void* context); |
| | | |
| | | //重新创建运行线程 |
| | | void reCreateRunning(); |
| | | |
| | | void refreshHWND(); |
| | | |
| | | bool isRunning(); |
| | | |
| | | static list<CurrentPriceData> capture(cv::Mat img); |
| | | |
| | | static list<CurrentPriceData> capture(); |
| | | |
| | | //全部开始 |
| | | void start(); |
| | | //全部结束 |
| | | void stop(); |
| | | bool isInited(); |
| | | }; |
| | | |
| | |
| | | #include<fstream> |
| | | #include "THSActionUtil.h" |
| | | #include <thread> |
| | | #include "TaskChecker.h" |
| | | bool L2DataCapture::inited; |
| | | bool L2DataCapture::tradeTimeCapture; |
| | | |
| | |
| | | //是否正在执行 |
| | | bool L2DataCapture::running; |
| | | bool L2DataCapture::runnings[THS_FRAME_COUNT]; |
| | | bool L2DataCapture::killRunnings[THS_FRAME_COUNT]; |
| | | clock_t L2DataCapture::latest_running_times[THS_FRAME_COUNT]; |
| | | |
| | | CallbackFun L2DataCapture::data_callback; |
| | |
| | | void L2DataCapture::_run(int index) |
| | | { |
| | | while (true) { |
| | | |
| | | if (killRunnings[index]) |
| | | break; |
| | | TaskChecker::clientLiveTime.l2[index] = clock(); |
| | | if (tradeTimeCapture) { |
| | | int time = getNowSecondTime(); |
| | | //9:20-11:31 12:59-15:01 |
| | |
| | | tradeQueueCapture[i] = new TradeQueueCapture(); |
| | | } |
| | | |
| | | |
| | | running = false; |
| | | int length = sizeof(runnings) / sizeof(runnings[0]); |
| | | for (int i = 0;i < length;i++) { |
| | | runnings[i] = false; |
| | | thread rt(&(L2DataCapture::_run), i); |
| | | rt.detach(); |
| | | killRunnings[i] = FALSE; |
| | | //thread rt_trade_queue(&(L2DataCapture::_run_trade_queue), i); |
| | | //rt_trade_queue.detach(); |
| | | } |
| | | |
| | | //获取同花顺窗口句柄 |
| | | try { |
| | |
| | | catch (string st) { |
| | | throw st; |
| | | } |
| | | running = false; |
| | | int length = sizeof(runnings) / sizeof(runnings[0]); |
| | | for (int i = 0;i < length;i++) { |
| | | runnings[i] = false; |
| | | thread rt(&(L2DataCapture::_run), i); |
| | | rt.detach(); |
| | | |
| | | //thread rt_trade_queue(&(L2DataCapture::_run_trade_queue), i); |
| | | //rt_trade_queue.detach(); |
| | | } |
| | | |
| | | void L2DataCapture::reCreateChannelRunner(int index) |
| | | { |
| | | //先杀死原有线程 |
| | | killRunnings[index] = TRUE; |
| | | Sleep(500); |
| | | killRunnings[index] = FALSE; |
| | | |
| | | thread rt(&(L2DataCapture::_run), index); |
| | | rt.detach(); |
| | | } |
| | | |
| | | bool L2DataCapture::isRunning() { |
| | |
| | | |
| | | clock_t starttime = clock(); |
| | | |
| | | /* |
| | | if (1 > 0) { |
| | | std:map<string, TradeData> map; |
| | | return map; |
| | | } |
| | | */ |
| | | list<TradeData> resultList= captureLevel2TradeData(openCLExcuter[identify], oimg, identify); |
| | | |
| | | std::cout << "-------L2行情识别结束任务: threadid-" << std::this_thread::get_id() << " 序号:" << identify << " 耗时:" << clock() - starttime <<" 数据量:"<< resultList.size() << endl; |
| | | |
| | | return resultList; |
| | | } |
| | | |
| | | list<TradeData> L2DataCapture::captureLevel2TradeData(OpenCLExcuter* openCLExcuter, cv::Mat oimg, int identify) |
| | | { |
| | | |
| | | //LogUtil::debug("截图完成"); |
| | | clock_t time_1 = clock(); |
| | |
| | | else { |
| | | if (oimg.channels() == 3) |
| | | { |
| | | openCLExcuter[identify]->rgb2Gray(oimg.data, oimg.cols, oimg.rows, imgData); |
| | | openCLExcuter->rgb2Gray(oimg.data, oimg.cols, oimg.rows, imgData); |
| | | } |
| | | else { |
| | | openCLExcuter[identify]->rgba2Gray(oimg.data, oimg.cols, oimg.rows, imgData); |
| | | openCLExcuter->rgba2Gray(oimg.data, oimg.cols, oimg.rows, imgData); |
| | | } |
| | | img.data = imgData; |
| | | oimg.release(); |
| | | clock_t time_2_ = clock(); |
| | | if (identify == 0) |
| | | { |
| | | std::cout << "灰度完成: threadid-" << std::this_thread::get_id() << " 耗时:" << (time_2_ - time_1) << endl; |
| | | std::cout << "灰度完成: threadid-" << std::this_thread::get_id() << " 耗时:" << (time_2_ - time_1) << " 截图尺寸:" << img.cols << "x" << img.rows << endl; |
| | | |
| | | std::cout <<"通道数:"<<oimg.channels()<<endl; |
| | | |
| | |
| | | } |
| | | //一维分块图像数据 |
| | | int* rowSplitDataOneLevel = (int*)malloc(sizeof(int) * rowDataList.size() * 4 * 7); |
| | | openCLExcuter[identify]->splitL2RowData(imgData, img.cols, img.rows, rowDataOneLevel, rowDataList.size(), rowSplitDataOneLevel); |
| | | openCLExcuter->splitL2RowData(imgData, img.cols, img.rows, rowDataOneLevel, rowDataList.size(), rowSplitDataOneLevel); |
| | | free(rowDataOneLevel); |
| | | |
| | | /* |
| | |
| | | //图像识别(除开数字的部分) |
| | | |
| | | int* notNumberResult = (int*)malloc(sizeof(int) * rowDataList.size() * 3); |
| | | openCLExcuter[identify]->recognitionNotNum(img.data, img.cols, img.rows, rowSplitDataOneLevel, 7, rowDataList.size(), notNumberResult); |
| | | openCLExcuter->recognitionNotNum(img.data, img.cols, img.rows, rowSplitDataOneLevel, 7, rowDataList.size(), notNumberResult); |
| | | |
| | | |
| | | int i = 0; |
| | |
| | | if (identify == 0) |
| | | std::cout << "数据准备-0数据准备: threadid-" << std::this_thread::get_id() << " 耗时:" << time_33 - time_32 << "总耗时:" << time_33 - time_1 << endl; |
| | | |
| | | openCLExcuter[identify]->splitL2Num(imgData, img.cols, img.rows, pos, 4 * rowDataList.size(), zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER, totalNumberData); |
| | | openCLExcuter->splitL2Num(imgData, img.cols, img.rows, pos, 4 * rowDataList.size(), zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER, totalNumberData); |
| | | free(zeroData); |
| | | free(pos); |
| | | |
| | |
| | | //准备模板数字 |
| | | uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowDataList.size()) * _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER); |
| | | |
| | | openCLExcuter[identify]->createNumberTemplates(rowDataList.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER, ImgUtil::numsOneLevel_level2, templateNums); |
| | | openCLExcuter->createNumberTemplates(rowDataList.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER, ImgUtil::numsOneLevel_level2, templateNums); |
| | | |
| | | //ImgUtil::createTemplateNumData(data.size()); |
| | | clock_t time_4 = clock(); |
| | |
| | | |
| | | |
| | | //数字识别 |
| | | uchar** numberResult = openCLExcuter[identify]->recognition_numbers(totalNumberData, templateNums, rowDataList.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER); |
| | | uchar** numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, rowDataList.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER); |
| | | //释放内存 |
| | | free(totalNumberData); |
| | | free(templateNums); |
| | |
| | | rowDataList.clear(); |
| | | list<int*>().swap(rowDataList); |
| | | free(rowSplitDataOneLevel); |
| | | |
| | | if (identify == 0) |
| | | std::cout << "-------L2行情识别结束任务: threadid-" << std::this_thread::get_id() << " 序号:" << identify << " 耗时:" << clock() - starttime << endl; |
| | | |
| | | return resultList; |
| | | } |
| | | |
| | |
| | | //是否正在执行 |
| | | static bool running; |
| | | static bool runnings[THS_FRAME_COUNT]; |
| | | static bool killRunnings[THS_FRAME_COUNT]; |
| | | static clock_t latest_running_times[THS_FRAME_COUNT]; |
| | | |
| | | static string gpCodes[THS_FRAME_COUNT]; |
| | |
| | | |
| | | //初始化 |
| | | void init(CallbackFun callback, CallbackFun_Trade_Queue trade_queue_callback, void* context); |
| | | |
| | | void reCreateChannelRunner(int index); |
| | | |
| | | void refreshHWND(); |
| | | |
| | |
| | | //捕获level2的盘口数据 |
| | | static list<TradeData> captureLevel2TradeData(HWND hwnd,int index) throw(int); |
| | | static list<TradeData> captureLevel2TradeData(cv::Mat oimg,int identify); |
| | | static list<TradeData> captureLevel2TradeData(OpenCLExcuter *openCLExcuter, cv::Mat oimg, int identify); |
| | | //设置代码 |
| | | static void setGPCode(int index, string code); |
| | | //获取代码 |
| | |
| | | #include "THSActionUtil.h" |
| | | #include <set> |
| | | #include "Win32Util.h" |
| | | #include "TaskChecker.h" |
| | | OpenCLExcuter* LimitUpCapture::openCLExcuter; |
| | | bool LimitUpCapture::inited; |
| | | //是否正在执行 |
| | | bool LimitUpCapture::running; |
| | | |
| | | bool LimitUpCapture::kill; |
| | | |
| | | CallbackFun_Limit_Up LimitUpCapture::data_callback; |
| | | |
| | |
| | | |
| | | void LimitUpCapture::_run() { |
| | | while (true) { |
| | | if (kill) |
| | | break; |
| | | TaskChecker::clientLiveTime.limitUp = clock(); |
| | | if (running && inited) { |
| | | clock_t start = clock(); |
| | | list<LimitUpData> codes = captureLimitUpCodes(); |
| | |
| | | data_callback(codes, context); |
| | | codes.clear(); |
| | | Sleep(3000); |
| | | } |
| | | else { |
| | | Sleep(1000); |
| | | } |
| | | } |
| | | } |
| | |
| | | data_callback = callback; |
| | | context = contex; |
| | | running = false; |
| | | kill = false; |
| | | recognitionManager = new RecognitionManager(); |
| | | openCLExcuter = new OpenCLExcuter(); |
| | | openCLExcuter->init(); |
| | |
| | | rt.detach(); |
| | | inited = true; |
| | | refreshHWND(); |
| | | } |
| | | void LimitUpCapture::reCreateRunning() |
| | | { |
| | | kill = TRUE; |
| | | Sleep(4000); |
| | | kill = FALSE; |
| | | thread rt(&(LimitUpCapture::_run)); |
| | | rt.detach(); |
| | | } |
| | | void LimitUpCapture::refreshHWND() { |
| | | HWND hwnd = getWindow(); |
| | |
| | | int* rowIndex = (int*)malloc(sizeof(int) * 4 * rowData.size()); |
| | | int count = 0; |
| | | for (std::list<int*>::iterator ele = rowData.begin();ele != rowData.end();ele++) { |
| | | |
| | | string path = "C:\\Users\\Administrator\\Desktop\\ocr\\limit_up\\"; |
| | | path.append(to_string(count)).append(".jpg"); |
| | | //cv::imwrite(path, cv::Mat(grayImg, cv::Rect((*ele)[0], (*ele)[1], (*ele)[2] - (*ele)[0] + 1, (*ele)[3] - (*ele)[1] + 1))); |
| | |
| | | |
| | | list<cv::Point>::iterator ele; |
| | | for (ele = pointList.begin();ele != pointList.end();ele++) { |
| | | if (kill) { |
| | | break; |
| | | } |
| | | int x = (*ele).x;//+ menuRect.left; |
| | | int y = (*ele).y;//+ menuRect.top; |
| | | printf("x:%d y:%d\n", x, y); |
| | |
| | | |
| | | for (int i = 0;i < 3;i++) |
| | | { |
| | | if (kill) { |
| | | break; |
| | | } |
| | | int x = wrect.right - 50; |
| | | int y = wrect.top + 50; |
| | | SendMessage(win, WM_MOUSEWHEEL, 0, MAKEWORD(x, y)); |
| | |
| | | //是否正在执行 |
| | | static bool running; |
| | | |
| | | static bool kill; |
| | | |
| | | static CallbackFun_Limit_Up data_callback; |
| | | |
| | | static void* context; |
| | |
| | | |
| | | public: |
| | | void init(CallbackFun_Limit_Up callback, void* context); |
| | | |
| | | //重新创建运行线程 |
| | | void reCreateRunning(); |
| | | |
| | | void refreshHWND(); |
| | | |
| | | bool isRunning(); |
| | |
| | | #include "THSActionUtil.h" |
| | | #include "ImgDivider.h" |
| | | #include "Win32Util.h" |
| | | #include <fstream> |
| | | |
| | | |
| | | bool isL2Screen(string str) { |
| | | if (str.find("同花顺(") != string::npos) { |
| | |
| | | std::string path = "C:\\Users\\Administrator\\Desktop\\ocr\\gpcode\\"; |
| | | path.append(std::to_string(rand())).append("_listen.jpg"); |
| | | imwrite(path, img); |
| | | throw string("代码数字分隔出错"); |
| | | throw string("代码数字分隔出错(32)"); |
| | | } |
| | | return nums; |
| | | } |
| | |
| | | } |
| | | |
| | | if (!zp) { |
| | | throw string("同花顺主屏L2窗口未打开"); |
| | | throw string("同花顺主屏L2窗口未打开(01)"); |
| | | } |
| | | |
| | | |
| | | if (!fp) { |
| | | throw string("同花顺副屏1没有打开"); |
| | | throw string("同花顺副屏1没有打开(02)"); |
| | | } |
| | | |
| | | if (!fp2) { |
| | | throw string("同花顺副屏2没有打开"); |
| | | throw string("同花顺副屏2没有打开(03)"); |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | void THSActionUtil::openL2Screen() { |
| | | |
| | | |
| | | HWND l2 = getL2Win(); |
| | | if (l2 <= 0) { |
| | | //尝试打开主屏 |
| | | HWND main = THSActionUtil::getMainWin(); |
| | | if (main > 0) |
| | | { |
| | | Win32Util::focus(main); |
| | | Win32Util::keyboardNum(".00", 200); |
| | | Win32Util::keyboard(13, 10); |
| | | Sleep(1000); |
| | | } |
| | | } |
| | | } |
| | | |
| | | void THSActionUtil::openSecondScreen() { |
| | |
| | | |
| | | if (!open) { |
| | | if (mainPage <= 0) { |
| | | throw string("未找到首页"); |
| | | throw string("未找到首页(04)"); |
| | | } |
| | | |
| | | Win32Util::focus(mainPage); |
| | |
| | | |
| | | if (!open) { |
| | | if (mainPage <= 0) { |
| | | throw string("未找到首页"); |
| | | throw string("未找到首页(05)"); |
| | | } |
| | | |
| | | Win32Util::focus(mainPage); |
| | |
| | | } |
| | | } |
| | | |
| | | void THSActionUtil::openTradeSuccessScreen() |
| | | { |
| | | HWND hwnd = getTradeSuccessWindow(); |
| | | if (hwnd <= 0) { |
| | | throw string("交易窗口未打开(06)"); |
| | | } |
| | | |
| | | hwnd = FindWindowExA(hwnd, NULL, "AfxMDIFrame140s", NULL); |
| | | hwnd = FindWindowExA(hwnd, NULL, "AfxWnd140s", NULL); |
| | | hwnd = FindWindowExA(hwnd, NULL, NULL, "HexinScrollWnd"); |
| | | hwnd = FindWindowExA(hwnd, NULL, NULL, "HexinScrollWnd2"); |
| | | hwnd = FindWindowExA(hwnd, NULL, "SysTreeView32", NULL); |
| | | if (hwnd <= 0) { |
| | | throw string("未找到交易窗口菜单(07)"); |
| | | } |
| | | //点击当日委托 |
| | | SendMessage(hwnd, WM_LBUTTONDOWN, 0x00000001, 0x00E70047); |
| | | SendMessage(hwnd, WM_LBUTTONUP, 0x00000000, 0x00E70047); |
| | | } |
| | | |
| | | |
| | | //添加股票 |
| | | bool THSActionUtil::setGP(std::string quickCode, list<std::string> codeList, RecognitionManager* recognitionManager) { |
| | |
| | | sw = getSecondWindow(); |
| | | } |
| | | if (sw <= 0) { |
| | | throw string("未打开副屏"); |
| | | throw string("未打开副屏(11)"); |
| | | } |
| | | |
| | | //打开板块 |
| | |
| | | cout << "副屏截图:" << oimg.rows << "-" << oimg.cols << endl; |
| | | |
| | | if (oimg.cols <= 0 || oimg.rows <= 0) { |
| | | throw string("板块截屏内容为空"); |
| | | throw string("板块截屏内容为空(12)"); |
| | | } |
| | | |
| | | cv::Mat img = ImgUtil::grayImage(oimg); |
| | |
| | | |
| | | oimg = CaptureUtil::capture(content); |
| | | if (oimg.cols <= 0 || oimg.rows <= 0) { |
| | | throw string("板块截屏内容为空"); |
| | | throw string("板块截屏内容为空(13)"); |
| | | } |
| | | img = ImgUtil::grayImage(oimg); |
| | | areaList = recognitionGPArea(img); |
| | |
| | | sw = getSecondWindow(); |
| | | } |
| | | if (sw <= 0) { |
| | | throw string("未打开副屏"); |
| | | throw string("未打开副屏(14)"); |
| | | } |
| | | |
| | | HWND content = FindWindowExA(sw, NULL, "AfxFrameOrView100s", NULL); |
| | | cv::Mat oimg = CaptureUtil::capture(content); |
| | | cv::Mat img = ImgUtil::grayImage(oimg); |
| | | if (img.cols <= 0 || img.rows <= 0) { |
| | | throw string("板块截屏内容为空"); |
| | | throw string("板块截屏内容为空(15)"); |
| | | } |
| | | std::list<GPCodeArea> areaList = recognitionGPArea(img); |
| | | for (std::list<GPCodeArea>::iterator ele = areaList.begin();ele != areaList.end();++ele) { |
| | |
| | | } |
| | | |
| | | if (contentStartRow < 0|| contentEndRow<0) { |
| | | throw string("起始行分隔出错"); |
| | | throw string("起始行分隔出错(16)"); |
| | | } |
| | | |
| | | //分隔列 |
| | |
| | | } |
| | | |
| | | if (startC < 0) { |
| | | throw string("内容框分隔出错"); |
| | | throw string("内容框分隔出错(17)"); |
| | | } |
| | | GPCodeArea area = GPCodeArea(); |
| | | area.startx = 0; |
| | |
| | | } |
| | | |
| | | if (contentStartRow < 0) { |
| | | throw string("起始行分隔出错"); |
| | | throw string("起始行分隔出错(18)"); |
| | | } |
| | | |
| | | //分隔列 |
| | |
| | | } |
| | | |
| | | if (startC < 0 || endC < 0) { |
| | | throw string("内容框分隔出错"); |
| | | throw string("内容框分隔出错(19)"); |
| | | } |
| | | |
| | | //再次分隔内容框,排除干扰 |
| | |
| | | } |
| | | |
| | | if (contentStartRow < 0) { |
| | | throw string("起始行分隔出错"); |
| | | throw string("起始行分隔出错(20)"); |
| | | } |
| | | |
| | | //分隔列 |
| | |
| | | } |
| | | |
| | | if (startC < 0 || endC < 0) { |
| | | throw string("内容框分隔出错"); |
| | | throw string("内容框分隔出错(21)"); |
| | | } |
| | | //cv::imshow("内容", cv::Mat(img, cv::Rect(startC, contentStartRow, endC - startC, rows - contentStartRow))); |
| | | |
| | |
| | | resultList = splitGPCodeArea(img, contentStartRow + 25, startC, rows, endC); |
| | | } |
| | | catch (...) { |
| | | throw string("分隔代码区域出错"); |
| | | throw string("分隔代码区域出错(22)"); |
| | | } |
| | | return resultList; |
| | | } |
| | |
| | | } |
| | | //contentStartRow < 0 || contentEndRow < 0 |
| | | if (contentStartRow < 0) { |
| | | throw string("起始行或结束行分隔出错"); |
| | | throw string("起始行或结束行分隔出错(23)"); |
| | | } |
| | | |
| | | contentEndRow = contentStartRow + 50; |
| | |
| | | } |
| | | //contentStartRow < 0 || contentEndRow < 0 |
| | | if (contentStartRow < 0) { |
| | | throw string("起始行或结束行分隔出错"); |
| | | throw string("起始行或结束行分隔出错(24)"); |
| | | } |
| | | |
| | | contentEndRow = contentStartRow + 50; |
| | |
| | | } |
| | | |
| | | |
| | | void THSActionUtil::betchAddGP(HWND addDialog, list<string> codeList) |
| | | { |
| | | //将代码写入txt文件 |
| | | string path = "D:\\gpcode\\gp.txt"; |
| | | ofstream ofs; |
| | | ofs.open(path, ios::trunc); |
| | | int index = 0; |
| | | for (list<string>::iterator ele = codeList.begin();ele != codeList.end();++ele) |
| | | { |
| | | index++; |
| | | ofs << *ele; |
| | | if (index < codeList.size()) |
| | | ofs << "\n"; |
| | | } |
| | | |
| | | Sleep(200); |
| | | addDialog = FindWindowExA(addDialog, NULL,"AfxWnd100s","CEFBrowser" ); |
| | | addDialog = FindWindowExA(addDialog, NULL, "CefBrowserWindow", NULL); |
| | | addDialog = FindWindowExA(addDialog, NULL, "Chrome_WidgetWin_0", NULL); |
| | | addDialog = FindWindowExA(addDialog, NULL, "Chrome_RenderWidgetHostHWND", NULL); |
| | | cout << "添加股票弹框:"<< addDialog << endl; |
| | | |
| | | |
| | | Win32Util::focus(addDialog); |
| | | //图片选择按钮 |
| | | SendMessage(addDialog, WM_LBUTTONDOWN, 0x00000001, 0x00370141); |
| | | SendMessage(addDialog, WM_LBUTTONUP, 0x00000000, 0x00370141); |
| | | Sleep(100); |
| | | //上传文件按钮 |
| | | SendMessage(addDialog, WM_LBUTTONDOWN, 0x00000001, 0x016000B1); |
| | | SendMessage(addDialog, WM_LBUTTONUP, 0x00000000, 0x016000B1); |
| | | |
| | | |
| | | HWND hwnd = HWND(0); |
| | | for (int i = 0;i < 10;i++) |
| | | { |
| | | HWND temp = FindWindowA("#32770", "打开"); |
| | | if (temp > 0) { |
| | | hwnd = temp; |
| | | break; |
| | | } |
| | | Sleep(1000); |
| | | } |
| | | |
| | | Win32Util::selectTexFileWin10(hwnd, "D:\\gpcode\\"); |
| | | Sleep(500); |
| | | Win32Util::focus(addDialog); |
| | | //点击添加全部按钮 |
| | | SendMessage(addDialog, WM_LBUTTONDOWN, 0x00000001, 0x00570139); |
| | | SendMessage(addDialog, WM_LBUTTONUP, 0x00000000, 0x00570139); |
| | | //关闭弹框 |
| | | HWND close = FindWindowA(0, "添加股票"); |
| | | SendMessage(close, WM_CLOSE, 0, 0); |
| | | } |
| | | |
| | | std::list<GPCodeArea> THSActionUtil::getListenL2GPAreaAndCode(RecognitionManager* recognitionManager) { |
| | | //截图当前有哪些股票代码 |
| | | list<HWND> wlist = Win32Util::searchWindow("同花顺("); |
| | |
| | | } |
| | | } |
| | | if (mainPage <= 0) { |
| | | throw string("L2监听未打开"); |
| | | throw string("L2监听未打开(25)"); |
| | | } |
| | | |
| | | HWND content = FindWindowExA(mainPage, NULL, "AfxFrameOrView100s", NULL); |
| | |
| | | |
| | | return fresultList; |
| | | |
| | | }void THSActionUtil::clearPlateCodes(HWND hwnd) |
| | | { |
| | | HWND content = FindWindowExA(hwnd, NULL, "AfxFrameOrView100s", NULL); |
| | | for (int i = 0;i < 15;i++) |
| | | { |
| | | //截图识别是否还有代码 |
| | | cv::Mat oimg = CaptureUtil::capture(content); |
| | | if (oimg.cols <= 0 || oimg.rows <= 0) { |
| | | throw string("板块截屏内容为空(26)"); |
| | | } |
| | | |
| | | cv::Mat img = ImgUtil::grayImage(oimg); |
| | | oimg.release(); |
| | | std::list<GPCodeArea> areaList = recognitionGPArea(img); |
| | | cout << "数据数量:" << areaList.size() << endl; |
| | | if (areaList.size() <= 2) { |
| | | //执行最后一次删除 |
| | | Win32Util::focus(hwnd); |
| | | Win32Util::keyboard(VK_DELETE, 30); |
| | | break; |
| | | } |
| | | //执行删除事件 |
| | | for (int j = 0;j < 20;j++) { |
| | | Win32Util::focus(hwnd); |
| | | Win32Util::keyboard(VK_DELETE, 30); |
| | | } |
| | | } |
| | | } |
| | | |
| | | RECT THSActionUtil::getPlateAddCodeBtnPostion(HWND win) |
| | | { |
| | | //获取添加按钮位置 |
| | | HWND content = FindWindowExA(win, NULL, "AfxFrameOrView100s", NULL); |
| | | RECT contentRect; |
| | | GetWindowRect(content, &contentRect); |
| | | |
| | | cv::Mat oimg = CaptureUtil::capture(content); |
| | | |
| | | if (oimg.cols <= 0 || oimg.rows <= 0) { |
| | | throw string("板块截屏内容为空(27)"); |
| | | } |
| | | |
| | | cv::Mat img = ImgUtil::grayImage(oimg); |
| | | oimg.release(); |
| | | std::list<GPCodeArea> areaList = recognitionGPArea(img); |
| | | for (std::list<GPCodeArea>::iterator ele = areaList.begin();ele != areaList.end();ele++) { |
| | | cout << "添加按钮位置:" << (*ele).startx << "," << (*ele).starty << "," << (*ele).endx << "," << (*ele).endy << endl; |
| | | if ((*ele).type == IMG_TYPE_ADD) { |
| | | RECT rect; |
| | | rect.left = contentRect.left + (*ele).startx; |
| | | rect.right = contentRect.left + (*ele).endx; |
| | | rect.top = contentRect.top + (*ele).starty; |
| | | rect.bottom = contentRect.top + (*ele).endy; |
| | | return rect; |
| | | } |
| | | } |
| | | throw string("尚未找到添加按钮(28)"); |
| | | } |
| | | |
| | | |
| | | bool THSActionUtil::setListenL2GP(int p, string code, RecognitionManager* recognitionManager) { |
| | | |
| | | |
| | |
| | | } |
| | | |
| | | if (contentStartRow < 0) { |
| | | throw string("起始行分隔出错"); |
| | | throw string("起始行分隔出错(29)"); |
| | | } |
| | | |
| | | //分隔列 |
| | |
| | | } |
| | | |
| | | if (startC < 0 || endC < 0) { |
| | | throw string("内容框分隔出错"); |
| | | throw string("内容框分隔出错(30)"); |
| | | } |
| | | |
| | | GPCodeArea area = GPCodeArea(); |
| | |
| | | |
| | | return area; |
| | | } |
| | | |
| | | void THSActionUtil::addTargetCodes(list<std::string> codeList, RecognitionManager* recognitionManager) |
| | | { |
| | | //获取同花顺主页 |
| | | HWND win = getMainWin(); |
| | | Win32Util::focus(win); |
| | | //快捷键打开板块 |
| | | Win32Util::keyboardNum("51", 200); |
| | | Win32Util::keyboard(13, 10); |
| | | Sleep(1000); |
| | | //删除板块内的所有内容 |
| | | clearPlateCodes(win); |
| | | //获取添加按钮位置 |
| | | RECT codeArea = getPlateAddCodeBtnPostion(win); |
| | | //点击添加按钮 |
| | | Win32Util::click(codeArea.left + 5, codeArea.top + 3); |
| | | |
| | | //批量添加代码 |
| | | HWND addDLG; |
| | | for (int i = 0;i < 10;i++) { |
| | | addDLG = FindWindowA("#32770", "添加股票"); |
| | | if (addDLG > 0) { |
| | | break; |
| | | } |
| | | Sleep(1000); |
| | | } |
| | | if (addDLG <= 0) { |
| | | throw string("添加股票窗口打开失败(31)"); |
| | | } |
| | | if (codeList.size() >= 100) |
| | | { |
| | | betchAddGP(addDLG, codeList); |
| | | } |
| | | else { |
| | | //逐个添加 |
| | | for (list<std::string>::iterator ele = codeList.begin();ele != codeList.end();++ele) { |
| | | string code = *ele; |
| | | Win32Util::focus(addDLG); |
| | | for (int i = 0;i < 6;i++) |
| | | { |
| | | Win32Util::keyboard(VK_BACK, 10); |
| | | } |
| | | Win32Util::focus(addDLG); |
| | | Win32Util::keyboardNum(code, 1000); |
| | | Win32Util::focus(addDLG); |
| | | Win32Util::keyboard(VK_RETURN, 1500); |
| | | } |
| | | Sleep(100); |
| | | SendMessage(addDLG, WM_CLOSE, 0, 0); |
| | | } |
| | | //TODO 校验代码的正确性 |
| | | } |
| | |
| | | { |
| | | private: |
| | | static void addGP(string code); |
| | | //批量添加股票 |
| | | static void betchAddGP(HWND addDialog,list<string> codeList); |
| | | static std::list<GPCodeArea> getListenL2GPAreaAndCode(RecognitionManager* recognitionManager); |
| | | //删除板块内的所有代码 |
| | | static void clearPlateCodes(HWND hwnd); |
| | | |
| | | //获取板块中代码添加按钮的位置 |
| | | static RECT getPlateAddCodeBtnPostion(HWND win); |
| | | |
| | | public: |
| | | static HWND getMainWin(); |
| | |
| | | static std::list<int*> splitPlateRowArea(cv::Mat img, int start_row, int start_col, int end_row, int end_col); |
| | | |
| | | //打开同花顺的副屏幕 |
| | | static void openL2Screen(); |
| | | static void openSecondScreen(); |
| | | static void openThirdScreen(); |
| | | static void openTradeSuccessScreen(); |
| | | |
| | | //设置股票 |
| | | static bool setGP(std::string quickCode, list<std::string> codeList,RecognitionManager* recognitionManager); |
| | |
| | | static GPCodeArea recognitionPlateContentArea(cv::Mat grayImg); |
| | | |
| | | |
| | | |
| | | //添加目标标的(目标标的的数量必须大于9个才行) |
| | | static void addTargetCodes(list<std::string> codeList, RecognitionManager* recognitionManager); |
| | | |
| | | |
| | | |
New file |
| | |
| | | #include "THSL2RepairTool.h" |
| | | #include "Win32Util.h" |
| | | #include "THSActionUtil.h" |
| | | |
| | | THSL2RepairTool::THSL2RepairTool() |
| | | { |
| | | openCLExcuter = new OpenCLExcuter(); |
| | | openCLExcuter->init(); |
| | | } |
| | | |
| | | void THSL2RepairTool::repairL2Data(RecognitionManager *recognitionManager, int index, string code, double min_price, double max_price) |
| | | { |
| | | try { |
| | | list<TradeData> dataList; |
| | | try { |
| | | dataList = L2DataCapture::captureLevel2TradeData(openCLExcuter, CaptureUtil::capture(index, CAPTURE_TYPE_L2), index); |
| | | } |
| | | catch (int c) { |
| | | cout << "获取L2数据出错:code-" << c << endl; |
| | | } |
| | | cout << "获取到的数据:" << dataList.size() << endl; |
| | | if (dataList.size() == 0) {//修正数据 |
| | | //上下滚动鼠标滚轮1次 |
| | | HWND win = CaptureUtil::getHWND(index, CAPTURE_TYPE_L2); |
| | | cout << "L2 win:" << win << endl; |
| | | RECT rect; |
| | | Win32Util::getWindowRect(win, &rect); |
| | | cout << "L2 rect:" << rect.left << rect.top << endl; |
| | | Win32Util::rollMouseWheel(false, win, rect.left + 20, rect.top + 10); |
| | | Sleep(100); |
| | | Win32Util::rollMouseWheel(true, win, rect.left + 20, rect.top + 10); |
| | | Sleep(500); |
| | | try { |
| | | dataList = L2DataCapture::captureLevel2TradeData(openCLExcuter, CaptureUtil::capture(index, CAPTURE_TYPE_L2), index); |
| | | cout << "获取到的数据:" << dataList.size() << endl; |
| | | } |
| | | catch (int c) { |
| | | cout << "获取L2数据出错:code-" << c << endl; |
| | | } |
| | | } |
| | | |
| | | //打开L2监控屏幕 |
| | | THSActionUtil::openL2Screen(); |
| | | |
| | | bool success = false; |
| | | int retryCount = 0; |
| | | while (!success) |
| | | { |
| | | if (retryCount > 3) { |
| | | break; |
| | | } |
| | | //点击代码 |
| | | retryCount++; |
| | | THSActionUtil::setListenL2GP(index, code, recognitionManager); |
| | | Sleep(1000); |
| | | bool normal = true; |
| | | |
| | | for (list<TradeData>::iterator ele = dataList.begin();ele != dataList.end();++ele) { |
| | | double price = stod((*ele).price); |
| | | if (price >= max_price + 0.0001) { |
| | | normal = false; |
| | | break; |
| | | } |
| | | else if (price <= min_price - 0.0001) { |
| | | normal = false; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | cout << code << "-repairL2Data是否修复成功:" << normal << endl; |
| | | |
| | | success = normal; |
| | | } |
| | | } |
| | | catch (int code) { |
| | | throw string("错误码:" + code); |
| | | } |
| | | catch (string st) { |
| | | throw st; |
| | | } |
| | | catch (...) { |
| | | std::exception_ptr p = std::current_exception(); |
| | | throw string("未知错误(unknown error)"); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | #pragma once |
| | | //L2修复工具 |
| | | #include "L2DataCapture.h" |
| | | class THSL2RepairTool |
| | | { |
| | | public: |
| | | THSL2RepairTool(); |
| | | void repairL2Data(RecognitionManager* recognitionManager, int index,string code, double min_price, double max_price); |
| | | |
| | | private: |
| | | OpenCLExcuter* openCLExcuter; |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | }; |
| | | |
New file |
| | |
| | | #include "TaskChecker.h" |
| | | ClientTaskLiveTime TaskChecker::clientLiveTime; |
New file |
| | |
| | | #pragma once |
| | | //任务检测器 |
| | | #include <time.h> |
| | | #include "L2DataCapture.h" |
| | | //任务生存时间 |
| | | |
| | | //客户端环境状态 |
| | | struct ClientEnvState { |
| | | //l2屏幕 |
| | | bool ths_l2_win; |
| | | //副屏1 |
| | | bool ths_fp_1; |
| | | //副屏2 |
| | | bool ths_fp_2; |
| | | //交易成功界面 |
| | | bool ths_trade_success; |
| | | |
| | | int l2_channel_valid_count; |
| | | int l2_channel_invalid_count; |
| | | //今日涨停 |
| | | bool limitUp; |
| | | //交易成功 |
| | | bool tradeSuccess; |
| | | |
| | | |
| | | |
| | | |
| | | }; |
| | | |
| | | |
| | | struct ClientTaskLiveTime |
| | | { |
| | | clock_t l2[THS_FRAME_COUNT]; |
| | | clock_t tradeSuccess; |
| | | clock_t limitUp; |
| | | }; |
| | | |
| | | class TaskChecker |
| | | { |
| | | public: |
| | | static ClientTaskLiveTime clientLiveTime; |
| | | |
| | | |
| | | |
| | | }; |
| | | |
| | |
| | | #include "TradeListCapture.h" |
| | | #include <set> |
| | | #include "Win32Util.h" |
| | | #include "TaskChecker.h" |
| | | OpenCLExcuter* TradeListCapture::openCLExcuter; |
| | | bool TradeListCapture::inited; |
| | | bool TradeListCapture::kill_d; |
| | | bool TradeListCapture::kill_s; |
| | | HWND TradeListCapture::trade_delegate_win; |
| | | HWND TradeListCapture::trade_success_win; |
| | | RecognitionManager* TradeListCapture::recognitionManager; |
| | |
| | | |
| | | void TradeListCapture::_run_s() { |
| | | while (true) { |
| | | //1s一次 |
| | | if (kill_s) |
| | | break; |
| | | TaskChecker::clientLiveTime.tradeSuccess = clock(); |
| | | if (running_s && inited) { |
| | | clock_t start = clock(); |
| | | try { |
| | |
| | | |
| | | void TradeListCapture::_run_d() { |
| | | while (true) { |
| | | if (kill_d) |
| | | break; |
| | | //1s一次 |
| | | if (running_d && inited) { |
| | | clock_t start = clock(); |
| | |
| | | |
| | | |
| | | } |
| | | void TradeListCapture::reCreateTradeSuccessRunning() |
| | | { |
| | | kill_s = TRUE; |
| | | Sleep(3000); |
| | | kill_s = FALSE; |
| | | thread rt(&(TradeListCapture::_run_s)); |
| | | rt.detach(); |
| | | |
| | | } |
| | | void TradeListCapture::reCreateTradeDelegateRunning() |
| | | { |
| | | kill_d = TRUE; |
| | | Sleep(3000); |
| | | kill_d = FALSE; |
| | | thread rt(&(TradeListCapture::_run_d)); |
| | | rt.detach(); |
| | | } |
| | | void TradeListCapture::refreshTradeDelegateHWND() { |
| | | HWND hwnd = THSActionUtil::getTradeDelegateWindow(); |
| | | if (hwnd <= 0) |
| | |
| | | //是否正在执行 |
| | | static bool running_s; |
| | | static bool running_d; |
| | | static bool kill_d; |
| | | static bool kill_s; |
| | | static CallbackFun_Trade_Success data_callback_success; |
| | | static CallbackFun_Trade_Delegate data_callback_delegate; |
| | | static void* context; |
| | |
| | | |
| | | public: |
| | | void init(CallbackFun_Trade_Success callback_s, CallbackFun_Trade_Delegate callback_d, void* context); |
| | | |
| | | //重新创建线程 |
| | | void reCreateTradeSuccessRunning(); |
| | | void reCreateTradeDelegateRunning(); |
| | | |
| | | void refreshTradeDelegateHWND(); |
| | | void refreshTradeSuccessHWND(); |
| | | static cv::Mat grayImgs(cv::Mat img); |
| | |
| | | SetFocus(hwnd); |
| | | } |
| | | |
| | | void Win32Util::copy(string text) |
| | | { |
| | | HWND hWnd = NULL; |
| | | OpenClipboard(hWnd);//打开剪切板 |
| | | EmptyClipboard();//清空剪切板 |
| | | HANDLE hHandle = GlobalAlloc(GMEM_FIXED, 1000);//分配内存 |
| | | char* pData = (char*)GlobalLock(hHandle);//锁定内存,返回申请内存的首地址 |
| | | strcpy(pData, text.c_str()); |
| | | SetClipboardData(CF_TEXT, hHandle);//设置剪切板数据 |
| | | GlobalUnlock(hHandle);//解除锁定 |
| | | CloseClipboard();//关闭剪切板 |
| | | } |
| | | |
| | | //键盘输入数字 |
| | | void Win32Util::keyboardNum(string num, int delay) { |
| | | thread runner(kbNumRunner, num, delay); |
| | |
| | | void Win32Util::keyboard(int code, int delay) { |
| | | thread runner(kbKeyRunner, code, delay); |
| | | runner.join(); |
| | | } |
| | | |
| | | void Win32Util::keyboardPaste() |
| | | { |
| | | keybd_event(VK_CONTROL, 0, 0, 0); // 按下CTRL键 |
| | | keybd_event('V', 0, 0, 0); // 按下a键 |
| | | Sleep(50); |
| | | keybd_event('V', 0, KEYEVENTF_KEYUP, 0);// 松开a键 |
| | | keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);// 松开CTRL键 |
| | | } |
| | | |
| | | DEVMODE Win32Util::getL2ScreenInfo() |
| | |
| | | ShowWindow(hwnd, SW_SHOWNORMAL); |
| | | } |
| | | |
| | | void Win32Util::selectTexFileWin10(HWND hwnd, string path) |
| | | { |
| | | //选择路径 |
| | | HWND pathWin = FindWindowExA(hwnd, NULL, "WorkerW", NULL); |
| | | pathWin = FindWindowExA(pathWin, NULL, "ReBarWindow32", NULL); |
| | | pathWin = FindWindowExA(pathWin, NULL, "Address Band Root", NULL); |
| | | pathWin = FindWindowExA(pathWin, NULL, "msctls_progress32", NULL); |
| | | pathWin = FindWindowExA(pathWin, NULL, "Breadcrumb Parent", NULL); |
| | | pathWin = FindWindowExA(pathWin, NULL, "ToolbarWindow32", NULL); |
| | | RECT p; |
| | | GetWindowRect(pathWin, &p); |
| | | Win32Util::focus(hwnd); |
| | | Win32Util::click(p.right - 5, p.top + 5, 10); |
| | | Sleep(1000); |
| | | |
| | | //复制路径 |
| | | Win32Util::copy(path); |
| | | //粘贴路径 |
| | | keyboardPaste(); |
| | | |
| | | //按enter按键 |
| | | keybd_event(VK_RETURN, 0, 0, 0); |
| | | keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0); |
| | | |
| | | |
| | | |
| | | |
| | | //选着导入Txt |
| | | HWND typeWin = FindWindowExA(hwnd, NULL, "ComboBox", NULL); |
| | | GetWindowRect(typeWin, &p); |
| | | Win32Util::focus(typeWin); |
| | | Win32Util::click(p.right - 5, p.top + 5, 10); |
| | | Win32Util::click(p.right - 5, p.bottom + 30, 100); |
| | | Sleep(500); |
| | | |
| | | |
| | | |
| | | //选中文件 |
| | | HWND contentWin = FindWindowExA(hwnd, NULL, "DUIViewWndClassName", NULL); |
| | | contentWin = FindWindowExA(contentWin, NULL, "DirectUIHWND", NULL); |
| | | HWND contentWin_ = FindWindowExA(contentWin, NULL, "CtrlNotifySink", NULL); |
| | | |
| | | for (int i = 0;i < 5;i++) |
| | | { |
| | | if (FindWindowExA(contentWin_, NULL, "SHELLDLL_DefView", NULL) > 0) |
| | | break; |
| | | contentWin_ = FindWindowExA(contentWin, contentWin_, "CtrlNotifySink", NULL); |
| | | } |
| | | GetWindowRect(contentWin_, &p); |
| | | |
| | | |
| | | Win32Util::click(p.left + 20, p.top + 10, 10); |
| | | Win32Util::click(p.left + 20, p.top + 10, 10); |
| | | Win32Util::click(p.left + 20, p.top + 10, 10); |
| | | |
| | | //Sleep(100); |
| | | |
| | | //点击打开 |
| | | //HWND openWin = FindWindowExA(hwnd, NULL, NULL, "打开(&O)"); |
| | | //GetWindowRect(openWin, &p); |
| | | //return; |
| | | //Win32Util::click((p.left + p.right) / 2, (p.top + p.bottom) / 2, 100); |
| | | } |
| | | |
| | | void Win32Util::rollMouseWheel(bool back, HWND win,int x, int y) |
| | | { |
| | | //back-是否往后滚 |
| | | SendMessage(win, WM_MOUSEWHEEL, back?0xFF880000:0x00780000, MAKEWORD(x, y)); |
| | | } |
| | | |
| | | void Win32Util::getWindowRect(HWND hwnd, RECT *rect) |
| | | { |
| | | GetWindowRect(hwnd, rect); |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | //获取焦点 |
| | | static void focus(HWND hwnd); |
| | | |
| | | //复制到粘贴板 |
| | | static void copy(string text); |
| | | |
| | | //键盘输入数字 |
| | | static void keyboardNum(string num, int delay=0); |
| | | |
| | | //键盘输入其他键 |
| | | static void keyboard(int code, int delay=0); |
| | | |
| | | //键盘键入粘贴 |
| | | static void keyboardPaste(); |
| | | |
| | | //获取L2屏幕数据 |
| | | static DEVMODE getL2ScreenInfo(); |
| | |
| | | static bool isWindowShow(HWND hwnd); |
| | | //显示窗口 |
| | | static void showWindow(HWND hwnd); |
| | | |
| | | //选择txt文件 |
| | | static void selectTexFileWin10(HWND hwnd, string path); |
| | | |
| | | //鼠标滚动 |
| | | static void rollMouseWheel(bool back,HWND win,int x, int y); |
| | | |
| | | //获取位置 |
| | | static void getWindowRect(HWND hwnd,RECT *rect); |
| | | }; |
| | | |
| | |
| | | #include "LimitUpCapture.h" |
| | | #include "IndustryCapture.h" |
| | | #include "TradeListCapture.h" |
| | | #include "CurrentPriceCapture.h" |
| | | void gray(); |
| | | void ths(); |
| | | /* |
| | |
| | | char tmp_s[64]; |
| | | strftime(tmp_s, sizeof(tmp_s), "%S", localtime(&timep)); |
| | | cout << string(tmp_h) << endl; |
| | | cout << string(tmp_m) << endl; |
| | | cout << string(tmp_s) << endl; |
| | | cout << string(tmp_m) << endl; cout << string(tmp_s) << endl; |
| | | |
| | | return stoi(string(tmp_h)) * 3600 + stoi(string(tmp_m)) * 60 + stoi(string(tmp_s)); |
| | | } |
| | | |
| | | int main() { |
| | | cout << "开始程序" << endl; |
| | | |
| | | //SetDlgItemText(HWND(0x0002269E), 0x0000040A, TEXT("100")); |
| | | //SetWindowText(GetDlgItem(HWND(0x0002269E), 0x0000040A),TEXT("100")); |
| | | //Win32Util::focus(GetDlgItem(HWND(0x0002269E), 0x00000408)); |
| | | //Win32Util::keyboardNum("000333", 10); |
| | | ImgUtil::init(); |
| | | |
| | | //int result= getNowSecondTime1(); |
| | | CurrentPriceCapture* currentPriceCapture = new CurrentPriceCapture(); |
| | | currentPriceCapture->init(NULL,NULL); |
| | | list<CurrentPriceData> resultList= currentPriceCapture->capture(); |
| | | for (list<CurrentPriceData>::iterator ele = resultList.begin();ele != resultList.end();++ele) { |
| | | cout<<(*ele).code<<":"<< (*ele).price <<endl; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | //TradeListCapture* tradeListCapture = new TradeListCapture(); |
| | | //tradeListCapture->init(NULL,NULL,NULL); |
| | | //tradeListCapture->refreshTradeDelegateHWND(); |
| | | |
| | | |
| | | //cv::Mat img= tradeListCapture->grayImgs(CaptureUtil::capture(HWND(0x00055B0E))); |
| | | //cv::imwrite("C:\\Users\\Administrator\\Desktop\\ocr\\trade\\gray_1.png",img); |
| | | |
| | | //list<TradeDelegateData> dataList = tradeListCapture->captureTradeDelegateInfo(); |
| | | cv::waitKey(0); |
| | | cv::destroyAllWindows(); |
| | | return 0; |
| | | |
| | | ImgUtil::init(); |
| | |
| | | { |
| | | "Name" = "8:Microsoft Visual Studio" |
| | | "ProductName" = "8:GP" |
| | | "ProductCode" = "8:{AD2DB9B9-91FB-4E17-ABA5-8C2DB663ACE2}" |
| | | "PackageCode" = "8:{33D97017-BA1B-4775-922F-FE62DB48947E}" |
| | | "ProductCode" = "8:{5C7E235C-AF45-420E-8568-E6BC84A5DAF7}" |
| | | "PackageCode" = "8:{74B1A9AE-7307-48A1-9E1E-E9CC63BCD059}" |
| | | "UpgradeCode" = "8:{746B406D-2250-4EC9-AC73-44489EBE2279}" |
| | | "AspNetVersion" = "8:2.0.50727.0" |
| | | "RestartWWWService" = "11:FALSE" |
| | | "RemovePreviousVersions" = "11:TRUE" |
| | | "DetectNewerInstalledVersion" = "11:TRUE" |
| | | "InstallAllUsers" = "11:FALSE" |
| | | "ProductVersion" = "8:1.0.0" |
| | | "ProductVersion" = "8:1.0.1" |
| | | "Manufacturer" = "8:yeshi" |
| | | "ARPHELPTELEPHONE" = "8:" |
| | | "ARPHELPLINK" = "8:" |
| | |
| | | #include "LimitUpCapture.h" |
| | | #include "TradeListCapture.h" |
| | | #include "IndustryCapture.h" |
| | | #include "CurrentPriceCapture.h" |
| | | #include "TaskChecker.h" |
| | | |
| | | class JsonUtil { |
| | | |
| | |
| | | return toJsonStr(root); |
| | | } |
| | | |
| | | static std::string loadGPPriceData(std::list<CurrentPriceData> dataList) { |
| | | Json::Value root; |
| | | root["type"] = 40; |
| | | Json::Value data; |
| | | |
| | | std::list<CurrentPriceData>::iterator ele; |
| | | int index = 0; |
| | | for (ele = dataList.begin();ele != dataList.end();ele++) { |
| | | Json::Value item; |
| | | item["code"] = (*ele).code; |
| | | item["price"] = (*ele).price; |
| | | data[index++] = item; |
| | | } |
| | | root["data"] = data; |
| | | return toJsonStr(root); |
| | | } |
| | | |
| | | |
| | | static std::string loadGPCodeData(std::list<IndustryData> codeList) { |
| | | Json::Value root; |
| | |
| | | return toJsonStr(root); |
| | | } |
| | | |
| | | static std::string loadHeartbeatData(int client,string memery) { |
| | | static std::string loadHeartbeatData(int client,string memery,string ownMemery) { |
| | | Json::Value root; |
| | | root["type"] = 30; |
| | | Json::Value data; |
| | | data["client"] = client; |
| | | data["memery"] = memery; |
| | | data["own_memery"] = ownMemery; |
| | | root["data"] = data; |
| | | return toJsonStr(root); |
| | | } |
| | |
| | | return toJsonStr(root); |
| | | } |
| | | |
| | | static std::string toJson(ClientEnvState state) { |
| | | Json::Value root; |
| | | root["ths_l2_win"] = state.ths_l2_win; |
| | | root["ths_fp_1"] = state.ths_fp_1; |
| | | root["ths_fp_2"] = state.ths_fp_2; |
| | | root["ths_trade_success"] = state.ths_trade_success; |
| | | root["l2_channel_valid_count"] = state.l2_channel_valid_count; |
| | | root["l2_channel_invalid_count"] = state.l2_channel_invalid_count; |
| | | root["limitUp"] = state.limitUp; |
| | | root["tradeSuccess"] = state.tradeSuccess; |
| | | return toJsonStr(root); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | |
| | | #include <thread> |
| | | #include <string> |
| | | |
| | | |
| | | SOCKET SocketManager::socketServer; |
| | | |
| | | ActionCallback SocketManager::actionCallback; |
| | |
| | | if (recv_len > 0) |
| | | { |
| | | cout << "接受到操作指令:" << recvBuff << endl; |
| | | try { |
| | | bool success = actionCallback(string(recvBuff), callbackContext); |
| | | |
| | | |
| | | string result = actionCallback(string(recvBuff), callbackContext); |
| | | |
| | | //发送操作结果 |
| | | if (success) |
| | | { |
| | | char buff[] = "OK"; |
| | | int iSend = send(client, buff, sizeof(buff), 0); |
| | | cout << "返回给客户端数据:" << buff << endl; |
| | | } |
| | | else { |
| | | char buff[] = "FAIL"; |
| | | int iSend = send(client, buff, sizeof(buff), 0); |
| | | cout << "返回给客户端数据:" << buff << endl; |
| | | } |
| | | } |
| | | catch (string st) { |
| | | char buff[] = "FAIL"; |
| | | int iSend = send(client, buff, sizeof(buff), 0); |
| | | cout << "设置采集代码出错:" << st << endl; |
| | | } |
| | | int iSend = send(client, result.c_str(), result.size(), 0); |
| | | cout << "返回给客户端数据:" << result << endl; |
| | | } |
| | | else { |
| | | cout << "客户端退出" << endl; |
| | |
| | | #define LOCAL_SERVER_ADDR "127.0.0.1" |
| | | #define LOCAL_SERVER_PORT 9006 |
| | | |
| | | typedef bool (*ActionCallback)(string data, void* contex); |
| | | typedef string (*ActionCallback)(string data, void* contex); |
| | | |
| | | class SocketManager |
| | | { |
| | |
| | | <PropertyGroup> |
| | | <RESOURCE_FILE>app.rc</RESOURCE_FILE> |
| | | </PropertyGroup> |
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |
| | | <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> |
| | | <RemoteDebuggerCommand>\\192.168.3.242\FXDMounter\Debug\DataCapture.exe</RemoteDebuggerCommand> |
| | | <RemoteDebuggerWorkingDirectory>\\192.168.3.242\FXDMounter\</RemoteDebuggerWorkingDirectory> |
| | | <RemoteDebuggerServerName>192.168.3.242</RemoteDebuggerServerName> |
| | | <RemoteDebuggerConnection>RemoteWithoutAuthentication</RemoteDebuggerConnection> |
| | | </PropertyGroup> |
| | | </Project> |
| | |
| | | #ifndef _TOOL_H |
| | | #define _TOOL_H 1 |
| | | #include "tool.h" |
| | | #include "TaskChecker.h" |
| | | #endif |
| | | #include "JsonUtil.h" |
| | | #include <exception> |
| | | |
| | | |
| | | #ifdef _DEBUG |
| | |
| | | #endif |
| | | #include <Win32Util.h> |
| | | #include "loginDlg.h" |
| | | #include <psapi.h> |
| | | #pragma comment(lib,"psapi.lib") |
| | | |
| | | |
| | | // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 |
| | |
| | | tradeListCapture = new TradeListCapture(); |
| | | industryCapture = new IndustryCapture(); |
| | | gpDataCapture = new THSGPDataCapture(); |
| | | currentPriceCapture = new CurrentPriceCapture(); |
| | | thsL2RepairTool = new THSL2RepairTool(); |
| | | } |
| | | |
| | | void CappDlg::DoDataExchange(CDataExchange* pDX) |
| | |
| | | DDX_Control(pDX, IDC_BUTTON22, refreshHWNDBtn); |
| | | DDX_Control(pDX, IDC_BUTTON21, resetTHSBtn); |
| | | DDX_Control(pDX, IDC_CHECK6, autoL2Check); |
| | | DDX_Control(pDX, IDC_CURRENT_PRICE, currentPriceBtn); |
| | | DDX_Control(pDX, IDC_STATIC_AUTO_MSG, autoMsgStatic); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CappDlg, CDialogEx) |
| | |
| | | ON_BN_CLICKED(IDC_BUTTON22, &CappDlg::OnBnClickedButton22) |
| | | ON_BN_CLICKED(IDC_LOGOUT_BTN, &CappDlg::OnBnClickedLogoutBtn) |
| | | ON_BN_CLICKED(IDC_CHECK6, &CappDlg::OnBnClickedCheck6) |
| | | ON_BN_CLICKED(IDC_CURRENT_PRICE, &CappDlg::OnBnClickedCurrentPrice) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | |
| | | if (settings.size() > 0) { |
| | | string c= *(settings.begin()); |
| | | if (c == "1") { |
| | | autoMsgStatic.SetWindowTextW(_T("正在自动启动中...")); |
| | | autoL2Check.SetCheck(TRUE); |
| | | thread rt(&(CappDlg::autoStartL2),this); |
| | | rt.detach(); |
| | | } |
| | | else { |
| | | autoMsgStatic.SetWindowTextW(_T("")); |
| | | autoL2Check.SetCheck(FALSE); |
| | | } |
| | | } |
| | |
| | | |
| | | if (authoritySet.count(AUTHORITY_TRADE_DELEGATE) > 0) { |
| | | delegateBtn.EnableWindow(TRUE); |
| | | currentPriceBtn.EnableWindow(TRUE); |
| | | } |
| | | else { |
| | | delegateBtn.EnableWindow(FALSE); |
| | | currentPriceBtn.EnableWindow(FALSE); |
| | | } |
| | | |
| | | |
| | |
| | | _list.clear(); |
| | | } |
| | | |
| | | void CappDlg::OnCurrentPriceCallback(list<CurrentPriceData> dataList, void* context) |
| | | { |
| | | //转为json |
| | | CappDlg* app = (CappDlg*)context; |
| | | |
| | | |
| | | bool CappDlg::OnActionCallback(string data, void* context) { |
| | | string data = JsonUtil::loadGPPriceData(dataList); |
| | | try { |
| | | app->socketManager->sendMsg(8, data.c_str()); |
| | | //AfxMessageBox(_T("上传成功")); |
| | | } |
| | | catch (string st) { |
| | | //重新连接服务器 |
| | | app->socketManager->resetClient(8); |
| | | app->socketManager->Connect(8); |
| | | } |
| | | dataList.clear(); |
| | | } |
| | | |
| | | string CappDlg::OnActionProcess(string data, void* context) |
| | | { |
| | | //转为json |
| | | CappDlg* app = (CappDlg*)context; |
| | | cout << "action回调:" << std::this_thread::get_id() << ":" << data << endl; |
| | |
| | | try { |
| | | |
| | | if (!app->capture->isInited()) { |
| | | throw string("采集器尚未初始化"); |
| | | app->initCapture(false); |
| | | } |
| | | |
| | | //暂停采集 |
| | |
| | | if (!result) { |
| | | throw string("设置版块监控的GP失败"); |
| | | } |
| | | |
| | | //刷新句柄 |
| | | THSActionUtil::setListenL2GP(index, code, recognitionManager); |
| | | //打开Level2监控屏幕 |
| | | THSActionUtil::openL2Screen(); |
| | | map<int, string> results = THSActionUtil::getListenL2GPCodes(recognitionManager); |
| | | //设置代码 |
| | | for (map<int, string>::iterator ele = results.begin();ele != results.end();ele++) { |
| | |
| | | } |
| | | } |
| | | catch (string e) { |
| | | //CString msg(e.c_str()); |
| | | //AfxMessageBox(msg); |
| | | throw e; |
| | | } |
| | | catch (...) { |
| | | throw string("未知错误"); |
| | | throw string("未知错误(unknown error)"); |
| | | } |
| | | |
| | | //恢复采集 |
| | | app->capture->start(index); |
| | | } |
| | | else if (action == "repairL2Data") { |
| | | |
| | | //修正代码与L2行情代码不对应 或者 L2行情无数据的情况 |
| | | cout << "修复L2数据" << endl; |
| | | if (!app->capture->isInited()) { |
| | | throw string("采集器尚未初始化"); |
| | | app->initCapture(false); |
| | | } |
| | | try { |
| | | //修正L2的数据 |
| | |
| | | string code = root["data"]["code"].asString(); |
| | | double min_price = root["data"]["min_price"].asDouble(); |
| | | double max_price = root["data"]["max_price"].asDouble(); |
| | | list<TradeData> dataList = app->capture->captureLevel2TradeData(CaptureUtil::capture(index, CAPTURE_TYPE_L2), index); |
| | | cout << index << ":" << code << ":" << min_price << ":" << max_price << endl; |
| | | app->thsL2RepairTool->repairL2Data(recognitionManager, index, code, min_price, max_price); |
| | | }catch (string st) { |
| | | throw st; |
| | | } |
| | | |
| | | bool success = false; |
| | | int retryCount = 0; |
| | | while (!success) |
| | | } |
| | | else if (action == "getEnvState") { |
| | | |
| | | app->initCapture(false); |
| | | |
| | | |
| | | ClientEnvState state; |
| | | |
| | | //获取同花顺的环境 |
| | | HWND l2 = THSActionUtil::getL2Win(); |
| | | HWND second = THSActionUtil::getSecondWindow(); |
| | | HWND third = THSActionUtil::getThirdWindow(); |
| | | HWND trade_success = THSActionUtil::getTradeSuccessWindow(); |
| | | if (l2 > 0 && Win32Util::isWindowShow(l2)) { |
| | | state.ths_l2_win = TRUE; |
| | | } |
| | | else { |
| | | state.ths_l2_win = FALSE; |
| | | } |
| | | if (second > 0 && Win32Util::isWindowShow(second)) { |
| | | state.ths_fp_1 = TRUE; |
| | | } |
| | | else { |
| | | state.ths_fp_1 = FALSE; |
| | | } |
| | | |
| | | if (third > 0 && Win32Util::isWindowShow(third)) { |
| | | state.ths_fp_2 = TRUE; |
| | | } |
| | | else { |
| | | state.ths_fp_2 = FALSE; |
| | | } |
| | | |
| | | if (trade_success > 0 && Win32Util::isWindowShow(trade_success)) { |
| | | state.ths_trade_success = TRUE; |
| | | } |
| | | else { |
| | | state.ths_trade_success = FALSE; |
| | | } |
| | | |
| | | //获取环境状态 |
| | | int l2_valid_count = 0; |
| | | int l2_invalid_count = 0; |
| | | for (int i = 0;i < THS_FRAME_COUNT;i++) |
| | | { |
| | | if (retryCount > 3) { |
| | | break; |
| | | clock_t latestTime = TaskChecker::clientLiveTime.l2[i]; |
| | | if (clock() - latestTime > 5000) { |
| | | //5s内不再活跃 |
| | | l2_invalid_count++; |
| | | } |
| | | //点击代码 |
| | | retryCount++; |
| | | THSActionUtil::setListenL2GP(index, code, recognitionManager); |
| | | Sleep(1); |
| | | bool normal = true; |
| | | else { |
| | | l2_valid_count++; |
| | | } |
| | | } |
| | | state.l2_channel_valid_count = l2_valid_count; |
| | | state.l2_channel_invalid_count = l2_invalid_count; |
| | | |
| | | for (list<TradeData>::iterator ele = dataList.begin();ele != dataList.end();++ele) { |
| | | double price = stod((*ele).price); |
| | | if (price >= max_price + 0.0001) { |
| | | normal = false; |
| | | break; |
| | | if (clock() - TaskChecker::clientLiveTime.limitUp > 5000) { |
| | | state.limitUp = false; |
| | | } |
| | | else if (price <= min_price - 0.0001) { |
| | | normal = false; |
| | | break; |
| | | else { |
| | | state.limitUp = true; |
| | | } |
| | | |
| | | if (clock() - TaskChecker::clientLiveTime.tradeSuccess > 5000) { |
| | | state.tradeSuccess = false; |
| | | } |
| | | else { |
| | | state.tradeSuccess = true; |
| | | } |
| | | |
| | | return JsonUtil::toJson(state); |
| | | |
| | | } |
| | | else if (action == "repairEnv") { |
| | | |
| | | app->initCapture(false); |
| | | |
| | | //同花顺环境修复 |
| | | app->OnBnClickedButton21(); |
| | | |
| | | //l2采集环境修复 |
| | | for (int i = 0;i < THS_FRAME_COUNT;i++) |
| | | { |
| | | clock_t latestTime = TaskChecker::clientLiveTime.l2[i]; |
| | | if (clock() - latestTime > 5000) { |
| | | //5s内不再活跃 |
| | | app->capture->reCreateChannelRunner(i); |
| | | } |
| | | } |
| | | |
| | | cout << code << "-repairL2Data是否修复成功:" << normal << endl; |
| | | |
| | | success = normal; |
| | | if (clock() - TaskChecker::clientLiveTime.tradeSuccess > 5000) { |
| | | app->tradeListCapture->captureTradeSuccessInfo(); |
| | | } |
| | | |
| | | if (clock() - TaskChecker::clientLiveTime.limitUp > 5000) { |
| | | app->limitUpCapture->reCreateRunning(); |
| | | } |
| | | |
| | | |
| | | } |
| | | else if (action == "syncTargetCodes") { |
| | | Json::Value data = root["data"]; |
| | | list<string> codeList; |
| | | for (int i = 0;i < data.size();i++) { |
| | | string code = data[i].asString(); |
| | | codeList.push_back(code); |
| | | } |
| | | THSActionUtil::addTargetCodes(codeList, app->recognitionManager); |
| | | } |
| | | |
| | | return ""; |
| | | } |
| | | |
| | | |
| | | |
| | | string CappDlg::OnActionCallback(string data, void* context) { |
| | | Json::Value root; |
| | | try { |
| | | string result = OnActionProcess(data, context); |
| | | root["code"] = 0; |
| | | root["data"] = result; |
| | | } |
| | | catch (string st) { |
| | | root["code"] = 1; |
| | | root["msg"] = st; |
| | | } |
| | | catch (...) { |
| | | throw string("未知错误"); |
| | | root["code"] = 2; |
| | | root["msg"] = "未知错误"; |
| | | } |
| | | } |
| | | return true; |
| | | return JsonUtil::jsonValue2String(root); |
| | | } |
| | | |
| | | //心跳信号 |
| | |
| | | //5s一次心跳 |
| | | while (true) |
| | | { |
| | | if (clientNum >= 0) |
| | | { |
| | | //用户已经登录 |
| | | MEMORYSTATUS ms; |
| | | ::GlobalMemoryStatus(&ms); |
| | | DWORD mer = ms.dwMemoryLoad; |
| | | cout << "内存使用率:" << mer << endl; |
| | | |
| | | //获取当前进程的内存使用情况 |
| | | HANDLE handle = GetCurrentProcess(); |
| | | PROCESS_MEMORY_COUNTERS pmc; |
| | | GetProcessMemoryInfo(handle, &pmc, sizeof(pmc)); |
| | | float memoryUsage_M = pmc.WorkingSetSize / (1024.0 * 1024.0); |
| | | |
| | | string ownMemory = to_string(memoryUsage_M); |
| | | ownMemory.append("MB"); |
| | | try { |
| | | string msg = JsonUtil::loadHeartbeatData(clientNum,to_string(mer)); |
| | | string msg = JsonUtil::loadHeartbeatData(clientNum, to_string(mer), ownMemory); |
| | | SocketManager::sendMsg(msg.c_str()); |
| | | //cout << "心跳信号" << endl; |
| | | } |
| | | catch (...) { |
| | | cout << "心跳信号异常" << endl; |
| | | } |
| | | } |
| | | Sleep(5000); |
| | | } |
| | | } |
| | | |
| | | void CappDlg::initCapture() |
| | | void CappDlg::initCapture(bool notify) |
| | | { |
| | | if (!capture->isInited()) |
| | | { |
| | |
| | | capture->init(OnL2DataCallback, OnTradeQueueDataCallback, this); |
| | | } |
| | | catch (string st) { |
| | | if (notify) |
| | | { |
| | | CString msg(st.c_str()); |
| | | AfxMessageBox(msg); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!limitUpCapture->isInited()) |
| | | { |
| | | try { |
| | | limitUpCapture->init(OnLimitUpDataCallback, this); |
| | | } |
| | | catch (string st) { |
| | | if (notify) |
| | | { |
| | | CString msg(st.c_str()); |
| | | AfxMessageBox(msg); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!tradeListCapture->isInited()) |
| | | { |
| | | try { |
| | | tradeListCapture->init(OnTradeSuccessDataCallback, OnTradeDelegateDataCallback, this); |
| | | } |
| | | catch (string st) { |
| | | if (notify) |
| | | { |
| | | CString msg(st.c_str()); |
| | | AfxMessageBox(msg); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!currentPriceCapture->isInited()) |
| | | { |
| | | try { |
| | | currentPriceCapture->init(OnCurrentPriceCallback, this); |
| | | } |
| | | catch (string st) { |
| | | if (notify) |
| | | { |
| | | CString msg(st.c_str()); |
| | | AfxMessageBox(msg); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | void CappDlg::checkTHSEnv(CappDlg *app) |
| | | { |
| | | |
| | | try { |
| | | THSActionUtil::checkEnv(); |
| | | } |
| | | catch (string e) { |
| | | //打开同花顺的所有屏幕 |
| | | try { |
| | | THSActionUtil::openL2Screen(); |
| | | THSActionUtil::openSecondScreen(); |
| | | Sleep(1000); |
| | | THSActionUtil::openThirdScreen(); |
| | | Sleep(1000); |
| | | } |
| | | catch (...) { |
| | | |
| | | } |
| | | } |
| | | |
| | | |
| | | HWND l2 = THSActionUtil::getL2Win(); |
| | | if (l2 > 0) |
| | | { |
| | | Win32Util::showWindow(l2); |
| | | //初始化l2的各个窗口句柄 |
| | | app->capture->refreshHWND(); |
| | | } |
| | | |
| | | HWND second = THSActionUtil::getSecondWindow(); |
| | | if (second <= 0) { |
| | | throw string("同花顺副屏1未打开"); |
| | | } |
| | | |
| | | Win32Util::showWindow(second); |
| | | |
| | | |
| | | HWND third = THSActionUtil::getThirdWindow(); |
| | | if (third <= 0) { |
| | | throw string("同花顺副屏2未打开"); |
| | | } |
| | | |
| | | Win32Util::showWindow(third); |
| | | |
| | | |
| | | //设置 |
| | | DEVMODE device = Win32Util::getL2ScreenInfo(); |
| | | int device_width = device.dmPelsWidth; |
| | | int device_height = device.dmPelsHeight; |
| | | POINTL device_pos = device.dmPosition; |
| | | //最大化L2 |
| | | Win32Util::moveWin(l2, device_pos.x, device_pos.y, device_width, device_height); |
| | | //将副屏1与副屏2缩小为屏幕的一半 |
| | | Win32Util::moveWin(second, device_pos.x, device_pos.y + device_height / 2, device_width / 2 - 50, device_height / 2); |
| | | Win32Util::moveWin(third, device_pos.x + device_width / 2 + 30, device_pos.y + device_height / 2, device_width / 2 - 50, device_height / 2); |
| | | } |
| | | |
| | | void CappDlg::autoStartL2(void* context) |
| | | { |
| | | Sleep(1500); |
| | | CappDlg* app =(CappDlg*) context; |
| | | app->autoMsgStatic.SetWindowTextW(_T("开始检测同花顺环境...")); |
| | | //点击检查同花顺 |
| | | app->OnBnClickedButton21(); |
| | | for (int i = 0;i < 10;i++) |
| | | { |
| | | try { |
| | | checkTHSEnv(app); |
| | | app->autoMsgStatic.SetWindowTextW(_T("同花顺环境检测通过...")); |
| | | break; |
| | | } |
| | | catch (string st) { |
| | | Sleep(2000); |
| | | CString msg(st.c_str()); |
| | | app->autoMsgStatic.SetWindowTextW(msg); |
| | | } |
| | | } |
| | | Sleep(1000); |
| | | app->autoMsgStatic.SetWindowTextW(_T("开始启动L2行情识别...")); |
| | | //启动L2行情识别 |
| | | app->OnBnClickedButton5(); |
| | | app->autoMsgStatic.SetWindowTextW(_T("L2行情识别启动完成...")); |
| | | //启动交易成功识别 |
| | | app->OnBnClickedButtonTrade(); |
| | | //启动涨停识别 |
| | |
| | | catch (string e) { |
| | | //打开同花顺的所有屏幕 |
| | | try { |
| | | HWND l2 = THSActionUtil::getL2Win(); |
| | | if (l2 <= 0) { |
| | | //尝试打开主屏 |
| | | HWND main = THSActionUtil::getMainWin(); |
| | | if (main > 0) |
| | | { |
| | | Win32Util::focus(main); |
| | | Win32Util::keyboardNum(".00", 200); |
| | | Win32Util::keyboard(13, 10); |
| | | Sleep(1000); |
| | | } |
| | | } |
| | | |
| | | THSActionUtil::openL2Screen(); |
| | | THSActionUtil::openSecondScreen(); |
| | | Sleep(1000); |
| | | THSActionUtil::openThirdScreen(); |
| | |
| | | if (l2 > 0) |
| | | { |
| | | Win32Util::showWindow(l2); |
| | | //初始化l2的各个窗口句柄 |
| | | capture->refreshHWND(); |
| | | } |
| | | |
| | | HWND second = THSActionUtil::getSecondWindow(); |
| | |
| | | try { |
| | | //刷新L2窗口句柄 |
| | | capture->refreshHWND(); |
| | | //刷新涨停句柄 |
| | | } |
| | | catch (string e) { |
| | | CString msg(e.c_str()); |
| | | AfxMessageBox(msg); |
| | | } |
| | | catch (...) { |
| | | AfxMessageBox(_T("未知错误")); |
| | | } |
| | | |
| | | try { |
| | | //刷新L2窗口句柄 |
| | | limitUpCapture->refreshHWND(); |
| | | } |
| | | catch (string e) { |
| | |
| | | //退出登录 |
| | | void CappDlg::OnBnClickedLogoutBtn() |
| | | { |
| | | clientNum = -1; |
| | | |
| | | SendMessage(WM_CLOSE); |
| | | loginDlg dlg(this); |
| | | dlg.setReLogin(true); |
| | |
| | | } |
| | | Tool::saveSettings("setting.txt", settings); |
| | | } |
| | | |
| | | //线价识别 |
| | | void CappDlg::OnBnClickedCurrentPrice() |
| | | { |
| | | if (!currentPriceCapture->isInited()) { |
| | | try { |
| | | currentPriceCapture->init(OnCurrentPriceCallback, this); |
| | | } |
| | | catch (string e) { |
| | | CString msg(e.c_str()); |
| | | AfxMessageBox(msg); |
| | | } |
| | | } |
| | | if (currentPriceCapture->isRunning()) { |
| | | currentPriceCapture->stop(); |
| | | currentPriceBtn.SetWindowTextW(_T("启动现价识别")); |
| | | } |
| | | else { |
| | | try { |
| | | currentPriceCapture->refreshHWND(); |
| | | } |
| | | catch (string e) { |
| | | CString msg(e.c_str()); |
| | | AfxMessageBox(msg); |
| | | } |
| | | currentPriceCapture->start(); |
| | | currentPriceBtn.SetWindowTextW(_T("暂停现价识别")); |
| | | |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | #include "TradeListCapture.h" |
| | | #include "IndustryCapture.h" |
| | | #include "THSGPDataCapture.h" |
| | | #include "CurrentPriceCapture.h" |
| | | #include "THSL2RepairTool.h" |
| | | #include "pthread.h" |
| | | #pragma comment(lib, "pthreadVC2.lib") |
| | | |
| | |
| | | TradeListCapture* tradeListCapture; |
| | | IndustryCapture* industryCapture; |
| | | THSGPDataCapture* gpDataCapture; |
| | | CurrentPriceCapture *currentPriceCapture; |
| | | THSL2RepairTool *thsL2RepairTool; |
| | | |
| | | void OnDataCallback(int index, list<TradeData> dataList); |
| | | static void OnL2DataCallback(int index,string code, list<TradeData> dataList, void* context); |
| | |
| | | static void OnTradeSuccessDataCallback(list<TradeSuccessData> dataList, void* context); |
| | | static void OnTradeDelegateDataCallback(list<TradeDelegateData> dataList,string money, void* context); |
| | | static void OnIndustryDataCallback(list<IndustryData> dataList, void* context); |
| | | static bool OnActionCallback(string data, void* context); |
| | | static void OnCurrentPriceCallback(list<CurrentPriceData> dataList, void* context); |
| | | static string OnActionProcess(string data, void* context); |
| | | static string OnActionCallback(string data, void* context); |
| | | |
| | | |
| | | |
| | | static void *runCaptureIndustryCodes(void* context); |
| | | |
| | |
| | | |
| | | static void onHeartbeat(); |
| | | |
| | | void initCapture(); |
| | | void initCapture(bool notify=true); |
| | | |
| | | //检查 |
| | | static void checkTHSEnv(CappDlg* app); |
| | | |
| | | static void autoStartL2(void* context); |
| | | |
| | |
| | | afx_msg void OnBnClickedLogoutBtn(); |
| | | CButton autoL2Check; |
| | | afx_msg void OnBnClickedCheck6(); |
| | | CButton currentPriceBtn; |
| | | afx_msg void OnBnClickedCurrentPrice(); |
| | | CStatic autoMsgStatic; |
| | | }; |
| | |
| | | #define IDC_LOGOUT_BTN 1035 |
| | | #define IDC_CHECK_AUTO_LOGIN 1036 |
| | | #define IDC_CHECK6 1037 |
| | | #define IDC_CURRENT_PRICE 1038 |
| | | #define IDC_STATIC_AUTO_MSG 1040 |
| | | |
| | | // Next default values for new objects |
| | | // |
| | |
| | | #ifndef APSTUDIO_READONLY_SYMBOLS |
| | | #define _APS_NEXT_RESOURCE_VALUE 136 |
| | | #define _APS_NEXT_COMMAND_VALUE 32771 |
| | | #define _APS_NEXT_CONTROL_VALUE 1038 |
| | | #define _APS_NEXT_CONTROL_VALUE 1041 |
| | | #define _APS_NEXT_SYMED_VALUE 101 |
| | | #endif |
| | | #endif |