void MYCTPTradeInterface::OnRspQryInstrumentCommissionRate(CThostFtdcInstrumentCommissionRateField *pInstrumentCommissionRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { // 成功了 if (pRspInfo == NULL || pRspInfo->ErrorID == 0) { if (pInstrumentCommissionRate) { MY_LOG_INFO("OnRspQryInstrumentCommissionRate, InstrumentID: %s" "; InvestorRange: %c" "; BrokerID: %s" "; InvestorID: %s" "; OpenRatioByMoney: %.4f" "; OpenRatioByVolume: %.4f" "; CloseRatioByMoney: %.4f" "; CloseRatioByVolume: %.4f" "; CloseTodayRatioByMoney: %.4f" "; CloseTodayRatioByVolume: %.4f", pInstrumentCommissionRate->InstrumentID, pInstrumentCommissionRate->InvestorRange, pInstrumentCommissionRate->BrokerID, pInstrumentCommissionRate->InvestorID, pInstrumentCommissionRate->OpenRatioByMoney, pInstrumentCommissionRate->OpenRatioByVolume, pInstrumentCommissionRate->CloseRatioByMoney, pInstrumentCommissionRate->CloseRatioByVolume, pInstrumentCommissionRate->CloseTodayRatioByMoney, pInstrumentCommissionRate->CloseTodayRatioByVolume ); } else { MY_LOG_ERROR("OnRspQryInstrumentCommissionRate, response info is null."); } } else { MY_LOG_ERROR("OnRspQryInstrumentCommissionRate, ErrorID: %d; ErrorMsg: %s", pRspInfo->ErrorID, pRspInfo->ErrorMsg); } // 查别的 if (bIsLast) { CThostFtdcQryInstrumentField instrument_struct; memset(&instrument_struct, 0, sizeof(instrument_struct)); memcpy(instrument_struct.InstrumentID, "", strlen("")); memcpy(instrument_struct.ExchangeID, "", strlen("")); memcpy(instrument_struct.ExchangeInstID, "", strlen("")); memcpy(instrument_struct.ProductID, "", strlen("")); boost::this_thread::sleep(boost::posix_time::millisec(1000)); // 查询要间隔1s int ret = p_trader_api_->ReqQryInstrument(&instrument_struct, ++nRequestID); MY_LOG_INFO("ReqQryInstrument, return_code: %d", ret); } }
void MYCTPTradeInterface::OnRspQryInstrumentMarginRate(CThostFtdcInstrumentMarginRateField *pInstrumentMarginRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { // 成功了 if (pRspInfo == NULL || pRspInfo->ErrorID == 0) { if (pInstrumentMarginRate) { MY_LOG_INFO("OnRspQryInstrumentMarginRate, InstrumentID: %s; " "InvestorRange: %c; BrokerID: %s; InvestorID: %s; HedgeFlag: %c; " "LongMarginRatioByMoney: %.4f; LongMarginRatioByVolume: %.4f; " "ShortMarginRatioByMoney: %.4f; ShortMarginRatioByVolume: %.4f; IsRelative: %d", pInstrumentMarginRate->InstrumentID, pInstrumentMarginRate->InvestorRange, pInstrumentMarginRate->BrokerID, pInstrumentMarginRate->InvestorID, pInstrumentMarginRate->HedgeFlag, pInstrumentMarginRate->LongMarginRatioByMoney, pInstrumentMarginRate->LongMarginRatioByVolume, pInstrumentMarginRate->ShortMarginRatioByMoney, pInstrumentMarginRate->ShortMarginRatioByVolume, pInstrumentMarginRate->IsRelative ); } else { MY_LOG_INFO("OnRspQryInstrumentMarginRate, response info is null."); } } else { MY_LOG_ERROR("OnRspQryInstrumentMarginRate, ErrorID: %d; ErrorMsg: %s", pRspInfo->ErrorID, pRspInfo->ErrorMsg); } // 查别的 if (bIsLast) { CThostFtdcQryInstrumentCommissionRateField instrument_commission_rate; memset(&instrument_commission_rate, 0, sizeof(instrument_commission_rate)); memcpy(instrument_commission_rate.BrokerID, broker_id_, strlen(broker_id_)); memcpy(instrument_commission_rate.InvestorID, user_, strlen(user_)); memcpy(instrument_commission_rate.InstrumentID, "", strlen("")); boost::this_thread::sleep(boost::posix_time::millisec(1000)); // 查询要间隔1s int ret = p_trader_api_->ReqQryInstrumentCommissionRate(&instrument_commission_rate, ++nRequestID); MY_LOG_INFO("ReqQryInstrumentCommissionRate, return_code: %d", ret); } }
bool IndexDB::get_index( IndexEntry & idx) { MY_LOG_DEBUG("IndexDB::get_index()"); MutexGuard guard(m_mutex); char cmd_buf[512]; int cmd_len = sprintf( cmd_buf, "select * from %s where id=%lu ", m_table.c_str(), idx.m_id ); int qret = mysql_real_query(m_conn, cmd_buf, cmd_len ); if( qret ) { MY_LOG_INFO("IndexDB::get_index() mysql_real_query() failed %s", mysql_error(m_conn) ); return false; } else { MYSQL_RES * result = mysql_store_result(m_conn); MY_LOG_DEBUG("IndexDB::get_index() mysql_store_result() result = %p ", result); if( NULL == result) { MY_LOG_INFO("IndexDB::get_index() mysql_store_result() failed %s", mysql_error(m_conn) ); mysql_free_result(result); return false; } else { MY_LOG_DEBUG("IndexDB::get_index() result is not empty"); MYSQL_ROW row; if( (row = mysql_fetch_row(result))) { size_t * row_len = mysql_fetch_lengths(result); idx.m_offset = strtoul(row[1], NULL, 0); idx.m_length = strtoul(row[2], NULL, 0); memcpy((void *)idx.m_contenthash, (const void *)row[3], row_len[3] ); idx.m_filenum = atoi(row[4]); } mysql_free_result(result); } } MY_LOG_DEBUG("IndexDB::get_index() idx.m_id=%lu, idx.m_offset=%lu, idx.m_length=%lu, idx.m_filenum=%d, hash=%s", idx.m_id, idx.m_offset, idx.m_length, idx.m_filenum, idx.hash_to_hex_string().c_str()); return true; }
bool IndexDB::add_index( const IndexEntry & idx) { MY_LOG_DEBUG("IndexDB::add_index() idx.m_id=%lu, idx.m_offset=%lu, idx.m_length=%lu, idx.m_filenum=%d, hash=%s", idx.m_id, idx.m_offset, idx.m_length, idx.m_filenum, idx.hash_to_hex_string().c_str()); MutexGuard guard(m_mutex); const int len = sizeof(IndexEntry) + sizeof(IndexEntry) +2; char cmd_buf[512]; char escape_buf[len]; mysql_real_escape_string(m_conn, escape_buf, (const char *)idx.m_contenthash, sizeof(idx.m_contenthash) ); int cmd_len = sprintf( cmd_buf, "insert into %s values( %lu, %lu, %lu, '%s', %d)", m_table.c_str(), idx.m_id, idx.m_offset, idx.m_length, escape_buf, idx.m_filenum ); int qret = mysql_real_query( m_conn, cmd_buf, cmd_len); if( qret) { MY_LOG_INFO("IndexDB::add_index() insert failed %s", mysql_error(m_conn) ); return false; } else { return true; } }
void MYCTPTradeInterface::OnRspQryTradingCode(CThostFtdcTradingCodeField *pTradingCode, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { // 成功了 if (pRspInfo == NULL || pRspInfo->ErrorID == 0) { if (pTradingCode) { MY_LOG_INFO("OnRspQryTradingCode, InvestorID: %s; BrokerID: %s; ExchangeID: %s; ClientID: %s; ClientIDType: %c", pTradingCode->InvestorID, pTradingCode->BrokerID, pTradingCode->ExchangeID, pTradingCode->ClientID, pTradingCode->ClientIDType ); } else { MY_LOG_INFO("OnRspQryTradingCode, response info is null."); } } else { MY_LOG_ERROR("OnRspQryTradingCode, ErrorID: %d; ErrorMsg: %s", pRspInfo->ErrorID, pRspInfo->ErrorMsg); } // 查别的 if (bIsLast) { CThostFtdcQryInstrumentMarginRateField instrument_margin_rate; memset(&instrument_margin_rate, 0, sizeof(instrument_margin_rate)); memcpy(instrument_margin_rate.BrokerID, broker_id_, strlen(broker_id_)); memcpy(instrument_margin_rate.InvestorID, user_, strlen(user_)); memcpy(instrument_margin_rate.InstrumentID, "", strlen("")); instrument_margin_rate.HedgeFlag = THOST_FTDC_CIDT_Speculation; boost::this_thread::sleep(boost::posix_time::millisec(1000)); // 查询要间隔1s int ret = p_trader_api_->ReqQryInstrumentMarginRate(&instrument_margin_rate, ++nRequestID); MY_LOG_INFO("ReqQryInstrumentMarginRate, return_code: %d", ret); } }
void MYCTPTradeInterface::OnRspQryBrokerTradingParams(CThostFtdcBrokerTradingParamsField *pBrokerTradingParams, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { // 成功了 if (pRspInfo == NULL || pRspInfo->ErrorID == 0) { if (pBrokerTradingParams) { MY_LOG_INFO("OnRspQryBrokerTradingParams, BrokerID: %s" "; InvestorID: %s" "; MarginPriceType: %c" "; Algorithm: %c" "; AvailIncludeCloseProfit: %c", pBrokerTradingParams->BrokerID, pBrokerTradingParams->InvestorID, pBrokerTradingParams->MarginPriceType, pBrokerTradingParams->Algorithm, pBrokerTradingParams->AvailIncludeCloseProfit ); } else { MY_LOG_ERROR("OnRspQryBrokerTradingParams, response info is null."); } } else { MY_LOG_ERROR("OnRspQryBrokerTradingParams, ErrorID: %d; ErrorMsg: %s", pRspInfo->ErrorID, pRspInfo->ErrorMsg); } // 处理完毕,登出,节约交易连接数 CThostFtdcUserLogoutField user_logout; memset(&user_logout, 0, sizeof(user_logout)); memcpy(user_logout.BrokerID, broker_id_, strlen(broker_id_)); memcpy(user_logout.UserID, user_, strlen(user_)); // 发出登出请求 boost::this_thread::sleep(boost::posix_time::millisec(1000)); // 间隔1s int ret = p_trader_api_->ReqUserLogout(&user_logout, ++nRequestID); MY_LOG_INFO("ReqUserLogout, return_code: %d", ret); }
void MYCTPTradeInterface::OnFrontConnected() { MY_LOG_INFO("CTP-Trade - OnFrontConnected."); // 已经获取合约列表了,无需登录 if (securities_get_finished) { return; } CThostFtdcReqUserLoginField user_logon; memset(&user_logon, 0, sizeof(user_logon)); memcpy(user_logon.BrokerID, broker_id_, strlen(broker_id_)); memcpy(user_logon.UserID, user_, strlen(user_)); memcpy(user_logon.Password, password_, strlen(password_)); // 发出登陆请求 p_trader_api_->ReqUserLogin(&user_logon, 1); MY_LOG_INFO("CTP-Trade - try to login trade server."); }
void MYCTPTradeInterface::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { // 登陆了,则查查信息 if (pRspInfo == NULL || pRspInfo->ErrorID == 0) { MY_LOG_INFO("CTP-Trade - OnRspUserLogin success."); } else { MY_LOG_ERROR("CTP-Trade - OnRspUserLogin, ErrorID: %d; ErrorMsg: %s", pRspInfo->ErrorID, pRspInfo->ErrorMsg); // 登录失败,不断重试 boost::this_thread::sleep(boost::posix_time::millisec(1000)); // 查询要间隔1s CThostFtdcReqUserLoginField user_logon; memset(&user_logon, 0, sizeof(user_logon)); memcpy(user_logon.BrokerID, broker_id_, strlen(broker_id_)); memcpy(user_logon.UserID, user_, strlen(user_)); memcpy(user_logon.Password, password_, strlen(password_)); // 发出登陆请求 p_trader_api_->ReqUserLogin(&user_logon, 1); } if (bIsLast) { // 查询交易编码 CThostFtdcQryTradingCodeField qry_trading_code; memset(&qry_trading_code, 0, sizeof(qry_trading_code)); memcpy(qry_trading_code.BrokerID, broker_id_, strlen(broker_id_)); memcpy(qry_trading_code.InvestorID, user_, strlen(user_)); memcpy(qry_trading_code.ExchangeID, "", strlen("")); memcpy(qry_trading_code.ClientID, user_, strlen(user_)); qry_trading_code.ClientIDType = THOST_FTDC_CIDT_Speculation; boost::this_thread::sleep(boost::posix_time::millisec(1000)); // 查询要间隔1s int ret = p_trader_api_->ReqQryTradingCode(&qry_trading_code, ++nRequestID); MY_LOG_INFO("CTP-Trade - ReqQryTradingCode, return_code: %d", ret); } }
void MYCTPTradeInterface::OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { if (pRspInfo == NULL || pRspInfo->ErrorID == 0) { MY_LOG_INFO("CTP-Trade - OnRspUserLogout success."); securities_get_finished = true; } else { MY_LOG_ERROR("CTP-Trade - OnRspUserLogout, ErrorID: %d; ErrorMsg: %s", pRspInfo->ErrorID, pRspInfo->ErrorMsg); } }
QuoteInterface_TDF::QuoteInterface_TDF(const SubscribeContracts* subscribe_contracts, const ConfigData& cfg) : cfg_(cfg), p_stock_md_save_(NULL), p_stock_idx_save_(NULL) { if (subscribe_contracts) { subscribe_contracts_ = *subscribe_contracts; } InitErrorMap(); sprintf(qtm_name_, "tdf_%s_%u", cfg.Logon_config().account.c_str(), getpid()); QuoteUpdateState(qtm_name_, QtmState::INIT); // create save object p_stock_md_save_ = new QuoteDataSave<TDF_MARKET_DATA_MY>(cfg_, qtm_name_, "tdf_market_data", TDF_STOCK_QUOTE_TYPE); p_stock_idx_save_ = new QuoteDataSave<TDF_INDEX_DATA_MY>(cfg_, qtm_name_, "tdf_index_data", TDF_INDEX_QUOTE_TYPE); p_stock_oq_save_ = new QuoteDataSave<T_OrderQueue>(cfg_, qtm_name_, "order_queue_data", KMDS_ORDER_QUEUE_TYPE); p_stock_pe_save_ = new QuoteDataSave<T_PerEntrust>(cfg_, qtm_name_, "per_entrust_data", KMDS_PER_ENTRUST_TYPE); p_stock_pb_save_ = new QuoteDataSave<T_PerBargain>(cfg_, qtm_name_, "per_bargain_data", KMDS_PER_BARGAIN_TYPE); s_p_stock_md_save = p_stock_md_save_; s_p_stock_idx_save = p_stock_idx_save_; s_p_stock_oq_save = p_stock_oq_save_; s_p_stock_pe_save = p_stock_pe_save_; s_p_stock_pb_save = p_stock_pb_save_; // environment settings //TDF_SetEnv(TDF_ENVIRON_HEART_BEAT_INTERVAL, 10); //TDF_SetEnv(TDF_ENVIRON_MISSED_BEART_COUNT, 2); //TDF_SetEnv(TDF_ENVIRON_OPEN_TIME_OUT, 30); // quote connection settings open_settings = new TDF_OPEN_SETTING(); InitOpenSetting(open_settings, cfg); TDF_ERR nErr = TDF_ERR_SUCCESS; g_hTDF = TDF_Open(open_settings, &nErr); // try till open success while (nErr == TDF_ERR_NETWORK_ERROR || g_hTDF == NULL) { MY_LOG_ERROR("TDF_Open returned: %s; try again.", GetErrStr(nErr)); QuoteUpdateState(qtm_name_, QtmState::CONNECT_FAIL); sleep(3); g_hTDF = TDF_Open(open_settings, &nErr); } MY_LOG_INFO("TDF_Open success."); QuoteUpdateState(qtm_name_, QtmState::CONNECT_SUCCESS); QuoteUpdateState(qtm_name_, QtmState::API_READY); }
bool FileMgr::get_page( const IndexEntry & idx, Page & page ) { MY_LOG_DEBUG("FileMgr::get_page() %ld", idx.m_id); MutexGuard guard(m_mutex); int num = idx.m_filenum; if( num <= m_lastFileNum && num >=0 ) { std::unique_ptr<char> p( new char [ idx.m_length] ); if( !p ) { MY_LOG_ERROR("unique_ptr"); } m_fileStream[num].clear(); m_fileStream[num].seekg( idx.m_offset , std::ios::beg); m_fileStream[num].read( p.get(), idx.m_length ); if( m_fileStream[num]) { std::string tmp( p.get(), idx.m_length ); Page pg(tmp); std::string hash = pg.get_hash(); if( 0 == memcmp( idx.m_contenthash, hash.c_str(), hash.size() )) { page = pg; return true; } IndexEntry idx2; memcpy((void *)idx.m_contenthash, (const void *)hash.c_str(), hash.size()); std::string hashstr1 = idx.hash_to_hex_string(); std::string hashstr2 = idx2.hash_to_hex_string(); MY_LOG_INFO("FileMgr::get_page() %ld hash not match {hash1:%s hash2:%s}, tmp={%s}\npage.m_content={%s}", idx.m_id, hashstr1.c_str(), hashstr2.c_str(), tmp.c_str(), page.m_content.c_str()); } } MY_LOG_DEBUG("FileMgr::get_page() %lu failed!", idx.m_id); return false; }
void MYCTPTradeInterface::OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { // 成功了 if (pRspInfo == NULL || pRspInfo->ErrorID == 0) { if (pInstrument) { MY_LOG_INFO("OnRspQryInstrument, InstrumentID: %s" "; ExchangeID: %s" "; InstrumentName: %s" "; ExchangeInstID: %s" "; ProductID: %s" "; ProductClass: %c" "; DeliveryYear: %08d" "; DeliveryMonth: %02d" "; MaxMarketOrderVolume: %d" "; MinMarketOrderVolume: %d" "; MaxLimitOrderVolume: %d" "; MinLimitOrderVolume: %d" "; VolumeMultiple: %d" "; PriceTick: %0.4f" "; CreateDate: %s" "; OpenDate: %s" "; ExpireDate: %s" "; StartDelivDate: %s" "; EndDelivDate: %s" "; InstLifePhase: %c" "; IsTrading: %d" "; PositionType: %c" "; PositionDateType: %c" "; LongMarginRatio: %0.4f" "; ShortMarginRatio: %.4f", pInstrument->InstrumentID, pInstrument->ExchangeID, pInstrument->InstrumentName, pInstrument->ExchangeInstID, pInstrument->ProductID, pInstrument->ProductClass, pInstrument->DeliveryYear, pInstrument->DeliveryMonth, pInstrument->MaxMarketOrderVolume, pInstrument->MinMarketOrderVolume, pInstrument->MaxLimitOrderVolume, pInstrument->MinLimitOrderVolume, pInstrument->VolumeMultiple, pInstrument->PriceTick, pInstrument->CreateDate, pInstrument->OpenDate, pInstrument->ExpireDate, pInstrument->StartDelivDate, pInstrument->EndDelivDate, pInstrument->InstLifePhase, pInstrument->IsTrading, pInstrument->PositionType, pInstrument->PositionDateType, InvalidToZeroD(pInstrument->LongMarginRatio), InvalidToZeroD(pInstrument->ShortMarginRatio) ); securities_exchcode.insert(std::make_pair(pInstrument->InstrumentID, ExchNameToExchCode(pInstrument->ExchangeID))); securities_volumn_multiple.insert(std::make_pair(pInstrument->InstrumentID, pInstrument->VolumeMultiple)); securities_tickprice.insert(std::make_pair(pInstrument->InstrumentID, pInstrument->PriceTick)); } else { MY_LOG_ERROR("OnRspQryInstrument, response info is null."); } } else { MY_LOG_ERROR("OnRspQryInstrument, ErrorID: %d; ErrorMsg: %s", pRspInfo->ErrorID, pRspInfo->ErrorMsg); } // 查别的 if (bIsLast) { MY_LOG_INFO("OnRspQryInstrument, task finished."); CThostFtdcQryBrokerTradingParamsField broker_param; memset(&broker_param, 0, sizeof(broker_param)); memcpy(broker_param.BrokerID, broker_id_, strlen(broker_id_)); memcpy(broker_param.InvestorID, user_, strlen(user_)); boost::this_thread::sleep(boost::posix_time::millisec(1000)); // 查询要间隔1s int ret = p_trader_api_->ReqQryBrokerTradingParams(&broker_param, ++nRequestID); MY_LOG_INFO("ReqQryBrokerTradingParams, return_code: %d", ret); } }
//系统消息回调,用于通知用户收到了网络断开事件、连接(重连)结果、代码表结果等。 //当获取系统消息时,pMsgHead->pAppHead指针为空, //pMsgHead->pData指向相应的结构体 void QuoteInterface_TDF::SystemMsgHandler(THANDLE hTdf, TDF_MSG* pMsgHead) { if (!pMsgHead || !hTdf) { return; } switch (pMsgHead->nDataType) { case MSG_SYS_DISCONNECT_NETWORK: { MY_LOG_INFO("network disconnected."); QuoteUpdateState(qtm_name_, QtmState::DISCONNECT); } break; case MSG_SYS_CONNECT_RESULT: { TDF_CONNECT_RESULT* pConnResult = (TDF_CONNECT_RESULT*) pMsgHead->pData; if (pConnResult && pConnResult->nConnResult) { MY_LOG_INFO("TDF - connect success."); QuoteUpdateState(qtm_name_, QtmState::CONNECT_SUCCESS); } else { MY_LOG_ERROR("TDF - connect failed."); QuoteUpdateState(qtm_name_, QtmState::CONNECT_FAIL); } } break; case MSG_SYS_LOGIN_RESULT: { TDF_LOGIN_RESULT* pLoginResult = (TDF_LOGIN_RESULT*) pMsgHead->pData; if (pLoginResult && pLoginResult->nLoginResult) { MY_LOG_INFO("TDF - login success."); QuoteUpdateState(qtm_name_, QtmState::LOG_ON_SUCCESS); for (int i = 0; i < pLoginResult->nMarkets; i++) { MY_LOG_INFO("market: %s, dyn_date: %d", pLoginResult->szMarket[i], pLoginResult->nDynDate[i]); } } else { MY_LOG_ERROR("TDF - login failed."); QuoteUpdateState(qtm_name_, QtmState::LOG_ON_FAIL); } } break; case MSG_SYS_CODETABLE_RESULT: { TDF_CODE_RESULT* pCodeResult = (TDF_CODE_RESULT*) pMsgHead->pData; MY_LOG_INFO("code table: %s; market count: %d", pCodeResult->szInfo, pCodeResult->nMarkets); for (int i = 0; i < pCodeResult->nMarkets; i++) { MY_LOG_INFO("market: %s; items: %d; date: %d", pCodeResult->szMarket[i], pCodeResult->nCodeCount[i], pCodeResult->nCodeDate[i]); //获取代码表 TDF_CODE* pCodeTable; unsigned int nItems; TDF_GetCodeTable(hTdf, pCodeResult->szMarket[i], &pCodeTable, &nItems); for (unsigned int i = 0; i < nItems; i++) { TDF_CODE& code = pCodeTable[i]; MY_LOG_INFO("code: %s; market: %s; type: %d", code.szCode, code.szMarket, code.nType); } TDF_FreeArr(pCodeTable); } } break; case MSG_SYS_QUOTATIONDATE_CHANGE: { TDF_QUOTATIONDATE_CHANGE* pChange = (TDF_QUOTATIONDATE_CHANGE*) pMsgHead->pData; if (pChange) { MY_LOG_INFO("date changed, prepare reconnect."); } } break; case MSG_SYS_MARKET_CLOSE: { TDF_MARKET_CLOSE* pCloseInfo = (TDF_MARKET_CLOSE*) pMsgHead->pData; if (pCloseInfo) { MY_LOG_INFO("close market: %s; time: %d", pCloseInfo->szMarket, pCloseInfo->nTime); } } break; case MSG_SYS_HEART_BEAT: { MY_LOG_INFO("TDF - heart beat."); } break; default: break; } }