// 国债逆回购,持仓是Net,我归类到了Long中,如果我直接从成交中分析出来的又归到了Net中 // 所有开平和投保类型都是空 void CTraderApi::OnRspQryInvestorPosition(CSecurityFtdcInvestorPositionField *pInvestorPosition, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) { if (pInvestorPosition) { PositionIDType positionId = { 0 }; sprintf(positionId, "%s:%s:%d:%d", pInvestorPosition->InstrumentID, pInvestorPosition->ExchangeID, TSecurityFtdcPosiDirectionType_2_PositionSide(pInvestorPosition->PosiDirection), TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pInvestorPosition->HedgeFlag)); PositionField* pField = nullptr; unordered_map<string, PositionField*>::iterator it = m_id_platform_position.find(positionId); if (it == m_id_platform_position.end()) { pField = new PositionField(); memset(pField, 0, sizeof(PositionField)); strcpy(pField->InstrumentID, pInvestorPosition->InstrumentID); strcpy(pField->ExchangeID, pInvestorPosition->ExchangeID); pField->Side = TSecurityFtdcPosiDirectionType_2_PositionSide(pInvestorPosition->PosiDirection); pField->HedgeFlag = TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pInvestorPosition->HedgeFlag); m_id_platform_position.insert(pair<string, PositionField*>(positionId, pField)); } else { pField = it->second; } pField->Position = pInvestorPosition->Position; pField->TdPosition = pInvestorPosition->TodayPosition; pField->YdPosition = pInvestorPosition->YdPosition; // 等数据收集全了再遍历通知一次 if (bIsLast) { int cnt = 0; int count = m_id_platform_position.size(); for (unordered_map<string, PositionField*>::iterator iter = m_id_platform_position.begin(); iter != m_id_platform_position.end(); iter++) { ++cnt; XRespone(ResponeType::OnRspQryInvestorPosition, m_msgQueue, this, cnt == count, 0, iter->second, sizeof(PositionField), nullptr, 0, nullptr, 0); } } } } if (bIsLast) ReleaseRequestMapBuf(nRequestID); }
void CTraderApi::OnTrade(TradeField *pTrade, bool bFromQry) { PositionIDType positionId = { 0 }; sprintf(positionId, "%s:%s:%d:%d", pTrade->InstrumentID, pTrade->ExchangeID, TradeField_2_PositionSide(pTrade), pTrade->HedgeFlag); PositionField* pField = nullptr; unordered_map<string, PositionField*>::iterator it = m_id_platform_position.find(positionId); if (it == m_id_platform_position.end()) { pField = new PositionField(); memset(pField, 0, sizeof(PositionField)); strcpy(pField->InstrumentID, pTrade->InstrumentID); strcpy(pField->ExchangeID, pTrade->ExchangeID); pField->Side = TradeField_2_PositionSide(pTrade); pField->HedgeFlag = TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pTrade->HedgeFlag); m_id_platform_position.insert(pair<string, PositionField*>(positionId, pField)); } else { pField = it->second; } if (pTrade->Side == OrderSide::Buy) { pField->Position += pTrade->Qty; pField->TdPosition += pTrade->Qty; } else { pField->Position -= pTrade->Qty; if (pTrade->OpenClose == OpenCloseType::CloseToday) { pField->TdPosition -= pTrade->Qty; } else { pField->YdPosition -= pTrade->Qty; // 如果昨天的被减成负数,从今天开始继续减 if (pField->YdPosition<0) { pField->TdPosition += pField->YdPosition; pField->YdPosition = 0; } } // 计算错误,直接重新查询 if (pField->Position < 0 || pField->TdPosition < 0 || pField->YdPosition < 0) { ReqQryInvestorPosition("", ""); return; } } XRespone(ResponeType::OnRspQryInvestorPosition, m_msgQueue, this, false, 0, pField, sizeof(PositionField), nullptr, 0, nullptr, 0); }
void CTraderApi::OnTrade(TradeField *pTrade) { PositionIDType positionId = { 0 }; sprintf(positionId, "%s:%s:%d:%d", pTrade->InstrumentID, pTrade->ExchangeID, TradeField_2_PositionSide(pTrade), pTrade->HedgeFlag); PositionField* pField = nullptr; unordered_map<string, PositionField*>::iterator it = m_id_platform_position.find(positionId); if (it == m_id_platform_position.end()) { pField = (PositionField*)m_msgQueue->new_block(sizeof(PositionField)); sprintf(pField->Symbol, "%s.%s", pTrade->InstrumentID, pTrade->ExchangeID); strcpy(pField->InstrumentID, pTrade->InstrumentID); strcpy(pField->ExchangeID, pTrade->ExchangeID); pField->Side = TradeField_2_PositionSide(pTrade); pField->HedgeFlag = TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pTrade->HedgeFlag); m_id_platform_position.insert(pair<string, PositionField*>(positionId, pField)); } else { pField = it->second; } if (pTrade->Side == OrderSide::OrderSide_Buy) { pField->Position += pTrade->Qty; pField->TodayPosition += pTrade->Qty; } else { pField->Position -= pTrade->Qty; if (pTrade->OpenClose == OpenCloseType::OpenCloseType_CloseToday) { pField->TodayPosition -= pTrade->Qty; } else { pField->HistoryPosition -= pTrade->Qty; // 如果昨天的被减成负数,从今天开始继续减 if (pField->HistoryPosition<0) { pField->TodayPosition += pField->HistoryPosition; pField->HistoryPosition = 0; } } // 计算错误,直接重新查询 //if (pField->Position < 0 || pField->TdPosition < 0 || pField->YdPosition < 0) //{ // ReqQryInvestorPosition("", ""); // return; //} } m_msgQueue->Input_Copy(ResponeType::ResponeType_OnRspQryInvestorPosition, m_msgQueue, m_pClass, false, 0, pField, sizeof(PositionField), nullptr, 0, nullptr, 0); }
void CTraderApi::OnTrade(CSecurityFtdcTradeField *pTrade, int nRequestID, bool bIsLast) { if (nullptr == pTrade) return; TradeField* pField = (TradeField*)m_msgQueue->new_block(sizeof(TradeField)); strcpy(pField->InstrumentID, pTrade->InstrumentID); strcpy(pField->ExchangeID, pTrade->ExchangeID); 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收续费以后要计算出来 pField->Time = GetTime(pTrade->TradeTime); strcpy(pField->TradeID, pTrade->TradeID); if (nRequestID == 0) { 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()); m_msgQueue->Input_Copy(ResponeType::ResponeType_OnRtnTrade, m_msgQueue, m_pClass, 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); } } else { m_msgQueue->Input_Copy(ResponeType::ResponeType_OnRspQryTrade, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(TradeField), nullptr, 0, nullptr, 0); } // 清理内存 m_msgQueue->delete_block(pField); }
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::OnOrder(CSecurityFtdcOrderField *pOrder, bool bFromQry) { if (nullptr == pOrder) return; OrderIDType orderId = { 0 }; sprintf(orderId, "%d:%d:%s", pOrder->FrontID, pOrder->SessionID, pOrder->OrderRef); OrderIDType orderSydId = { 0 }; { // 保存原始订单信息,用于撤单 unordered_map<string, CSecurityFtdcOrderField*>::iterator it = m_id_api_order.find(orderId); if (it == m_id_api_order.end()) { // 找不到此订单,表示是新单 CSecurityFtdcOrderField* pField = new CSecurityFtdcOrderField(); memcpy(pField, pOrder, sizeof(CSecurityFtdcOrderField)); m_id_api_order.insert(pair<string, CSecurityFtdcOrderField*>(orderId, pField)); } else { // 找到了订单 // 需要再复制保存最后一次的状态,还是只要第一次的用于撤单即可?记下,这样最后好比较 CSecurityFtdcOrderField* pField = it->second; memcpy(pField, pOrder, sizeof(CSecurityFtdcOrderField)); } // 保存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); strncpy(pField->InstrumentID, pOrder->InstrumentID, sizeof(TSecurityFtdcInstrumentIDType)); strncpy(pField->ExchangeID, pOrder->ExchangeID, sizeof(TSecurityFtdcExchangeIDType)); pField->HedgeFlag = TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pOrder->CombHedgeFlag[0]); pField->Side = TSecurityFtdcDirectionType_2_OrderSide(pOrder->Direction); pField->Price = atof(pOrder->LimitPrice); pField->StopPx = pOrder->StopPrice; strncpy(pField->Text, pOrder->StatusMsg, sizeof(TSecurityFtdcErrorMsgType)); pField->OpenClose = TSecurityFtdcOffsetFlagType_2_OpenCloseType(pOrder->CombOffsetFlag[0]); pField->Status = CSecurityFtdcOrderField_2_OrderStatus(pOrder); pField->Qty = pOrder->VolumeTotalOriginal; pField->Type = CSecurityFtdcOrderField_2_OrderType(pOrder); pField->TimeInForce = CSecurityFtdcOrderField_2_TimeInForce(pOrder); pField->ExecType = ExecType::ExecNew; strcpy(pField->OrderID, pOrder->OrderSysID); // 添加到map中,用于其它工具的读取,撤单失败时的再通知等 m_id_platform_order.insert(pair<string, OrderField*>(orderId, pField)); } else { pField = it->second; strcpy(pField->ID, orderId); pField->LeavesQty = pOrder->VolumeTotal; pField->Price = atof(pOrder->LimitPrice); pField->Status = CSecurityFtdcOrderField_2_OrderStatus(pOrder); pField->ExecType = CSecurityFtdcOrderField_2_ExecType(pOrder); strcpy(pField->OrderID, pOrder->OrderSysID); strncpy(pField->Text, pOrder->StatusMsg, sizeof(TSecurityFtdcErrorMsgType)); } XRespone(ResponeType::OnRtnOrder, m_msgQueue, this, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); } }