void CTraderApi::OnFrontConnected() { XRespone(ResponeType::OnConnectionStatus, m_msgQueue, this, ConnectionStatus::Connected, 0, nullptr, 0, nullptr, 0, nullptr, 0); //连接成功后自动请求认证或登录 //if(m_szAuthCode.length()>0 // &&m_szUserProductInfo.length()>0) //{ // //填了认证码就先认证 // ReqAuthenticate(); //} //else { ReqUserLogin(); } }
void CTraderApi::OnFrontConnected() { XRespone(ResponeType::OnConnectionStatus, m_msgQueue, this, ConnectionStatus::Connected, 0, nullptr, 0, nullptr, 0, nullptr, 0); ////连接成功后自动请求认证或登录 //if (strlen(m_ServerInfo.AuthCode)>0 // && strlen(m_ServerInfo.UserProductInfo)>0) //{ // //填了认证码就先认证 // ReqAuthenticate(); //} //else //{ ReqUserLogin(); //} }
void CTraderApi::OnTrade(CSecurityFtdcTradeField *pTrade, bool bFromQry) { if (nullptr == pTrade) return; TradeField* pField = new TradeField(); strncpy(pField->InstrumentID, pTrade->InstrumentID, sizeof(TSecurityFtdcInstrumentIDType)); strncpy(pField->ExchangeID, pTrade->ExchangeID, sizeof(TSecurityFtdcExchangeIDType)); pField->Side = TSecurityFtdcDirectionType_2_OrderSide(pTrade->Direction); pField->Qty = pTrade->Volume; pField->Price = atof(pTrade->Price); pField->OpenClose = TSecurityFtdcOffsetFlagType_2_OpenCloseType(pTrade->OffsetFlag); pField->HedgeFlag = TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pTrade->HedgeFlag); pField->Commission = 0;//TODO收续费以后要计算出来 strncpy(pField->Time, pTrade->TradeTime, sizeof(TSecurityFtdcTimeType)); strcpy(pField->TradeID, pTrade->TradeID); OrderIDType orderSysId = { 0 }; sprintf(orderSysId, "%s:%s", pTrade->ExchangeID, pTrade->OrderSysID); unordered_map<string, string>::iterator it = m_sysId_orderId.find(orderSysId); if (it == m_sysId_orderId.end()) { // 此成交找不到对应的报单 assert(false); } else { // 找到对应的报单 strcpy(pField->ID, it->second.c_str()); XRespone(ResponeType::OnRtnTrade, m_msgQueue, this, 0, 0, pField, sizeof(TradeField), nullptr, 0, nullptr, 0); unordered_map<string, OrderField*>::iterator it2 = m_id_platform_order.find(it->second); if (it2 == m_id_platform_order.end()) { // 此成交找不到对应的报单 assert(false); } else { // 更新订单的状态 // 是否要通知接口 } OnTrade(pField, bFromQry); } }
void CTraderApi::ReqQryUserInvestor() { if (nullptr == m_pApi) return; SRequest* pRequest = MakeRequestBuf(E_QryUserInvestorField); if (pRequest) { XRespone(ResponeType::OnConnectionStatus, m_msgQueue, this, ConnectionStatus::Doing, 0, nullptr, 0, nullptr, 0, nullptr, 0); CUstpFtdcQryUserInvestorField& body = pRequest->QryUserInvestorField; strncpy(body.BrokerID, m_ServerInfo.BrokerID, sizeof(TUstpFtdcBrokerIDType)); strncpy(body.UserID, m_UserInfo.UserID, sizeof(TUstpFtdcInvestorIDType)); AddToSendQueue(pRequest); } }
void CTraderApi::Disconnect() { // 如果队列中有请求包,在后面又进行了Release,又回过头来发送,可能导致当了 StopThread(); if(m_pApi) { m_pApi->RegisterSpi(nullptr); m_pApi->Release(); m_pApi = nullptr; XRespone(ResponeType::OnConnectionStatus, m_msgQueue, this, ConnectionStatus::Disconnected, 0, nullptr, 0, nullptr, 0, nullptr, 0); } m_lRequestID = 0;//由于线程已经停止,没有必要用原子操作了 ReleaseRequestListBuf(); ReleaseRequestMapBuf(); }
void CTraderApi::ReqUserLogin() { if (nullptr == m_pApi) return; SRequest* pRequest = MakeRequestBuf(E_ReqUserLoginField); if (pRequest) { XRespone(ResponeType::OnConnectionStatus, m_msgQueue, this, ConnectionStatus::Logining, 0, nullptr, 0, nullptr, 0, nullptr, 0); CThostFtdcReqUserLoginField& body = pRequest->ReqUserLoginField; strncpy(body.accountID, m_UserInfo.UserID, sizeof(TThostFtdcTraderIDType)); strncpy(body.password, m_UserInfo.Password, sizeof(TThostFtdcPasswordType)); body.loginType = BANKACC_TYPE; AddToSendQueue(pRequest); } }
void CTraderApi::ReqUserLogin() { if (nullptr == m_pApi) return; SRequest* pRequest = MakeRequestBuf(E_ReqUserLoginField); if (pRequest) { XRespone(ResponeType::OnConnectionStatus, m_msgQueue, this, ConnectionStatus::Logining, 0, nullptr, 0, nullptr, 0, nullptr, 0); CUstpFtdcReqUserLoginField& body = pRequest->ReqUserLoginField; strncpy(body.UserID, m_UserInfo.UserID, sizeof(TUstpFtdcInvestorIDType)); strncpy(body.BrokerID, m_ServerInfo.BrokerID, sizeof(TUstpFtdcBrokerIDType)); strncpy(body.Password, m_UserInfo.Password, sizeof(TUstpFtdcPasswordType)); strncpy(body.UserProductInfo, m_ServerInfo.UserProductInfo, sizeof(TUstpFtdcProductInfoType)); AddToSendQueue(pRequest); } }
void CTraderApi::OnErrRtnOrderAction(CSecurityFtdcOrderActionField *pOrderAction, CSecurityFtdcRspInfoField *pRspInfo) { OrderIDType orderId = { 0 }; sprintf(orderId, "%d:%d:%s", pOrderAction->FrontID, pOrderAction->SessionID, pOrderAction->OrderRef); unordered_map<string, OrderField*>::iterator it = m_id_platform_order.find(orderId); if (it == m_id_platform_order.end()) { // 没找到?不应当,这表示出错了 assert(false); } else { // 找到了,要更新状态 // 得使用上次的状态 OrderField* pField = it->second; pField->ExecType = ExecType::ExecCancelReject; pField->ErrorID = pRspInfo->ErrorID; strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(TSecurityFtdcErrorMsgType)); XRespone(ResponeType::OnRtnOrder, m_msgQueue, this, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); } }
void CTraderApi::OnErrRtnQuoteInsert(CUstpFtdcInputQuoteField *pInputQuote, CUstpFtdcRspInfoField *pRspInfo) { OrderIDType quoteId = { 0 }; sprintf(quoteId, "%s:%s", m_RspUserLogin__.SessionID, pInputQuote->UserQuoteLocalID); unordered_map<string, QuoteField*>::iterator it = m_id_platform_quote.find(quoteId); if (it == m_id_platform_quote.end()) { // 没找到?不应当,这表示出错了 assert(false); } else { QuoteField* pField = it->second; //strcpy(pField->ID, quoteId); pField->ExecType = ExecType::ExecRejected; pField->Status = OrderStatus::Rejected; pField->ErrorID = pRspInfo->ErrorID; strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(TUstpFtdcErrorMsgType)); strcat(pField->Text, "OnErrRtnQuoteInsert"); XRespone(ResponeType::OnRtnQuote, m_msgQueue, this, 0, 0, pField, sizeof(QuoteField), nullptr, 0, nullptr, 0); } }
void CTraderApi::OnErrRtnOrderInsert(CUstpFtdcInputOrderField *pInputOrder, CUstpFtdcRspInfoField *pRspInfo) { OrderIDType orderId = { 0 }; sprintf(orderId, "%s:%s", m_RspUserLogin__.SessionID, pInputOrder->UserOrderLocalID); unordered_map<string, OrderField*>::iterator it = m_id_platform_order.find(orderId); if (it == m_id_platform_order.end()) { // 没找到?不应当,这表示出错了 assert(false); } else { // 找到了,要更新状态 // 得使用上次的状态 OrderField* pField = it->second; pField->ExecType = ExecType::ExecRejected; pField->Status = OrderStatus::Rejected; pField->ErrorID = pRspInfo->ErrorID; strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(TUstpFtdcErrorMsgType)); strcat(pField->Text, "OnErrRtnOrderInsert"); XRespone(ResponeType::OnRtnOrder, m_msgQueue, this, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); } }
void CTraderApi::OnRspOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { OrderIDType orderId = { 0 }; sprintf(orderId, "%d:%d:%s", m_RspUserLogin.FrontID, m_RspUserLogin.SessionID, pInputOrder->OrderRef); unordered_map<string, OrderField*>::iterator it = m_id_platform_order.find(orderId); if (it == m_id_platform_order.end()) { // 没找到?不应当,这表示出错了 assert(false); } else { // 找到了,要更新状态 // 得使用上次的状态 OrderField* pField = it->second; strcpy(pField->ID, orderId); pField->ExecType = ExecType::ExecRejected; pField->Status = OrderStatus::Rejected; pField->ErrorID = pRspInfo->ErrorID; strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(TSecurityFtdcErrorMsgType)); XRespone(ResponeType::OnRtnOrder, m_msgQueue, this, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); } }
void CTraderApi::OnFrontConnected() { XRespone(ResponeType::OnConnectionStatus, m_msgQueue, this, ConnectionStatus::Connected, 0, nullptr, 0, nullptr, 0, nullptr, 0); ReqUserLogin(); }
void CTraderApi::OnQuote(CUstpFtdcRtnQuoteField *pQuote) { if (nullptr == pQuote) return; OrderIDType quoteId = { 0 }; sprintf(quoteId, "%s:%s", m_RspUserLogin__.SessionID, pQuote->UserQuoteLocalID); OrderIDType orderSydId = { 0 }; { // 保存原始订单信息,用于撤单 unordered_map<string, CUstpFtdcRtnQuoteField*>::iterator it = m_id_api_quote.find(quoteId); if (it == m_id_api_quote.end()) { // 找不到此订单,表示是新单 CUstpFtdcRtnQuoteField* pField = new CUstpFtdcRtnQuoteField(); memcpy(pField, pQuote, sizeof(CUstpFtdcRtnQuoteField)); m_id_api_quote.insert(pair<string, CUstpFtdcRtnQuoteField*>(quoteId, pField)); } else { // 找到了订单 // 需要再复制保存最后一次的状态,还是只要第一次的用于撤单即可?记下,这样最后好比较 CUstpFtdcRtnQuoteField* pField = it->second; memcpy(pField, pQuote, sizeof(CUstpFtdcRtnQuoteField)); } // 这个地方是否要进行其它处理? // 保存SysID用于定义成交回报与订单 //sprintf(orderSydId, "%s:%s", pQuote->ExchangeID, pQuote->QuoteSysID); //m_sysId_quoteId.insert(pair<string, string>(orderSydId, quoteId)); } { // 从API的订单转换成自己的结构体 QuoteField* pField = nullptr; unordered_map<string, QuoteField*>::iterator it = m_id_platform_quote.find(quoteId); if (it == m_id_platform_quote.end()) { // 开盘时发单信息还没有,所以找不到对应的单子,需要进行Order的恢复 pField = new QuoteField(); memset(pField, 0, sizeof(QuoteField)); strcpy(pField->InstrumentID, pQuote->InstrumentID); strcpy(pField->ExchangeID, pQuote->ExchangeID); pField->AskQty = pQuote->AskVolume; pField->AskPrice = pQuote->AskPrice; pField->AskOpenClose = TUstpFtdcOffsetFlagType_2_OpenCloseType(pQuote->AskOffsetFlag); pField->AskHedgeFlag = TUstpFtdcHedgeFlagType_2_HedgeFlagType(pQuote->AskHedgeFlag); pField->BidQty = pQuote->BidVolume; pField->BidPrice = pQuote->BidPrice; pField->BidOpenClose = TUstpFtdcOffsetFlagType_2_OpenCloseType(pQuote->BidOffsetFlag); pField->BidHedgeFlag = TUstpFtdcHedgeFlagType_2_HedgeFlagType(pQuote->BidHedgeFlag); strcpy(pField->ID, quoteId); strcpy(pField->AskOrderID, pQuote->AskOrderSysID); strcpy(pField->BidOrderID, pQuote->BidOrderSysID); //strncpy(pField->Text, pQuote->, sizeof(TThostFtdcErrorMsgType)); //pField->ExecType = ExecType::ExecNew; pField->Status = CUstpFtdcRtnQuoteField_2_OrderStatus(pQuote); pField->ExecType = ExecType::ExecNew; // 添加到map中,用于其它工具的读取,撤单失败时的再通知等 m_id_platform_quote.insert(pair<string, QuoteField*>(quoteId, pField)); } else { pField = it->second; strcpy(pField->ID, quoteId); strcpy(pField->AskOrderID, pQuote->AskOrderSysID); strcpy(pField->BidOrderID, pQuote->BidOrderSysID); pField->Status = CUstpFtdcRtnQuoteField_2_OrderStatus(pQuote); pField->ExecType = CUstpFtdcRtnQuoteField_2_ExecType(pQuote); } XRespone(ResponeType::OnRtnQuote, m_msgQueue, this, 0, 0, pField, sizeof(QuoteField), nullptr, 0, nullptr, 0); } }
void CTraderApi::OnOrder(CUstpFtdcOrderField *pOrder) { if (nullptr == pOrder) return; OrderIDType orderId = { 0 }; sprintf(orderId, "%s:%s", m_RspUserLogin__.SessionID, pOrder->UserOrderLocalID); //OrderIDType orderSydId = { 0 }; { // 保存原始订单信息,用于撤单 unordered_map<string, CUstpFtdcOrderField*>::iterator it = m_id_api_order.find(orderId); if (it == m_id_api_order.end()) { // 找不到此订单,表示是新单 CUstpFtdcOrderField* pField = new CUstpFtdcOrderField(); memcpy(pField, pOrder, sizeof(CUstpFtdcOrderField)); m_id_api_order.insert(pair<string, CUstpFtdcOrderField*>(orderId, pField)); } else { // 找到了订单 // 需要再复制保存最后一次的状态,还是只要第一次的用于撤单即可?记下,这样最后好比较 CUstpFtdcOrderField* pField = it->second; memcpy(pField, pOrder, sizeof(CUstpFtdcOrderField)); } //// 保存SysID用于定义成交回报与订单 //sprintf(orderSydId, "%s:%s", pOrder->ExchangeID, pOrder->OrderSysID); //m_sysId_orderId.insert(pair<string, string>(orderSydId, orderId)); } { // 从API的订单转换成自己的结构体 OrderField* pField = nullptr; unordered_map<string, OrderField*>::iterator it = m_id_platform_order.find(orderId); if (it == m_id_platform_order.end()) { // 开盘时发单信息还没有,所以找不到对应的单子,需要进行Order的恢复 pField = new OrderField(); memset(pField, 0, sizeof(OrderField)); strcpy(pField->ID, orderId); strcpy(pField->InstrumentID, pOrder->InstrumentID); strcpy(pField->ExchangeID, pOrder->ExchangeID); pField->HedgeFlag = TUstpFtdcHedgeFlagType_2_HedgeFlagType(pOrder->HedgeFlag); pField->Side = TUstpFtdcDirectionType_2_OrderSide(pOrder->Direction); pField->Price = pOrder->LimitPrice; pField->StopPx = pOrder->StopPrice; //strcpy(pField->Text, pOrder->StatusMsg); pField->OpenClose = TUstpFtdcOffsetFlagType_2_OpenCloseType(pOrder->OffsetFlag); pField->Status = CUstpFtdcOrderField_2_OrderStatus(pOrder); pField->Qty = pOrder->Volume; pField->Type = CUstpFtdcOrderField_2_OrderType(pOrder); pField->TimeInForce = CUstpFtdcOrderField_2_TimeInForce(pOrder); pField->ExecType = ExecType::ExecNew; strcpy(pField->OrderID, pOrder->OrderSysID); strcat(pField->Text, "OnRtnOrder"); // 添加到map中,用于其它工具的读取,撤单失败时的再通知等 m_id_platform_order.insert(pair<string, OrderField*>(orderId, pField)); } else { pField = it->second; strcpy(pField->ID, orderId); pField->LeavesQty = pOrder->VolumeRemain; pField->Price = pOrder->LimitPrice; pField->Status = CUstpFtdcOrderField_2_OrderStatus(pOrder); pField->ExecType = CUstpFtdcOrderField_2_ExecType(pOrder); strcpy(pField->OrderID, pOrder->OrderSysID); strcat(pField->Text, "OnRtnOrder"); } XRespone(ResponeType::OnRtnOrder, m_msgQueue, this, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); } }