int CSingleUser::OnRespone_ReqQryInvestorPosition(CTdxApi* pApi, RequestRespone_STRUCT* pRespone) { if (pRespone->pErr) { ErrorField* pField = (ErrorField*)m_msgQueue->new_block(sizeof(ErrorField)); pField->RawErrorID = pRespone->pErr->ErrCode; strcpy(pField->Text, pRespone->pErr->ErrInfo); strcpy(pField->Source, "OnRespone_ReqQryInvestorPosition"); m_msgQueue->Input_NoCopy(ResponeType::ResponeType_OnRtnError, m_msgQueue, m_pClass, 0, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } GFLB_STRUCT** ppRS = nullptr; CharTable2GFLB(pRespone->ppFieldInfo, pRespone->ppResults, &ppRS, pRespone->Client); int count = GetCountStructs((void**)ppRS); for (int i = 0; i < count; ++i) { PositionField* pField = (PositionField*)m_msgQueue->new_block(sizeof(PositionField)); // 应当处理一下,可能一个账号对应的有多个,如信用账户 GFLB_2_PositionField(ppRS[i], pField); m_msgQueue->Input_NoCopy(ResponeType::ResponeType_OnRspQryInvestorPosition, m_msgQueue, m_pClass, i == count - 1, 0, pField, sizeof(PositionField), nullptr, 0, nullptr, 0); } return 0; }
int CSingleUser::OnRespone_ReqQryInvestor(CTdxApi* pApi, RequestRespone_STRUCT* pRespone) { if (pRespone->pErr) { ErrorField* pField = (ErrorField*)m_msgQueue->new_block(sizeof(ErrorField)); pField->RawErrorID = pRespone->pErr->ErrCode; strcpy(pField->Text, pRespone->pErr->ErrInfo); strcpy(pField->Source, "OnRespone_ReqQryInvestor"); m_msgQueue->Input_NoCopy(ResponeType::ResponeType_OnRtnError, m_msgQueue, m_pClass, 0, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } GDLB_STRUCT** ppRS = nullptr; CharTable2GDLB(pRespone->ppFieldInfo, pRespone->ppResults, &ppRS, pRespone->Client); int count = GetCountStructs((void**)ppRS); if (count>0) { for (int i = 0; i < count; ++i) { InvestorField* pField = (InvestorField*)m_msgQueue->new_block(sizeof(InvestorField)); GDLB_2_InvestorField(ppRS[i], pField); m_msgQueue->Input_NoCopy(ResponeType::ResponeType_OnRspQryInvestor, m_msgQueue, m_pClass, i == count - 1, 0, pField, sizeof(InvestorField), nullptr, 0, nullptr, 0); } m_msgQueue->Input_NoCopy(ResponeType::ResponeType_OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::ConnectionStatus_Done, 0, nullptr, 0, nullptr, 0, nullptr, 0); } return 0; }
int CSingleUser::OnRespone_ReqUserLogin(CTdxApi* pApi, RequestRespone_STRUCT* pRespone) { if (pRespone->pErr) { RspUserLoginField* pField = (RspUserLoginField*)m_msgQueue->new_block(sizeof(RspUserLoginField)); pField->RawErrorID = pRespone->pErr->ErrCode; strcpy(pField->Text, pRespone->pErr->ErrInfo); m_msgQueue->Input_NoCopy(ResponeType::ResponeType_OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::ConnectionStatus_Disconnected, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); m_pApi->RemoveUser((CSingleUser*)pRespone->pUserData_Public); } else { m_msgQueue->Input_NoCopy(ResponeType::ResponeType_OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::ConnectionStatus_Logined, 0, nullptr, 0, nullptr, 0, nullptr, 0); m_pApi->StartQueryThread(); } // 查询股东列表,华泰证券可能一开始查会返回非知请求[1122] GDLB_STRUCT** ppRS = nullptr; CharTable2Login(pRespone->ppResults, &ppRS, pRespone->Client); int count = GetCountStructs((void**)ppRS); if (count > 0) { for (int i = 0; i < count; ++i) { InvestorField* pField = (InvestorField*)m_msgQueue->new_block(sizeof(InvestorField)); GDLB_2_InvestorField(ppRS[i], pField); m_msgQueue->Input_NoCopy(ResponeType::ResponeType_OnRspQryInvestor, m_msgQueue, m_pClass, i == count - 1, 0, pField, sizeof(InvestorField), nullptr, 0, nullptr, 0); } m_msgQueue->Input_NoCopy(ResponeType::ResponeType_OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::ConnectionStatus_Done, 0, nullptr, 0, nullptr, 0, nullptr, 0); } return 0; }
int CSingleUser::OnRespone_ReqQryTradingAccount(CTdxApi* pApi, RequestRespone_STRUCT* pRespone) { if (pRespone->pErr) { ErrorField* pField = (ErrorField*)m_msgQueue->new_block(sizeof(ErrorField)); pField->RawErrorID = pRespone->pErr->ErrCode; strcpy(pField->Text, pRespone->pErr->ErrInfo); strcpy(pField->Source, "OnRespone_ReqQryTradingAccount"); m_msgQueue->Input_NoCopy(ResponeType::ResponeType_OnRtnError, m_msgQueue, m_pClass, 0, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } //if (pRespone->ppResults == nullptr) //{ // return; //} ZJYE_STRUCT** ppRS = nullptr; CharTable2ZJYE(pRespone->ppFieldInfo, pRespone->ppResults, &ppRS, pRespone->Client); int count = GetCountStructs((void**)ppRS); for (int i = 0; i < count; ++i) { AccountField* pField = (AccountField*)m_msgQueue->new_block(sizeof(AccountField)); ZJYE_2_AccountField(ppRS[i], pField); //// 可能资金账号查不出来,手工填上 //if (strlen(pField->AccountID) <= 0) //{ // // 多账户会有问题 // strcpy(pField->AccountID, m_pApi->GetAccount()); //} m_msgQueue->Input_NoCopy(ResponeType::ResponeType_OnRspQryTradingAccount, m_msgQueue, m_pClass, i == count - 1, 0, pField, sizeof(AccountField), nullptr, 0, nullptr, 0); } return 0; }
int CTraderApi::OnResponse_Subscribe(CTdxApi* pApi, RequestResponse_STRUCT* pRespone) { HQ_STRUCT** ppRS = nullptr; CharTable2HQ(pRespone->ppFieldInfo, pRespone->ppResults, &ppRS, pRespone->Client, m_msgQueue); int count = GetCountStructs((void**)ppRS); for (int i = 0; i < count; ++i) { DepthMarketDataNField* pField = (DepthMarketDataNField*)m_msgQueue->new_block(sizeof(DepthMarketDataNField)+sizeof(DepthField)* 10); HQ_STRUCT* pDepthMarketData = ppRS[i]; strcpy(pField->InstrumentID, pDepthMarketData->ZQDM); //pField->Exchange = JYSDM_2_ExchangeType(pDepthMarketData->JYSDM); sprintf(pField->Symbol, "%s.%s", pField->InstrumentID, ""); // 交易时间 GetExchangeTime(time(nullptr), &pField->TradingDay, &pField->ActionDay, &pField->UpdateTime); pField->LastPrice = pDepthMarketData->DQJ_; //pField->Volume = 0; //pField->Turnover = pDepthMarketData->Turnover; //pField->OpenInterest = pDepthMarketData->OpenInterest; //pField->AveragePrice = pDepthMarketData->AveragePrice; pField->UpperLimitPrice = pDepthMarketData->ZTJG_; pField->LowerLimitPrice = pDepthMarketData->DTJG_; pField->PreClosePrice = pDepthMarketData->ZSJ_; pField->OpenPrice = pDepthMarketData->JKJ_; InitBidAsk(pField); do { if (pDepthMarketData->BidSize1_ == 0) break; AddBid(pField, pDepthMarketData->BidPrice1_, pDepthMarketData->BidSize1_, 0); if (pDepthMarketData->BidSize2_ == 0) break; AddBid(pField, pDepthMarketData->BidPrice2_, pDepthMarketData->BidSize2_, 0); if (pDepthMarketData->BidSize3_ == 0) break; AddBid(pField, pDepthMarketData->BidPrice3_, pDepthMarketData->BidSize3_, 0); if (pDepthMarketData->BidSize4_ == 0) break; AddBid(pField, pDepthMarketData->BidPrice4_, pDepthMarketData->BidSize4_, 0); if (pDepthMarketData->BidSize5_ == 0) break; AddBid(pField, pDepthMarketData->BidPrice5_, pDepthMarketData->BidSize5_, 0); } while (false); do { if (pDepthMarketData->AskSize1_ == 0) break; AddAsk(pField, pDepthMarketData->AskPrice1_, pDepthMarketData->AskSize1_, 0); if (pDepthMarketData->AskSize2_ == 0) break; AddAsk(pField, pDepthMarketData->AskPrice2_, pDepthMarketData->AskSize2_, 0); if (pDepthMarketData->AskSize3_ == 0) break; AddAsk(pField, pDepthMarketData->AskPrice3_, pDepthMarketData->AskSize3_, 0); if (pDepthMarketData->AskSize4_ == 0) break; AddAsk(pField, pDepthMarketData->AskPrice4_, pDepthMarketData->AskSize4_, 0); if (pDepthMarketData->AskSize5_ == 0) break; AddAsk(pField, pDepthMarketData->AskPrice5_, pDepthMarketData->AskSize5_, 0); } while (false); m_msgQueue->Input_NoCopy(ResponseType::ResponseType_OnRtnDepthMarketData, m_msgQueue, m_pClass, 0, 0, pField, pField->Size, nullptr, 0, nullptr, 0); } return 0; }
int CSingleUser::OnRespone_ReqQryTrade(CTdxApi* pApi, RequestRespone_STRUCT* pRespone) { ReqQueryData_STRUCT* pQuery = (ReqQueryData_STRUCT*)pRespone->pContent; if (pRespone->pErr) { ErrorField* pField = (ErrorField*)m_msgQueue->new_block(sizeof(ErrorField)); pField->RawErrorID = pRespone->pErr->ErrCode; strcpy(pField->Text, pRespone->pErr->ErrInfo); strcpy(pField->Source, "OnRespone_ReqQryTrade"); m_msgQueue->Input_NoCopy(ResponeType::ResponeType_OnRtnError, m_msgQueue, m_pClass, 0, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } CJLB_STRUCT** ppRS = nullptr; CharTable2CJLB(pRespone->ppFieldInfo, pRespone->ppResults, &ppRS, pRespone->Client); // 操作前清空,按说之前已经清空过一次了 m_NewTradeList.clear(); if (ppRS) { // 利用成交编号的大小来判断正反序 if (!m_TradeListReverse) { int count = GetCountStructs((void**)ppRS); if (count > 1) { // 转成数字的比较,是否会有非数字的情况出现? long CJBH0 = atol(ppRS[0]->CJBH); long CJBH1 = atol(ppRS[count - 1]->CJBH); if (CJBH0 > CJBH1) { m_TradeListReverse = true; } } } int i = 0; while (ppRS[i]) { // 有部分券商,撤单也计成交了,真无语了,需要过滤 if (ppRS[i]->CJSL_ <= 0) { ++i; continue; } TradeField* pField = (TradeField*)m_msgQueue->new_block(sizeof(TradeField)); CJLB_2_TradeField(ppRS[i], pField); pField->Date = ppRS[i]->CJRQ_ == 0 ? Today(0) : ppRS[i]->CJRQ_;//日期为0,重新赋值 if (m_TradeListReverse) { // 华泰查出来的表后生成的排第一,所以要处理一下 m_NewTradeList.push_front(pField); } else { m_NewTradeList.push_back(pField); } ++i; } } // 新查出来的反而少了,华泰有合并成交的情况,这种如何处理? // 对同ID的需要累加,有发现累加不对应的,应当处理 // 同样条数的,也有可能其中的有变化,如何处理? bool bTryMerge = false; int OldTradeListCount = m_OldTradeList.size(); int NewTradeListCount = m_NewTradeList.size(); if (NewTradeListCount < OldTradeListCount) { // 行数变少了,应当是合并了 bTryMerge = true; } else if (OldTradeListCount == 0) { // 如果上一次的为空,不管这次查出来的是合并还是没有合并,都没有关系,当成没合并处理即可 } else if (NewTradeListCount == OldTradeListCount) { // 行数不变,但有可能是其中的一条部分成交的更新,所以检查一下 double OldQty = GetTradeListQty(m_OldTradeList, m_OldTradeList.size()); double NewQty = GetTradeListQty(m_NewTradeList, m_NewTradeList.size()); if (NewQty != OldQty) { // 同样长度成交量发生了变化,可能是合并的列表其中一个新成交了 bTryMerge = true; } } else { // 行数变多了,只要其中上次的部分有变化就需要检查一下 double OldQty = GetTradeListQty(m_OldTradeList, m_OldTradeList.size()); double NewQty = GetTradeListQty(m_NewTradeList, m_NewTradeList.size()); if (NewQty != OldQty) { bTryMerge = true; } } if (bTryMerge) { // 合并列表的处理方法 // 如果上次是合并,这次就没有必要再生成一次了 if (m_OldTradeMap.size() == 0 || !m_LastIsMerge) { for (unordered_map<string, TradeField*>::iterator it = m_OldTradeMap.begin(); it != m_OldTradeMap.end(); ++it) { TradeField* pField = it->second; delete[] pField; } m_OldTradeMap.clear(); TradeList2TradeMap(m_OldTradeList, m_OldTradeMap); } TradeList2TradeMap(m_NewTradeList, m_NewTradeMap); CompareTradeMapAndEmit(m_OldTradeMap, m_NewTradeMap); // 交换 for (unordered_map<string, TradeField*>::iterator it = m_OldTradeMap.begin(); it != m_OldTradeMap.end(); ++it) { TradeField* pField = it->second; delete[] pField; } m_OldTradeMap.clear(); m_OldTradeMap = m_NewTradeMap; m_NewTradeMap.clear(); m_LastIsMerge = true; } else { // 普通的处理方法 CompareTradeListAndEmit(m_OldTradeList, m_NewTradeList); m_LastIsMerge = false; } if (pQuery->bAll) { int i = 0; int count = m_NewTradeList.size(); for (list<TradeField*>::iterator it = m_NewTradeList.begin(); it != m_NewTradeList.end(); ++it) { TradeField* pField = *it; m_msgQueue->Input_Copy(ResponeType::ResponeType_OnRspQryTrade, m_msgQueue, m_pClass, i == count - 1, 0, pField, sizeof(TradeField), nullptr, 0, nullptr, 0); ++i; } } // 将老数据清理,防止内存泄漏 for (list<TradeField*>::iterator it = m_OldTradeList.begin(); it != m_OldTradeList.end(); ++it) { TradeField* pField = *it; m_msgQueue->delete_block(pField); } // 做交换 m_OldTradeList.clear(); m_OldTradeList = m_NewTradeList; m_NewTradeList.clear(); return 0; }